基于ArcPy的GDB地理数据库拓扑检查

ArcPy实现拓扑检查,输出结果

ArcPy 是一个以成功的 arcgisscripting 模块为基础并继承了 arcgisscripting 功能进而构建而成的站点包。目的是为以实用高效的方式通过 Python 执行地理数据分析、数据转换、数据管理和地图自动化创建基础。

基础环境

python版本:需要使用与ArcGIS协同安装的python2.7
我的路径是:C:\Python27\ArcGISx6410.2\python.exe

具体实现

1.基础环境设置
参考了网上其他人的一些用法,发现这个的defaultencoding"utf-8"不生效,具体环境设置可以根据自己的实际需求配置。

# coding=utf-8
# design by @bill_love_3
import os
import sys
import arcpy

sys.path.append(r'C:\arcgis10.2\Desktop10.2\arcpy')

reload(sys)
sys.setdefaultencoding('utf-8')
arcpy.AddMessage(sys.getdefaultencoding())
arcpy.env.XYResolution = "0.0001 Meters"  # 设置XY分辨率
arcpy.env.XYTolerance = "0.001 Meters"  # 设置XY容差

2.拓扑规则介绍
通过arcpy.AddRuleToTopology_management()的方法添加拓扑规则,该方法的用法如下:AddRuleToTopology_management(in_topology, rule_type, in_featureclass, {subtype}, {in_featureclass2}, {subtype2})
六个参数,第一个是拓扑的路径(必须指定到拓扑本身,例如’C:\drea\python3\Check_Topology\Check_Topology.gdb\dataset\topology’)、第二个参数是拓扑规则(具体用法请参考arcpy拓扑规则)、第三个参数是检查的要素的路径,方法和拓扑路径相同必须指定到要素本身、第四个和第六个参数根据官方文档的释义是输入要素类或原始要素类的子类型(输入子类型的描述(而不是代码)。如果原始要素类中不存在子类型,或者希望将规则应用于要素类中的所有子类型,请将此项留空。)、第五个参数是拓扑规则的目标要素类,需要在两个要素层之间进行的拓扑需要输入该参数的值,否则为空。

arcpy.AddRuleToTopology_management(self.topology_path, "Must Not Overlap (Area)", dataset_fc_path, "", "", "")

arcpy.AddRuleToTopology_management(self.topology_path, "Must Be Inside (Line-Area)", dataset_fc_path, "", os.path.join(self.dataset_path, 'CJXZQ'), "")

3.实现过程
首先在待检查GDB的同级目录下新建CheckTopology.gdb;接下来在新的GDB中新建数据集dataset,导入检查GDB的要素到数据集dataset;然后在数据集dataset中创建拓扑,向拓扑中添加要素类;再然后添加拓扑规则,验证拓扑;最后导出拓扑结果。
4.最终成果
在数据集dataset导出拓扑检查的错误图层。
基于ArcPy的GDB地理数据库拓扑检查_第1张图片

完整代码

# coding:gbk
# design by @bill_love_3
import os
import sys
import arcpy

# sys.path.append(r'C:\arcgis10.2\Desktop10.2\arcpy')

reload(sys)
sys.setdefaultencoding('gbk')
arcpy.env.XYResolution = "0.0001 Meters"  # 设置XY分辨率
arcpy.env.XYTolerance = "0.001 Meters"  # 设置XY容差


