4 votos

Uso de postgis para aplanar todos los polígonos de la tabla

Tengo una tabla con muchos polígonos. Todos los polígonos tienen un nombre y un valor.

Quiero aplanar estos polígonos para que cada borde de los polígonos permanezca como borde de los polígonos resultantes. En lugar de tener una pila de polígonos me quedaré con un mosaico de polígonos basados en las mismas líneas.

A stack of polygons

Resultando en esto:

enter image description here

Los nombres son insignificantes. Quiero sumar los valores de cada polígono original dentro de los diferentes mosaicos del mosaico. También sería relevante calcular el número de solapamientos.

Estoy buscando una solución utilizando PostGIS. He resuelto esto usando FME, pero el tamaño de mis datos (más de 20.000 objetos con millones de solapamientos) hace que esto consuma demasiado tiempo. El función de unión en QGIS lo hace de forma bastante sencilla, tal y como ilustran sus páginas web de documentos.

Figure on QGIS union from the QGIS webpage

Para los que necesiten un contexto, los datos son en realidad topes de varios anillos alrededor de los sitios de anidación de aves marinas en Noruega. Los conjuntos de datos son por especie y estamos viendo varios miles de sitios de anidación por especie.

Puede descargar un conjunto de datos de prueba aquí .

0 votos

¿Funciona ST_Union sin un GROUP BY?

0 votos

@DPSSpatial no, he estado probando en el conjunto de datos de la imagen anterior. Lo ideal es que obtenga 7 mosaicos individuales.

0 votos

¡hmmm no estoy seguro de esto, tenía algunas ideas pero no funcionan... espero que alguien pueda opinar ya que esto parece fácil!

2voto

Gary Peck Puntos 151

Descargue los complementos de PostGIS desde este enlace: https://github.com/pedrogit/postgisaddons

Instale ejecutando el archivo postgis_addons.sql.

Pruebe ejecutando el archivo postgis_addons_test.sql.

Aquí hay un ejemplo de un problema similar al suyo:

WITH geomtable AS (
  SELECT 1 id, ST_GeomFromText('POLYGON((0 0, 0 2, 2 2, 2 0, 0 0), (0.2 0.5, 0.2 1.5, 0.8 1.5, 0.8 0.5, 0.2 0.5))') geom
  UNION ALL
  SELECT 2 id, ST_GeomFromText('POLYGON((1 0.2, 1 1, 3 1, 3 0.2, 1 0.2))') geom
  UNION ALL
  SELECT 3 id, ST_GeomFromText('POLYGON((1.5 0.8, 1.5 1.2, 2.5 1.2, 2.5 0.8, 1.5 0.8))') geom
  UNION ALL
  SELECT 4 id, ST_GeomFromText('MULTIPOLYGON(((3 0, 3 2, 5 2, 5 0, 3 0)), ((4 3, 4 4, 5 4, 5 3, 4 3)))') geom
)
SELECT a.id, unnest(ST_SplitAgg(a.geom, b.geom, 0.00001)) geom
FROM geomtable a,
     geomtable b
WHERE ST_Equals(a.geom, b.geom) OR
      ST_Contains(a.geom, b.geom) OR
      ST_Contains(b.geom, a.geom) OR
      ST_Overlaps(a.geom, b.geom)
GROUP BY a.id;

En su consulta, sólo tiene que sustituir geomtable por su tabla:

SELECT a.id, unnest(ST_SplitAgg(a.geom, b.geom, 0.00001)) geom
FROM polytest a,
     polytest b
WHERE ST_Equals(a.geom, b.geom) OR
      ST_Contains(a.geom, b.geom) OR
      ST_Contains(b.geom, a.geom) OR
      ST_Overlaps(a.geom, b.geom)
GROUP BY a.id;

Debería funcionar para miles de polígonos y cuando hay más de dos solapamientos.

1voto

sibams Puntos 33

Puedes ir por partes... Utilice el enfoque mencionado anteriormente:

CREATE TABLE tbl_intersection AS
SELECT
    ST_INTERSECTION(t1.geom, t2.geom) as geom
FROM original_dataset t1, original_dataset t2 
WHERE t1.ID < t2.ID AND ST_INTERSECTS(t1.geom, t2.geom);

Y luego se utiliza la tabla anterior y el conjunto de datos original para ejecutar el ST_Diferencia (El orden es importante en este caso) entre entonces. Debería ponerte en la pista

SELECT
    ST_Difference(t2.geom, t1.geom) AS geom
FROM
  original_dataset t1, tbl_intersection t2

0 votos

Todavía no está ahí. En la primera consulta de la tercera línea quizás debería ser "ST_INTERSECTION(t1.geom, t2.geom) AS geom"? Cuando elimino la condición "t1.id > t2.id and" obtengo nueve objetos únicos. Sin embargo, no consigue aislar más de dos solapamientos a la vez. Recuerda que el caso implica decenas, si no cientos, de solapamientos. Estoy buscando todas las piezas posibles en el mosaico - aplanado sin solapamientos. Al igual que el ejemplo de QGIS anterior.

0voto

Bodo Hombah Puntos 48

Si has añadido todos los índices correctos (en el ID así como el índice GIST en geom), lo siguiente debería hacer el trabajo - siempre y cuando tu servidor esté a la altura;

   select st_intersection(a.geom, b.geom) as geom
   from table a, table b
   where st_intersects(a.geom, b.geom)
   group by st_intersection(a.geom, b.geom)

0 votos

Si no es así, intente algo como lo que se indica en este artículo: postgis.net/2014/03/14/tip_intersection_faster

1 votos

No está mal. El anterior sale con nueve objetos individuales. Entonces los divide totalmente lo cual es bueno. Pero también me gustaría mantener un atributo de selección y resumir un valor entero en los polígonos superpuestos. Así que estamos avanzando con seguridad. Debo mencionar que en mi caso no tengo dos tablas diferentes, sino una. Introduciendo la misma tabla en su consulta SQL es lo que hice.

1 votos

Genial, sí deberías poder modificar la consulta para incluir la suma de enteros. Sí, la tabla a y la tabla b deben ser la misma. Buena suerte.

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