¿Hay una función de disolución en PostGIS que no sea st_union?

22

Estoy buscando una función para disolver los límites compartidos entre las características de polígono en una tabla. ST_UNION () casi hace lo que estoy buscando, pero crea un multipolígono a partir de todos los polígonos en la capa, independientemente de si comparten un límite común o no. Prefiero solo disolver los límites entre los polígonos que se tocan. Pensé que debería haber alguna forma de usar ST_TOUCHES (), pero la necesidad de una función de disolución parece tan común que me sorprendería si no hay una función incorporada para lograr esto.

El caso de uso se ve así: descargué datos de Corine Landcover para un gran país europeo y quiero disolver los límites entre los diferentes tipos de bosques (aproximadamente 75,000 polígonos en una tabla). Intenté ST_UNION, pero me falla con un error de "falta de memoria" (30,000 polígonos sí funcionaron):

create table corine00 as 
  select st_union(the_geom) as the_geom, 
         sum(area_ha) as area_ha,
         substr(code_00,1,2) as code_00
  from clc00_c31_forests
  group by substr(code_00,1,2)

Nota: Todos los códigos forestales comienzan con '31' y estoy usando PostGIS 1.4, versión GEOS: 3.2.0-CAPI-1.6.0

bajo oscuro
fuente

Respuestas:

21

ST_MemUnion () ejecutará un proceso ingenuo y lento de memoria amigable. Puede intentar eso, si su problema es lo suficientemente pequeño, puede terminar en un tiempo razonable. También puede dividir su problema en mitades, luego ejecutar las mitades juntas. Como los resultantes tendrán muchos menos puntos que las entradas, es posible que pueda ajustar todo el problema en la memoria de esa manera. O use la rutina de memoria rápida en las mitades y la rutina más lenta en la fusión final.

Paul Ramsey
fuente
44
Fantástico tenerte aquí Paul, gracias por traerte una experiencia incomparable.
fmark
1
Gracias, parece que mi problema no es lo suficientemente pequeño. ST_MemUnion () ha estado funcionando durante 24 horas. Intentaré dividir el problema.
oscuro
5

Creo que ST_Dump es lo que quieres:

ST_Dump :

Devuelve un conjunto de filas geometry_dump (geom, path) que forman una geometría g1 .... Por ejemplo, se puede usar para expandir MULTIPOLYGONS en POLYGONS. ...

Entonces para su caso:

 SELECT (ST_Dump( ST_Union( the_geom ) )).geom
 FROM clc00_c31_forests
 GROUP BY substr(code_00,1,2)

No estoy seguro de cómo interactuará con la creación de la tabla que está intentando hacer, pero debería darle las geometrías como entradas separadas. Entonces podría hacer una unión espacial (usando && y ST_Contains) entre las dos tablas para recopilar los datos en las geometrías.

yhw42
fuente
2
Nota: ¡esto solo será útil si se solucionan los problemas de memoria de ST_Union! :)
yhw42
4

¿Su PostGIS está compilado contra GEOS 3.1.0+? Para esa versión, se implementó una unión en cascada mucho más rápida , pero si no se encuentra, se usará el código anterior, que es mucho más lento.

Actualización : parece que su PostGIS está utilizando el enfoque de unión en cascada, pero el hambre de memoria es real. Intentaría aumentar la memoria disponible para su instancia de Postgres, aquí hay algunos consejos de la charla PostGIS FOSS4G 2007 de Paul Ramsey :

  • El acceso al disco es lento, por lo que se puede obtener un mayor rendimiento utilizando más memoria para almacenar en caché los datos.
    • Incrementar shared_buffers
    • RAM física: el sistema operativo necesita * 75%
  • La clasificación es más rápida en la memoria
    • Incrementar work_mem
  • La limpieza del disco es más rápida con más memoria
    • Incrementar maintenance_work_mem
  • Asignado por conexión
  • también
    • Incrementar wal_buffers
    • Incrementar checkpoint_segments
    • Disminución random_page_cost

En su caso, trataría de aumentar shared_buffers, la recomendación general es el 25% de su memoria disponible para un servidor de base de datos, pero intente aumentarlo a 3-4x su valor actual y ver si se completa.

scw
fuente
postgis_geos_version () devuelve: 3.2.0-CAPI-1.6.0 ... Supongo que está bien. Intentará ST_Collect, gracias.
oscuro
Bueno, ST_Collect no parece disolver ningún límite y también crea un Multipolígono gigante.
oscuro
Sí, leí mal la página de ST_Collect. He actualizado mi respuesta para proporcionar consejos más específicos para ajustar el uso de memoria de Postgres.
scw