用Python在ArcGIS Pro中写脚本工具
ArcGIS Pro中可以自定义工具箱,工具箱之中可以自动以Python脚本,但是有部分接口规范需要注意,特此记录。ArcGIS 10.x操作类似,原理相同,但是使用的是Python 2.7版本,很多第三方库都用不了了,并且Python 2的语法我自己也是忘得差不多了,调试时各种不顺,因此建议还是用Pro版本,这样就可以使用Python 3.9或以上版本了,目前最新的是ArcGIS Pro 3.3使用Python 3.11环境。
新建工具
在ArcGIS中,打开Catelog面板,在Toolboxes工具栏点击右键,"New Tool Box(.atbx)",即可新建一个自定义的工具箱,对应在文件系统里面会有一个atbx文件和一个xml文件产生,而不是像gdb格式一样的文件夹。
一个工具箱内可以有多个工具,也可以通过工具集(Toolsets)的方式组织管理,直接右键点击刚刚新建的atbx工具箱,点击New→Toolset可以新建工具集,本文简单起见直接新建Script(脚本)
脚本新建窗口中Name只能填英文,是ArcGIS Pro或其它脚本工具调用的索引符,Label可以是中文,用来显示给用户,方便区分,建议简单填写Description项,简单介绍工具用途,方便以后推广使用。(PS:只给自己用的就没必要做成工具了,直接运行arcpy还更方便)
点击OK新建完成,此后点击该脚本的右键菜单中Properties即可回到此窗口
编写功能代码
ArcGIS Pro支持直接在软件内编辑代码,也支持调用PyCharm等编辑器编辑代码,但是我个人的习惯是先在PyCharm中直接调用arcpy把功能实现后再迁移到ArcGIS Pro内,方便调试。
PyCharm中调用arcpy
PyCharm中新建一个普通的空项目,点击File→Settings→Project→Python interpreter→Add Interpreter
ArcGIS官方建议是在conda中运行,但是我个人比较习惯实用venv,其实也是没问题的,只是运行时会有一个warning而已,目前来看没有因为这个影响功能的实现。所以New一个venv,base interpreter选择ArcGIS Pro安装目录/bin/Python/envs/arcgispro-py3/python.exe
,勾选Inherit global site-pakages
,以便引入ArcGIS Pro的Python解释器的各种库,包括arcpy,点击OK,环境就配置好了,新建一个Python文件,输入import arcpy
看看有没有红色波浪线报错就能验证环境配置是否成功。
关于路径参数
很多时候我们处理的都是gdb形式的数据库,在文件管理器里看到的都是一堆看不懂的gdbtable之类的文件(就像下图这样)
这里特别说明一下,我们不必在意gdb内部在文件系统上的路径名,如需访问gdb内的数据,例如访问D:\原始数据库.gdb
内的图斑
数据,直接将路径D:\原始数据库.gdb\图斑
传入arcpy的函数中就能自动识别,当然了,如果不用arcpy直接用os库来访问那必然是Not Found了
小声吐槽一下:gdb这样的文件结构设计属实抽象,处理起来有点尴尬
功能实现
至此,我们便可以放心地在PyCharm中写bug了,以平滑面为例,我一般的操作流程是:
在ArcGIS Pro中搜索找到此功能并打开
点击此功能右上角的
?
帮助图标,跳转到ArcGIS Pro的官方文档库查看该功能的Python代码文档参考文档回到PyCharm中写bug
主要原因是ArcGIS Pro的功能实在过于复杂,arcpy也略微抽象,导致我自己无法记住各种要用的功能,IDE(PyCharm)也不能实现自动提示与补全(现在借助Copilot可以一定程度上实现自动补全)
进入帮助文档后下滑就能找到该函数的Python文档
于是,据此,我就来写一写
TuRangTU_Smooth = arcpy.cartography.SmoothPolygon(TuRangTU, "土壤图_平滑", "PAEK", "100 Meters", "FIXED_ENDPOINT",
"RESOLVE_ERRORS")
最终的示例代码片段如下,请读者自行修改代码内的参数和路径:
import arcpy
if __name__ == '__main__':
arcpy.env.workspace = r"\工作空间.gdb" # 设置工作空间,即待会儿结果输出的默认位置
TuRangTU = r"土壤图" # 要平滑图斑的路径
arcpy.env.overwriteOutput = True # 设置如有同名文件则覆盖
TuRangTU_Smooth = arcpy.cartography.SmoothPolygon(TuRangTU, "土壤图_平滑", "PAEK", "100 Meters", "FIXED_ENDPOINT",
"RESOLVE_ERRORS")
这样就能实现平滑面的功能了,置于arcpy的具体玩法,这里不再展开,详情可参阅ArcGIS Pro官方文档;为实现多个功能连续作业,那就自己叠叠乐了。
此时即可在PyCharm中点击运行或调试把代码跑起来了,去看看默认工作空间里面确实已经生成了"土壤图_平滑"这份数据,证明代码没毛病。
移植到工具箱
工具箱传参实现
工具参数设置
我们此前写的Python代码中是直接指定了“土壤图”数据的路径,但是工具箱中为了适应多种情况,需要传入参数指定该路径,首先我们需要修改脚本工具的属性(右键→属性),在Parameter项中设置所有需要传入的参数,包括以下项目
Label:标签,用来显示给用户看的
Name:用来索引的,就是在另一个Python脚本里面调用这个脚本时传入参数的名字,但是我们写本脚本时不能直接用名字来索引获取值
Data Type:传入参数的类型,这里我们选择“要素类”,有很多类型可选,支持的还是挺丰富的,甚至还可以允许多种类型,允许表格形式或多项值传入,还是很nice的
Type:选择此参数是否必填,默认是必填项
Direction:设置此参数是输入参数,还是指定输出结果的参数。例如我们的例子中输入参数就是土壤图,输出结果就是平滑后的土壤图,如果需要,我们也可以新建一个输出类型的参数用来让用户指定输出位置
Filter:非必填,还可以进一步限制参数类型,例如我们限制输入的要素类型为面要素
Default:非必填,默认值,用来调试或演示的时候比较有用
其余项目空着也没事
详情参阅ArcGIS Pro官方文档https://pro.arcgis.com/zh-cn/pro-app/3.0/help/analysis/geoprocessing/basics/create-a-python-script-tool.htm
从参数的设置项来看,自定义程度还是挺高的,玩法挺丰富,后面有机会好好盘一盘它
代码获取参数值
正如ArcGIS给的示例代码中注释所说,可以通过GetParameter或GetParameterAsText获取参数值,至于说这么多种类型的数据是怎么都变成text的,规则是怎样,这就暂时还没搞懂了,至少知道我们的Feature Class参数传进来的是那个要素类的绝对路径字符串
代码中我们需要通过参数的下标(序号)来获取参数值,所以改成下面这样
TuRangTU = arcpy.GetParameterAsText(0)
此外,在ArcGIS Pro中运行不需要再设置工作空间,可以删掉下面这行,ArcGIS默认选择本项目的项目数据库为工作空间
arcpy.env.workspace = r"\工作空间.gdb" # 设置工作空间,即待会儿结果输出的默认位置
改好后,就可以将代码直接复制到Excecution窗口中,点击OK保存,工具就做好了
运行工具
双击工具,就像平常使用ArcGIS Pro工具一样设置好参数,点击运行,工具就运行起来了
用户交互
运行过程非常漫长(在线@ESRI什么时候能优化一下算法?),我们很多时候还需要实时地向用户反馈当前程序运行状态,可以通过消息或进度条的方式实现,因为本文示例不涉及多步操作,无法做到高细粒度的统计,此处只作记录,不作演示
消息
其实类似于Python中的print函数,实时打印一些信息,arcpy中可以调用
arcpy.AddMessage("正在处理中,请稍候")
调用后ArcGIS中就会像下图这样有提示
并且调用此函数,在PyCharm中运行时控制台也会有输出(虽然说是乱码,改一下编码应该能显示),不再需要另外print
进度条
对于可以进行步骤细粒度统计的操作,可以通过以下方式添加进度条。可以设置消息(第2个参数)、总步数(第3个参数)
arcpy.SetProgressor("step", "正在处理...", 0, total_steps, 1)
随后在每完成一个步骤的时候,调用设置进度条位置,传入当前已完成的步数,ArcGIS会自动计算百分比显示进度条
arcpy.SetProgressorPosition(2)
在所有操作结束后可以重置进度条
arcpy.ResetProgressor()
效果如图所示
但是,由于我们无法获得更高细粒度的统计信息(例如平滑操作平滑了几个图斑了),只知道一个大步骤是否完成,所以给出的进度条往往都是卡在那很久不动,一个步骤完成后又突飞猛进,用户体验属实不太友好。
第三方库
我们写脚本有时候难免需要使用到第三方库,PyCharm中调试时直接安装即可,毕竟是venv或conda的虚拟环境,但是也正因为是虚拟环境,实际移植到ArcGIS Pro中就会缺少相应的库,因为没有实际影响到ArcGIS的Python解释器,所以需要给ArcGIS Pro的Python解释器也安装上相应的库,建议是直接在PyCharm中一次性导出一份requirements.txt
可以有两种方法进行安装
方法一:PyCharm里改——图省事儿
PyCharm里头设置解释器,直接设置为ArcGIS Pro安装目录/bin/Python/envs/arcgispro-py3/python.exe
,不再是虚拟环境,然后使用gui或命令行操作安装相应的库,安装成功后在脚本工具中就能调用了。
十分不推荐直接设置ArcGIS Pro为项目解释器而不构建虚拟环境,很可能会导致ArcGIS Pro出错
方法二:传统命令行
命令行中cd到ArcGIS Pro安装目录\bin\Python\envs\arcgispro-py3\Scripts
,运行./pip --version
看看pip位置是否正确(默认是系统环境变量里面那个),确认正确后执行安装操作
./pip install -r requirements.txt
同样地,安装完成后在脚本工具中就能调用了。
也是十分不推荐在此环境安装各种杂七杂八乱七八糟的库,建议还是在虚拟环境中调试好确认没问题再进行移植
其它玩法
从刚刚的设置过程中所见到的各种设置项可以看到,还有很多设置项我们完全没碰过,更别提API里面提供的众多特性了,因此还有很多玩法这里不再赘述,只是简单讲清楚做一个基本的Python脚本工具所需要的步骤。