class CheckTopology():
    def __init__(self, path):
        self.dir_path = os.path.dirname(path)
        self.path = path
        self._gdb = ''
        self.dataset_path = ''
        self.topology_path = ''
        self.fc_list = []

    def CreateNewGdb(self):
        arcpy.env.workspace = self.dir_path
        gdb_name1 = os.path.basename(os.path.splitext(self.path)[0] + '_Topology')
        result_gdb = os.path.join(self.dir_path, gdb_name1)
        self._gdb = (result_gdb + '.gdb')
        # print(result_gdb)
        if arcpy.Exists(self._gdb):
            print('当前路径已存在' + result_gdb)
            sys.exit(1)
        else:
            arcpy.AddMessage("    新建 " + os.path.basename(result_gdb) + " ...")
            arcpy.CreateFileGDB_management(self.dir_path, gdb_name1)

    def CreateFeatureDataset(self):
        arcpy.env.workspace = self.path
        fc_list = []
        fc_list1 = arcpy.ListDatasets(feature_type='feature')  # 返回当前工作空间中的数据集
        if fc_list1:
            for i in fc_list1:
                fc_list += arcpy.ListFeatureClasses(feature_dataset=i)  # 返回当前工作空间中的要素类
        else:
            fc_list = arcpy.ListFeatureClasses()
        # 判断是否检查
        if 'CJXZQ' in fc_list:
            self.fc_list = fc_list
        else:
            arcpy.AddError('...缺失CJXZQ或图层名称不符合规范,无法检查拓扑...')
            # print('...缺失CJXZQ或图层名称不符合规范,无法检查...'.encode('utf-8'))
            sys.exit(1)
        in_fc_path_list = []
        for fc in fc_list:
            in_fc_path_list.append(os.path.join(self.path, fc))
        # print(in_fc_path_list)
        arcpy.AddMessage("    在 " + os.path.basename(self._gdb) + " 内新建要素数据集...")
        dataset_name = "dataset"
        dataset_path = os.path.join(self._gdb, dataset_name)
        self.dataset_path = dataset_path
        # 引用包含要应用的空间参考的要素类或要素数据集,
        # 将in_fc_path_list[0]的坐标作为要素数据集的坐标,所以gdb内的所有要素类应该是统一坐标
        sr = arcpy.SpatialReference(".\\XZQFW.prj")
        arcpy.CreateFeatureDataset_management(self._gdb, dataset_name, sr)  # (out_dataset_path, out_name,
        # {spatial_reference}) {spatial_reference}可以是 .prj 文件的路径、引用包含要应用的空间参考的要素类或要素数据集、在使用此工具之前定义空间参考对象
        # 导入要素类到数据集
        arcpy.AddMessage("    向 " + dataset_path + " 导入要素类图层...")
        arcpy.FeatureClassToGeodatabase_conversion(in_fc_path_list, dataset_path)
        # 引用外部数据,进行拓扑检查
        J_BNT = r'.\YJJBNTBHTB_JCX.shp'
        XZQ = r'.\XZQFW.shp'
        self.fc_list.append('YJJBNTBHTB_JCX')
        self.fc_list.append('XZQFW')
        arcpy.FeatureClassToGeodatabase_conversion(J_BNT, dataset_path)
        arcpy.FeatureClassToGeodatabase_conversion(XZQ, dataset_path)

    def CreateTopology(self):
        arcpy.AddMessage("    创建拓扑...")  # 在dataset数据内创建拓扑
        topology_name = "topology"
        topology_path = os.path.join(self.dataset_path, topology_name)
        self.topology_path = topology_path
        arcpy.CreateTopology_management(self.dataset_path, topology_name)
        for ifc_name in self.fc_list:
            dataset_fc_path = os.path.join(self.dataset_path, ifc_name)  # 拼接数据集中的要素类绝对路径
            arcpy.AddMessage("    向拓扑中添加要素类" + dataset_fc_path + "...")  # 将导入dataset的要素类添加到拓扑中
            arcpy.AddFeatureClassToTopology_management(topology_path, dataset_fc_path, "1", "1")

    def AddRules_ValidateTopology(self):
        # 按要素属性添加拓扑规则
        for ifc_name in self.fc_list:
            dataset_fc_path = os.path.join(self.dataset_path, ifc_name)  # 拼接数据集中的要素类绝对路径
            desc = arcpy.Describe(dataset_fc_path)  # 要素属性 shapeType[Polygon,Polyline,Point,Multipoint,MultiPatch]
            # 面要素  不能重叠  在CJXZQ范围内
            if desc.shapeType == 'Polygon' and ifc_name != 'YJJBNTBHTB_JCX' and ifc_name != 'XZQFW' and ifc_name != 'CJXZQ':
                arcpy.AddRuleToTopology_management(self.topology_path, "Must Not Overlap (Area)", dataset_fc_path, "",
                                                   "",
                                                   "")
                arcpy.AddRuleToTopology_management(self.topology_path, "Must Be Covered By (Area-Area)",
                                                   dataset_fc_path, "",
                                                   os.path.join(self.dataset_path, 'CJXZQ'), "")
            elif desc.shapeType == 'Point':  # 点要素 不能接合
                arcpy.AddRuleToTopology_management(self.topology_path, "Must Be Disjoint (Point)", dataset_fc_path, "",
                                                   "",
                                                   "")
            elif desc.shapeType == 'Polyline':  # 线要素 在CJXZQ范围内
                arcpy.AddRuleToTopology_management(self.topology_path, "Must Be Inside (Line-Area)", dataset_fc_path,
                                                   "",
                                                   os.path.join(self.dataset_path, 'CJXZQ'), "")
                # 测试
                # arcpy.AddRuleToTopology_management(self.topology_path, "Must Not Overlap (Line)", dataset_fc_path, "",
                #                                    "",
                #                                    "")
        # 按要素名称添加拓扑规则
        for ifc_name in self.fc_list:
            dataset_fc_path = os.path.join(self.dataset_path, ifc_name)
            if ifc_name == 'CJXZQ':  # Polygon   # 在XZQFW_JCX范围内
                if 'XZQFW' in self.fc_list:
                    arcpy.AddRuleToTopology_management(self.topology_path, "Must Be Covered By (Area-Area)",
                                                       dataset_fc_path, "", os.path.join(self.dataset_path, 'XZQFW'),
                                                       "")
            if ifc_name == 'STBHHX':  # Polygon 不能与YJJBNT、ZJDJSFWX要素层重叠。
                if 'ZJDJSFWX' in self.fc_list:
                    arcpy.AddRuleToTopology_management(self.topology_path, "Must Not Overlap With (Area-Area)",
                                                       dataset_fc_path,
                                                       "", os.path.join(self.dataset_path, 'ZJDJSFWX'), "")
                if 'YJJBNT' in self.fc_list:
                    arcpy.AddRuleToTopology_management(self.topology_path, "Must Not Overlap With (Area-Area)",
                                                       dataset_fc_path, "", os.path.join(self.dataset_path, 'YJJBNT'),
                                                       "")
            elif ifc_name == 'YJJBNT':  # Polygon 不能与STBHHX、ZJDJSFWX要素层重叠;在YJJBNTBHTB_JCX范围内。
                if 'YJJBNTBHTB_JCX' in self.fc_list:
                    arcpy.AddRuleToTopology_management(self.topology_path, "Must Be Covered By (Area-Area)",
                                                       dataset_fc_path, "",
                                                       os.path.join(self.dataset_path, 'YJJBNTBHTB_JCX'), "")
                if 'STBHHX' in self.fc_list:
                    arcpy.AddRuleToTopology_management(self.topology_path, "Must Not Overlap With (Area-Area)",
                                                       dataset_fc_path,
                                                       "", os.path.join(self.dataset_path, 'STBHHX'), "")
                if 'ZJDJSFWX' in self.fc_list:
                    arcpy.AddRuleToTopology_management(self.topology_path, "Must Not Overlap With (Area-Area)",
                                                       dataset_fc_path, "", os.path.join(self.dataset_path, 'ZJDJSFWX'),
                                                       "")
            elif ifc_name == 'ZJDJSFWX':  # Polygon 不能与STBHHX、YJJBNT要素层重叠。
                if 'STBHHX' in self.fc_list:
                    arcpy.AddRuleToTopology_management(self.topology_path, "Must Not Overlap With (Area-Area)",
                                                       dataset_fc_path,
                                                       "", os.path.join(self.dataset_path, 'STBHHX'), "")
                if 'YJJBNT' in self.fc_list:
                    arcpy.AddRuleToTopology_management(self.topology_path, "Must Not Overlap With (Area-Area)",
                                                       dataset_fc_path, "", os.path.join(self.dataset_path, 'YJJBNT'),
                                                       "")

        arcpy.AddMessage("    拓扑验证...")
        arcpy.ValidateTopology_management(self.topology_path, "Full_Extent")
        arcpy.AddMessage("    导出拓扑错误...")
        arcpy.ExportTopologyErrors_management(self.topology_path, self.dataset_path, "topoError")



