26 votos

¿Existe alguna función de disolución en PostGIS que no sea st_union?

Estoy buscando una función para disolver límites compartidos entre características poligonales en una tabla. ST_UNION() casi hace lo que busco, pero crea un multipolígono a partir de todos los polígonos de la capa independientemente de si comparten o no un límite común. Preferiría disolver sólo los límites entre los polígonos que se tocan entre sí. Me imaginé, que debería haber alguna manera usando ST_TOUCHES() pero entonces la necesidad de una función de disolver parece tan común que me sorprendería si no hay una función incorporada para lograr esto.

El caso de uso es el siguiente: He descargado los datos de Corine Landcover de un gran país europeo y quiero disolver los límites entre los diferentes tipos de bosque (aprox. 75.000 polígonos en una tabla). He probado ST_UNION, pero me falla con un error de "memoria agotada" (aunque 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 empiezan por "31" y estoy utilizando PostGIS 1.4, GEOS versión: 3.2.0-CAPI-1.6.0

24voto

NilObject Puntos 7874

ST_MemUnion() ejecutará un proceso ingenuo y lento, amigable con la memoria. Puedes intentarlo, si tu problema es lo suficientemente pequeño, puede que termine en un tiempo razonable. También puede dividir su problema en mitades, y luego ejecutar las mitades juntas. Dado que las resultantes tendrán muchos menos puntos que las entradas, es posible que puedas meter todo el problema en la memoria de esta manera. O utilizar la rutina rápida en las mitades y la rutina más lenta en la fusión final.

7voto

Nerdfest Puntos 563

Creo que ST_Dump es lo que quieres:

ST_Dump :

Devuelve un conjunto de geometry_dump (geom,path), que conforman una geometría g1.... Por ejemplo, se puede utilizar para expandir MULTIPOLIGONOS en POLIGONOS. ...

Así que 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 va a interactuar con la creación de la tabla que está tratando de hacer, pero debe darle las geometrías como entradas separadas. A continuación, sería capaz de hacer una unión espacial (utilizando && y ST_Contains ) entre las dos tablas para recoger los datos en las geometrías.

5voto

Robert Höglund Puntos 5572

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

Actualización El problema: parece como si PostGIS estuviera utilizando el enfoque de unión en cascada, pero la falta de memoria es real. Yo trataría de aumentar la memoria disponible para su instancia Postgres, aquí hay algunos consejos de Paul Ramsey's 2007 FOSS4G PostGIS talk :

  • El acceso al disco es lento, por lo que se puede obtener un mayor rendimiento utilizando más memoria para almacenar los datos en caché.
    • Aumentar shared_buffers
    • RAM física - necesidades del SO * 75%
  • La clasificación es más rápida en memoria
    • Aumentar work_mem
  • La limpieza de disco es más rápida con más memoria
    • Aumentar maintenance_work_mem
  • Asignado por conexión
  • También
    • Aumentar wal_buffers
    • Aumentar checkpoint_segments
    • Disminuir random_page_cost

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

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