Détection de la forme d'un polygone ramifié?

13

J'ai une couche vectorielle avec des millions de polygones assurant une couverture continue. J'ai besoin de les classer selon leur forme. J'utilise déjà plusieurs indices de forme de l'écologie du paysage comme la compacité ( 4piA / P ^ 2 ), la largeur moyenne ( 2A / P ), le numéro de forme ( P / sqrt (A) ), j'ai également vu cette réponse à Calcul de la rondeur / compacité de polygone?

Mon problème est que toutes ces mesures utilisent uniquement un certain rapport de surface et de périmètre. Même l' indice de dimension fractale utilise uniquement l'aire et le périmètre ( 2ln (0,25 P) / ln (A) ). Mais comment distinguer deux polygones ayant la même surface et le même périmètre mais une forme absolument différente? Comme ce polygone ramifié A:

polygone ramifié vs bande incurvée

que j'ai essayé de dessiner avec la même surface et le même périmètre que la bande courbe B. Tous mes index connus seront les mêmes pour eux. Mais pour moi, il est très important de différencier les bandes simples (y compris incurvées comme la nouvelle lune) des formes ramifiées complexes.

Je montre intentionnellement le polygone B sous forme de bande incurvée et non de bande droite parce que je connais l' indice de cercle circonscrit qui détecte les formes allongées droites, mais mes polygones peuvent également avoir les mêmes cercles. Même si je construis une coque convexe et calcule un ratio de zones Apolygone / Aconvex , cela peut être très similaire ici.

