Existe-t-il une fonction de dissolution dans PostGIS autre que st_union?

22

Je recherche une fonction pour dissoudre les limites partagées entre les entités surfaciques d'une table. ST_UNION () fait presque ce que je recherche, mais il crée un multipolygone à partir de tous les polygones de la couche, qu'ils partagent ou non une frontière commune. Je préfère seulement dissoudre les frontières entre les polygones qui se touchent. J'ai pensé qu'il devrait y avoir un moyen d'utiliser ST_TOUCHES () mais le besoin d'une fonction de dissolution semble si commun que je serais surpris s'il n'y avait pas de fonction intégrée pour y parvenir.

Le cas d'utilisation ressemble à ceci: j'ai téléchargé les données Corine Landcover pour un grand pays européen et je veux dissoudre les frontières entre les différents types de forêts (environ 75 000 polygones dans une table). J'ai essayé ST_UNION, mais il m'échoue avec une erreur de "mémoire insuffisante" (30 000 polygones fonctionnaient cependant):

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)

Remarque: Tous les codes forestiers commencent par '31' et j'utilise PostGIS 1.4, version GEOS: 3.2.0-CAPI-1.6.0

obscur
la source

Réponses:

21

ST_MemUnion () exécutera un processus convivial de mémoire naïf et lent. Vous pouvez essayer cela, si votre problème est suffisamment petit, il pourrait se terminer dans un délai raisonnable. Vous pouvez également diviser votre problème en deux, puis exécuter les moitiés ensemble. Étant donné que les résultantes auront beaucoup moins de points que les entrées, vous pourrez peut-être mettre tout le problème en mémoire de cette façon. Ou utilisez la routine de mémoire rapide sur les moitiés et la routine plus lente sur la fusion finale.

Paul Ramsey
la source
4
Fantastique de vous avoir ici Paul, merci de vous avoir apporté une expertise incomparable.
fmark
1
Merci, on dirait que mon problème n'est pas assez petit. ST_MemUnion () fonctionne maintenant depuis 24 heures. Je vais essayer de diviser le problème.
underdark
5

Je crois que ST_Dump est ce que vous voulez:

ST_Dump :

Renvoie un ensemble de lignes geometry_dump (geom, path), qui composent une géométrie g1 .... Par exemple, elle peut être utilisée pour développer MULTIPOLYGONS en POLYGONS. ...

Donc pour votre cas:

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

Je ne sais pas comment cela va interagir avec la création de table que vous essayez de faire, mais cela devrait vous donner les géométries en tant qu'entrées distinctes. Vous seriez alors en mesure de faire une jointure spatiale (en utilisant && et ST_Contains) entre les deux tables pour collecter les données sur les géométries.

yhw42
la source
2
Remarque: cela ne sera utile que si vous résolvez les problèmes de mémoire de ST_Union! :)
yhw42
4

Votre PostGIS est-il compilé avec GEOS 3.1.0+? Pour cette version, un union en cascade beaucoup plus rapide a été implémentée, mais si elle n'est pas trouvée, elle utilisera l'ancien code qui est plus lent de plusieurs ordres de grandeur.

Mise à jour : il semble que votre PostGIS utilise l'approche de l'union en cascade, mais la famine est réelle. J'essaierais d'augmenter la mémoire disponible de votre instance Postgres, voici quelques conseils de la conférence FOSS4G PostGIS 2007 de Paul Ramsey :

  • L'accès au disque est lent, donc des performances plus élevées peuvent être obtenues en utilisant plus de mémoire pour mettre en cache les données!
    • Augmenter shared_buffers
    • RAM physique - Besoins du système d'exploitation * 75%
  • Le tri est plus rapide en mémoire
    • Augmenter work_mem
  • Le nettoyage du disque est plus rapide avec plus de mémoire
    • Augmenter maintenance_work_mem
  • Alloué par connexion
  • Également
    • Augmenter wal_buffers
    • Augmenter checkpoint_segments
    • Diminution random_page_cost

Dans votre cas, j'essaierais d'augmenter shared_buffers, la recommandation générale est de 25% de votre mémoire disponible pour un serveur de base de données, mais essayez de l'augmenter à 3-4x sa valeur actuelle et de voir si elle se termine.

scw
la source
postgis_geos_version () renvoie: 3.2.0-CAPI-1.6.0 ... Je suppose que ça va. Va essayer ST_Collect, merci.
underdark
Eh bien, ST_Collect ne semble pas dissoudre les frontières et crée également un Multipolygon géant.
underdark
ouais, j'ai mal lu la page de ST_Collect. J'ai mis à jour ma réponse pour fournir des conseils plus spécifiques sur le réglage de l'utilisation de la mémoire de Postgres.
scw