求助:ArcPy/ArcGIS Pro实现非水域多边形合并(含50米邻近与水域分隔规则)
基于ArcPy实现带水域屏障的多边形合并方案
实现思路
核心逻辑是用50米缓冲区划定可合并范围,再用水域要素切割缓冲区,确保被水域分隔的区域无法合并,最后基于切割后的缓冲区分组融合原始非水域多边形:
- 分离目标要素(非"Water"多边形)与屏障要素("Water"多边形)
- 为目标要素生成50米缓冲区并合并相邻部分
- 用水域屏障切割缓冲区,将被分隔的缓冲区拆分为独立单元
- 通过空间关联让原始目标要素绑定对应缓冲区单元ID
- 按缓冲区ID融合原始要素,得到最终斑块
代码实现
import arcpy import os # 配置工作环境 arcpy.env.workspace = r"C:\YourWorkspacePath" # 替换为你的工作空间路径 arcpy.env.overwriteOutput = True # 原始要素类路径 input_shp = "your_input_shapefile.shp" # 替换为你的输入shapefile名 output_shp = "merged_non_water_patches.shp" # 输出结果文件名 # 1. 分离非Water和Water要素 # 创建临时图层 arcpy.management.MakeFeatureLayer(input_shp, "all_features_lyr") # 选择非Water要素 arcpy.management.SelectLayerByAttribute("all_features_lyr", "NEW_SELECTION", "Current_RE <> 'Water'") arcpy.management.CopyFeatures("all_features_lyr", "non_water_temp.shp") # 选择Water要素 arcpy.management.SelectLayerByAttribute("all_features_lyr", "NEW_SELECTION", "Current_RE = 'Water'") arcpy.management.CopyFeatures("all_features_lyr", "water_temp.shp") # 2. 为非Water要素生成50米缓冲区(合并相邻缓冲区) arcpy.management.Buffer("non_water_temp.shp", "non_water_buffer_50m.shp", "50 Meters", dissolve_option="ALL") # 3. 用水域要素切割缓冲区,拆分被分隔的区域 arcpy.management.Clip("non_water_buffer_50m.shp", "", "clipped_buffer_temp.shp", "water_temp.shp") # 4. 给切割后的缓冲区添加唯一ID字段(用于分组) arcpy.management.AddField("clipped_buffer_temp.shp", "Patch_ID", "LONG") arcpy.management.CalculateField("clipped_buffer_temp.shp", "Patch_ID", "!OBJECTID!", "PYTHON3") # 5. 空间连接:将原始非Water要素与缓冲区ID关联 arcpy.analysis.SpatialJoin("non_water_temp.shp", "clipped_buffer_temp.shp", "joined_non_water_temp.shp", join_type="KEEP_ALL", match_option="INTERSECT") # 6. 按Patch_ID融合,得到最终斑块 arcpy.management.Dissolve("joined_non_water_temp.shp", output_shp, dissolve_field="Patch_ID") # 清理临时文件 temp_files = ["non_water_temp.shp", "water_temp.shp", "non_water_buffer_50m.shp", "clipped_buffer_temp.shp", "joined_non_water_temp.shp"] for file in temp_files: if arcpy.Exists(file): # 删除shapefile的所有关联文件 arcpy.management.Delete_management(file) # 处理.shp之外的附属文件(如.shx, .dbf等) base_name = os.path.splitext(file)[0] for ext in [".shx", ".dbf", ".prj", ".sbn", ".sbx", ".shp.xml", ".cpg"]: temp_file = base_name + ext if os.path.exists(temp_file): os.remove(temp_file) print("斑块合并完成,结果已保存至:", output_shp)
关键步骤说明
- 缓冲区融合:生成50米缓冲区时使用
dissolve_option="ALL",确保原本相邻的目标要素缓冲区合并为一个单元 - 缓冲区裁剪:用水域要素切割缓冲区后,被水域隔开的区域会成为独立的缓冲区单元,后续融合时自然无法跨水域合并
- 空间关联与融合:通过
SpatialJoin让每个原始要素绑定对应的缓冲区ID,最终按ID融合即可得到符合要求的斑块
内容的提问来源于stack exchange,提问作者Jabbar
相关产品推荐
相关产品推荐

