Ich versuche, die Fläche eines Polygons in meinem Python-Skript zu berechnen. Ich erstelle ein neues Polygon aus dem Zusammenführen von zwei und möchte den Bereich des resultierenden Polygons einem Feld in der Ausgabedatei hinzufügen. Das Polygon wird in einem regulären Shapefile gespeichert und projiziert. Fläche vorzugsweise in Karteneinheiten.
Ich hätte gedacht, dass dies eine recht häufige und einfache Aufgabe ist, aber trotz viel Googleing konnte ich bisher keine funktionierende Lösung finden.
Ich hatte vor arcpy.updateCursor
, den Wert nach seiner Berechnung mit einzufügen (derzeit gibt es nur eine Funktion in der FC). Am einfachsten ist es also, wenn er als Variable zurückgegeben werden kann. Jede alternative Lösung, die dieselbe Aufgabe ausführt (den Bereichswert in das richtige Feld bringen), funktioniert auch.
Ich habe auch den Field-Rechner von Python ausprobiert. Geändert von den Hilfeseiten dachte ich, das folgende würde funktionieren, aber bisher kein Glück.
arcpy.AddField_management(tempPgs, "Shape_area", 'DOUBLE')
exp = "float(!SHAPE.AREA!.split())"
arcpy.CalculateField_management(tempPgs, "Shape_area", exp)
Ausführen von ArcGIS Basic 10.1 SP1 mit Python 2.7 unter Windows 7.
Relevante Teile meines aktuellen Codes sehen folgendermaßen aus:
#/.../
arcpy.Copy_management(inpgs, outpgs)
arcpy.AddField_management(outpgs, 'Shape_area', 'LONG')
fields = AM.FieldLst(outpgs)
#/.../
# Identify and search for shapes smaller than minimum area
where1 = '"' + 'Shape_Area' + '" < ' + str(msz)
polyrows = arcpy.SearchCursor(inpgs, where1)
for prow in polyrows:
grd1 = prow.GridID # GridID on the current polygon
grd2 = nDD.get(grd1) # GridID on the polygon downstream
# Update features
if grd2
geometry1 = prow.Shape
geometry2 = geometryDictionary[grd2]
# Update temporary features
arcpy.Merge_management([geometry1, geometry2], tempMerged)
arcpy.Dissolve_management(tempMerged, tempPgs)
fds = AM.FieldLst(tempPgs)
for field in fields[2:]:
arcpy.AddField_management(tempPgs, field, 'DOUBLE')
for fd in fds[2:]:
arcpy.DeleteField_management(tempPgs, fd)
exp = "float(!SHAPE.AREA!.split())"
arcpy.CalculateField_management(tempPgs, "Shape_area", exp)
# Append them to output FC
try:
arcpy.Append_management(tempPgs, outpgs, "TEST")
except arcgisscripting.ExecuteError:
arcpy.Append_management(tempPgs, outpgs, "NO_TEST")
elif ...
else ...
quelle
SHAPE@AREA
als Teil Ihres Cursors zum Lesen des Bereichs verwenden. Die Struktur des Codes hängt jedoch davon ab, ob sich Ihr Gebiet in denselben Einheiten befindet wie das, was Sie ausschreiben möchten.Antworten:
Es gibt drei verschiedene Möglichkeiten, Polygonbereiche mit Arcpy zu finden und in einer Feature-Class zu speichern: 1) Feldrechner, 2) "klassische" Arcpy-Cursor und 3)
arcpy.da
Cursor. Ein Teil davon stammt aus meiner vorherigen Antwort zur Verwendung von SearchCursor .1. Feldrechner
Bei Verwendung des Feldrechners gibt es drei verschiedene Ausdruckstypen, die unterschiedliche Ausdrucksparser verwenden. Dies wird im dritten Parameter des Geoverarbeitungswerkzeugs "Feld berechnen" angegeben . Wenn
!shape.area!
Sie mit like in auf die Eigenschaften des Geometry-Objekts zugreifen , sollten Sie den Python 9.3-Parser verwenden.Der Ausdruck, den Sie zuvor
split()
für das Ergebnis von ausgeführt haben!SHAPE.AREA!
. Dies gibt ein Python-list
Objekt zurück, das nicht in einfloat
Objekt umgewandelt werden kann.In Ihrem Ausdruck können Sie die Einheit des zurückgegebenen Bereichs mithilfe des
@SQUAREKILOMETERS
Flags angeben, dasSQUAREKILOMETERS
auf der Hilfeseite Feld berechnen durch die Einheiten ersetzt wird .Hier ist der Python-Code, den ich für diese Methode verwenden würde:
2. Arc 10.0 - "Klassische" Cursor
Bei Verwendung klassischer Cursor (dh
arcpy.UpdateCursor
) ist das Cursorobjekt ein iterierbares Objekt, dasrow
Objekte enthält. Sie müssen die MethodengetValue
undsetValue
verwenden, um die Geometrie aus der Zeile (als Geometrieobjekt) abzurufen und den Flächenwertrow
als Gleitkommazahl festzulegen.Ihre Ausgabezeile wird in einem temporären Arbeitsbereich gespeichert, bis Sie die
updateRow
Methode auf dem Cursor aufrufen . Dadurch werden die neuen Daten im tatsächlichen Datensatz gespeichert.Hier ist der Python-Code, den ich für diese Methode verwenden würde:
3. Arc 10.1 - arcpy.da-Cursor
Wenn Sie die neuen Cursor im Datenzugriffsmodul (dh
arcpy.da.UpdateCursor
) verwenden, müssen Sie eine Liste von Feldnamen als zweiten Parameter im Cursorkonstruktor übergeben. Dies erfordert etwas mehr Vorarbeit, aber die resultierendenrow
Objekte sind Python-Listen, was das Lesen und Schreiben von Daten beim Durchlaufen von Cursorzeilen erleichtert.arcpy.da.UpdateCursor
hat auch eine bessere Leistung alsarcpy.UpdateCursor
, teilweise, weil unwichtige Felder, insbesondere Geometrie, übersprungen werden.Wenn Geometrie lesen, können Sie eine aus einer Reihe von Geometrie Token wählen, zum Beispiel
SHAPE@TRUECENTROID
,SHAPE@AREA
oderSHAPE@
. Durch die Verwendung eines "einfacheren" Tokens wird die Leistung im Vergleich zu einem TokenSHAPE@
, der alle Geometrieinformationen enthält, erheblich verbessert . Die vollständige Liste der Token finden Sie auf derarcpy.da.UpdateCursor
Hilfeseite.Nach wie vor wird Ihre Ausgabezeile in einem temporären Arbeitsbereich gespeichert, bis Sie die
updateRow
Methode auf dem Cursor aufrufen . Dadurch werden die neuen Daten im tatsächlichen Datensatz gespeichert.Hier ist der Python-Code, den ich für diese Methode verwenden würde:
quelle
row[1] = row[0]
weil es keinarea
Attribut mehr gibt . Sie können den Cursor auch als Kontextmanager in einerwith
Anweisung verwenden und müssen sich nicht um das Löschen von Elementen kümmern.