Aide à la géométrie des polygones PostGIS - anneaux non fermés

10

J'ai ramassé une copie du livre super méchant «Python Geospatial Development» d'Erik Westra ( lien Amazon ), et je travaille dessus. Actuellement, il m'apprend à charger des données côtières GSHHS à partir d'un fichier de formes dans une base de données PostGIS, en préparation de la construction d'une application Web géospatiale.

Mon problème est le suivant: lorsque j'essaie d'importer les données GSHHS dans PostGIS, elles sont rejetées car les polygones du littoral ne sont pas considérés comme «valides». Plus précisément, je reçois un message d'erreur décrivant certains (mais pas tous) des polygones du littoral comme étant des «anneaux non fermés».

Je comprends que cette erreur essaie de me dire que les premier et dernier points du polygone ne sont pas les mêmes. Cependant, ce n'est tout simplement pas vrai. J'ai examiné la représentation WKT de nombreux polygones, et ils sont corrects. Ils commencent et se terminent définitivement par la même coordonnée.

Les polygones sont extraits des fichiers de formes à l'aide de la bibliothèque OGR et exportent chaque entité surfacique vers WKT. J'ai essayé de reconstituer le polygone via Shapely et expérimenté avec WKB, mais en vain. J'ai été en mesure de charger les mêmes données dans PostGIS comme une table MULTIPOLYGON, en utilisant le chargeur de shp2pgsql.

Je me demandais si quelqu'un là-bas avait:
(a) peut-être utilisé le même livre, était coincé avec le même problème et avait la réponse pour moi?
(b) a rencontré un problème similaire et a trouvé une solution?
(c) à défaut, a-t-il des conseils sur les «meilleures pratiques» pour garantir une géométrie valide avant le chargement dans PostGIS?

MISE À JOUR: un collègue a suggéré que le problème des «anneaux non fermés» pourrait simplement être le symptôme d'un autre problème. Il est possible que ma configuration PostGIS / PostgreSQL ait des limites de taille (sur les transactions d'insertion, les paquets reçus, les chaînes de texte, etc.).

Comme j'utilise de très longs polygones WKT en entrée, PostGIS peut les couper trop tôt pour permettre à chaque polygone de se terminer. Je vais le tester demain, mais cela semble probable. Mon insert de frontières de pays n'acceptait que certains enregistrements et pas d'autres. De mémoire, les géométries acceptées étaient pour de petites nations insulaires comme Antigua (et avaient donc probablement de courtes représentations WKT).

Ainsi, cela pourrait devenir plus un thread d'administration de base de données PostGIS, plutôt qu'un thread de géométrie non valide.

timmy
la source
pouvez-vous fournir un exemple de fichier shp?
Mario Miler
Pas de soucis.Les données du littoral GSHHS que j'utilise sont téléchargeables à 96 Mo d' ici . Les données sur les frontières mondiales que j'utilise sont l'ensemble de données sur les frontières mondiales de thematicmapping.org
timmy

Réponses:

6

J'ai regardé vos données et l'exemple de livre, le problème est qu'il y a trois polygones invalides dans les données qui sont traités dans le livre:

GSHHS_l_L1.shp

ID = 92-W

POLYGON ((-180.0 71.514793999999995,-179.69008299999999 71.577888999999999,-178.648889 71.577416999999997,-178.40644399999999 71.549916999999994,-177.406306 71.244167000000004,-177.877444 71.022889000000006,-179.500111 70.863749999999996,-179.93011100000001 70.979583000000005,-180.0 70.962072000000006))

ID = 486-W

POLYGON ((-180.0 -16.799126,-179.84419399999999 -16.691278,-179.80041700000001 -16.789193999999998,-179.850472 -16.878361000000002,-180.0 -16.959561))

GSHHS_l_L2.shp

ID = 7333-W

POLYGON ((-180.0 65.393473,-179.76583299999999 65.428332999999995,-179.95416700000001 65.385555999999994,-179.90972199999999 65.316389,-180.0 65.321635))

Étant donné qu'il s'agit d'un exemple, il serait plus simple de supprimer ces polygones du jeu de données ou d'en ajouter simplement un si l'instruction dans votre code

if geometry.IsValid():
       cursor.execute("INSERT INTO gshhs (level, geom) VALUES (%s, ST_GeomFromText(%s, 4326))", (level, wkt))
Mario Miler
la source
Merci Mario, il semble que j'allais prendre de l'avance sur moi-même, au lieu de valider correctement TOUS mes polygones d'entrée. Votre réponse était correcte - ces polygones se sont révélés non valides lors du test avec OGR. Fait intéressant, le QGis avait l'air bien, mais ArcMap leur a montré qu'il manquait un anneau complet. Ces trois polygones sont tous tombés sur la ligne de données, et je suppose que la géométrie du fichier de formes ne comptait pas le bord du polygone le long de la ligne de données. Votre solution est un moyen agréable et facile de détecter les polygones invalides. Je marquerai le message comme répondu.
timmy
Si vous vous sentez charitable, avez-vous de bonnes solutions pour la prochaine étape du processus, qui consiste à corriger les polygones invalides? J'ai essayé d'utiliser la fonction .CloseRing () d'OGR, mais en vain. Il a simplement ignoré l'appel de fonction, je pense.
timmy
J'ai essayé d'utiliser "buffer buffer" ( workshops.opengeo.org/postgis-intro/validity.html ) avec galbe et ogr mais sans succès. Lamentablement ne lira pas le polygone invalide et l'ogr ne fera pas de tampon, actuellement je ne sais pas pourquoi. Si je tombe sur la réponse, je vous le ferai savoir. Peut-être que quelqu'un d'autre a plus de succès avec ce problème. Désolé.
Mario Miler
Je pense que ma validation de polygone fonctionne maintenant. Je pense que j'utilisais la fonction .CloseRings () d'OGR dans le mauvais sens. Je l'ai appelé comme méthode du polygone (c'est-à-dire poly.CloseRings ()). Au lieu de cela, j'ai dû extraire l'anneau linéaire du polygone, puis l'exécuter sur celui-ci (c.-à-d. Lr = poly.GetGeometryRef (0); lr.CloseRings ()). Les résultats ont été insérés avec succès dans PostGIS, et je peux utiliser les 3 polygones problématiques dans QGis sans aucun souci. La vérification de la validité de CHAQUE polygone ne représente qu'un petit coût de calcul.
timmy