if __name__ == "__main__":
    inpath = 'C:\\drea\\python3\\Check_Topology\\规划数据库.gdb'
    my_Topology = CheckTopology(inpath)
    my_Topology.CreateNewGdb()
    my_Topology.CreateFeatureDataset()
    my_Topology.CreateTopology()
    my_Topology.AddRules_ValidateTopology()

总结及反思

添加拓扑规则的过程中,涉及外部.SHP数据的两条规则一直报错,开始以为是规则参数不正确;后面DeBug发现外部.SHP数据没有添加到类的属性列表self.fc_list中,导致这两个要素在后面的方法实现过程中没有添加到topology。对一些通用的属性,在使用前最好是打印输出验证一下,确保方法修改后没有遗漏。

存在的问题

AddMessage(sys.getdefaultencoding())
添加的中文消息在输出后显示乱码,因为只追求拓扑检查的结果,对该问题没有深入的了解和学习。
有兴趣的可以参考ArcPy官方文档:
AddMessage
向脚本工具或 Python 工具箱工具的消息中添加自定义信息性消息(严重性为 0)。运行工具时,arcpy 完全知晓调用该工具的应用程序。其中一个主要作用是您可以在 Python 中写入消息,且您的消息会自动出现在工具对话框、历史记录和 Python 窗口中。
ArcPy-AddMessage

