邱建平 徐玉玲 刘文军
(1.江西省自然资源测绘与监测院 江西南昌 330002;2.江西省自然资源政策调查评估中心 江西南昌 330025)
地理数据处理是GIS 软件功能的一个重要组成部分。作为测绘地理空间数据处理人员,经常会遇到各类地理数据处理任务,如数据格式转换、矢量数据合并、影像裁剪、投影变换等,当某个数据处理任务面临数据量大、重复性操作时,批处理方法的实现就显得尤为重要。ArcGIS 软件平台中ArcTooLBox工具箱自带有批处理方法[1],即右键ArcTooLBox 工具箱中的各工具,选择“批处理”即可实现批处理操作,ArcTooLBox 工具箱批处理如图1 所示。本文案例有两个数据图层,分别是点图层和线图层,当比例尺很小的时候看起来点落在线上,即点和线相交(如图2 所示),实际上将比例尺放大到一定程度时,会发现点没有落在线上,即点和线不相交(如图3 所示)。现在的任务是将不在线上的点移动到线上。传统的方法是在ArcMap 桌面软件中,加载点图层和线图层,进行要素编辑,将显示比例尺放大到最大程度,然后将点一个一个移动到线上。然而当数据量很大时,需要移动成千上万个点,该方法是不明智的。能否找到一种快速而有效的方法来完成以上任务,ArcGIS Python 脚本提供了解决方案。为此本文基于ArcGIS 邻近分析思想,利用ArcGIS Python 脚本语言编程制作工具,批处理点线拓扑关系的检查与修正,提高了工作效率,满足了生产应用需求。
图1 ArcTooLBox工具箱批处理
图2 点在线上(小比例尺显示)
图3 点未在线上(大比例尺显示)
Python 是一种不受局限、可跨平台的开源编程语言[2-3]。Python 脚本因功能强大且易于上手、处理速度快的优点被广泛应用,深受用户认可和支持[4-7]。Python 脚本语言可在脚本环境中独立运行,也可将其添加到工具箱中通过对话框或加入到模型中运行[3]。为此,ESRI 将它作为脚本语言嵌入到ArcGIS中[8-12],从而使得ArcGIS软件中所有能在ArcTooLBox工具箱或Model Builder模型构建器中使用的工具都可以通过Python脚本进行调用,表现出了强大的生命力。
本文的实例数据一个点图层(公交站点数据),一个线图层(公交路线数据),点数据量有420 个,线数据量有30 条。在ArcMap 软件中,加载以上点线数据,将比例尺放大到最大程度,有些点落在线上,即点线相交,而有些点未落在线上,即点线未相交。
为进一步挖掘数据的利用价值,要求点数据全部落在线上,即满足点在线上的拓扑关系。最直接的方法是在ArcMap 桌面软件中,加载点图层和线图层,进行要素编辑,将图形显示比例尺放大到最大,然后将点一个一个移动到线上;也可以利用ArcGIS中的邻近分析工具,快速找出不满足点在线上拓扑关系的数据,再将点一个一个移动到线上;然而完成点在线上的数据修正,需要大量的人工操作。
基于ArcGIS 邻近分析思想[13],本文利用ArcGIS Python脚本语言编程制作工具[14],批处理自动找出不在线上的点,并将其移动到最邻近的线上,以满足拓扑要求。
在Python 中分别获取点、线两个要素图层数据,通过邻近分析,获得点到线上的最近距离以及对应的线上的点X、Y坐标,并写入到点的属性表中。再判断是否满足点在线上的拓扑规则,若满足则输出结果;若不满足则通过游标获得最近点的坐标并根据该坐标构建一个新的点,最后把对应不相交点的属性赋值给新点,同时删除原有点。具体技术路线图如图4所示。
图4 技术路线图
在ArcGIS 中建立Python 脚本主要有两种方法[15]:一是在ArcGIS 软件平台中打开Python 窗口编写并执行Python 代码;二是在txt 文本编辑器中编写Python 代码,然后将其后缀改为“.py”,即可在ArcTooLBox 工具箱中进行调用。由于Python窗口能够支持代码的自由编写,具有代码提示功能,因此本文选择第一种方法建立脚本。打开Python 窗口(如图5 所示),将所有代码编辑完成后,保存为Python脚本文件(*.py),然后在ArcTooLBox 工具箱中新建工具集,右键选择添加脚本,按照向导添加保存好的脚本文件即可,如图6所示。
图5 Python窗口
图6 添加Python脚本
(1)添加路径识别代码
主要解决因数据存储路径中存在中文导致Python脚本无法识别数据的问题,代码如下:
import arcpy,sys,os,string
reload(sys)
sys.setdefaultencoding(“utf8”)
(2)获得点线图层数据
infc=r“D:Arcpy2dian.shp”#点数据
line=r“D:Arcpy2xian.shp”#线数据
(3)进行邻近分析
arcpy.Near_analysis(infc,line,“”,“true”)
(4)判断是否满足拓扑规则,创建一个新点并输出结果
#查询游标
rows=arcpy.UpdateCursor(infc)
for row in rows:
#距离大于零,表示不相交
if row.NEAR_DIST>0:
#插入游标
cur=arcpy.InsertCursor(infc)
#创建一个空的新行
new_row=cur.newRow()
#创建一个新的点几何
newpnt=arcpy.Point()
#把线上对应点的坐标赋值给新点
newpnt.X=row.NEAR_X
newpnt.Y=row.NEAR_Y pointGeometry=arcpy.PointGeometry(newpnt)
new_row.shape=pointGeometry
#把不相交点的属性赋值给新点 new_row.NEAR_DIST=row.NEAR_DIST
new_row.NEAR_X=row.NEAR_X
new_row.NEAR_Y=row.NEAR_Y
new_row.ID=row.ID
#插入新点
cur.insertRow(new_row)
#删除不相交的点
#rows.deleteRow(row)
对建好的脚本,设置好各项脚本参数,经过测试运行后,得到的结果是:满足点在线上拓扑规则那些点的位置不变,不满足点在线上拓扑规则点的位置发生了移动,即点落在线上了(如图7 所示)。从运行后点的属性表中(如图8 所示)可以看到,点图层属性表中增加了三个NEAR_DIST,NEAR_X,NEAR_Y 字段,分别表示点到线上的距离、线上点的X坐标、线上点的Y坐标。NEAR_DIST 值为0 表示点线已经相交,即满足点在线上的拓扑规则,直接输出结果;NEAR_DIST 值不为0则不满足点在线上的拓扑规则,要插入新点后输出结果。属性表中选中的部分即为新插入的点,可以看到新插入点的属性与对应旧点的属性一致(FID 除外)。
图7 运行后点落在线上
图8 运行后点的属性截图
最后,本文通过脚本代码批处理执行和人工操作实现点在线上的拓扑规则检查及将不在线上的点移动到线上。将这两种方法所耗时间和优缺点进行了对比分析,见表1所示。
表1 两种方法及优缺点对比汇总表
本文基于ArcGIS 邻近分析思想,利用ArcGIS Python 脚本语言编程制作工具,批处理实现了对点线拓扑关系的检查与修正,解决了实际生产中的问题,具有高效、省时之优势,为地理信息数据相关自动化处理提供了解决方案。