Joindre de nombreux petits polygones pour former un polygone plus grand avec PostGIS?


47

J'ai la couche suivante en utilisant SRID 27700 dans postgis:

entrez la description de l'image ici

Il s’agit de toutes les régions administratives du Royaume-Uni et, comme vous pouvez le constater à partir du groupe de couleurs, chacune d’entre elles possède un champ de texte spécifiant le comté dans lequel elles se trouvent.

Ce que j'aimerais faire, c'est créer des polygones de comté plus grands à partir des plus petits d'un comté donné. Ainsi, dans l'image, les polygones de couleur bleu sarcelle formeraient un grand polygone à partir du seul anneau extérieur contenant tous les polys de cette image. couleur, comme tous les violet, marron, rose, gris, etc. doivent tous former un polygone.

J'ai déjà essayé ce qui suit:

insert into parishesmerged (geometry)
select astext(multi(ST_Union(the_geom))) as the_geom from parishes
group by county_name

Mais il continue de générer des géométries brisées que je rencontre ensuite de gros problèmes de traitement.

J'essaie de faire une carte au niveau du comté plus simple avec les principales zones de sortie en.

Toutes les solutions ne doivent pas nécessairement être dans Postgis non plus, j'ai toute la pile OS4Geo installée, la dernière version de QGis et plus d'utilitaires que je ne peux me permettre.

Les seules choses que je n'ai pas sont les grands garçons comme ArcGis (bien que je puisse avoir un vieux Mapinfo traînant quelque part)


Pour mémoire, le jeu de données que j'essaie de créer doit accompagner un livre SIG que je suis en train d'écrire et destiné aux programmeurs .NET souhaitant écrire des applications SIG à l'aide de .NET.


Après avoir essayé les suggestions ci-dessous, celle qui a fonctionné le mieux a été la solution «Paul Ramseys».

J'ai maintenant un joli fichier simplifié de comtés et arrondissements qui est juste assez simple pour mon livre, mais assez complexe pour me permettre de démontrer un SQL géo-spatial intéressant.

Même si la solution de Paul a finalement été celle qui a fonctionné pour moi, j'ai également utilisé d'autres réponses pour simplifier la carte des polygones et réduire davantage la complexité.

Cependant, bien que ST_Collect soit plus rapide que ST_Union, il a été observé que c’était aussi le principal responsable des géométries brisées. Je suppose que l’augmentation de la vitesse est obtenue au détriment d’une précision moindre de la fonction principale.


Ce processus s'appelle une "dissolution". Je ne connais pas bien PostGIS, mais je pense que vous pouvez utiliser la commande ST_Union pour effectuer la dissolution.
dmahr

Bonjour dmahr, merci pour la clarification, je ne savais pas comment ça s'appelait, cependant si vous lisez ma question, vous verrez que j'ai déjà essayé ça :-)
shawty

Oups, désolé ... je n'ai pas vu ça. Avez-vous essayé la déclaration select sans la astext(multi())partie? Je m'éloigne simplement de ce que je vois dans d'autres exemples de dissolution PostGIS.
dmahr

Pas encore, je vais essayer ça maintenant. Tks. Avez-vous un lien pour dissoudre des exemples?
shawty

Veuillez éditer pour exprimer si vous voulez "l'anneau extérieur unique" ou non. (Voir ma réponse)
Peter Krauss

Réponses:


43

ST_Union fonctionnerait, mais votre travail en ligne n’est presque pas propre. Les limites de vos petits trucs ne sont donc pas toutes parfaitement égales. Vous pouvez les aligner doucement sur une grille pour essayer d'augmenter les chances que les sommets s'alignent, mais je parie que vous aurez encore quelques cas qui ne fonctionneront pas. Soit ils vont au-delà de la tolérance ou, plus probablement, il y aura des endroits où les sommets ne sont pas liés, il y a donc une ligne d'un côté et un sommet de l'autre.

 CREATE TABLE merged AS
 SELECT ST_Union(ST_SnapToGrid(the_geom,0.0001)) 
 FROM parishes
 GROUP BY county_name;

Si vous utilisez PostGIS 2.0, la construction d'une structure de topologie avec une tolérance peut vous permettre d'obtenir la réponse que vous recherchez, si vous avez de la chance.


Bon indice pour la correction des géométries, mais environ "... un grand polygone de l'anneau extérieur unique qui contient tous les polys ..."?
Peter Krauss

