Diviser un fichier de formes complexe en une grille

11

J'ai un fichier de formes assez détaillé avec des fonctionnalités de polygone / multipolygone (le fichier fait environ 500 Mo). C'est en fait un fichier de formes du monde entier, avec les caractéristiques représentant les côtes. J'ai besoin de diviser ces données à l'aide d'une grille. Pour être clair, je ne veux pas «trier» les données, mais découper les polygones en tuiles. Je réalise que cette question a déjà été posée mais les solutions que j'ai trouvées n'ont pas fonctionné pour moi.

J'ai essayé:

  • En utilisant QGIS et en croisant le contenu de mon fichier de formes avec une grille vectorielle - les résultats sont terribles. La plupart des principales terres émergées disparaissent comme par magie, bien qu'il semble que de plus petits morceaux de terre y parviennent parfois. Je dois noter que cette méthode fonctionne très bien avec des données beaucoup plus simples (c'est-à-dire moins de points)

  • Utilisation des outils d'intersection d'OGR. Je l'ai essayé à la fois via ogr2ogr et même en faisant rouler mon propre outil C ++. Les deux ont le même problème que QGIS. Ils ne présentent pas non plus ce problème pour les fichiers simples, mais échouent aux plus complexes. Pour référence, j'utilise un fichier de formes de l'Australie et de la Nouvelle-Zélande, de moins de 20 Mo, et QGIS et OGR ne parviennent pas à le `` mailler ''.

Quelqu'un a suggéré d'utiliser PostGIS à un moment donné, car il a une fonction d'intersection - mais ST_Intersect de PostGIS utilise le même back-end GEOS que OGR. En fait, ils appellent tous les deux la même fonction pour autant que je sache, donc je ne pense pas que PostGIS produira des résultats différents.

Je cherchais des suggestions sur ce que je pouvais essayer d'autre. J'ai besoin d'une application ou d'une boîte à outils robuste qui peut diviser des fichiers de formes très détaillés en tuiles.

EDIT: Ajout d'informations supplémentaires

