文章目录
- 创建工具步骤
- 第一步:
- 第二步:
- 第三步:
- 定义工具
- 工具箱Toolbox
- 工具类
- 1、__init__
- 2、getParameterInfo
- 3、isLicensed
- 4、updateParameters
- 5、updateMessage
- 6、execute
- 进度条的使用
- 代码
相比于自定义工具箱的源脚本和参数定义难以集中管理的缺点,在Python工具箱中,参数定义、代码验证和源代码都在同一位置进行处理,因而,Python 工具的创建和维护更加容易。此外,Python 工具箱支持脚本工具不支持的功能,例如值表、复合数据类型和自定义许可检查。Python 工具箱 (.pyt) 只是一个基于 ASCII 的文件,该文件定义了工具箱和一个或多个工具。
环境:ArcGis10.2
创建工具步骤
第一步:
在arcgis中任意选择一个文件夹,右键选择新建——Python Toolbox。
第二步:
编写工具内容,右键新建工具箱的菜单——Edit。这边打开默认是UTF-8编码的,此时如果里面存在中文可能会乱码,需要把txt另存为ANSI编码。
第三步:
Python工具箱打开后已经有了一个模板了,接下来只需要在相应的位置写自己的工具实现逻辑就行。写完后的样子,样例代码放在最后了
定义工具
工具箱Toolbox
__init__方法:定义了工具箱的属性,
self.label定义标签
self.alias定义别名
self.tools定义了包含的所有工具名称列表
工具类
工具类中共有以下六个方法:
1、init
必填信息。定义了工具属性
label:标注是工具的显示名称,如“目录”窗口 中所示
description:工具的描述
canRunInBackground:如果 canRunInBackground 取消设置或设置为 True,此工具将遵循地理处理选项 对话框中的当前后台处理 设置。
2、getParameterInfo
可选。定义了参数,每个参数用Parameter类创建对象。其中参数parameter属性:
displayName:工具对话框中显示的参数名称
name:Python 中的工具语法中显示的参数名称
datatype:每个 Python 工具箱的工具参数都有关联的数据类型。打开脚本工具对话框后,地理处理使用数据类型检查参数值。数据类型也可用于浏览数据 - 只有与参数数据类型匹配的数据才会显示在浏览对话框中。https://desktop.arcgis.com/zh-cn/arcmap/10.6/analyze/creating-tools/defining-parameter-data-types-in-a-python-toolbox.htm
parameterType:提供三种 parameterType 选项:
必选 - 必须提供值才能执行工具。
可选 - 不需要为参数提供值。
派生 - 该参数只适用于输出参数(请参阅下文的方向参数)。派生的输出参数不会显示在工具对话框中。
direction:该属性定义参数是工具的输入参数还是工具的输出参数。如果将 parameterType 设置为“派生”,则应将参数 direction 设置为“输出”。
multiValue:是否为多值参数。
filter:可以限定参数类型。
displayOrder:定义参数在工具框的显示顺序。
parameterDependencies:定义参数依赖性。
3、isLicensed
可选。可以控制许可行为,验证能否执行,检入检出许可。如果isLicensed方法返回False,则工具不能执行。如果该方法返回True或未使用该方法,则工具可以执行。
4、updateParameters
可选。定义了工具内部验证的过程,比如输入数据达到某个条件,则启用或者禁用某个参数,或者为某个参数设置默认值。
5、updateMessage
可选。在从内部验证例程返回后调用。您可以检查在内部验证过程中创建的消息并根据需要进行更改。
6、execute
必填信息,包含了工具执行逻辑,必要方法,只包括该方法也可以运行工具,但是没有参数界面。
进度条的使用
脚本中进度条使用
代码
import arcpy
import socket
class Toolbox(object):
def __init__(self):
"""Define the toolbox (the name of the toolbox is the name of the
.pyt file)."""
self.label = "测试工具箱"
self.alias = "测试"
# List of tool classes associated with this toolbox
self.tools = [Intersect, CalculateField]
class Intersect(object):
def __init__(self):
"""Define the tool (tool name is the name of the class)."""
# 初始化工具类
self.label = "相交"
self.description = "相交工具描述"
self.canRunInBackground = False
def getParameterInfo(self):
# 定义工具的参数
"""Define parameter definitions"""
in_features = arcpy.Parameter(displayName="输入要素",
name="in_features",
datatype="GPFeatureLayer",
parameterType="Required",
direction="Input",
multiValue=True)
in_features.filter.list = ["Polygon"]
# Derived Output Features parameter
out_features = arcpy.Parameter(
displayName="输出要素",
name="out_features",
datatype="GPFeatureLayer",
parameterType="输出",
direction="Output")
params = [in_features, out_features]
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."""
# 在用户每次在工具对话框中更改参数时调用。从 updateParameters 返回后,地理处理将调用它的内部验证例程。
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."""
# 工具的源代码
in_features = parameters[0].valueAsText
out_feature = parameters[1].valueAsText
arcpy.Intersect_analysis(in_features, out_feature)
return
class CalculateField(object):
def __init__(self):
"""Define the tool (tool name is the name of the class)."""
self.label = "计算随机值"
self.description = "计算随机值描述"
self.canRunInBackground = False
self.params = arcpy.GetParameterInfo()
def getParameterInfo(self):
"""Define parameter definitions"""
# 定义工具面板上的参数形式
in_features = arcpy.Parameter(
displayName="Input Features",
name="in_features",
datatype="GPFeatureLayer",
parameterType="Required",
direction="Input"
)
vt = arcpy.Parameter(
name='summary_fields',
displayName='融合字段',
datatype='Field',
direction='Input',
parameterType='Optional',
multiValue=True
)
vt.parameterDependencies = [in_features.name]
out_features = arcpy.Parameter(
displayName="输出要素",
name="out_features",
datatype="GPFeatureLayer",
parameterType="输出",
direction="Output")
params = [in_features, vt, out_features]
return params
def isLicensed(self):
"""Set whether tool is licensed to execute."""
r = socket.gethostbyname(socket.gethostname())
if r == '192.168.2.58':
return True
return False
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."""
if parameters[0].altered:
parameters[2].enabled = True
else:
parameters[2].enabled = False
return
def updateMessages(self, parameters):
"""Modify the messages created by internal validation for each tool
parameter. This method is called after internal validation."""
try:
if parameters[0].altered:
field_names = []
fields = arcpy.ListFields(parameters[0].valueAsText)
for field in fields:
field_names.append(field.baseName.upper())
if not ("BSM" in field_names):
parameters[0].setErrorMessage("输入要素必须包含 BSM 字段")
except Exception as e:
parameters[0].setErrorMessage(e.message)
return
def execute(self, parameters, messages):
"""The source code of the tool."""
in_features = parameters[0].valueAsText
out_feature = parameters[2].valueAsText
arcpy.env.overwriteOutput = True
arcpy.Copy_management(in_features, out_feature)
arcpy.AddField_management(out_feature, 'RandomNum', 'LONG')
arcpy.SetProgressor("default", "This is the default progressor")
record_count = int(arcpy.GetCount_management(out_feature).getOutput(0))
if record_count == 0:
raise ValueError("{0} has no records to count".format(out_feature))
increment = 1
arcpy.SetProgressor("step", "Step progressor: Counting from 0 to {0}".format(record_count), 0, record_count,
increment) # 方法主要有五个参数,p1-对话框名称类型;p2-消息字符串;p3-进度的最小值默认0,;p4-进度的最大值默认100;p5-步进值 一般情况为1
with arcpy.da.UpdateCursor(out_feature, ["RandomNum", 'OID@']) as cursor:
for row in cursor:
row[0] = rando()
cursor.updateRow(row)
arcpy.SetProgressorLabel("Iteration: {0}".format(row[1])) # 方法是处理进度中设置处理消息的方法
arcpy.SetProgressorPosition() # 步进的方法,处理改变进度时调用
arcpy.SetProgressorPosition(record_count)
arcpy.ResetProgressor() # 将进度条重置为初始状态
return
# 生成随机整数1-5
def rando():
import random
rand = int(random.uniform(1, 6))
return rand
好记心不如烂笔头,写写记记罢了