ArcGISReclassifyがPythonToolboxで失敗する

Sep 28 2020

海底地すべりを分析するためのPythonツールボックスを構築しようとしています。とりわけ、アスペクトツールを実行してから、45度の間隔でアスペクトをグループに再分類したいと思います。したがって、私は次のことを行います。

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

奇妙なことに、上記のコードはPycharmまたはArcGIS Pythonウィンドウから実行する限り正常に機能しますが、Pythonツールボックス(.pyt)に入れて実行しようとすると、次のエラーがスローされます。

エラー000864:再分類:入力が定義されたドメイン内にありません。

エラー000893:空のGP値またはテキストが入力されました。

ツールボックスで機能しない理由がよくわかりません。それ以外の方法で機能するという事実は、コード内に根本的な問題がないことを示しています。そのため、私はそれが欠けている背景のものであると期待しています。私はここで本当に途方に暮れています。

Windows10でArcGIS10.6.1を使用しています

回答

1 coleuch Sep 28 2020 at 19:56

OK、実際に私は今それを修正しました。私の質問に答えるために、私はもう少し背景を提供する必要があります:

基本的に、アスペクト間隔はハードコーディングされておらず、パラメーターを介して提供されます。ただし、値を文字列として返す.ValueAsTextメソッドを介してアクセスされました。ただし、その後は整数として扱われ、エラーの原因になります。確かに、なぜそれがPyCharmでうまく機能したが、.pytとしては機能しなかったのか。以下のmweを参照してください。

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)