En réponse à Simbamangu:

  • Le fichier de formes est essentiellement des données côtières d'OpenStreetMap. C'est une version fusionnée du fichier 'processor_p' (donc ce n'est pas divisé en tuiles) que j'ai obtenu en envoyant un e-mail à leur liste de développeurs. Notez que leur division des tuiles (en morceaux de 100 km x 100 km avec chevauchement) n'est pas nécessairement ce que je veux - je ne veux pas de chevauchement, et je veux la liberté de choisir la taille de la grille, ou j'utiliserais simplement le traitées par défaut_p.

  • Par défaut, les données du littoral comportent des erreurs de géométrie signalées par QGIS. Je corrige ces erreurs avec un petit outil que j'ai mis en place à l'aide d'un code que j'ai trouvé conçu pour résoudre spécifiquement ce problème (réparation des erreurs de géométrie dans les données du littoral: https://github.com/tudelft-gist/prepair ). Le fait de parcourir les fichiers avec cet outil corrige pratiquement toutes les erreurs détectées par QGIS. J'essaie seulement de faire l'intersection après avoir nettoyé les fichiers.

  • Exactement ce que j'ai fait en utilisant QGIS: ouvrez les données pour vous assurer qu'elles sont correctes dans QGIS. Essayez de le diviser en tuiles en créant une couche de tuiles à l'aide de la grille vectorielle avec un espacement spécifié, puis en coupant les deux couches - pas question. Essayez d'utiliser un ensemble de données plus petit - sélectionnez des fonctionnalités en Océanie (Aus, NZ) pour essayer un ensemble de données plus petit - ce fichier de forme a une taille <20 Mo. Essayez à nouveau de le diviser, cela ne fonctionne pas.

  • Ce que j'ai fait avec OGR: ogr2ogr en utilisant directement les options '-spat' et '-clipsrc' avec spat_extent. A également écrit un petit outil C ++ qui fonctionne sur WKT, donc je convertis le fichier de formes en WKT en utilisant ogr2ogr, puis j'alimente le fichier texte dans mon application. Il parcourt le fichier et appelle la méthode Intersection () documentée ici: http://www.gdal.org/ogr/classOGRGeometry.html . Je pense que cela finit par faire exactement la même chose que d'utiliser directement ogr2ogr.

En réponse à Brent:

  1. Cela fait. Tout est en WGS84 Lat / Lon
  2. J'aurais pensé que le contraire est vrai - que pour un ensemble donné de tuiles de grille, il faudrait beaucoup plus de temps pour croiser un multipolygone géant plutôt qu'un tas de caractéristiques fragmentées qui pourraient être plus spatialement localisées sur chaque tuile, mais c'est une suggestion intéressante - je vais l'essayer et faire rapport.
  3. Aucun champ d'attribut n'est conservé pendant le processus, je ne m'intéresse qu'à la géométrie.
  4. Je ne suis pas sûr, mais je pense que vous dites que je devrais sélectionner les polygones qui chevauchent une tuile de grille donnée, puis effectuer l'intersection. C'est trop lourd manuellement avec QGIS. Mon outil le fait déjà dans une certaine mesure avec une case à cocher englobante. Il y a un peu d'accélération, mais le résultat final est toujours médiocre et pas sensiblement différent.
  5. Ce n'est pas une option. En ce moment, j'essaie de diviser les données de manière à ce que leur 1 deg lat x 1 deg lon, et je cherche une méthodologie générale / robuste qui fonctionne avec tous les cas. J'ai essayé d'augmenter la taille de la grille (c'est-à-dire 10 x 10) pour voir si j'obtiendrais de meilleurs résultats et je ne vois aucune corrélation entre la taille de la grille et la qualité de la sortie.

Édition n ° 2:

J'ai essayé de jouer avec cela plus et en général, il semble que les résultats ne soient pas fiables à la fois en utilisant GEOS et avec QGIS (qui utilise fTools, je ne sais pas si cela utilise à son tour GEOS à nouveau). J'ai eu tort de dire que la taille de la grille n'a rien à voir avec les résultats - plus la grille est grande, meilleurs sont les résultats (c'est bon à savoir mais toujours pas une solution). Voici une capture d'écran d'une grille très espacée qui a fonctionné principalement, mais a échoué partiellement sur une seule tuile:

entrez la description de l'image ici

La géométrie est propre - QGIS affiche 0 erreur avec l'outil "Vérifier la validité". Je ne cherche pas à aborder ce problème pas à pas; vérifier si certaines entités ont échoué ou non l'intersection sur un jeu de données si grand quand il n'est pas visuellement apparent (et ce ne sera pas avec des tuiles plus petites) n'est pas pratique.

Pris
la source
Où avez-vous obtenu le fichier de formes du monde ou de l'Australie? Je soupçonne que la géométrie de ce fichier peut avoir quelques problèmes (essayez Vector | Outils de géométrie | Vérifier la validité de la géométrie dans QGIS). Je viens d'essayer une intersection sur un fichier de formes plus petit et des tuiles à 5 degrés et cela fonctionne parfaitement dans QGIS.
Simbamangu
1
Essayé avec le littoral australien de 100K de Geoscience Australia (20 Mo) et des tuiles à 4 degrés, fonctionne également très bien (QGIS 1.7.4, OSX 10.7). Pourriez-vous décrire plus en détail vos données et ce que vous avez fait?
Simbamangu
Merci pour toutes les informations supplémentaires. Je soupçonne qu'il y a quelque chose d'étrange dans les données OSM; essayez-le avec le jeu de données que j'ai mentionné et voyez si vous obtenez de meilleurs résultats. Je me souviens avoir connu une certaine bizarrerie avec les données du lac OSM dans le passé, j'essaierai de le rechercher.
Simbamangu
Pourriez-vous partager l'ensemble de données, ou même une partie tronquée de celui-ci (comme dans votre exemple ci-dessus)?
Simbamangu

Réponses:

7

Je viens de créer mes propres outils pour ce faire.

J'ai utilisé la bibliothèque Clipper ( http://www.angusj.com/delphi/clipper.php ) avec OGR pour diviser ma configuration de données. Quelque chose à noter effectuer des intersections naïvement avec cette bibliothèque prend très longtemps, j'ai donc plutôt utilisé une approche à quatre arbres ... c'est-à-dire, diviser en quatre cellules de grille, diviser chacune de celles-ci en quatre autres, etc., jusqu'à ce que vous obteniez la résolution souhaitée. La bibliothèque fonctionne très bien cependant, j'ai joint une capture d'écran montrant les résultats sur l'hémisphère oriental:

entrez la description de l'image ici

Le résultat ci-dessus a pris environ 4,5 heures sur un processeur à 1,33 GHz.

Voici les outils au cas où quelqu'un rencontrerait un problème similaire à l'avenir. Veuillez noter qu'ils sont piratés ensemble des preuves de concepts et que vous ne devriez probablement pas les utiliser directement (cela pourrait cependant servir de bon point de départ pour quelque chose):

https://github.com/preet/scratch/tree/master/gis/polytoolkit

https://github.com/preet/scratch/tree/master/gis/shapefiles/shptk

Pris
la source
Le code lié n'est plus disponible :-(
Shaun McDonald
J'ai déplacé le référentiel vers github.com/preet/scratch/tree/master/gis/polytoolkit . Selon ce que vous essayez d'accomplir, vous trouverez peut- être plus utile github.com/preet/scratch/tree/master/gis/shapefiles/shptk .
Pris le
Le dernier est plus utile. J'ai maintenant trouvé une méthode qui utilise PostGIS, mais je serais intéressé à savoir si cela était plus rapide. Avez-vous un fichier lisez-moi pour compiler et installer?
Shaun McDonald
Pourriez-vous peut-être modifier votre réponse pour corriger le lien? Merci
Afr
4

Il semble que vous ayez des problèmes de géométrie. Il est peu probable qu'il puisse produire des résultats nets à partir d'un fichier d'entrée sale quel que soit le logiciel utilisé, à moins que vous ne résolviez d'abord vos problèmes de géométrie. Une fois que vous avez résolu vos problèmes de géométrie, vous pouvez essayer ce qui suit si vous rencontrez toujours des problèmes:

1) Assurez-vous que votre jeu de données de grille a la même projection que votre jeu de données de polygone mondial. Sinon, recréez-le dans la projection appropriée.

2) Convertissez toutes les fonctionnalités en une seule pièce - beaucoup plus facile à traiter

