1

I'm trying to build a Python Toolbox to analyze submarine landslides. Among other things I want to run the aspect tool and then reclassify the aspects into groups with a 45 degree interval. Therfore I do the following:

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')

The weird thing is that the above code works fine as long as I run it from Pycharm or the ArcGIS Python window, but when I try to put it into a python toolbox (.pyt) and run it, it throws the following errors:

ERROR 000864: Reclassification: The input is not within the defined domain.

ERROR 000893: An empty GP value or text is entered.

I really don't understand why it won't work in a toolbox. The fact that it works otherwise tells my that there isn't a fundamental problem within my code, which is why I'm expecting it to be some background stuff that I'm missing. I'm really at a loss here.

I'm using ArcGIS 10.6.1 on Windows 10

  • 1
    This is not a Python Toolbox (.pyt) formatted file. It appears to be a script tool, but with all parameters hard-coded. – Vince Sep 28 at 12:18
  • actually, you're right. It's a bigger project, so what I do is I have some custom modules and functions that are called in the Python Toolbox. This code is what is called in the python toolbox when it throws the error. I can provide additional code if needed. – coleuch Sep 28 at 12:22
  • you're right. 'aspect_raster' is what I meant. I edited it accordingly – coleuch Sep 28 at 12:32
1

OK, actually I just fixed it now. To answer my question, I need to provide a bit of additional background:

Basically, the aspect interval isn't hard coded, it's supplied through a parameter. However, it was accessed through the .ValueAsText method, which returns the value as a string. However, afterwards it is treated as an integer, which is where the errors come from. For sure also why it worked fine in PyCharm but not as a .pyt. See the mwe below:

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)
| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.