填充多部件多边形间隙且不生成重叠多边形的实现方法咨询
问题描述
- 待完成任务:对多部件(multipart)多边形做间隙填充,最终为每个空间要素生成具备单一外轮廓的多边形
- 已有方案效果:对多部件要素先后执行250m正向缓冲区、250m负向缓冲区计算,生成的多边形轮廓符合预期,但相邻要素处理后存在多边形互相重叠的问题
- 需求:寻找与现有实现逻辑相近、可保证处理结果无多边形重叠的可行方案
原有参考实现代码:
library(sf) library(dplyr) unzip("Areas.zip") Areas <- st_read("Areas.gpkg") Area_1 <- Areas %>% filter(name == "Area 1") %>% st_buffer(., 250) %>% st_buffer(., -250) New_Areas <- bind_rows(Area_1, Areas %>% filter(name != "Area 1"))
解决方案
之前的方案出现重叠的核心原因是只单独对单个要素做缓冲,没有给相邻要素加边界约束,缓冲后的范围自然会侵占邻接要素的空间。完全保留正负缓冲填间隙的核心逻辑,补一层拓扑互斥裁切就能解决重叠问题,实现代码如下:
library(sf) library(dplyr) Areas <- st_read("Areas.gpkg") # 统一对所有要素做正负缓冲填充内部间隙,不要单独处理单个要素 buffered_areas <- Areas %>% st_buffer(250) %>% st_buffer(-250) %>% st_make_valid() # 修复缓冲生成的微小拓扑错误 # 逐要素扣减被其他要素占压的重叠区域,保证所有要素边界互斥 non_overlap_areas <- buffered_areas %>% mutate(feat_id = row_number()) %>% group_split(feat_id) %>% lapply(function(current_feat){ other_feats <- buffered_areas %>% filter(feat_id != current_feat$feat_id) cleaned_feat <- st_difference(current_feat, st_union(other_feats)) return(cleaned_feat) }) %>% bind_rows() %>% select(-feat_id) # 校验:最终结果不存在重叠要素 stopifnot(sum(st_overlaps(non_overlap_areas, sparse = FALSE)) == 0)
方案说明:
- 核心逻辑兼容:填充步骤和原有方案完全一致,没有更换间隙填充的实现思路,学习和改造成本极低
- 边界精度可控:如果缓冲裁切后边界出现细碎锯齿,可以在最后加一步
st_snap(),设置1m以内的容差把相邻要素边界对齐,不会影响整体范围精度 - 无重叠保证:所有要素统一做缓冲再做互斥裁切,从流程上避免了单要素缓冲侵占邻域的问题,最终输出的多边形无重叠
内容的提问来源于stack exchange,提问作者Chris
相关产品推荐
相关产品推荐

