“ python工具箱使用python类构建,所有工具写在一个.pyt文件中。”
01
—
创建和编辑python工具箱
在catalog中新建一个pyt工具箱,其下会自动生成一个默认名称的工具Tool。用任意编辑器将.pyt与python文件做关联,以下为在vs code中关联:
"files.associations": {
"*.pyt": "python"
},
打开后能看到工具箱的模板
import arcpy
class Toolbox(object):
def __init__(self):
"""Define the toolbox (the name of toolbox is the name of the .pyt file)."""
self.label = "Toolbox"
self.alias = ""
# List of tool classes associated with this toolbox
self.tools = [Tool]
class Tool(object):
def __init__(self):
"""Define the tool (tool name is the name of the class)."""
self.label = "Tool"
self.description = ""
self.canRunInBackground = False
def getParameterInfo(self):
"""Define parameter definetions"""
params = None
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"""
return
工具箱使用python类和方法构建,Toolbox类名称不能更改,其__init__方法定义了工具箱的属性,self.tools定义了包含的所有工具名称列表,self.label定义标签,self.alias定义别名,self.category可以把工具组织成不同工具集。
工具以类的形式定义,类名可更改,举个例子:
class Toolbox(object):
def __init__(self):
self.label = "Random Sample Tools"
self.alias = "randomsampleing"
self.tools = [RandomSample]
class RandomSample(object):
def __init__(self):
self.label = "Random Sample"
保存脚本文件后,更新工具箱,可以看到如下变化:
工具箱使用python类和方法构建,Toolbox类名称不能更改,
工具类定义了六种方法,__init__定义了工具属性;
02
—
定义工具和参数
getParameterInfo()方法定义工具参数,每个参数用Parameter类创建对象。
Parameter对象有多个属性,
有多个方法,多用来做消息处理。
定义完参数后需要返回参数列表,如下
def getParameterInfo():
param0 = arcpy.Parameter(
displayName="Input Features",
name="in_features",
datatype="GPFeatureLayer",
parameterType="Required",
direction="Input")
param0.filter.list = ["Polyline"]
parameters = [param0]
return parameters
可以对参数命名为param0,param1,param2,如此规律命令方便索引;当然也可以以其他方式命名。
在pro中更新python工具箱,如下,更改已应用到工具界面的参数属性中。
03
—
创建Random Sample工具
根据参数定义的方法,对上一篇脚本工具中的Random Sample定义参数如下
class RandomSample(object):
def __init__(self):
self.label = "Random Sample"
def getParameterInfo(self):
input_features = arcpy.Parameter(
name="input_features",
displayName="Input Features",
datatype="GPFeatureLayer",
parameterType="Required",
direction="Input")
output_features = arcpy.Parameter(
name="output_features",
displayName="Output Features",
datatype="GPFeatureLayer",
parameterType="Required",
direction="Output")
no_of_features = arcpy.Parameter(
name="number_of_features",
displayName="Number of Features",
datatype="GPLong",
parameterType="Required"
direction="Input")
no_of_features.filter.type = "Range"
no_of_features.filter.list = [1, 1000000000]
params = [input_features, output_features, no_of_features]
return params
更新工具后,可以在pro界面查看界面和属性。
最后想要工具能执行,还要定义execute()方法,通过Parameter的value和valueAsText方法获取之前定义的参数,因为最后有输出结果,execute不需要返回值。
def execute(self, params, messages):
"""The source code of the tool."""
inputfc = params[0].valueAsText
outputfc = params[1].valueAsText
outcount = params[2].value
inlist = []
with arcpy.da.SearchCursor(inputfc, "OID@") as cursor:
for row in cursor:
id = row[0]
inlist.append(id)
randomlist = random.sample(inlist, outcount)
desc = arcpy.da.Describe(inputfc)
fldname = desc["OIDFieldName"]
sqlfield = arcpy.AddFieldDelimiters(inputfc,fldname)
sqlexp = "{} in {}".format(sqlfield,tuple(randomlist))
arcpy.Select_analysis(inputfc, outputfc, sqlexp)
工具类中只有execute方法是必须的,getParameterInfo方法定义了工具界面和参数属性,updateParameters方法可以对工具做更精细的控制。
04
—
比较脚本工具与python工具箱
脚本工具和python工具各有优势,都能创建自定义工具。
脚本工具是自定义工具箱(.tbx)的一部分,关联了一份.py文件,工具界面在pro内设置。
python工具箱所有代码都在.pyt文件中,工具界面也在代码中设置完成。
但是只能在IDE中debug py文件。两者组织工具文档的方式类似。
参考
https://pro.arcgis.com/zh-cn/pro-app/latest/arcpy/geoprocessing_and_python/a-quick-tour-of-creating-tools-in-python.htm