ghcy.py 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206
  1. # -*- coding: utf-8 -*-
  2. import arcpy
  3. import os
  4. import datetime
  5. def calculate_spatial_relationship_optimized():
  6. try:
  7. # 设置工作环境
  8. arcpy.env.overwriteOutput = True
  9. # 输入参数配置
  10. A_table = r"D:\Python\sde\KJGH.sde\SDE.ZXCQ_XXGH" # A表SDE路径
  11. B_table = r"D:\Python\sde\KJGH.sde\SDE.ZXCQ_ZTGH" # B表SDE路径
  12. output_folder = r"D:\test\ghcy" # 输出文件夹路径
  13. # 创建输出文件夹
  14. if not os.path.exists(output_folder):
  15. os.makedirs(output_folder)
  16. # 时间戳用于生成唯一文件名
  17. timestamp = datetime.datetime.now().strftime("%Y%m%d_%H%M%S")
  18. # 临时工作空间
  19. temp_workspace = "in_memory"
  20. print("开始处理SDE.ZXCQ_XXGH和SDE.ZXCQ_ZTGH的空间关系...")
  21. # 验证表是否存在
  22. if not arcpy.Exists(A_table):
  23. print("错误: A表不存在 - {0}".format(A_table))
  24. return
  25. if not arcpy.Exists(B_table):
  26. print("错误: B表不存在 - {0}".format(B_table))
  27. return
  28. # 检查必需字段是否存在
  29. required_fields = ["YDYHFLDM", "YDYHFLMC"]
  30. a_fields = [f.name for f in arcpy.ListFields(A_table)]
  31. b_fields = [f.name for f in arcpy.ListFields(B_table)]
  32. for field in required_fields:
  33. if field not in a_fields:
  34. print("错误: A表中找不到 {0} 字段".format(field))
  35. print("A表字段列表: {0}".format(a_fields))
  36. return
  37. if field not in b_fields:
  38. print("错误: B表中找不到 {0} 字段".format(field))
  39. print("B表字段列表: {0}".format(b_fields))
  40. return
  41. print("字段验证通过,开始处理...")
  42. # 步骤1: 定义查询字段(只保留需要的字段)
  43. a_cursor_fields = ["OID@", "SHAPE@", "YDYHFLDM", "YDYHFLMC"]
  44. b_cursor_fields = ["OID@", "SHAPE@", "YDYHFLDM", "YDYHFLMC"]
  45. # 用于存储需要裁剪的要素
  46. features_to_clip = []
  47. # 创建B表的临时图层
  48. print("正在创建临时图层...")
  49. B_layer = "B_table_layer"
  50. arcpy.MakeFeatureLayer_management(B_table, B_layer)
  51. print("开始遍历A表要素...")
  52. with arcpy.da.SearchCursor(A_table, a_cursor_fields) as a_cursor:
  53. a_count = 0
  54. processed_count = 0
  55. for a_row in a_cursor:
  56. a_count += 1
  57. a_oid = a_row[0]
  58. a_geometry = a_row[1]
  59. a_ydyhfldm = a_row[2]
  60. a_ydyhflmc = a_row[3]
  61. if a_count % 100 == 0:
  62. print("已处理 {0} 个A表要素,找到 {1} 个需要裁剪的要素".format(a_count, processed_count))
  63. # 检查几何是否有效
  64. if a_geometry is None or a_geometry.length == 0:
  65. continue
  66. try:
  67. # 使用SelectLayerByLocation选择与A表要素相交的B表要素
  68. arcpy.SelectLayerByLocation_management(B_layer, "INTERSECT", a_geometry)
  69. # 获取选中的要素数量
  70. result = arcpy.GetCount_management(B_layer)
  71. selected_count = int(result.getOutput(0))
  72. if selected_count > 0:
  73. # 遍历选中的B表要素
  74. with arcpy.da.SearchCursor(B_layer, b_cursor_fields) as b_cursor:
  75. for b_row in b_cursor:
  76. b_oid = b_row[0]
  77. b_geometry = b_row[1]
  78. b_ydyhfldm = b_row[2]
  79. b_ydyhflmc = b_row[3]
  80. # 检查几何是否有效
  81. if b_geometry is None or b_geometry.length == 0:
  82. continue
  83. # 处理YDYHFLDM字段比较
  84. a_ydyhfldm_str = str(a_ydyhfldm) if a_ydyhfldm is not None else ""
  85. b_ydyhfldm_str = str(b_ydyhfldm) if b_ydyhfldm is not None else ""
  86. # 判断是否需要执行后续操作
  87. need_process = False
  88. if b_ydyhfldm_str.endswith('0000'):
  89. # 如果b_ydyhfldm_str以0000结尾,比较前两位
  90. if len(a_ydyhfldm_str) >= 2 and len(b_ydyhfldm_str) >= 2:
  91. if a_ydyhfldm_str[:2] != b_ydyhfldm_str[:2]:
  92. need_process = True
  93. else:
  94. # 其他情况,直接比较整个字符串
  95. if a_ydyhfldm_str != b_ydyhfldm_str:
  96. need_process = True
  97. if need_process:
  98. processed_count += 1
  99. if processed_count % 50 == 0:
  100. print(
  101. " 发现第 {0} 个不一致要素: A表OID={1}, B表OID={2}".format(processed_count,
  102. a_oid, b_oid))
  103. # 获取相交部分几何
  104. try:
  105. intersect_geom = a_geometry.intersect(b_geometry, 4) # 4表示平面相交
  106. # 检查相交几何是否有效
  107. if intersect_geom is not None and intersect_geom.length > 0:
  108. # 创建要素信息
  109. a_feature = {
  110. 'geometry': intersect_geom,
  111. 'a_ydyhfldm': a_ydyhfldm_str,
  112. 'a_ydyhflmc': str(a_ydyhflmc) if a_ydyhflmc is not None else "",
  113. 'b_ydyhfldm': b_ydyhfldm_str,
  114. 'b_ydyhflmc': str(b_ydyhflmc) if b_ydyhflmc is not None else ""
  115. }
  116. features_to_clip.append(a_feature)
  117. except Exception as e:
  118. print(" 计算相交几何时出错: {0}".format(e))
  119. continue
  120. except Exception as e:
  121. print(" 空间查询B表时出错: {0}".format(e))
  122. continue
  123. # 清理临时图层
  124. try:
  125. arcpy.Delete_management(B_layer)
  126. except:
  127. pass
  128. print("处理完成!总共处理了 {0} 个A表要素,找到 {1} 个需要裁剪的要素".format(a_count, len(features_to_clip)))
  129. # 如果有需要处理的要素,进行导出
  130. if features_to_clip:
  131. print("开始导出 {0} 个裁剪要素...".format(len(features_to_clip)))
  132. # 创建输出要素类
  133. output_fc_name = "clipped_features_{0}".format(timestamp)
  134. output_fc_path = os.path.join(temp_workspace, output_fc_name)
  135. # 获取空间参考
  136. spatial_ref = arcpy.Describe(A_table).spatialReference
  137. # 创建输出要素类
  138. arcpy.CreateFeatureclass_management(temp_workspace,
  139. output_fc_name,
  140. "POLYGON",
  141. None,
  142. "DISABLED",
  143. "DISABLED",
  144. spatial_ref)
  145. # 添加必需字段
  146. arcpy.AddField_management(output_fc_path, "A_YDYHFLDM", "TEXT", "", "", 50)
  147. arcpy.AddField_management(output_fc_path, "A_YDYHFLMC", "TEXT", "", "", 100)
  148. arcpy.AddField_management(output_fc_path, "B_YDYHFLDM", "TEXT", "", "", 50)
  149. arcpy.AddField_management(output_fc_path, "B_YDYHFLMC", "TEXT", "", "", 100)
  150. # 准备插入字段列表
  151. output_fields = [
  152. "SHAPE@",
  153. "A_YDYHFLDM",
  154. "A_YDYHFLMC",
  155. "B_YDYHFLDM",
  156. "B_YDYHFLMC"
  157. ]
  158. print("输出字段: {0}".format(output_fields))
  159. # 插入数据
  160. print("正在插入裁剪后的要素...")
  161. inserted_count = 0
  162. with arcpy.da.InsertCursor(output_fc_path, output_fields) as insert_cursor:
  163. for feature in features_to_clip:
  164. try:
  165. # 构建插入行数据
  166. row_data = [
  167. feature['geometry'],
  168. feature['a_ydyhfldm'],
  169. feature['a_ydyhflmc'],
  170. feature['b_ydyhfldm'],
  171. feature['b_ydyhflmc']
  172. ]
  173. insert_cursor.insertRow(row_data)
  174. inserted_count += 1
  175. if inserted_count % 100 == 0:
  176. print("已插入 {0} 个要素".format(inserted_count))
  177. except Exception as e:
  178. print("插入要素时出错: {0}".format(e))
  179. continue
  180. # 导出为Shapefile
  181. output_shp = os.path.join(output_folder, "clipped_results_{0}.shp".format(timestamp))
  182. arcpy.CopyFeatures_management(output_fc_path, output_shp)
  183. mjField = "TBMJ"
  184. arcpy.AddField_management(output_shp, mjField, "DOUBLE")
  185. arcpy.CalculateField_management(output_shp, mjField, "!shape.area@SQUAREMETERS!", "PYTHON_9.3")
  186. print("结果已导出到: {0}".format(output_shp))
  187. print("总共导出了 {0} 个要素".format(inserted_count))
  188. # 清理临时数据
  189. try:
  190. arcpy.Delete_management(output_fc_path)
  191. except:
  192. pass
  193. else:
  194. print("没有找到需要裁剪的要素")
  195. print("处理完成!")
  196. except Exception as e:
  197. print("处理过程中发生错误: {0}".format(e))
  198. import traceback
  199. print(traceback.format_exc())
  200. if __name__ == "__main__":
  201. calculate_spatial_relationship_optimized()