----------------------------23.04.09更新--------------------------------------------

bug修复1

使用的过程中发现,有GDB中创建了要素数据集,要素分别存在于不同的要素数据集中,会导致上文CreateFeatureDataset()创建数据集时遍历不到要导入的数据。修改如下:

    def CreateFeatureDataset(self):
        arcpy.env.workspace = self.path
        fc_list = arcpy.ListFeatureClasses()  # 列出gdb内的要素类图层

修改为:

    def CreateFeatureDataset(self):
        arcpy.env.workspace = self.path
        fc_list = []
        fc_list1 = arcpy.ListDatasets(feature_type='feature')  # 列出地理数据库中所有的要素类,包括要素数据集中的所有要素类。
        if fc_list1:
            for i in fc_list1:
                fc_list += arcpy.ListFeatureClasses(feature_dataset=i)
        else:
            fc_list = arcpy.ListFeatureClasses()

----------------------------23.04.21更新--------------------------------------------
更新了上文完整代码

问题处理 2

阅读官方文档和及代码测试后发现ArcPy中AddMessage工具添加的地理工作流消息,其中文编码方式默认为‘gbk’。所以将.py文件和系统的默认编码都设置为‘gbk’保持统一,修改如下:

# coding:gbk
# design by @bill_love_3
import os
import sys
import arcpy

# sys.path.append(r'C:\arcgis10.2\Desktop10.2\arcpy')

reload(sys)
sys.setdefaultencoding('gbk')

1. 在使用中,只在当前程序执行窗口显示消息,可以直接用encode=‘utf-8’,将消息以‘utf-8’方式编码成bytes型,与IDE默认的编码方式‘utf-8’保持一致即可正常显示中文消息。
2. 当被当作脚本调用(这里特指python3调用python2.py,具体如何实现请参阅其他资料),需要处理当前py的标准输出流stdout时:(output.decode(‘gbk’)).encode(‘utf-8’),可以以‘gbk’解码成Unicode,再使用‘utf-8’编码;需要保存在文件或者显示在画布中,可以再decode(‘utf-8’)。

----------------------------23.06.02更新--------------------------------------------
处理了一些已知问题,优化了检查速度

问题处理 3

  1. 增加了arcgis授权未启动或未授权错误处理。
  2. 优化了整体检查速度(提升约40%),对没有元素的图层进行判断,不再检查。
  3. 完善了添加拓扑规则消息显示。
    基于ArcPy的GDB地理数据库拓扑检查_第2张图片
