Yo estoy usando esta función para resolver el problema, pero no tiene ninguna fuente/referencia (¿tiene? por favor, informar a la publicación de un comentario)... Así que, he publicado también demostraciones y pruebas.
CREATE FUNCTION pointbuffer_width(g geometry, N integer DEFAULT 8) RETURNS float AS $$
-- Returns the value of W in the approximation "g ~ ST_Buffer(ST_Centroid(g),W,'quad_segs=N')"
-- where N>0 indicates the reference-shape, 1=square, 2=heptagon, ... circle.
--
SELECT sqrt( area/(0.5*n*sin(2*pi()/n)) )
FROM ( SELECT ST_Area($1) as area,
(CASE WHEN $2<=1 THEN 4 ELSE 4*$2 END)::float as n
) as t;
$$ LANGUAGE SQL immutable;
DEMOSTRANDO
Las principales formas, círculo y cuadrado, tiene áreas
A = pi*w^2 # circle with radius w
A = 2*w^2 # square circumscribed into a circle of radius w
El intermediario formas son los polígonos regulares de n
lados. La plaza tiene n
=4, el octágono n
=8, etc. Así, podemos sustituir el factor de w^2
a través de una función f(n)
que oferta el valor adecuado para el n
lados.
La fórmula del área de un polígono regular de n
lados con un circunradio w
, es:
A = 0.5*n*sin(2*pi/n)*w^2
Donde podemos comprobar: para n=4
el factor de 0.5*n*sin(2*pi/n)
es 2; n=400
(infinito) es 3.14 (~pi).
Para el estándar ST_Buffer(g,'quad_segs=N')
polígono generador se puede comprobar que esto N
es 4*n
.
La confirmación de la N=4*n
con PostGIS:
SELECT ST_AsEWKT((p_geom).geom) As geom_ewkt
FROM (SELECT ST_DumpPoints(
ST_Buffer(ST_GeomFromText('POINT(100 90)'),50,'quad_segs=5')
) AS p_geom ) AS t;
Devuelve 4+1 filas cuando N=1, 20+1 filas cuando N=5, etc. El objeto de dumping última fila de la repetición de la primera, para cerrar el polígono.
PRUEBAS
Pruebas de simulación de tampones (se necesitan más pruebas con los irregulares)
-- FORMULA TESTER FOR POINTS AND ITS BUFFERS:
SELECT w,
(array['square','octagon','','','','','','~circle'])[shape] as shape,
round(pointbuffer_width(circle8,shape),1) as circle8,
round(pointbuffer_width(octagon,shape),1) as octagon,
round(pointbuffer_width(square,shape),1) as square
FROM (
SELECT
w, shape, -- 1, 2, 3 or 10
ST_Buffer(g, w) as circle8, -- default 8, use 20 for perfect circle
ST_Buffer(g, w, 'quad_segs=2') as octagon,
ST_Buffer(g, w, 'quad_segs=1') as square
FROM ( SELECT ST_GeomFromText('POINT(100 90)') as g,
unnest(array[1.0,150.0]) as w,
unnest(array[1,2,8]) as shape
) as t
) as t2;
RESULTADOS:
w | shape | circle8 | octagon | square
-------+---------+---------+---------+--------
1.0 | square | 1.2 | 1.2 | *1
150.0 | octagon | 157.6 | *150 | 126.1
1.0 | ~circle | *1 | 1 | 0.8
150.0 | square | 187.4 | 178.4 | *150
1.0 | octagon | 1.1 | *1 | 0.8
150.0 | ~circle | *150 | 142.8 | 120.1
Conclusión: es estable para cualquier valor de anchura (!); es exacto al del modelo de la forma se adapte a la geometría de la forma (*).