Suite

Détermination des voisins de la parcelle à l'aide de PYTHON

Détermination des voisins de la parcelle à l'aide de PYTHON


Comme vous pouvez le voir sur la première photo, j'ai le colis 220, et je veux déterminer la position de chacun de ses voisins ! L'idée était donc de calculer le relèvement entre le centroinde de 220, et l'autre centroïde des voisins (lorsque le relèvement est compris entre [50,150] = Nord ; [150, 250]= Est ; [250,350]= Ouest… ). Donc, pour déterminer les voisins, j'utilise la fonctionarcpy.PolygonNeighbors_analysis (in_features, out_table, {in_fields})(Photo 2), et à la photo 3, nous avons une parcelle de centre de gravité (X,Y). Donc à chaque fois je devrais prendre

  1. (X,Y) de P220 comme point de départ et (X,Y) de P228 comme point final que de calculer le relèvement
  2. (X,Y) de P220 comme point de départ et (X,Y) de P227 comme point final, calculez le relèvement
  3. (X,Y) de P220 comme point de départ et (X,Y) de P226 comme point final, calculez le relèvement
  4. que pour tous les voisins sur la photo 2

Pour ce faire, j'ai utilisé trois boucles, et je pense que cela tourne à droite, mais cela ne le fait que pour la première rangée et ne passe pas à la nouvelle rangée!

Le code est celui-ci :

>>> cur = arcpy.UpdateCursor("Join_Output_12") >>> cur2 = arcpy.UpdateCursor("Join_Output_12") >>> cur_t = arcpy.UpdateCursor("tb20_12_2014_") >>> del row2, Refname__table_neighbor, start_x1, start_y1 , end_x1, end_y1, copy_field >>> pour la ligne dans cur :… Refname_feature = row.getValue("RefName")… pour row_t dans cur_t :… Refname__table_target = row_t.getValue("src_RefName")… if(Refname__table_target==Refname_feature) :… start_x1 = row.getValue("POINT_X")… start_y1 = row.getValue("POINT_Y")… print Refname_feature… print start_x1… print start_y1… Refname__table_neighbor = row_t.getValue("nbr_RefName")… print Refname__table_neighbor… pour row2 dans cur2 :… copy_field = row2.getValue("copy_field")… if (copy_field==Refname__table_neighbor):… end_x1 = row2.getValue("POINT_X")… end_y1 = row2.getValue("POINT_Y")… print copy_field… print end_x1 … imprimer end_y1… ligne = cur.next()

Le résultat est:

1 221408.8543 200288.7235 1 1 221408.8543 200288.7235

Donc je pense que le problème vient de la boucle for!

Maintenant après avoir obtenu ce résultat, que vous pouvez voir sur la photo 4 (Positionner chaque parcelle) Le résultat que j'ai obtenu était bon ! Mais ça ne répond pas à 100% à mon besoin, pour être plus clair voyons l'exemple de la parcelle 221, elle a la parcelle voisine 220 au Nord et aussi à l'Ouest, mais à la table on voit juste Nord, pour ça je veux pour canncatener ce résultat au résultat de la fonctionCalculateAdjacentFields_cartography (in_features, in_field)vous me direz pourquoi tout simplement ne pas utiliser uniquement cette fonction ? mais c'est aussi incomplet ! regarde la photo 5 pour voir le résultat Prenons l'exemple P220, on voit qu'il met juste 224, 226 sur Nord, même s'il y en a More ! L'idée est donc de concaténer les deux résultats pour obtenir enfin un résultat plus complet et plus fiable ! Mais comment le faire ? je ne trouve pas de logique pour les combiner !!

EDIT : Ceci est un exemple de relation compliquée, et sur la table après ce que j'obtiens comme résultat le lin en couleur, présente les Voisins récupérés par le programme, et quand j'ai regardé quelle sorte de bordel de colis, j'ai trouvé c'est juste qui n'est pas en contact avec la parcelle taget (comme 164 P2 et 150 au Nord… )!!


Les curseurs intégrés sont la pire façon de programmer quoi que ce soit. Ne le fais pas. Votre code échoue car les curseurs ne lisent qu'une seule fois. Ainsi, le curseur intérieur doit être complètement reconstruit à partir de zéro et recommencé pour chaque enregistrement dans le curseur extérieur. Pour chaque enregistrement supplémentaire que vous devez comparer dans chaque table, le temps nécessaire pour comparer les deux tables augmente essentiellement sur une courbe de croissance exponentielle, ce qui devrait être évité à tout prix si vous avez plus de 50 enregistrements dans chaque table.

