乐于分享
好东西不私藏

openclaw已学会ArcGIS的拓扑检查

openclaw已学会ArcGIS的拓扑检查
#!/usr/bin/env python3"""拓扑检查 - 线要素不能有悬挂点(Must Not Have Dangles"""import osimport arcpyimport shutilimport timedef get_desktop_gis_path():"""获取桌面 GIS 文件夹路径"""desktop = os.path.join(os.environ.get("USERPROFILE", os.path.expanduser("~")), "Desktop")    gis_path = os.path.join(desktop, "GIS")    os.makedirs(gis_path, exist_ok=True)return gis_pathdef check_line_dangles(input_line, output_gdb_name="line.gdb"):"""使用标准拓扑规则检查线悬挂点    1. 创建文件地理数据库    2. 创建要素数据集    3. 导入数据    4. 创建拓扑(线不能有悬挂点)    5. 验证拓扑    6. 导出拓扑错误    """output_folder = get_desktop_gis_path()    print(f"输入数据:{input_line}")    print(f"输出目录:{output_folder}")    print(f"输出 GDB: {output_gdb_name}")    print()检查输入是否存在if not arcpy.Exists(input_line):        print(f"[ERROR] 输入数据不存在:{input_line}")return None获取输入数据信息count = int(arcpy.GetCount_management(input_line)[0])    desc = arcpy.Describe(input_line)    spatial_ref = desc.spatialReference    print(f"要素数量:{count}")    print(f"坐标系:{spatial_ref.name if spatial_ref else '未知'}")    print()# ========== 步骤 1: 创建文件地理数据库 ==========gdb_path = os.path.join(output_folder, output_gdb_name)if arcpy.Exists(gdb_path):        print(f"删除已存在的地理数据库:{gdb_path}")try:            arcpy.management.Delete(gdb_path)            print("  -> 删除成功(arcpy")except Exception as e1:            print(f"  -> arcpy 删除失败:{e1}")try:                shutil.rmtree(gdb_path, ignore_errors=True)                print("  -> 删除成功(shutil")except Exception as e2:                print(f"  -> shutil 删除失败:{e2}")                new_name = gdb_path + f".old.{int(time.time())}"os.rename(gdb_path, new_name)                print(f"  -> 已重命名为:{new_name}")    print("[1/6] 创建文件地理数据库...")    arcpy.management.CreateFileGDB(output_folder, output_gdb_name)    print(f"  -> 创建:{gdb_path}")    print()# ========== 步骤 2: 创建要素数据集 ==========dataset_name = "LineDS"dataset_path = os.path.join(gdb_path, dataset_name)    print("[2/6] 创建要素数据集...")    arcpy.management.CreateFeatureDataset(        out_dataset_path=gdb_path,        out_name=dataset_name,        spatial_reference=spatial_ref    )    print(f"  -> 创建:{dataset_path}")    print()# ========== 步骤 3: 导入数据到数据集 ==========feature_class_name = "Line_FC"feature_class_path = os.path.join(dataset_path, feature_class_name)    print("[3/6] 导入数据到要素数据集...")    arcpy.management.CopyFeatures(        in_features=input_line,        out_feature_class=feature_class_path    )    fc_count = int(arcpy.GetCount_management(feature_class_path)[0])    print(f"  -> 创建:{feature_class_path}")    print(f"  -> 要素数量:{fc_count}")    print()# ========== 步骤 4: 创建拓扑 ==========topology_name = "Line_Topology"topology_path = os.path.join(dataset_path, topology_name)    print("[4/6] 创建拓扑规则(线不能有悬挂点)...")创建拓扑arcpy.management.CreateTopology(        in_dataset=dataset_path,        out_name=topology_name,        in_cluster_tolerance="0.001 Meters")    print(f"  -> 创建拓扑:{topology_path}")添加要素类到拓扑arcpy.management.AddFeatureClassToTopology(        in_topology=topology_path,        in_featureclass=feature_class_path,        z_rank=1)    print(f"  -> 添加要素类:{feature_class_name}")添加拓扑规则:Must Not Have Dangles(不能有悬挂点)print("  -> 添加拓扑规则:Must Not Have Dangles (Line)")    arcpy.AddRuleToTopology_management(        topology_path,"Must Not Have Dangles (Line)",        feature_class_path    )    print("  -> 规则添加成功")    print()# ========== 步骤 5: 验证拓扑 ==========print("[5/6] 验证拓扑...")    arcpy.management.ValidateTopology(topology_path)    print("  -> 验证完成")    print()# ========== 步骤 6: 导出拓扑错误 ==========print("[6/6] 导出拓扑错误...")拓扑错误输出路径error_output = os.path.join(output_folder, "line_拓扑错误.shp")if arcpy.Exists(error_output):        arcpy.Delete_management(error_output)使用 ExportTopologyErrors 工具导出错误try:        arcpy.ExportTopologyErrors_conversion(            in_topology=topology_path,            out_featureclass=error_output,            error_type="ALL")except AttributeError:如果 ExportTopologyErrors_conversion 不可用,使用替代方法print("  -> ExportTopologyErrors 不可用,使用 FeatureVerticesToPoints 方法...")对于悬挂点,使用 FeatureVerticesToPoints 查找端点error_output = os.path.join(output_folder, "line_悬挂点.shp")        arcpy.management.FeatureVerticesToPoints(            in_features=feature_class_path,            out_feature_class=error_output,            point_location="BOTH_ENDS")统计错误数量if arcpy.Exists(error_output):        error_count = int(arcpy.GetCount_management(error_output)[0])创建.cpg 文件cpg_path = error_output.replace(".shp"".cpg")with open(cpg_path, "w", encoding="utf-8"as f:            f.write("CP936")        print()        print("=" 60)        print("[OK] 拓扑检查完成!")        print("=" 60)        print(f"输出文件:{error_output}")        print(f"拓扑错误数量:{error_count}")        print()if error_count > 0:            print("[WARNING] 发现悬挂点错误!")            print()            print("修复步骤:")            print("  1.  ArcGIS Pro 中添加拓扑错误图层")            print("  2. 启动编辑会话")            print("  3. 使用拓扑错误检查器查看悬挂点")            print("  4. 使用延伸、修剪或捕捉工具修复悬挂点")            print("  5. 重新验证拓扑")else:            print("[OK] 数据拓扑良好,未发现悬挂点错误!")        print()        print(f"地理数据库:{gdb_path}")        print(f"拓扑数据集:{dataset_path}")        print(f"拓扑规则:{topology_path}")return error_output, error_countelse:        print("[ERROR] 未能导出拓扑错误")return None0def main():输入数据input_line = r"C:\Users\yl\Documents\ArcGIS\Projects\MyProject14\MyProject14.gdb\Line"输出 GDB 名称output_gdb_name = "line.gdb"print("=" 60)    print("ArcGIS Pro 拓扑检查 - 线不能有悬挂点")    print("=" 60)    print()设置环境arcpy.env.overwriteOutput = True执行检查result = check_line_dangles(input_line, output_gdb_name)if __name__ == "__main__":    main()