ArcGIS Reclassify échoue dans Python Toolbox
J'essaie de créer une boîte à outils Python pour analyser les glissements de terrain sous-marins. Entre autres, je souhaite exécuter l'outil d'aspect, puis reclasser les aspects en groupes avec un intervalle de 45 degrés. Par conséquent, je fais ce qui suit:
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')
La chose étrange est que le code ci-dessus fonctionne bien tant que je l'exécute à partir de Pycharm ou de la fenêtre ArcGIS Python, mais lorsque j'essaye de le mettre dans une boîte à outils python (.pyt) et de l'exécuter, il génère les erreurs suivantes:
ERREUR 000864: reclassification: l'entrée n'est pas dans le domaine défini.
ERREUR 000893: une valeur GP ou un texte vide est entré.
Je ne comprends vraiment pas pourquoi cela ne fonctionnera pas dans une boîte à outils. Le fait que cela fonctionne autrement me dit qu'il n'y a pas de problème fondamental dans mon code, c'est pourquoi je m'attends à ce que ce soit des éléments d'arrière-plan qui me manquent. Je suis vraiment perdu ici.
J'utilise ArcGIS 10.6.1 sur Windows 10
Réponses
OK, en fait je viens de le réparer maintenant. Pour répondre à ma question, je dois fournir quelques informations supplémentaires:
Fondamentalement, l'intervalle d'aspect n'est pas codé en dur, il est fourni via un paramètre. Cependant, il a été accédé via la méthode .ValueAsText, qui renvoie la valeur sous forme de chaîne. Cependant, il est ensuite traité comme un entier, d'où proviennent les erreurs. Pour sûr aussi pourquoi cela fonctionnait bien dans PyCharm mais pas en tant que .pyt. Voir le mwe ci-dessous:
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)