5 votos

¿Cuál es el ancho de la playa de una isla pequeña polígono?

Este es un "clásico" del problema, que no tienen ninguna utilidad práctica (véase la nota-1 para aplicaciones), pero ilustra otro de los SIG problemas...

little island figure

Podemos hacer algunas aproximaciones para modelar la situación,

  • el verdadero centro (coco) no está en la ST_Centroid punto, pero se puede aproximar a;
  • la forma real (una isla) no es un círculo, ni una plaza, son opcionales referencias.

Así, la traducción de la pregunta a una ecuación, y utilizando el estándar OGC funciones... "¿Cuál es el valor de w?" en la ecuación

ST_Area(ST_Buffer(ST_Centroid(littleIsland), w, quad_segs)) = ST_Area(littleIsland)

Cuando quad_segs=1, la referencia es un cuadrado, cuando quad_segs>=8 el de referencia se encuentra cerca del círculo (ver ejemplos de polígonos generados).


NOTA-1: Para entender este problema en un contexto de aplicaciones, consulte "hay un st_buffer de la función inversa, que devuelve un ancho de estimación?" y consulte "Cómo ajustar un polígono a un "mejor buffer" sobre una geometría de referencia?".

NOTA-2: la "función inversa" es tan general y complejo, porque puede que opera con el punto, línea y polígono de entradas. Aquí podemos discutir el caso más simple, cuando la entrada es como un punto, con ninguna área o longitud.

4voto

Iznogood Puntos 143

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.

different buffers

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 (*).

i-Ciencias.com

I-Ciencias es una comunidad de estudiantes y amantes de la ciencia en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X