Je ne savais pas à propos de 'SnapTo', je vais l'essayer :-) Tks. Malheureusement, non, la PG 2 n’est pas encore utilisée, la mise à niveau est en cours.
shawty

Pas sûr que votre syntaxe soit correcte. Selon postgis.net/docs/ST_Union.html , aucune signature n’accepte un nombre dans le deuxième paramètre.
Aren Cambre

Vous avez raison, la parenthèse était au mauvais endroit. Édité.
Paul Ramsey

y a-t-il un équivalent mysql à cela? Je continue à obtenir Incorrect parameter count in the call to native function 'ST_Union'et je ne sais pas si c'est une limitation de MySQL.
Jayen

7

Vous dites qu'il faut "... former un grand polygone à partir de l'anneau extérieur unique qui contient tous les polys ...". Le ST_ExteriorRing le fait,

SELECT ST_MakePolygon(ST_ExteriorRing(ST_Union(GEOM)))
FROM GEOMTABLE GROUP BY ATTRCOLUMN

Vous pouvez utiliser ST_Union (), comme suggéré, ou tester avec ST_Collection ().


NOTES: pour éviter les petits creux ou les "géométries brisées", vous pouvez utiliser st_convexhull et / ou ST_Simplify pour chaque geom,

SELECT ST_MakePolygon(ST_ExteriorRing(ST_union(ST_Simplify(GEOM,0.5))))
FROM GEOMTABLE GROUP BY ATTRCOLUMN

et vérifiez vos géométries,

SELECT * FROM (
   SELECT gid, ST_IsValid(geom) as valid, ST_IsSimple(geom) as simple 
   FROM GEOMTABLE) AS t  
WHERE NOT(valid AND simple); 

Désolé pour la confusion: ce que je voulais dire par ma description était un polygone plus grand créé à partir des plus petits, je réalise que, selon le contexte, "anneau externe" peut signifier différentes choses pour différentes personnes, mon intention était de décrire un seul polygone créé à partir de la limite présente autour de chaque groupe de polygones.
shawty

7

La fonction ST_Collect est une fonction "agrégée" dans la terminologie de PostgreSQL

" SELECT ST_Collect(GEOM) FROM GEOMTABLE GROUP BY ATTRCOLUMN" renverra une GEOMETRYCOLLECTION distincte pour chaque valeur distincte d'ATTRCOLUM

http://postgis.net/docs/ST_Collect.html

Remarque: ST_Collect est beaucoup plus rapide que ST_Union.


3
J'ai essayé cela et obtenu des résultats légèrement différents, mais une collection de géométrie est-elle ce dont j'ai besoin? J'essaie essentiellement de créer un grand polygone, avec éventuellement des trous (particulièrement dans le Derbyshire et le Nottingham où le derby et le Nottingham forment des quartiers distincts au centre. J'ai observé la différence de vitesse, donc c'est kewl.
shawty

2

D'après votre question, je suppose que vous utilisez le produit Boundary-Line d'Ordnance Survey. Si tel est le cas, il inclut déjà un jeu de données au niveau du comté, il n’est donc pas nécessaire de le générer vous-même à partir de zones paroissiales de niveau inférieur.

Si vous n'utilisez pas Boundary-Line, je vous recommande de le faire car il est gratuit sous la licence OpenData du système d'exploitation et dispose d'un niveau comté comme fichier de forme que vous pouvez charger directement dans PostGIS.


2
Que diriez-vous de fournir un lien pour ceux qui ne le savent pas? Merci.
Jonatr

1
Bonjour CHEnderson, vous avez effectivement raison. Oui, j'utilise le jeu de données de couche limite d'OS Opendata. Malheureusement, les limites des comtés ne sont pas complètes. Le fichier de forme du comté ne comprend que les comtés. London et d'autres fichiers comportent tous des parties, des niveaux inférieurs et inférieurs aux autres. Le seul fichier qui contient tout le contour du Royaume-Uni et, par la suite, toute possibilité d'extraire tous les comtés de niveau supérieur et les limites municipales dans une couche est la couche paroisses, d'où l'intérêt que j'essaie de faire.
shawty

Pour ceux qui sont intéressés, vous pouvez télécharger les limites du comté et plus encore, ici: ordnancesurvey.co.uk/oswebsite/products/os-opendata.html
shawty Le
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.