Vos curseurs ne sont pas non plus des curseurs da, ils sont donc 10 fois plus lents à sortir de la porte. Utilisez deux boucles de curseur complètement séparées. L'un pour lire les données des sources dans deux dictionnaires et l'autre pour mettre à jour les fonctionnalités en fonction des correspondances apportées aux dictionnaires. Les dictionnaires sont des structures à accès aléatoire, les curseurs ne le sont pas et les dictionnaires sont en mémoire alors que les curseurs ne le sont pas. Ainsi, vous obtenez des performances environ 20 à 100 fois supérieures avec l'approche que je recommande. Voir mon blog sur la manipulation de données de charge turbo avec des curseurs et des dictionnaires Python.

Vous utilisez UpdateCursors mais n'écrivez rien dans la table. Pourquoi? Vous avez besoin d'un champ X et Y pour écrire. Vous n'avez besoin que d'un seul UpdateCursor sur une source, jamais deux sur la même source de données. Définissez ces champs et leurs noms et dans quelle table ils résideront.

Alors étudiez mon blog et recommencez. Tu seras content de l'avoir fait.

Merci d'avoir édité votre message avec un graphique qui explique la source des tableaux et l'objectif de l'analyse ainsi que de meilleurs tableaux avec lesquels travailler. La première étape consiste à ajouter 4 champs Double à la table avec les deux champs src_RefName et nbr_RefName pour contenir les XY des deux centroïdes de l'autre table afin qu'il y ait un endroit pour stocker les résultats du curseur de mise à jour. Je les appellerai X_Start, Y_Start, X_End et Y_End. Ajoutez également un autre champ double pour le roulement. Le relèvement calculé ci-dessous est le relèvement trigonométrique qui commence à l'est et va dans le sens inverse des aiguilles d'une montre, et non le relèvement de navigation qui commence au nord et va dans le sens des aiguilles d'une montre. Si vous voulez le relèvement de navigation, changez la ligne qui lit : updateRow6 = (angle + 360) % 360 en updateRow6 = (90 - angle) % 360. L'association des relèvements aux points cardinaux est [45-135] = North, [ 135-225] = Ouest, [225-315] = Sud, [315-359.9… , 0-45] = Est.

Chargez maintenant la table avec le centroïde XY dans un dictionnaire. Récupérez ensuite les deux valeurs RefName de chaque ligne et remplissez les 2 coordonnées XY et les champs doubles de relèvement. Le troisième exemple de mon blog peut être adapté pour faire le processus.

from time import strftime print "Start script: " + strftime("%Y-%m-%d %H:%M:%S") import arcpy from math import degrés, atan2 sourceFC = r"C:PathSourceFeatureClass " sourceFieldsList = ["RefName", "POINT_X", "POINT_Y"] # Utilisez la compréhension de liste pour construire un dictionnaire à partir d'un da SearchCursor valueDict = {r[0]:(r[1:]) pour r dans arcpy.da. SearchCursor(sourceFC, sourceFieldsList)} updateFC = r"C:PathUpdateFeatureClass" updateFieldsList = ["src_RefName", "nbr_RefName", "X_Start", "Y_Start", "X_End", "Y_End", "Bearing"] avec arcpy.da.UpdateCursor(updateFC, updateFieldsList) as updateRows : pour updateRow dans updateRows : # stocker les valeurs src_RefName et nbr_RefName de la ligne dans une paire de variables keyValue keyValue1 = updateRow[0] keyValue2 = updateRow[1] # vérifier que le Les keyValues ​​sont dans le dictionnaire si keyValue1 dans valueDict et keyValue2 dans valueDict : # transfère la valeur stockée sous les keyValues ​​du dictionnaire vers le champ mis à jour. updateRow[2] = valueDict[keyValue1][0] updateRow[3] = valueDict[keyValue1][2] updateRow[4] = valueDict[keyValue2][0] updateRow[5] = valueDict[keyValue2][3] angle = degrés(atan2(valueDict[keyValue1][4] - valueDict[keyValue2][5], valueDict[keyValue1][0] - valueDict[keyValue2][0])) updateRow[6] = (angle + 360) % 360 updateRows .updateRow(updateRow) del valueDict print "Script terminé : " + strftime("%Y-%m-%d %H:%M:%S")

Éditer:

Vous avez étendu votre question à un problème différent consistant à essayer de décrire avec précision l'image à l'aide d'un tableau de directions de boussole. En faisant cela, vous soulevez un problème beaucoup plus important. Écrire un programme pour évaluer correctement votre image dans ce tableau, c'est comme essayer d'amener un groupe d'aveugles à se mettre d'accord sur ce qu'est un éléphant alors qu'ils n'en ressentent qu'une petite partie. C'est ce que vous essayez lorsque vous programmez des réalités complexes en généralisations simplifiées et que vous les divisez en examens séparés de petites parties. Il est presque impossible que des hommes aveugles opérant de cette manière proposent la même description de la réalité qu'une personne voyante expliquera.

