ArcGIS Reclassify falla en Python Toolbox
Estoy intentando construir una caja de herramientas Python para analizar deslizamientos de tierra submarinos. Entre otras cosas, quiero ejecutar la herramienta de aspecto y luego reclasificar los aspectos en grupos con un intervalo de 45 grados. Por lo tanto, hago lo siguiente:
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')
Lo extraño es que el código anterior funciona bien siempre que lo ejecute desde Pycharm o la ventana de ArcGIS Python, pero cuando intento ponerlo en una caja de herramientas de Python (.pyt) y ejecutarlo, arroja los siguientes errores:
ERROR 000864: Reclasificación: La entrada no está dentro del dominio definido.
ERROR 000893: Se ingresó un valor GP o texto vacío.
Realmente no entiendo por qué no funcionará en una caja de herramientas. El hecho de que funcione de otra manera me dice que no hay un problema fundamental dentro de mi código, por lo que espero que sea algo de fondo lo que me falta. Estoy realmente perdido aquí.
Estoy usando ArcGIS 10.6.1 en Windows 10
Respuestas
De acuerdo, en realidad lo acabo de arreglar ahora. Para responder a mi pregunta, necesito proporcionar algunos antecedentes adicionales:
Básicamente, el intervalo de aspecto no está codificado, se proporciona a través de un parámetro. Sin embargo, se accedió a través del método .ValueAsText, que devuelve el valor como una cadena. Sin embargo, luego se trata como un número entero, que es de donde provienen los errores. Seguro también por qué funcionó bien en PyCharm pero no como .pyt. Vea el mwe a continuación:
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)