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 None, 0def 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()