PAYATHON 2026

如何只平滑 sf 多边形的部分边界,同时保留海岸线?

数据小陈

可以先将记录点的凸包圆角化,再用巴西国界多边形裁剪。圆角处理放在 st_intersection() 之前,裁剪后的海岸线仍来自原始国界数据。

首先要确定是否允许分布范围扩大。正缓冲会向外扩展并形成圆角;如果希望边界向内收圆,可以先负缓冲再正缓冲,但这样可能将凸包顶点处的记录点排除在外。

为什么要先处理凸包,再裁剪?

原来的计算顺序是:

distribution <- st_intersection(
  brazil,
  st_convex_hull(st_union(occurrences))
)

求交后的多边形既包含凸包边界,也包含海岸线。直接对结果做平滑或缓冲,海岸线也会受到处理。

先生成凸包并处理圆角,再与国界求交,就不用从最终多边形中逐段识别海岸线。

允许范围扩大时:对凸包做正缓冲

使用正距离的 st_buffer() 可以在凸包外侧生成圆角,同时保留原凸包覆盖的范围。下面先将数据转换到以米为单位的投影坐标系,再设置缓冲距离:

library(ggplot2)
library(sf)
library(rnaturalearth)

brazil <- ne_countries(
  country = "Brazil",
  scale = "medium",
  returnclass = "sf"
)

occurrences <- st_as_sf(
  data.frame(
    X = c(-50, -52, -48, -42, -43),
    Y = c(-28, -20, -15, -18, -23)
  ),
  coords = c("X", "Y"),
  crs = 4326
)

# 针对此示例区域设置局部投影,坐标单位为米
crs_local <- paste(
  "+proj=laea +lat_0=-22 +lon_0=-50",
  "+datum=WGS84 +units=m +no_defs"
)

brazil_m <- st_transform(brazil, crs_local)
occurrences_m <- st_transform(occurrences, crs_local)

hull_m <- st_convex_hull(st_union(occurrences_m))

# 示例值:100 km,可按所需效果调整
radius <- 100000

rounded_hull_m <- st_buffer(
  hull_m,
  dist = radius,
  nQuadSegs = 30
)

# 最后裁剪,海岸线来自未经平滑的 brazil_m
distribution_m <- st_intersection(
  brazil_m,
  rounded_hull_m
)

distribution <- st_transform(distribution_m, st_crs(brazil))

 ggplot(brazil) +
  geom_sf(col = NA) +
  geom_sf(data = distribution, fill = "darkred") +
  geom_sf(data = occurrences, size = 5) +
  ylim(c(-30, -12)) +
  xlim(c(-60, -40)) +
  theme_minimal()

radius 决定向外扩展的距离,也决定转角圆弧的尺度。nQuadSegs 控制每个四分之一圆弧的近似线段数;增加它可以让圆弧显示得更细腻,但不会改变缓冲距离。

这种方法也会将凸包的直线边向外移动。如果只接受向内削圆,可以使用下面的方法。

希望边界向内收圆时:先负缓冲,再正缓冲

将上面生成 rounded_hull_m 的部分替换为:

inner_hull_m <- st_buffer(hull_m, dist = -radius)

if (any(st_is_empty(inner_hull_m))) {
  stop("负缓冲后几何为空,请减小 radius。")
}

rounded_hull_m <- st_buffer(
  inner_hull_m,
  dist = radius,
  nQuadSegs = 30
)

然后与 brazil_m 求交,再转换回绘图坐标系。

对于这个凸包,先收缩再扩张可以削去尖角,使边界向内变圆。不过,凸包顶点附近的原始记录点可能落在结果之外,靠近尖角的部分海岸线也可能不再被覆盖。如果必须包含所有记录点,应优先考虑前面的正缓冲方案。

“保留海岸线”的具体含义

最后的裁剪会沿用国界数据中的海岸线形状,但圆角处理可能改变分布范围与海岸线相交的位置。因此,海岸线细节可以保留,结果中包含的海岸线段仍可能发生变化。

如果要求原结果中的全部海岸线段及其端点都严格固定,就需要以这些线段为约束,单独重建其余边界;仅调整操作顺序不能保证这一点。

缓冲距离应根据研究区域和用途选择。示例中的 100000 只是演示参数,所用的局部投影也不代表整个巴西范围内都具有相同的距离精度。边界变圆是几何处理,本身不能证明生成的范围更符合物种的实际分布。

备注:内容仅供参考。