Ich versuche, zwei separate Feature-Classes zu vergleichen, um Unterschiede zwischen ihnen zu identifizieren (eine Art Diff-Funktion). Mein grundlegender Workflow:
- Ich extrahiere die Geometrien mit einem SearchCursor
- Speichern Sie die Geometrien der beiden Feature-Classes als GeoJSON mit einer geänderten
__geo_interface__
(von valveLondonreturn {'type': 'Polygon', 'coordinates': [[((pt.X, pt.Y) if pt else None) for pt in part] for part in self]}
). Dies soll das gemeinsame Geometrieobjekt vermeiden, das ESRI mit Cursorn verwendet, und die Unfähigkeit, tiefe Kopien zu erstellen (einige Diskussionen hier auf gis.stackexchange sprechen darüber). - Überprüfen Sie die Geometrien der beiden Feature-Classes anhand eines eindeutigen Bezeichners. Vergleichen Sie beispielsweise die FC1-OID1-Geometrie mit der FC2-OID1-Geometrie. Um die Geometrie als ESRI-Objektinstanz abzurufen, rufen Sie
arcpy.AsShape()
(geändert, um Polygone mit Löchern zu lesen (siehe Punkt 2 oben) mitreturn cls(Array([map(lambda p: Point(*p) if p is not None else Point(), part) for part in coordinates]))
. Der Vergleich erfolgt einfachgeom1.equals(geom2)
wie in der Geometrieklasse angegeben .
Ich erwarte etwa 140 Änderungen in den Geometrien, aber mein Skript besteht darauf, dass es 430 gibt. Ich habe versucht, diese GeoJSON-Darstellungen zu überprüfen, und sie sind identisch, aber die Geometrieklasse equals () weigert sich, dies zu sagen.
Ein Beispiel ist unten:
>>> 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
Das erwartete Verhalten sollte hier True (nicht False) sein.
Hat jemand irgendwelche Vorschläge, bevor ich alles auf OGR-Geometrien verschiebe? (Ich zögere, da ogr.CreateGeometryFromGeoJSON () einen String erwartet und arcpy's __geo_interface__
ein Wörterbuch zurückgibt und ich das Gefühl habe, zusätzliche Komplexität hinzuzufügen.)
Fanden die folgenden Ressourcen hilfreich, obwohl sie die Frage nicht beantworten:
- arcpy.Geometry Frage hier auf gis.stackexchange.com, die oben in meinem Text verlinkt wurde.
- Fehler in der Polygon-Klasse von arcpy aus den arcgis.com-Foren (anscheinend gibt es viele Präzisionsfehler in ArcGIS 10.0, die theoretisch in 10.1 behoben wurden, aber ich kann nicht überprüfen, dass in 10.0 SP5 der Fehler weiterhin auftritt).
numpy.allclose()
rtol
Parameter auf 0 zu setzen. Standardmäßig ist es 1e-05 und es kann zu einer großen Toleranz führen, wenn die Array-Werte groß sind. Siehe: stackoverflow.com/a/57063678/1914034Die Koordinatengenauigkeit wird hier eine wichtige Rolle spielen. Gleitkommazahlen können nicht exakt gespeichert werden.
Wenn Sie das Feature Compare- Tool verwenden, wird das erwartete Ergebnis mit der Standard-XY-Toleranz erzielt?
quelle
Neben der Antwort @ blah328 haben Sie die Wahl, zwei Tabellen zu vergleichen, um Unterschiede und Ähnlichkeiten mit Tabellenwerten und Felddefinitionen mit Table Compare zu melden .
Beispiel:
quelle
Wenn die
.equals()
Funktion nicht wie erwartet funktioniert und / oder die Koordinaten in ArcGIS geringfügig geändert werden, können Sie die XY-Koordinaten massieren und dann das Zeichenfolgenäquivalent der Geometrie vergleichen. Beachten Sie, dasstruncateCoordinates()
alle Werte nach der 4. Dezimalstelle abgeschnitten werden.quelle
Sie können das Werkzeug Layer nach Speicherort auswählen (Datenverwaltung) mit dem Parameter "ARE_IDENTICAL_TO" verwenden, die Auswahl ändern, die Zeilenzahl überprüfen und dann die Zeilen durchlaufen, um die Objekt-IDs oder andere relevante Informationen zu sammeln.
quelle