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

如何使用R sf移除多边形中的“类孔洞”结构?

问题描述

我有一个包含孔洞和若干细长“类孔洞”(即深入多边形的狭长入口)的多边形。

原始多边形加载代码

field <- sf::read_sf("example_field.kml")
ggplot() +
  geom_sf(data = field) +
  theme_void()

多边形原始效果

移除真孔洞的操作

我已经用以下代码移除了多边形中的“真孔洞”:

field_no_holes <- nngeo::st_remove_holes(field)
ggplot() +
  geom_sf(data = field_no_holes) +
  theme_void()

移除真孔洞后的效果

但处理后仍残留若干细长的“类孔洞”,请问如何高效移除这些结构?以下是手动删除顶点实现的期望最终效果:

field_fixed <- sf::read_sf("example_field_fixed.kml") %>%
  nngeo::st_remove_holes()
ggplot() +
  geom_sf(data = field_fixed) +
  theme_void()

最终目标效果


解决方案

这类狭长的“类孔洞”属于多边形边界的凹陷结构,并非拓扑意义上的真孔洞,所以nngeo::st_remove_holes()无法识别处理。可以通过以下几种高效方法清理:

方法1:平滑+拓扑简化组合

借助smoothr包的平滑功能填充凹陷,再用sf的简化功能去除冗余顶点:

library(smoothr)
library(sf)
library(ggplot2)
library(nngeo)

# 读取数据并移除真孔洞
field_no_holes <- st_remove_holes(read_sf("example_field.kml"))

# 平滑处理:adjust参数控制平滑程度,值越大平滑效果越强
field_smoothed <- smooth(field_no_holes, method = "ksmooth", adjust = 2)

# 拓扑简化:dTolerance单位与数据坐标系一致,按需调整
field_cleaned <- st_simplify(field_smoothed, dTolerance = 10)

# 验证结果
ggplot() +
  geom_sf(data = field_cleaned) +
  theme_void()

方法2:缓冲区膨胀+收缩

利用缓冲区的“侵蚀-膨胀”效应消除狭长凹陷:

library(sf)
library(ggplot2)
library(nngeo)

# 读取数据并移除真孔洞
field_no_holes <- st_remove_holes(read_sf("example_field.kml"))

# 先膨胀填充凹陷,再收缩恢复形状:dist参数按需调整
field_cleaned <- field_no_holes %>%
  st_buffer(dist = 5) %>%
  st_buffer(dist = -5)

# 修复可能出现的拓扑错误
field_cleaned <- st_make_valid(field_cleaned)

# 验证结果
ggplot() +
  geom_sf(data = field_cleaned) +
  theme_void()

注意事项

  • 所有参数(adjust、dTolerance、dist)需要根据你的多边形坐标系单位(如米、经纬度)和凹陷实际尺寸调整,多测试找到最优值。
  • 若处理后出现拓扑异常,用st_make_valid()修复即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 22:45:45