Nos yeux et notre cerveau sont incroyables pour déterminer presque instantanément ce qu'il faut prendre et quoi jeter en essayant d'évaluer l'image que vous avez donnée, et aucun programme que vous ou moi pouvons écrire ne peut l'égaler. Cependant, même pour les personnes voyantes, la complexité de vos formes signifie qu'il n'y a pas de tableau parfait, car même les personnes voyantes peuvent aborder votre problème de plusieurs points de vue et proposer différents tableaux de description de la direction de la boussole (je peux voir plusieurs réponses correctes moi-même, selon les méthodes que j'adopte). Donc, à un moment donné, il faut se satisfaire des imperfections que les généralisations créent toujours et des limites d'une méthodologie choisie. Mais cela ne signifie pas que vous êtes limité à un programme qui ne considère qu'une seule méthodologie. Cependant, les méthodologies devraient être appliquées d'une manière progressivement plus complexe après que des approches moins complexes se révèlent inadéquates.

Par exemple, vous n'avez pas vraiment évalué les relèvements de vos polygones là où ils se touchent, vous n'avez évalué que les relèvements de vos centroïdes de polygones. C'est la partie de l'éléphant que vos aveugles ont expérimentée et vous ont actuellement parlé de cet éléphant.

Ces centroïdes peuvent avoir une mauvaise relation avec le bord partagé de vos polygones. Une analyse potentiellement meilleure consiste à examiner les deux relèvements des centroïdes des polygones par rapport au centroïde qui tombe sur le bord partagé de vos polygones. Dans le cadre de cette analyse, vous devez probablement également déterminer quel polygone se trouve le long du côté droit du bord partagé et lequel se trouve le long du côté gauche du bord partagé pour obtenir l'angle normal par rapport à la ligne au centre de la ligne pour chaque polygone. Cela formera un autre ensemble d'angles qui pourraient révéler la suffisance ou l'insuffisance du relèvement centroïde que vous avez déjà examiné pour décrire les orientations relatives de la boussole des deux polygones. De toute évidence, traduire cet ensemble d'angles pour qu'il corresponde à ce que vos yeux et votre esprit considèrent est plus difficile, mais probablement plus semblable à ce que votre cerveau fait réellement. Vous pouvez également regarder les extrémités du bord partagé et leurs angles normaux comme un autre moyen d'évaluer l'adéquation du centre de gravité du bord partagé pour donner une image de la réalité. Voici une image de la partie de l'éléphant que cette analyse de centroïde de bord partagé pourrait peindre :

Si vous regardez le relèvement du centre de gravité du polygone 224 par rapport au centre de gravité du polygone 220 dans la première image, il apparaît que la relation de relèvement doit être décrite comme étant vers le sud-ouest. Cependant, lorsque vous regardez l'image des relèvements du centre de gravité du polygone 224 par rapport au centre de gravité de son bord partagé avec le polygone 220, il est clair que la relation de relèvement entre 224 et 220 de ce point de vue est plus précisément décrite comme un relation de direction sud-est. De différents points de vue, les deux sont vrais pour cet éléphant. La question est : acceptez-vous seulement une de ces réponses comme vraie ou acceptez-vous les deux comme vraies ?

Mais que se passe-t-il si les deux polygones se touchent à plusieurs endroits et partagent plus d'un bord continu ? Que faites-vous alors? La réponse est toujours de résoudre d'abord les problèmes les plus simples, puis de trouver un moyen d'isoler l'ensemble d'objets qui défient cette solution et de retester uniquement cet ensemble. C'est ce qui rend un bon processus de programme efficace sans perdre un temps précieux à faire beaucoup d'évaluations inutiles.

Comme vous pouvez le voir, ce problème peut aller bien au-delà de ce qu'un simple message peut répondre et selon l'importance de ce tableau pour vos besoins d'analyse, vous seul pouvez déterminer combien de temps vous êtes prêt à consacrer à rapprocher les aveugles programmatiques de la réalité de l'éléphant que vous, l'homme voyant, voyez. Néanmoins, vous pouvez maintenant voir que la technique de conversion des curseurs à accès non aléatoire en dictionnaires à accès aléatoire (et maintenant en listes à l'intérieur des dictionnaires) est essentielle pour permettre une évaluation efficace du problème.


Voir la vidéo: Python: tiedostonkäsittely ja kirjastot