Étant donné plusieurs polygones qui se chevauchent de plusieurs manières, je voudrais exporter de ces entités tous les polygones qui ne se chevauchent pas de manière itérative.
Le produit serait un certain nombre de fonctionnalités sans chevauchement qui, réunies, constituent l'original.
Les produits pourraient ensuite être utilisés comme entrées dans les statistiques zonales, ce qui serait beaucoup plus rapide que l'itération des statistiques zonales sur chaque polygone.
J'ai essayé de coder cela dans ArcPy sans succès.
Le code pour cela existe-t-il déjà?
arcpy
algorithm
overlapping-features
ndimhypervol
la source
la source
Réponses:
Il s'agit d'un problème de coloration de graphique .
Rappelez-vous qu'un coloriage de graphe est une affectation d'une couleur aux sommets d'un graphe de telle sorte qu'aucun deux sommets qui partagent un bord n'auront également la même couleur. Plus précisément, les sommets (abstraits) du graphique sont les polygones. Deux sommets sont connectés avec une arête (non orientée) chaque fois qu'ils se croisent (sous forme de polygones). Si nous prenons une solution au problème - qui est une séquence de (disons k ) collections disjointes des polygones - et attribuons une couleur unique à chaque collection de la séquence, alors nous aurons obtenu un k- coloriage du graphique . Il est souhaitable de trouver un petit k .
Ce problème est assez difficile et reste non résolu pour les graphiques arbitraires. Considérez une solution approximative simple à coder. Un algorithme séquentiel devrait faire l'affaire. L'algorithme Welsh-Powell est une solution gourmande basée sur un ordre décroissant des sommets par degré. Traduit dans la langue des polygones d'origine, triez d'abord les polygones dans l'ordre décroissant du nombre d'autres polygones qu'ils chevauchent. En travaillant dans l'ordre, donnez au premier polygone une couleur initiale. À chaque étape successive, essayez de colorer le polygone suivant avec une couleur existante: c'est-à-dire, choisissez une couleur qui n'est pasdéjà utilisé par l'un des voisins de ce polygone. (Il existe plusieurs façons de choisir parmi les couleurs disponibles; essayez soit celle qui a été la moins utilisée, soit choisissez-en une au hasard.) Si le polygone suivant ne peut pas être coloré avec une couleur existante, créez une nouvelle couleur et coloriez-la avec celle-ci.
Une fois que vous avez réalisé une coloration avec un petit nombre de couleurs, effectuez zonalstats couleur par couleur: par construction, vous êtes assuré qu'il n'y a pas deux polygones d'une couleur donnée qui se chevauchent.
Voici un exemple de code dans
R
. (Le code Python ne serait pas très différent.) Premièrement, nous décrivons les chevauchements entre les sept polygones montrés.Autrement dit, les polygones 1 et 2 se chevauchent, tout comme les polygones 2 et 3, 3 et 4, ..., 1 et 7.
Triez les sommets par degré décroissant:
Un algorithme de coloration séquentielle (brut) utilise la première couleur disponible qui n'est pas déjà utilisée par un polygone se chevauchant:
Initialisez les structures de données (
colors
etcolor.next
) et appliquez l'algorithme:Divisez les polygones en groupes selon la couleur:
La sortie de cet exemple utilise quatre couleurs:
Il a divisé les polygones en quatre groupes qui ne se chevauchent pas. Dans ce cas, la solution n'est pas optimale ({{3,6,5}, {2,4}, {1,7}} est un tricolore pour ce graphique). En général, la solution qu'il obtient ne devrait cependant pas être trop mauvaise.
la source
La méthodologie recommandée par #whuber m'a inspiré à prendre une nouvelle direction, et voici ma solution arcpy, en deux fonctions. Le premier, appelé countOverlaps, crée deux champs, "overlaps" et "ovlpCount" pour enregistrer pour chaque poly les polys qui se chevauchent avec lui, et combien de chevauchements se sont produits. La deuxième fonction, explodeOverlaps, crée un troisième champ, "expl", qui donne un entier unique à chaque groupe de polys non chevauchants. L'utilisateur peut alors exporter de nouveaux fc en fonction de ce champ. Le processus est divisé en deux fonctions car je pense que l'outil countOverlaps peut s'avérer utile en soi. Veuillez excuser la négligence du code (et la convention de dénomination imprudente), car c'est assez préliminaire, mais cela fonctionne. Assurez-vous également que le "idName" champ représente un champ avec des ID uniques (uniquement testé avec des ID entiers). Merci whuber de m'avoir fourni le cadre nécessaire pour aborder ce problème!
la source
countOverlaps
correspond aux deux lignesnbrhoods <- sapply(vertices, neighbors); degrees <- sapply(nbrhoods, length)
de mon code:degrees
est le nombre de chevauchements. Bien sûr, votre code est plus long car il reflète la majeure partie de l'analyse SIG qui est tenue pour acquise dans ma solution: à savoir, que vous identifiez d'abord les polygones qui se chevauchent et qu'à la fin, vous utilisez la solution pour générer des jeux de données de polygones. Ce serait une bonne idée d'encapsuler les calculs de la théorie des graphes, donc si jamais vous trouvez un meilleur algorithme de coloration, il serait facile de le brancher.Cela fait un moment, mais j'ai utilisé ce code pour ma propre application et cela fonctionne très bien - merci. J'ai réécrit une partie de celui-ci pour le mettre à jour, l'appliquer aux lignes (avec une tolérance) et l'accélérer considérablement (ci-dessous - je l'exécute sur 50 millions de tampons qui se croisent et cela ne prend que quelques heures).
la source
Dans ce cas, j'utilise généralement la méthode suivante:
Je crois que le résultat sera celui que vous vouliez, et vous pouvez même compter le nombre de chevauchements. Je ne sais pas si en termes de performances ce sera mieux pour vous ou non.
la source