空间数据包含属性特征、几何特征和拓扑特征,在将空间数据入库之前,我们需要进行属性检查、逻辑一致性等一系列检查,通过Arcpy提供的方法,可以减少除拓扑错误编辑之外的重复性工作,可以实现数据检查入库流程的自动化。
矢量数据检查内容:
基础检查
要素类检查
拓扑检查
应用arcpy.Describe函数可以获取FeatureClass、GDB FeatureClass、Table、Dataset的文件路径、数据类型等通用属性,还能获取空间数据的几何类型、要素类型、空间参考、是否具有空间索引等属性信息。
def checkDataTypeAndSpatialRef(logger,landUseFeatureClass):
desc = arcpy.Describe(landUseFeatureClass)
#########################第一步:要素类型检查######################
#要素的几何类型
shapeType = desc.shapeType
#要素类型
featureType = desc.featureType
if(featureType=="Simple" and shapeType=="Polygon"):
arcpy.AddMessage("{0}数据类型检查:符合简单面状要素要求!".format(landUseFeatureClass))
logger.info("{0}数据类型检查:符合简单面状要素要求!".format(landUseFeatureClass))
else:
arcpy.AddMessage("{0}数据类型检查:不符合简单面状要素要求!".format(landUseFeatureClass))
logger.error("{0}数据类型检查:不符合简单面状要素要求!".format(landUseFeatureClass))
#########################第二步:要素空间参考######################
#projectionName投影坐标系名称 GCSName地理坐标系名称
spatial_ref = desc.spatialReference
if spatial_ref.name == "Unknown":
arcpy.AddMessage("{0}具有未知的空间参考".format(landUseFeatureClass))
logger.error("{0}具有未知的空间参考".format(landUseFeatureClass))
elif(spatial_ref.name == "GCS_China_Geodetic_Coordinate_System_2000"):
arcpy.AddMessage("{0} : {1}符合空间参考要求".format(landUseFeatureClass, spatial_ref.name))
logger.info("{0} : {1}符合空间参考要求".format(landUseFeatureClass, spatial_ref.name))
else:
arcpy.AddMessage("{0} : {1}不符合空间参考要求".format(landUseFeatureClass, spatial_ref.name))
logger.error("{0} : {1}不符合空间参考要求".format(landUseFeatureClass, spatial_ref.name))
进行要素类属性结构检查的应用场景主要有以下几种:
ArcPy提供了DetectFeatureChanges_management方法,可以实现对于线状地物的变化监测,返回如下图所示变化前后的线状地物变化类型对照表。
对于其他类型的要素,可以采用ArcPy提供了FeatureCompare_management方法,能够得到整体的状态信息,通过将需要入库的要素类与目标数据库中的要素类进行比较,如果几何定义和字段属性都相同,就可以进行数据的增量追加了。
def checkAttrSchema(targetLandUseFeatureClass,landUseFeatureClass):
#########################第三步:要素属性结构检查######################
#得到总体描述
out_compare_file="D:/developdemo/dev2018/data/schemaresult.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' 值
arcpy.AddMessage(compare_result.getOutput(1))
arcpy.AddMessage(arcpy.GetMessages())
FeatureCompare_management方法处理生成的结果入下图所示:
def checkDataTopology(landUseFeatureClass,buildingFeatureClass,topoGdbPath):
#########################第四步:拓扑检查######################
#创建拓扑检查的数据集 "GCS_China_Geodetic_Coordinate_System_2000"
nowTimeStr=datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S').replace("-","").replace(":","").replace(" ","")
outSpRef = arcpy.SpatialReference(4490)
featureDatasetName="landUse"+nowTimeStr
topologyFeatureDataset = topoGdbPath +"/"+featureDatasetName
topologyName = "landuse_Topology"+nowTimeStr
arcpy.CreateFeatureDataset_management(topoGdbPath, featureDatasetName, outSpRef)
#拓扑路径
in_topology = topologyFeatureDataset+"/"+topologyName
#原始待检查土地利用数据
#获取文件名称 desc.name=desc.file=desc.baseName desc.extension desc.path
landUseDesc = arcpy.Describe(landUseFeatureClass)
landUseFileNameNoExt = landUseDesc.baseName
buildingDesc = arcpy.Describe(buildingFeatureClass)
buildingFileNameNoExt = buildingDesc.baseName
#数据集中需要导入进行拓扑检查的数据
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,"")
#针对企业级地理数据库,拓扑分析的要素集不能注册版本
arcpy.ValidateTopology_management(in_topology,"Full_Extent")
#将有拓扑错误的数据导出
arcpy.ExportTopologyErrors_management(in_topology, topologyFeatureDataset, "TopologyError")
拓扑检查错误导出会按照数据集中的要素类型生成对应的错误要素。
采用Append的方法将质检通过的数据追加到数据库中,然后更新这部分数据的相关属性。
def data2TargetGDB(targetLandUseFeatureClass,landUseFeatureClass):
#########################第五步:入库更新######################
arcpy.Append_management(landUseFeatureClass, 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("土地利用数据入库完成!")
想了解ArcGIS最新的技术动态和环保最新的应用,请关注微信公众号“环保GIS技术与应用”