You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用nngeo包st_remove_holes函数去除shapefile孔洞存在残留问题

孔洞去除不彻底的原因
  • st_remove_holes()仅识别单个POLYGON对象的内部环作为孔洞:你按街区分组并调用st_union()后得到的是MULTIPOLYGON对象,多个POLYGON子要素围合形成的空白区域不会被判定为孔洞,因此不会被移除。
  • 合并后存在拓扑错误:原始普查 tract 数据合并后可能存在自相交、环方向错误等拓扑异常,导致函数无法正确识别内部孔洞。
  • 未明确匹配面积阈值:若残留孔洞面积极小,可能触发函数的精度识别阈值,导致遗漏。
解决方案

你可以按照以下步骤调整代码,即可完全移除所有孔洞:

library(dplyr) 
library(sf)
library(nngeo) 
library(geobr) 

sf_use_s2(FALSE)
# 读取原始普查小区数据
shape.muni <- read_census_tract(year = 2010, code_tract = 3304557) 

# 方法1:基础修复方案,适配绝大多数场景
shape.muni <- shape.muni %>% 
  group_by(code_neighborhood, name_neighborhood) %>% 
  summarise(geometry = st_union(geom)) %>% 
  # 先修复拓扑错误,避免识别异常
  st_make_valid() %>%
  # 明确指定移除所有面积大于0的孔洞
  st_remove_holes(min_area = 0)

# 方法2:如果方法1仍有残留孔洞,可追加缓冲区二次处理
# 缓冲区距离根据数据坐标系调整,地理坐标系下0.0001约对应10米精度,可按需调整
shape.muni <- shape.muni %>%
  st_buffer(0.0001) %>%
  st_buffer(-0.0001) %>%
  st_remove_holes(min_area = 0)

# 方法3:终极方案,手动提取外环直接移除所有内部环
remove_all_holes <- function(sf_obj) {
  sf_obj$geometry <- st_sfc(lapply(st_geometry(sf_obj), function(x) {
    if (st_geometry_type(x) == "MULTIPOLYGON") {
      polys <- lapply(x, function(poly) st_polygon(poly[1]))
      st_multipolygon(polys)
    } else if (st_geometry_type(x) == "POLYGON") {
      st_polygon(x[1])
    } else {
      x
    }
  }), crs = st_crs(sf_obj))
  return(sf_obj)
}
shape.muni <- remove_all_holes(shape.muni)

内容的提问来源于stack exchange,提问作者Igor

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.01 07:57:02