上一篇中,我介绍如何通过ArcPy调用自定义或第三方工具,本节将介绍如果从利用ArcPy创建一个自定义的工具。
工具参数
在ArcGIS中,我们使用工具,这些工具都有参数,比如选择处理的数据,处理结果的保存路径等。ArcPy中使用arcpy.GetParameter(parameterIndex)
来获取指定索引parameterIndex处的参数的信息,该方法返回的是一个object对象。此外还有一个函数arcpy.GetParameterAsText(parameterIndex)
,也是用来获取指定索引parameterIndex处的参数,但是从函数名可以看出,这个函数会将获取的参数以字符串的形式进行返回。
这两个函数都具有一个形参parameterIndex,这个形参是指参数的索引,从0开始。
编写脚本
下面我们来写一个工具,该工具用来将对点进行一个缓冲区分析,但是与ArcGIS中自带的不同,该缓冲的结果是正方形,即以点为中心,向四周做两个半径长度的正方形。工具中有三个参数:输入要素类,距离半径,输入位置。
首先接受参数:
# 输入要素
input_fs = arcpy.GetParameterAsText(0)
# distance convert string to number
distance_str = arcpy.GetParameterAsText(1)
distance = float(distance_str)
# output
output_fs = arcpy.GetParameterAsText(2)
然后创建输出shapefile:
output_dir = os.path.dirname(output_fs)
output_name = os.path.basename(output_fs)
arcpy.CreateFeatureclass_management(output_dir, output_name, "Polygon", spatial_reference=input_fs)
接着遍历原来的点图层,输出缓冲结果:
with arcpy.da.InsertCursor(output_fs, ['SHAPE@']) as i_cur:
with arcpy.da.SearchCursor(input_fs, ['SHAPE@']) as s_cur:
for row in s_cur:
point = row[0].firstPoint
# buffer for the point, and return a polygon geometry
point_buffer = buffer_point(point, distance)
insert_row = [point_buffer]
i_cur.insertRow(insert_row)
注意,里面的注释我都是使用的英文,而使用中文的地方,注释与代码间是相隔了一个空行。这是因为,如果声明文件编码为utf8,如果没有空行的存在,在运行工具的时候,可能会得到“Name xxx is not defined”的错误;如果声明编码为cp936(即:GB2312),则不需要如此。
创建工具
ArcGIS中每个工具都是存在于工具箱之中,为了将该脚本变为工具使用,需要先选择一个工具箱,这里选择上一节中定义的MyTools.tbx工具箱。在工具箱上右键,选择添加|脚本(如图 1所示),打开脚本的添加界面(如图2所示),这里我们为该脚本工具命名为RectBuffer。
图 1 工具箱右键菜单
图 2 添加脚本(第一步)
点击下一步进入添加脚本第二步,这里我们需要选择脚本的路径(如图 3所示)。
图 3 添加脚本(第二步)
点击下一步,接下来,我们需要为该脚本工具设置参数了。该脚本工具有三个参数,分别为输入数据(限制为点图层),缓冲的半径距离(这里做的比较简单,将单位设置为与输入数据的坐标单位一样即可,数字)以及输出文件。
现在我们先将三个参数输入进去,其数据类型依次为:要素图层、双精度和要素类。为什么第一个参数类型选择的是要素图层呢?因为如果这个图层已经在ArcGIS中打开了,我们可以通过下来菜单选择,而不必再选择去路径了。
接下来,我们选择输入数据,在下方的过滤器中选择要素类,然后将其限制为点图层(如图 4所示)。
图 4 添加脚本(第三步,限制输入要素类型)
由于输出结果是向我们的磁盘上写入文件,而不是读取文件,因此我们还需要将出输出位置的方向设置为Output(如图 5所示)。
图 5 添加脚本(第四步,更改输出要素的方向)
接下来点击完成,即可将该脚本封装为工具,双击RectBuffer工具,其界面如图 6所示。
图 6 RectBuffer工具
分别进行5度,10度的缓冲(元素数据是WGS84坐标系,因此缓冲单位为度),结果如图 7所示。
图 7 RectBuffer结果
进阶
添加消息输出
ArcPy脚本中的print
函数的执行结果并不会显示在工具运行时的对话框中,但我们想在知道程序运行到了哪一步怎么办呢?ArcPy提供了一些函数来实现这些功能,其中常用的是下面三个:
AddMessage
:向工具对话框、历史记录和 Python 窗口显示一条消息;AddWarning
:向工具对话框、历史记录和 Python 窗口显示一条警告;AddError
:向工具对话框、历史记录和 Python 窗口显示一条错误;
现在向脚本中添加以下三行代码,结果如图 8所示。在图7中,我们可以看到工具对话框中显示了这三条信息,并且还有了颜色进行区分。
arcpy.AddMessage(u"这是一条普通消息")
arcpy.AddWarning(u"这是一条警告消息")
arcpy.AddError(u"这是一条错误消息")
添加进度条
另一个用于显示处理进度的是进度条,进度条的使用要复杂些,先看Demo:
arcpy.SetProgressor("step", "Title", 0, 100, 1)
time.sleep(5)
for i in range(1, 100):
arcpy.SetProgressorLabel("Loading {0}...".format(i))
time.sleep(1)
arcpy.SetProgressorPosition()
arcpy.ResetProgressor()
这是使用的time.sleep
函数来模拟数据的处理,其效果如图9所示:
a 初始化显示标注
b 处理过程中
图 9 进度条
使用过程
- 设置进度条
使用进度条前要先使用arcpy.SetProgressor
声明一个进度条,arcpy.SetProgressor
的定义如下:
SetProgressor(type, {message}, {min_range}, {max_range}, {step_value})
参数 | 说明 | 数据类型 |
---|---|---|
type | 进度条类型(默认或步骤)。default —进度条连续向后或向前移动;step —进度条显示完成百分比。(默认值为 default) | String |
message | 进度条标注。默认情况下没有标注。 | String |
min_range | 进度条的开始值。默认值为 0。(默认值为 0) | Integer |
max_range | 进度条的结束值。默认值为 100。(默认值为 100) | Integer |
step_value | 用于更新进度条的进度条步长间隔。(默认值为 1) | Integer |
引用自:https://desktop.arcgis.com/zh-cn/arcmap/10.3/analyze/arcpy-functions/setprogressor.htm
- 更新进度条
更新进度条则需要使用arcpy.SetProgressorPosition
函数,其定义如下:
SetProgressorPosition({position})
参数position用来设置进度条的进度,其不是百分比,百分比是根据(position-min_range)/max_range计算的。如果不指定position,则会在上次的position(初始为min_range)基础上递增step_value
- 重置进度条
当进度条达到100%后,我们可能想为下一个操作设置进度条,这时候,我们需要使用arcpy.ResetProgressor
函数。如果是最后处理完成, 我们也可以不用重置进度条。