# coding:gbk
# design by @bill_love_3
import os
import sys
import time

try:
    import arcpy

except RuntimeError:
    print('...ArcGIS产品授权未启动或授权启动失败,请检查后再执行拓扑检查!')
    sys.stdout.flush()
    time.sleep(2)
    sys.exit(0)

# sys.path.append(r'C:\arcgis10.2\Desktop10.2\arcpy')

reload(sys)
sys.setdefaultencoding('gbk')
arcpy.env.XYResolution = "0.0001 Meters"  # 设置XY分辨率
arcpy.env.XYTolerance = "0.001 Meters"  # 设置XY容差


class CheckTopology():
    def __init__(self, path):
        self.dir_path = os.path.dirname(path)
        self.path = path
        self._gdb = ''
        self.dataset_path = ''
        self.topology_path = ''
        self.fc_list = []

    def CreateNewGdb(self):
        arcpy.env.workspace = self.dir_path
        gdb_name1 = os.path.basename(os.path.splitext(self.path)[0] + '_Topology')
        result_gdb = os.path.join(self.dir_path, gdb_name1)
        self._gdb = (result_gdb + '.gdb')
        # print(result_gdb)
        if arcpy.Exists(self._gdb):
            arcpy.AddMessage('...当前路径已存在' + result_gdb + "请删除后再执行检查...")
            time.sleep(2)
            sys.exit(0)
        else:
            arcpy.AddMessage("...新建 " + os.path.basename(result_gdb) + " ...")
            arcpy.CreateFileGDB_management(self.dir_path, gdb_name1)

    def CreateFeatureDataset(self):
        arcpy.env.workspace = self.path
        fc_list = []
        fc_list1 = arcpy.ListDatasets(feature_type='feature')  # 返回当前工作空间中的数据集
        if fc_list1:
            for i in fc_list1:
                for ii in arcpy.ListFeatureClasses(feature_dataset=i):  # 返回当前工作空间中的要素类
                    if int(arcpy.GetCount_management(ii).getOutput(0)) > 0:
                        fc_list.append(ii)
        else:
            fc_list = [i for i in arcpy.ListFeatureClasses() if int(arcpy.GetCount_management(i).getOutput(0)) > 0]
        # 判断是否检查
        if 'CJXZQ' in fc_list:
            self.fc_list = fc_list
        else:
            arcpy.AddError('...缺失CJXZQ或图层名称不符合规范,无法检查拓扑...')
            time.sleep(2)
            sys.exit(0)
        in_fc_path_list = [os.path.join(self.path, fc) for fc in self.fc_list]
        # print(in_fc_path_list)
        arcpy.AddMessage("...在 " + os.path.basename(self._gdb) + " 内新建要素数据集...")
        dataset_name = "dataset"
        dataset_path = os.path.join(self._gdb, dataset_name)
        self.dataset_path = dataset_path
        # 引用包含要应用的空间参考的要素类或要素数据集,
        sr = arcpy.SpatialReference(".\\recourse\\XZQFW.prj")
        arcpy.CreateFeatureDataset_management(self._gdb, dataset_name, sr)  # (out_dataset_path, out_name,
        # {spatial_reference}) {spatial_reference}可以是 .prj 文件的路径、引用包含要应用的空间参考的要素类或要素数据集、在使用此工具之前定义空间参考对象
        # 导入要素类到数据集
        arcpy.AddMessage("...向 " + dataset_path + " 导入要素类图层...")
        arcpy.FeatureClassToGeodatabase_conversion(in_fc_path_list, dataset_path)
        # 引用外部数据,进行拓扑检查
        J_BNT = r'.\recourse\YJJBNTBHTB_JCX.shp'
        XZQ = r'.\recourse\XZQFW.shp'
        self.fc_list.append('YJJBNTBHTB_JCX')
        self.fc_list.append('XZQFW')
        arcpy.FeatureClassToGeodatabase_conversion(J_BNT, dataset_path)
        arcpy.FeatureClassToGeodatabase_conversion(XZQ, dataset_path)

    def CreateTopology(self):
        arcpy.AddMessage("...创建拓扑...")  # 在dataset数据内创建拓扑
        topology_name = "topology"
        topology_path = os.path.join(self.dataset_path, topology_name)
        self.topology_path = topology_path
        arcpy.CreateTopology_management(self.dataset_path, topology_name)
        for ifc_name in self.fc_list:
            dataset_fc_path = os.path.join(self.dataset_path, ifc_name)  # 拼接数据集中的要素类绝对路径
            arcpy.AddMessage("...向拓扑中添加要素类" + dataset_fc_path + "...")  # 将导入dataset的要素类添加到拓扑中
            arcpy.AddFeatureClassToTopology_management(topology_path, dataset_fc_path, "1", "1")

    def AddRules_ValidateTopology(self):
        # 按要素属性添加拓扑规则
        arcpy.AddMessage("...添加拓扑规则...")
        for ifc_name in self.fc_list:
            dataset_fc_path = os.path.join(self.dataset_path, ifc_name)  # 拼接数据集中的要素类绝对路径
            desc = arcpy.Describe(dataset_fc_path)  # 要素属性 shapeType[Polygon,Polyline,Point,Multipoint,MultiPatch]
            # 面要素  不能重叠  在CJXZQ范围内
            if desc.shapeType == 'Polygon' and ifc_name != 'YJJBNTBHTB_JCX' and ifc_name != 'XZQFW' and ifc_name != 'CJXZQ':
                arcpy.AddMessage("...添加拓扑规则:%s" % ifc_name + "面的内部不能重叠...")
                arcpy.AddRuleToTopology_management(self.topology_path, "Must Not Overlap (Area)", dataset_fc_path, "",
                                                   "",
                                                   "")
                arcpy.AddMessage("...添加拓扑规则:%s" % ifc_name + "面必须包含于CJXZQ面中...")
                arcpy.AddRuleToTopology_management(self.topology_path, "Must Be Covered By (Area-Area)",
                                                   dataset_fc_path, "",
                                                   os.path.join(self.dataset_path, 'CJXZQ'), "")
            elif desc.shapeType == 'Point':  # 点要素 不能接合
                arcpy.AddMessage("...添加拓扑规则:%s" % ifc_name + "点与相同要素类中的其他点在空间上必须相互分离...")
                arcpy.AddRuleToTopology_management(self.topology_path, "Must Be Disjoint (Point)", dataset_fc_path, "",
                                                   "",
                                                   "")
            elif desc.shapeType == 'Polyline':  # 线要素 在CJXZQ范围内
                arcpy.AddMessage("...添加拓扑规则:%s" % ifc_name + "线必须包含在CJXZQ面要素的边界内...")
                arcpy.AddRuleToTopology_management(self.topology_path, "Must Be Inside (Line-Area)", dataset_fc_path,
                                                   "",
                                                   os.path.join(self.dataset_path, 'CJXZQ'), "")
                # 测试
                # arcpy.AddRuleToTopology_management(self.topology_path, "Must Not Overlap (Line)", dataset_fc_path, "",
                #                                    "",
                #                                    "")
        # 按要素名称添加拓扑规则
        for ifc_name in self.fc_list:
            dataset_fc_path = os.path.join(self.dataset_path, ifc_name)
            if ifc_name == 'CJXZQ':  # Polygon   # 在XZQFW_JCX范围内
                if 'XZQFW' in self.fc_list:
                    arcpy.AddMessage("...添加拓扑规则:%s" % ifc_name + "面必须包含于XZQFW面中...")
                    arcpy.AddRuleToTopology_management(self.topology_path, "Must Be Covered By (Area-Area)",
                                                       dataset_fc_path, "", os.path.join(self.dataset_path, 'XZQFW'),
                                                       "")
            if ifc_name == 'STBHHX':  # Polygon 不能与YJJBNT、ZJDJSFWX要素层重叠。
                if 'ZJDJSFWX' in self.fc_list:
                    arcpy.AddMessage("...添加拓扑规则:%s" % ifc_name + "要素类面的内部不得与ZJDJSFWX要素类面的内部相重叠...")
                    arcpy.AddRuleToTopology_management(self.topology_path, "Must Not Overlap With (Area-Area)",
                                                       dataset_fc_path,
                                                       "", os.path.join(self.dataset_path, 'ZJDJSFWX'), "")
                if 'YJJBNT' in self.fc_list:
                    arcpy.AddMessage("...添加拓扑规则:%s" % ifc_name + "要素类面的内部不得与YJJBNT要素类面的内部相重叠...")
                    arcpy.AddRuleToTopology_management(self.topology_path, "Must Not Overlap With (Area-Area)",
                                                       dataset_fc_path, "", os.path.join(self.dataset_path, 'YJJBNT'),
                                                       "")
            elif ifc_name == 'YJJBNT':  # Polygon 不能与STBHHX、ZJDJSFWX要素层重叠;在YJJBNTBHTB_JCX范围内。
                if 'YJJBNTBHTB_JCX' in self.fc_list:
                    arcpy.AddMessage("...添加拓扑规则:%s" % ifc_name + "面必须包含于YJJBNTBHTB_JCX面中...")
                    arcpy.AddRuleToTopology_management(self.topology_path, "Must Be Covered By (Area-Area)",
                                                       dataset_fc_path, "",
                                                       os.path.join(self.dataset_path, 'YJJBNTBHTB_JCX'), "")
                if 'STBHHX' in self.fc_list:
                    arcpy.AddMessage("...添加拓扑规则:%s" % ifc_name + "要素类面的内部不得与STBHHX要素类面的内部相重叠...")
                    arcpy.AddRuleToTopology_management(self.topology_path, "Must Not Overlap With (Area-Area)",
                                                       dataset_fc_path,
                                                       "", os.path.join(self.dataset_path, 'STBHHX'), "")
                if 'ZJDJSFWX' in self.fc_list:
                    arcpy.AddMessage("...添加拓扑规则:%s" % ifc_name + "要素类面的内部不得与ZJDJSFWX要素类面的内部相重叠...")
                    arcpy.AddRuleToTopology_management(self.topology_path, "Must Not Overlap With (Area-Area)",
                                                       dataset_fc_path, "", os.path.join(self.dataset_path, 'ZJDJSFWX'),
                                                       "")
            elif ifc_name == 'ZJDJSFWX':  # Polygon 不能与STBHHX、YJJBNT要素层重叠。
                if 'STBHHX' in self.fc_list:
                    arcpy.AddMessage("...添加拓扑规则:%s" % ifc_name + "要素类面的内部不得与STBHHX要素类面的内部相重叠...")
                    arcpy.AddRuleToTopology_management(self.topology_path, "Must Not Overlap With (Area-Area)",
                                                       dataset_fc_path,
                                                       "", os.path.join(self.dataset_path, 'STBHHX'), "")
                if 'YJJBNT' in self.fc_list:
                    arcpy.AddMessage("...添加拓扑规则:%s" % ifc_name + "要素类面的内部不得与YJJBNT要素类面的内部相重叠...")
                    arcpy.AddRuleToTopology_management(self.topology_path, "Must Not Overlap With (Area-Area)",
                                                       dataset_fc_path, "", os.path.join(self.dataset_path, 'YJJBNT'),
                                                       "")

        arcpy.AddMessage("...拓扑验证...")
        arcpy.ValidateTopology_management(self.topology_path, "Full_Extent")
        arcpy.AddMessage("...导出拓扑错误...")
        arcpy.ExportTopologyErrors_management(self.topology_path, self.dataset_path, "topoError")


if __name__ == "__main__":
    in_path = sys.argv[1] 
    my_Topology = CheckTopology(in_path)
    my_Topology.CreateNewGdb()
    my_Topology.CreateFeatureDataset()
    my_Topology.CreateTopology()
    my_Topology.AddRules_ValidateTopology()

你可能感兴趣的:(ArcPy,arcgis,python,数据库)