ArcGIS Reclassify schlägt in der Python Toolbox fehl
Ich versuche eine Python Toolbox zu erstellen, um U-Boot-Erdrutsche zu analysieren. Unter anderem möchte ich das Aspekt-Tool ausführen und die Aspekte dann in Gruppen mit einem 45-Grad-Intervall neu klassifizieren. Deshalb mache ich folgendes:
import arcpy
import arcpy.sa
arcpy.env.workspace = r'C:\FIP_Tools20191118\GIS_files\SBP_Toolbox.gdb'
arcpy.CheckOutExtension('Spatial')
aspect_ras = arcpy.sa.Aspect('Smooth_Bathymetry', 'PLANAR', 'METER')
aspect_ras.save('aspect_raster')
remap = RemapRange([[0, 45, 45], [45, 90, 90], [90, 135, 135], [135, 180, 180], [180, 225, 225], [225, 270, 270], [270, 315, 315], [315, 360, 360]])
reclass_ras = arcpy.sa.Reclassify('aspect_raster', 'Value', remap, 'NODATA')
arcpy.CopyRaster_management(reclass_ras, 'reclass_Ras')
Das Seltsame ist, dass der obige Code einwandfrei funktioniert, solange ich ihn über Pycharm oder das ArcGIS Python-Fenster ausführe. Wenn ich jedoch versuche, ihn in eine Python-Toolbox (.pyt) einzufügen und auszuführen, werden die folgenden Fehler ausgegeben:
FEHLER 000864: Neuklassifizierung: Die Eingabe befindet sich nicht innerhalb der definierten Domäne.
FEHLER 000893: Ein leerer GP-Wert oder Text wird eingegeben.
Ich verstehe wirklich nicht, warum es in einer Toolbox nicht funktioniert. Die Tatsache, dass es ansonsten funktioniert, zeigt mir, dass es kein grundlegendes Problem in meinem Code gibt, weshalb ich erwarte, dass es sich um Hintergrundinformationen handelt, die mir fehlen. Ich bin hier wirklich ratlos.
Ich verwende ArcGIS 10.6.1 unter Windows 10
Antworten
OK, eigentlich habe ich es gerade repariert. Um meine Frage zu beantworten, muss ich einige zusätzliche Hintergrundinformationen bereitstellen:
Grundsätzlich ist das Aspektintervall nicht fest codiert, sondern wird über einen Parameter bereitgestellt. Der Zugriff erfolgte jedoch über die .ValueAsText-Methode, die den Wert als Zeichenfolge zurückgibt. Danach wird es jedoch als Ganzzahl behandelt, von der die Fehler stammen. Sicher auch, warum es in PyCharm gut funktioniert hat, aber nicht als .pyt. Siehe die mwe unten:
import arcpy
from arcpy.sa import *
arcpy.CheckOutExtension('Spatial')
class Toolbox(object):
def __init__(self):
"""Define the toolbox (the name of the toolbox is the name of the
.pyt file)."""
self.label = "ShearBandPropagation"
self.alias = "Shear Band Propagation"
# List of tool classes associated with this toolbox
self.tools = [CreateGeometry]
def getParameterInfo(self):
"""Define parameter definitions"""
param0 = arcpy.Parameter(
displayName='Workspace',
name='workspace',
datatype='DEWorkspace',
parameterType='Required',
direction='Input')
param1 = arcpy.Parameter(
displayName='Smooth Bathymetry',
name='smooth_bathymetry',
datatype='Raster Layer',
parameterType='Required',
direction='Input')
param2 = arcpy.Parameter(
displayName='Aspect Interval',
name='aspect_interval',
datatype='GPLong',
parameterType='Required',
direction='Input')
param2.value = 45
param2.filter.type = "Range"
param2.filter.list = [1, 360]
param3 = arcpy.Parameter(
displayName='Output',
name='output_name',
datatype='Raster Layer',
parameterType='Required',
direction='Output')
params = [param0, param1, param2, param3]
return params
def isLicensed(self):
"""Set whether tool is licensed to execute."""
return True
def updateParameters(self, parameters):
"""Modify the values and properties of parameters before internal
validation is performed. This method is called whenever a parameter
has been changed."""
return
def updateMessages(self, parameters):
"""Modify the messages created by internal validation for each tool
parameter. This method is called after internal validation."""
return
def execute(self, parameters, messages):
"""The source code of the tool."""
workspace = parameters[0].valueAsText
smooth_bathymetry = parameters[1].valueAsText
aspect_interval = parameters[2].valueAsText
output = parameters[3].ValueAsText
aspect_ras = arcpy.sa.Aspect(smooth_bathymetry, 'PLANAR', 'METER')
aspect_ras.save('aspect_raster')
reclassified_list = [] # create values for remap range based on input parameter
# here is where it went wrong: the correct thing to do would have been: aspect_range = int(aspect_interval)
aspect_range = aspect_interval
while aspect_range <= 360:
if aspect_range % 1 != 0:
reclassified_list.append([aspect_range - aspect_interval, aspect_range, int(aspect_range*10)])
aspect_range += aspect_interval
else:
reclassified_list.append([aspect_range - aspect_interval, aspect_range, int(aspect_range)])
aspect_range += aspect_interval
reclass_ras = arcpy.sa.Reclassify('aspect_raster', 'Value', RemapRange(reclassified_list), 'NODATA')
arcpy.CopyRaster_management(reclass_ras, output)