李乃强
(江苏省测绘工程院,江苏 南京 210013)
Python作为一种高级程序设计语言,凭借其简洁、易读及可扩展性日渐成为程序设计领域备受青睐的语言之一。使用Python作为ArcGIS的脚本语言将大大提升ArcGIS数据处理的效率,更好地实现ArcGIS内部的任务自动化[1]。
ArcPy 封装了ArcGIS大部分功能进而构建而成的站点包,目的是以实用高效的方式通过 Python 执行地理数据分析、数据转换、数据管理和地图自动化创建基础。
基于菜单界面的ArcGIS for Desktop能够支持许多复杂的操作和空间分析,但用户还需要更多的功能来解决遇到的难题。那么,通过Python脚本调用ArcPy可以自动执行在ArcGIS中需要通过菜单建模才能实现的繁琐操作。例如,将1 000个shapefile文件转成地理数据库中的要素类,虽然可以运行1 000次相应的工具,但是在ArcGIS中肯定还有其他更高效和更简捷的方法。这时,只需要使用Python编写一小段代码就能解决这个问题。
地理空间数据在入库之前,需要进行属性检查、逻辑一致性等一系列检查,空间数据包含属性特征、几何特征和拓扑特征,通过Arcpy提供的方法,可以减少除拓扑错误编辑之外的重复性工作,实现数据检查入库流程的自动化[2]。
在公开文献中,基于Arcpy的脚本工具虽然已在地理国情监测数据接边检查、长江河道水下空间数据提取批处理、建设用地数据裁切、数据转换等方面被广泛应用[3-5],主要通过ArcGIS基础功能的组合应用,但是对要素变化检测、空间参考信息、拓扑检查等方面的高级功能描述较少。为此,本文结合最新版本的ArcPy站点包新扩展功能,以土地利用更新数据检查为例,介绍了相关技术原理和关键功能代码。
Python的诸多特点使它可以作为ArcGIS的脚本语言,这些特点包括以下几个方面:
1)简单易学。相对于其他高度结构化的编程语言(如C++或Visual Basic)而言,Python更容易被掌握。它的语法简单,编程者将有更多的时间来解决实际问题,而不需要在学习Python语言上耗费太多精力。
2)免费且开源。Python是一款免费并且开源的软件,用户可以自由地分发该软件的副本,查看并修改源代码,或者将其中一部分代码用在其他免费的程序里。Python语言如此好用的一个重要原因在于它有一个十分活跃的用户社区,社区里的成员都积极地参与Python的开发和维护。
3)跨平台。Python支持包括Windows、Mac、Linux在内的各种平台。不同平台上的Python程序只需要作极小的改动甚至不改动,就能在其他平台上正常运行。由于ArcGIS for Desktop只能在Windows上运行,所以Python的这种特性在ArcGIS中似乎没有得到明显的体现,但是需要了解的是,Python的用户之所以如此庞大,其中一个重要原因就是它跨平台的特性。
4)解释性。许多程序语言(如C++或Visual Basic)需要将程序源文件转换成计算机可以理解的二进制代码。这就需要有适用于各种程序语言的编译器。而Python是一种解释性语言,它不需要编译就可以直接运行。这一特点使Python使用起来更加简单,并具有更强的移植性。
5)面向对象。Python是一门面向对象的编程语言。面向对象的程序不再是功能的堆砌,而是由一系列相互作用的对象构建起来的,很多现代编程语言都支持面向对象编程。
与其他语言比较,Python也有不足之处:
1)Python大部分扩展软件包是由许多企业或个人开发和维护,并没有直接集成在Python软件中,用户如要用到这些软件包,需要收集和安装。
2)Python是解释型语言,不是以本地机器码运行,所以运行速度比编译型语言慢。
ArcPy 封装了ArcGIS大部分功能进而构建而成的站点包(见图1)。目的是以实用高效的方式通过 Python 执行地理数据分析、数据管理、数据转换和地图自动化创建基础[6-8]。
图1 ArcPy体系结构Fig.1 Arcpy architecture
地理空间数据质检内容主要包括:要素几何类型、空间参考系统、数据空间范围等基础检查;字段类型、字段值域、关系类等要素类检查;自相交、伪节点、悬挂点、压盖相交等拓扑检查[9]。
应用arcpy.Describe函数不仅可以获取FeatureClass、GDB FeatureClass、Table、Dataset的文件路径、数据类型等通用属性,还能获取空间数据的几何类型、要素类型、空间参考、是否具有空间索引等属性信息。实现代码如下:
def checkDataTypeAndSpatialRef(logger,landUseFeatureClass):
desc=arcpy.Describe(landUseFeatureClass)
#【要素类型获取】
#要素的几何类型
shapeType=desc.shapeType
#要素类型
featureType=desc.featureType
#【要素空间参考获取】
#projectionName投影坐标系名称GCSName地理坐标系名称
spatial_ref=desc.spatialReference
要素类属性结构检查主要针对要素类的入库管理、变化监测等应用需求。
ArcPy提供了DetectFeatureChanges_management方法,可以实现对线状地物的变化监测,查找更新线要素与基本线要素在空间上匹配的位置,并检测空间更改、属性更改或同时检测这两种更改以及无更改的情况,并创建一个包含匹配的更新要素及其更改信息、不匹配的更新要素和不匹配的基础要素的输出要素类[10],返回如图2所示变化前后的线状地物变化类型对照表。
图2 线状地物变化类型对照表Fig.2 Comparison of types for linear feature changes
图2中变化检测类型:
1)S代表空间,表示空间发生更改的匹配更新要素。
2)A代表属性,表示属性发生更改的匹配更新要素。
3)SA代表空间和属性,表示空间和属性均发生更改的匹配更新要素。
4)S_LD代表空间更改以及线的反方向。
5)SA_LD代表空间和属性的更改以及线的反方向。
6)NC代表无更改,表示未发生任何更改的匹配更新要素。
7)N代表新要素,表示新加入基础数据的不匹配更新要素。
8)D代表删除,表示可能需要从基础数据中删除的不匹配基础要素。
对于其他类型的要素,ArcPy提供了FeatureCompare_management方法,能够得到整体的状态信息,通过将需要入库的要素类与目标数据库中的要素类进行比较,如果几何定义和字段属性都相同,就可以进行数据的增量追加了。代码如下:
def checkAttrSchema(targetLandUseFeatureClass,landUseFeatureClass):
#【要素几何定义和字段属性检查】
#得到总体描述
out_compare_file="D:/developdemo/dev2018dataschemaresult.txt"
compare_result=arcpy.FeatureCompare_management(targetLandUseFeatureClass,landUseFeatureClass,"OBJECTID","SCHEMA_ONLY","",".000000008983 Unknown",".001",".001","","","CONTINUE_COMPARE",out_compare_file)
#result.getOutput(1) 获取此工具的状态未检测到差异时将显示′true′值;检测到差异时将显示′false′值。
要素拓扑检查包括7个步骤:①创建数据集;②导入需要拓扑检查数据;③创建拓扑;④向拓扑中添加要素类;⑤添加拓扑规则;⑥验证拓扑;⑦导出拓扑错误。本文主要介绍土地利用数据库拓扑检查,创建拓扑检查的数据集,针对同一个图层内要素压盖、缝隙,不同图层要素空间包含关系等图形拓扑问题自动化检查。具体实现代码如下:
def checkDataTopology(landUseFeatureClass,buildingFeatureClass,topoGdbPath):
#【拓扑检查】
#数据集中需要导入进行拓扑检查的数据
landUseTopoFeature=topologyFeatureDataset+"/"+landUseFileNameNoExt
#根据土地利用类型抽取水田
expression="CLASS='水田'"
out_Layer="selectlayer"
arcpy.MakeFeatureLayer_management(landUseFeatureClass,out_Layer,expression,"","")
if int(arcpy.GetCount_management(out_Layer).getOutput(0)) > 0:
arcpy.CopyFeatures_management(out_Layer,landUseTopoFeature)
buildingTopoFeature=topologyFeatureDataset+"/"+buildingFileNameNoExt
arcpy.CopyFeatures_management(buildingFeatureClass,buildingTopoFeature)
#创建拓扑规则
arcpy.CreateTopology_management(topologyFeatureDataset,topologyName,"")
#添加拓扑规则适用的空间数据
arcpy.AddFeatureClassToTopology_management(in_topology,landUseTopoFeature,1,1)
arcpy.AddFeatureClassToTopology_management(in_topology,buildingTopoFeature,1,1)
#针对土地利用数据进行单项检查
#arcpy.AddRuleToTopology_management(in_topology,"Must Not Have Gaps (Area)",landUseTopoFeature,"","#","")
arcpy.AddRuleToTopology_management(in_topology,"Must Not Overlap (Area)",landUseTopoFeature,"","#","")
#针对建设用地数据进行压盖检查
arcpy.AddRuleToTopology_management(in_topology,"Must Not Overlap With (Area-Area)",landUseTopoFeature,"",buildingTopoFeature,"")
拓扑检查错误导出会按照数据集中的要素类型生成对应的错误要素。
采用Append的方法将质检通过的数据追加到数据库中,并更新追加数据的相关属性。实现代码如下:
def data2TargetGDB(targetLandUseFeatureClass,landUseFeatureClass):
#【入库更新】
arcpy.Append_management(landUseFeature-Class,targetLandUseFeatureClass,"NO_TEST",","")
queryfilter="timeVersion=""
fields=[′timeVersion′]
with arcpy.da.UpdateCursor(targetLandUseFeatureClass,fields,queryfilter) as cursor:
for row in cursor:
row[0]=datetime.datetime.now().strftime(′%Y-%m-%d %H:%M:%S′)
cursor.updateRow(row)
arcpy.AddMessage("地理空间数据入库完成!")
本文详细介绍了地理空间数据检查的主要内容,并结合要素类型和空间参考检查、要素类属性结构检查、要素拓扑检查、数据入库和属性更新等功能需求,介绍了利用 Python调用ArcPy相关功能函数的技术原理和实现代码,可供同类项目借鉴。