J'essaie de comparer deux classes d'entités distinctes pour identifier les différences entre elles (une sorte de fonction diff). Mon workflow de base:
- J'extrait les géométries à l'aide d'un SearchCursor
- Enregistrez les géométries des deux classes d'entités en tant que GeoJSON en utilisant une modification
__geo_interface__
(obtenue de valveLondonreturn {'type': 'Polygon', 'coordinates': [[((pt.X, pt.Y) if pt else None) for pt in part] for part in self]}
). C'est pour éviter l'objet de géométrie partagée qu'ESRI utilise avec les curseurs et l'impossibilité de faire des copies complètes (certaines discussions ici sur gis.stackexchange en parlent). - Vérifiez les géométries des deux classes d'entités en fonction d'un identifiant unique. Par exemple, comparez la géométrie FC1 OID1 avec la géométrie FC2 OID1. Pour obtenir la géométrie en tant qu'occurrence d'objet ESRI, appelez
arcpy.AsShape()
(modifié pour lire les polygones avec des trous (voir point 2 ci-dessus) avecreturn cls(Array([map(lambda p: Point(*p) if p is not None else Point(), part) for part in coordinates]))
. La comparaison est simplementgeom1.equals(geom2)
comme indiqué dans la classe de géométrie .
Je m'attends à trouver ~ 140 changements dans les géométries, mais mon script insiste sur le fait qu'il y en a 430. J'ai essayé de vérifier ces représentations GeoJSON et elles sont identiques, mais la classe de géométrie equals () refuse de le dire.
Un exemple est ci-dessous:
>>> geom1geoJSON
{'type': 'Polygon', 'coordinates': [[(-122.8423481559999, 47.060497293000083), (-122.84239755599992, 47.059262423000064), (-122.84416913599989, 47.059309693000046), (-122.84416913599989, 47.060497293000083), (-122.8423481559999, 47.060497293000083)]]}
>>> geom2geoJSON
{'type': 'Polygon', 'coordinates': [[(-122.8423481559999, 47.060497293000083), (-122.84239755599992, 47.059262423000064), (-122.84416913599989, 47.059309693000046), (-122.84416913599989, 47.060497293000083), (-122.8423481559999, 47.060497293000083)]]}
>>> geom1 = arcpy.AsShape(geom1geoJSON)
>>> geom2 = arcpy.AsShape(geom2geoJSON)
>>> geom1.equals(geom2)
False
>>> geom2.equals(geom1)
False
Le comportement attendu ici doit être True (pas False).
Quelqu'un a-t-il des suggestions avant de tout déplacer vers les géométries ogr? (J'hésite car ogr.CreateGeometryFromGeoJSON () attend une chaîne, et arcpy __geo_interface__
retourne un dictionnaire et j'ai l'impression d'ajouter une complexité supplémentaire).
Les ressources suivantes ont été utiles, même si elles ne répondent pas à la question:
- question arcpy.Geometry ici sur gis.stackexchange.com qui a été lié ci-dessus dans mon texte.
- Erreurs dans la classe Polygon d'arcpy sur les forums arcgis.com (apparemment il y a beaucoup d'erreurs de précision dans ArcGIS 10.0 qui ont théoriquement été corrigées dans 10.1 mais je ne peux pas vérifier que, dans 10.0 SP5, vous obtenez toujours l'erreur).
numpy.allclose()
rtol
paramètre sur 0. Par défaut, c'est 1e-05 et cela peut conduire à une grande tolérance si les valeurs des tableaux sont grandes voir: stackoverflow.com/a/57063678/1914034La précision des coordonnées va être une considération importante ici. Les nombres à virgule flottante ne peuvent pas être stockés exactement.
Si vous utilisez l' outil de comparaison des fonctionnalités , obtient-il le résultat attendu en utilisant la tolérance XY par défaut?
la source
à côté de la réponse @ blah328, vous avez le choix de comparer deux tableaux pour signaler les différences et les similitudes avec les valeurs tabulaires et les définitions de champ avec Table Compare .
Exemple:
la source
Si la
.equals()
fonction ne fonctionne pas comme prévu et / ou si les coordonnées sont légèrement modifiées dans ArcGIS, vous pouvez masser les coordonnées XY, puis comparer l'équivalent chaîne de la géométrie. Remarquez,truncateCoordinates()
coupez toutes les valeurs au-delà de la 4ème décimale.la source
Vous pouvez utiliser l' outil Sélectionner une couche par emplacement (gestion des données) avec le paramètre overlap_type "ARE_IDENTICAL_TO", basculer la sélection , vérifier le nombre de lignes, puis parcourir les lignes pour collecter les objectids ou toute autre information pertinente.
la source