有时候手里就是闲不住,大好假期竟然无意休息。于是想和大家分享分享ArcGIS工具箱制作的一些经验。最先接触自定义工具箱制作是在大四,当时毕设就是写数字水印工具箱,但当时主要任务在于算法实现,所以工具箱的研究还是比较浅显,后面自己私下也做了比较深入的研究,下面直接进入主题。
ArcGIS自定义工具制作可以分为两种,当然我是从Python这个角度出发。而这两种分别是“脚本工具”和“Python工具箱”,说到这里估计很多人蒙了,刚开始我也是蒙的。下面我简易的从开发层面来说一下他们的区别,以Pro为例:
脚本工具的制作不是完全使用Python实现的,需要在Pro中先新建.atbx工具箱,然后在此工具箱中新建一个脚本,而脚本中的变量这些都需要手动设置,比如名称啊,类型啊关联关系等。核心实现可以通过导入Python脚本。而变量接收这块可以使用arcpy.GetParameterAsText和GetParameter,但是个人推荐前者。对于这一块不再多说,感兴趣的可以去官网查阅相关资料,特别全。
Python工具箱则是完全使用Python实现,当然这里除去工具和工具箱说明。Python工具箱不需要手动去创建工具,变量设置等等,直接一套代码搞定所有。对于初学者比较推荐脚本工具,了解其调用原理后可转至Python工具箱。今天着重分享一下Python工具箱开发。
Python工具箱听其名便可知道里面可以包含多个工具。开发时直接新建个.py文件,下面放上官网模板。
# -*- coding: utf-8 -*-
import arcpy
class Toolbox(object):
def __init__(self):
"""Define the toolbox (the name of the 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 definitions"""
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
def postExecute(self, parameters):
"""This method takes place after outputs are outputs are processed and
added to the display."""
return
上面说到Python工具箱中包含多个工具,而每个工具在脚本中其实就是一个类,比如示例中的Tool作为一个工具,可以再写的类为Tool2,属于另一个工具。而最顶层的Toolbox类属于整个工具箱的定义,可以定义其名称等,同时self.tools变量控制这个工具箱包含哪些工具。
来说说单个工具中参数的定义。工具输入框等是在getParameterInfo函数中定义,通过定义变量,该方法详细参数可以直接在帮助文档中查看。
定义变量之后,可以对变量进行特定设置,比如下面示例:
param1 = arcpy.Parameter(
displayName="Hbase连接方式",
name="hbase_con_type",
datatype="GPString",
parameterType="Required",
direction="Input"
)
param1.filter.type = "ValueList"
param1.filter.list = ["配置文件", "连接信息"]
param1.value = "配置文件"
上述示例定义了一个参数,而这个参数我想做成个下拉列表,列表中有两个值,在选择不同值时下面弹出的参数不同,这个参数就可以这样定义。而怎么控制下面参数的显隐?这就涉及到工具中另一个函数updateParameters。
再来说说参数状态更新。在上面下拉菜单选择的值不同时我想让有些参数不显示或者某些值为空,这就需要在updateParameters函数中编码了。
if parameters[1].valueAsText == "连接信息":
parameters[2].enabled = True
parameters[3].enabled = True
parameters[4].enabled = True
parameters[5].enabled = False
parameters[5].value = None
elif parameters[1].valueAsText == "配置文件":
parameters[5].enabled = True
parameters[2].enabled = False
parameters[2].value = None
parameters[3].enabled = False
parameters[3].value = None
parameters[4].enabled = False
parameters[4].value = None
可以通过parameters获取参数,然后通过参数值来判断,最后设置其他参数的状态或者值,达到上面预期目标。
updateMessages函数主要是用来当参数发生变化时进行验证的。比如下面示例:
# getParameterInfo函数中
param2 = arcpy.Parameter(
displayName="Hbase连接地址",
name="hbase_zk",
datatype="GPString",
parameterType="Optional",
direction="Input"
)
param3 = arcpy.Parameter(
displayName="Hbase节点信息",
name="znode_parent",
datatype="GPString",
parameterType="Optional",
direction="Input"
)
# updateMessages函数中
if parameters[1].valueAsText == '连接信息':
if parameters[2].value is None:
parameters[2].setIDMessage("ERROR", 735)
if parameters[3].value is None:
parameters[3].setIDMessage("ERROR", 735)
在参数定义时定义了参数2和参数3为可选类型,但是当参数1的值为连接信息时想验证参数2和3的值是否为空,若为空提示参数为必填。那么便可以在updateMessages函数中加入判断逻辑,然后向参数中添加消息提示,这里MessageID 735特指参数类型为必填,具体代表的意思可在ArcGIS官方资料中查找。
最后核心代码部分在execute函数中进行编写,也就是点击执行后工具运行的核心过程,这里就不多说了。
使用那种方式开发工具根据个人喜好,就个人而言初学时使用的脚本工具开发方式,后面理解后转入Python工具箱。此次分享为个人实践所得,若哪部分描述有问题可后台留言探讨。
Python工具箱学会后感觉任何手工处理的都可以通过点选执行去完成,大大节省工作时间,感兴趣的小伙伴快自己也搞起来~
聊聊如何制作自定义ArcGIS Python工具箱https://mp.weixin.qq.com/s/ptl5n-VZOVNhp4KcraG0sQ