3) Supprimez tous les champs superflus en ne gardant que le champ id qui vous permettra de rejoindre vos attributs une fois l'intersection effectuée - encore une fois beaucoup plus facile à traiter

4) Au lieu de couper l'intégralité du jeu de données de la grille avec l'ensemble du jeu de données du polygone du monde, essayez de faire une boucle sur vos polygones de grille, en sélectionnant les polygones qui se croisent dans votre jeu de données du monde et en effectuant un clip en fonction de votre polygone de grille. Cela vous permettra d'isoler tous les problèmes et, à la fin, vous pourrez fusionner les résultats ensemble pour atteindre votre objectif initial.

5) Essayez d'utiliser des polygones de grille plus grands.

Brent Edwards
la source
+1 Vraiment intéressant - dans quelle mesure cela affecte-t-il la vitesse de géotraitement si vous conservez le champ ID, ou multipartie, dans les données?
Simbamangu
1
Je n'ai jamais essayé de quantifier les différences. Je ne peux parler que de l'expérience où les opérations de géotraitement ont échoué et ce sont des choses qui ont aidé à résoudre le problème.
Brent Edwards
Je n'ai pas réussi du tout à faire travailler (2). Sélectionner des fonctionnalités et essayer de les fusionner à l'aide de QGIS semble fondamentalement bloquer mon système - peut-être que son traitement est toujours en cours, mais à ce rythme ce n'est pas pratique: j'ai laissé mon système pendant la nuit avec QGIS essayant toujours de fusionner quelques fonctionnalités dans le ensemble de données et il y allait encore le matin.
Pris
1
Il ne devrait pas y avoir de fusion. Le but est d'exploser les fonctionnalités en plusieurs parties. Par exemple, dans votre capture d'écran de la vignette défaillante, le but est d'exploser tous vos enregistrements contenant des polygones groupés et spatialement disjoints comme les entités insulaires le long de la côte de la Colombie-Britannique et de l'Alaska, dans des enregistrements de polygones séparés en une seule partie. Ceci peut être réalisé dans QGIS en utilisant l'outil "Multipart to singleparts" sous le menu Vector> Geometry Tools.
Brent Edwards
Une fois que vous avez converti en fonction de pièce unique, vous devez revalider votre géométrie, juste pour être certain que tout est propre.
Brent Edwards
0

Une autre approche aurait pu être d'essayer une conversion de vecteur en raster pour créer un jeu de données de point, puis d'utiliser le jeu de données de point comme base pour écrire du code pour créer vos tuiles.

Ian Allan
la source