Alors, comment puis-je distinguer clairement le polygone ramifié A du polygone B dans les données vectorielles automatiquement? (Les convertir en raster nécessiterait une taille de cellule extrêmement petite, un énorme ensemble de données et un manque de mémoire, donc ce n'est pas possible). Existe-t-il d'autres indices de forme qui incluent d'autres paramètres? Idéalement, la méthode distinguerait non seulement des polygones clairement ramifiés, mais même C et D:

entrez la description de l'image ici

Ma seule idée est de construire la coque convexe puis d'effacer le polygone de sa coque convexe et de compter le nombre de (gros) morceaux qu'elle laisse (effacer polygone par polygone et non la couche entière). Cela pourrait montrer la complexité de la frontière.

Je me réjouis des solutions / algorithmes mathématiques, que je mettrais plus tard en œuvre en Python.

Nadya
la source
1
Vous n'avez pas besoin de beaucoup de Python. Essayez! forme!. enveloppe convexe (). symmetricDifference (! shape!) Dans la calculatrice de champ. Essayez d'abord sur une petite copie de sous-ensemble. Voir l'aide sur la géométrie arcpy pour la syntaxe correcte.
FelixIP
Cela pourrait être une excellente question, mais pour le moment, vous posez plusieurs questions en ne déterminant pas si vous posez des questions sur QGIS ou ArcGIS Desktop, puis en lançant également Python. Une fois que vous avez spécifié précisément ce que vous avez essayé, il est plus facile pour les répondeurs potentiels de vous aider où vous êtes coincé. Je suggère de le concentrer sur QGIS pour éviter d'échouer votre première réponse.
PolyGeo
1
J'ai des données dans la géodatabase Esri car un fichier de formes dépassait déjà 2 Go. Je pourrais faire quelque chose à ce sujet s'il existe une solution de travail dans QGIS ou quelque part. Mais je ne demande pas à l'intérieur d'un logiciel spécifique. Je demande une métrique, une méthode pour détecter mathématiquement une forme avec une bordure complexe (ramifiée). 1 question. Un article scientifique avec une formule serait également correct, je vais penser comment le mettre en œuvre moi-même.
nadya
1
Ma première pensée a été la même que la vôtre, en regardant les différences entre le nombre et la taille des polygones restants après avoir soustrait l'original de sa coque convexe (ou concave) (voir aussi les formes alpha).
user2856
1
Si seulement le squelette était suffisamment rapide pour calculer, je l'utiliserais pour calculer 4A / PL, l'aire, le périmètre et la longueur entre les nœuds les plus importants du squelette pour la compacité. Il en va de même pour le plus grand cercle inscrit.
FelixIP

Réponses:

11

Vous pouvez jeter un œil à la méthode suivante: squelette vos polygones et plutôt travailler sur des entités de type ligne liées à votre polygone d'origine avec un ID de polygone source unique. Je suppose qu'il y a quelques suppositions à faire (par exemple, quand considérer une polyligne comme une vraie ligne médiane: longueur minimale pour qu'une polyligne soit éligible au statut de ligne centrale). Lorsque le nombre d'axes est supérieur à 1 pour un seul polygone source, il est ramifié.

Un polygone ramifié, lorsqu'il est nettoyé jusqu'à une ligne médiane, aura plusieurs lignes alors qu'un polygone droit peut n'avoir qu'une seule grande ligne au centre (identique à l'interprétation humaine en fait).

Exemple :

  • lorsque vous dessinez une lettre Y, vous utilisez au moins 2 traits continus (= 2 polylignes), donc elle est ramifiée car le nombre minimal de traits est> 1.
  • lorsque vous dessinez une lettre L, vous utilisez au moins 1 trait continu. Ce n'est pas ramifié.

Plus d'exemples de cette logique:

  • Lorsque vous dessinez un A: 2 traits = il est ramifié
  • Lorsque vous daw un B: 3 coups = il est ramifié
  • lorsque vous dessinez un trait C: 1 = il n'est pas ramifié
  • etc

Je n'ai rien essayé, juste essayer la logique, mais je pense que cela pourrait fonctionner.

Voir: Skeletonize vecteurs dans QGIS / Python ou http://postgis.net/docs/ST_StraightSkeleton.html

Ou

Exemple

Source: Extraction de la ligne centrale d'un polygone complexe dans PostGIS / Python

EDIT: Pour les cas C & D, vous devez déjà avoir filtré les formes B (non ramifiées).

  • Assurez-vous qu'un ID unique relie la ligne médiane et le polygone source.
  • Transformez vos polygones en polylignes
  • Densifiez la polyligne centrale et la polyligne limite avec des points réguliers (pas trop pour éviter les problèmes de mémoire plus tard mais suffisamment pour "attraper" les bits irréguliers.
  • Créer une matrice de distance entre les points de la ligne médiane et les points de la frontière
  • Conserver dans les lignes de matrice uniquement celles où ID_centerline = ID_borderline
  • Créer des statistiques pour avoir une valeur d'écart type
  • Définissez une valeur liée pour indiquer pour les valeurs SD élevées qu'il s'agit d'un contour non régulier et créez l'indicateur requis, pour chaque ID unique
  • Remettez l'indicateur dans le polygone d'origine en joignant le champ sur la base de l'ID unique.
gisnside
la source
Merci pour l'idée, je vais essayer de créer des traits d'axe
nadya
Juste, le problème pour distinguer mes polygones C et D restera
nadya
Vous pourriez avoir besoin de différentes méthodes pour différents cas et diviser le travail. Une fois que vous avez des polygones non ramifiés (B), vous pouvez affiner B pour essayer de trouver C et D. Le problème est que je ne vois pas quelle logique vous utilisez pour distinguer C de D. vous devrez probablement le formuler clairement avec critères.
gisnside
1
La différence entre C et D semble être qu'en C, les côtés du polygone sont approximativement à une distance uniforme de la ligne médiane, tandis qu'en D les côtés sont une distance non uniforme de la ligne médiane.
csk
1
@csk je vois ça. Je suppose que traduire cela en code équivaudrait à calculer des statistiques sur la distance entre la ligne médiane et la ligne frontière. En densifiant la polyligne de bordure avec plus de points, puis en convertissant cette bordure en points + en prenant une distance par rapport au travail équivalent sur la ligne médiane, vous obtiendriez des statistiques sur ce comportement. Si l'écart-type est élevé, la forme sera probablement irrégulière. Difficile de voir comment faire ça sur tous les polygones ... beau défi là
gisnside