Mehr

Verwenden Sie den Python-Parser des Feldrechners mit ArcPy?

Verwenden Sie den Python-Parser des Feldrechners mit ArcPy?


Ich habe ein Punkt-Shapefile mit zwei Spalten, die ich verarbeiten möchte. Die erste Spalte ist aspekt und die zweite aspekt_m60, es gibt nur eine Zeile mit dem Aspekt meines Punktes. Ich habe versucht, ein Skript in Python für ArcGIS 10.2.2 zu schreiben, weil ich es in meinen Code einfügen möchte, aber ohne Erfolg. Der Code ist dieser:

# Feldimport berechnen arcpy # Umgebungseinstellungen festlegen arcpy.env.workspace = "c:/W/Sik" # Lokale Variablen setzen inTable = "Point" fieldName = "aspect_m60" expression = "getCalc(!aspect!, !aspect_m60!) " codeblock = """def getCalc(aspekt, aspekt_m60): if (aspekt < 60): aspekt_m60 = (aspekt - 60) + 360 if (aspekt = 60): aspekt_m60 = aspekt - 60 else: aspekt_m60 = aspekt - 60" ""

Es ist meiner Meinung nach viel intuitiver, mit Cursors zu arbeiten (anstatt zu versuchen, den Feldrechner in einem Skript zu emulieren) für diese Art von Problem. So würden Sie das Problem auf einen Update-Cursor übertragen:

import arcpy # Die Eingabe FC fc = "C:/W/Sik.gdb/yourFC" with arcpy.da.UpdateCursor(fc, ["aspect", "aspect_m60"]) als Cursor: für Zeile im Cursor: # row[ 0] = "aspekt" # row[1] = "aspect_m60" if row[0] < 60: row[1] = (row[0] - 60) + 360 elif row[0] == 60: row[1 ] = row[0] - 60 sonst: row[1] = row[0] - 60 cursor.updateRow(row)

Sie versuchen, das Feld innerhalb des Codeblocks zu setzen, obwohl Sie den Codeblock tatsächlich benötigenRückkehrder gesuchte Wert. Wenn du nur hinzufügstzurück Aspekt_m60Nach dem else-Block sollte es gut funktionieren.

Stellen Sie sich den Codeblock als einen Ort zum Schreiben von Funktionen vor, deren Ergebnisse in Ihrem Feldrechnerausdruck verwendet werden können.


Ihre Funktion gibt nichts zurück. Ich habe Ihren Code so geändert, dass er den Wert von aspekt_m60 zurückgibt.

# Feldimport berechnen arcpy # Umgebungseinstellungen festlegen arcpy.env.workspace = "c:/W/Sik" # Lokale Variablen setzen inTable = "Point" fieldName = "aspect_m60" expression = "getCalc(!aspect!)" codeblock = " ""def getCalc(aspekt): if (aspekt < 60): aspekt_m60 = (aspekt - 60) + 360 if (aspekt = 60): aspekt_m60 = aspekt - 60 else: aspekt_m60 = aspekt - 60 return aspekt_m60"""

Wie einige andere darauf hingewiesen haben, fehlt Ihnen ein Rückgabewert. Du verwechselst auch den Zuweisungsoperator=für einen Gleichheitsoperator==(im 2. wenn). Die if-Struktur ist ebenfalls falsch (if/if/else) und berechnet den falschen Wert für alles unter 60 (sollte if/elif/else sein).

Wenn Sie CalculateField trotzdem verwenden möchten (die andere Antwort mit UpdateCursor ist absolut gültig), wäre der folgende Codeblock das, was Sie beabsichtigt haben.

codeblock = """def getCalc(aspekt, aspekt_m60): if aspekt < 60: aspekt_m60 = (aspekt - 60) + 360 elif aspekt == 60: aspekt_m60 = aspekt - 60 else: aspekt_m60 = aspekt - 60 return aspekt_m60 """