3 votos

Uso de PostGIS para generar un polígono que represente el área compartida por algunos (pero no todos) de un conjunto de polígonos

Tengo una aplicación en la que varios usuarios envían polígonos, y estoy buscando crear un polígono agregado que represente una especie de promedio de sus envíos. Utilizamos PostGIS para nuestras necesidades de análisis espacial.

Digamos que recibimos polígonos de 10 usuarios. Si utilizamos ST_Intersection en esos polígonos, el polígono restante sólo representaría los puntos incluidos en los 10 polígonos. Si utilizamos ST_Union, la salida representaría los puntos incluidos en al menos 1 polígono.

¿Alguien puede recomendar una manera de dar salida a un polígono que represente los puntos que están en n polígonos, donde n es mayor que 1 y menor que el número total de polígonos (10 en este caso)?

2 votos

Requisito interesante. ¿Puede publicar una imagen de un conjunto típico de polígonos?

1 votos

Creo que un enfoque sería formar una cobertura a partir de las líneas de los polígonos, y luego extraer el área creada por los polígonos de cobertura que tienen al menos N padres.

3voto

NilObject Puntos 7874

Sólo estoy escupiendo:

  • ST_GeneratePoints() en cada geometría de entrada con N puntos.
  • Aleatoriza ese conjunto de puntos y toma un 1/M de ellos.
  • Construir polígonos de voronoi de ese conjunto.
  • Unir espacialmente los polígonos de Voronoi con el conjunto de puntos original y conservar sólo los polígonos con más de P puntos en ellos
  • Unión de esos polígonos.
  • Obtenga el resultado.

¿Qué te parece?

1 votos

Acabo de encontrar la entrada del blog que escribiste en respuesta a esta pregunta. info.crunchydata.com/blog/polygon-averaging-in-postgis

1voto

mathieu Puntos 53

Algunas opciones, de la parte superior de mi cabeza; no probado y no optimizado.

  • Para obtener el área del conjunto de puntos "promedio" para los puntos con 1 < cnt < total se superponen:

    SELECT  ST_ConvexHull(ST_Collect(geom)) AS geom
    FROM    (
        SELECT  dmp.geom, COUNT(DISTINCT a.*) AS cnt
        FROM    mask AS a,
                mask AS b,
                LATERAL ST_DumpPoints(b.geom) AS dmp
        WHERE   ST_Intersects(a.geom, dmp.geom)
        GROUP BY
                1
    ) q
    WHERE   cnt > 1 AND cnt < (SELECT COUNT(*) FROM mask)
    ;
  • Para obtener el área poligonal precisa de las partes con 1 < cnt < total se superponen:

    SELECT  ST_Union(geom) AS geom
    FROM    (
        SELECT  a.geom, COUNT(b.*) AS cnt
        FROM    (
            SELECT  (ST_Dump(ST_Split(ST_Union(a.geom), ST_Union(ST_ExteriorRing(b.geom))))).geom
            FROM    mask AS a
            JOIN    mask AS b
              ON    a.id <> b.id AND ST_Intersects(a.geom, b.geom)
        ) AS a
        JOIN    mask AS b
          ON    ST_Intersects(ST_Centroid(a.geom), b.geom)
        GROUP BY
                a.geom
    ) q
    WHERE cnt > 1 AND cnt < (SELECT COUNT(*) FROM mask)
    ;

Tenga en cuenta que la primera consulta garantiza un polígono de una sola parte, pero con una forma generalizada sobre el conjunto de puntos, mientras que la segunda coserá partes exactas del polígono, pero puede resultar en un polígono de varias partes.

0voto

BenGoldberg Puntos 111

Una de las personas que respondió (ver Paul Ramsey arriba) publicó una gran respuesta en este blog aquí: https://info.crunchydata.com/blog/polygon-averaging-in-postgis .

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