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

如何基于dplyr与sf包按组计算多个多边形的交集?

哈哈,这个问题我之前也遇到过!sf包里st_union配合dplyr::group_by()做多对象并集简直丝滑,但st_intersection()偏偏只能两两处理,确实有点烦。不过咱们结合dplyr的分组和purrr的累积操作就能完美解决,下面给你一步步拆解:

问题回顾

你提到的痛点很准确:用dplyr::group_by() + st_union()计算多多边形并集非常顺手,但st_intersection()默认仅支持两个对象的交集计算,要按组批量处理多个多边形的交集就得动点脑筋。

修正后的示例数据

先把你提供的示例数据调整得更清晰(避免冗余操作):

library(sf)
library(dplyr)
library(purrr)

# 生成三个多边形
s1 <- rbind(c(1, 1), c(10, 1), c(10, 10), c(1, 10), c(1, 1)) %>% 
  list() %>% st_polygon() %>% st_sfc()
s2 <- s1 + 4  # 等价于你原来的s2
s3 <- s1 - 4  # 等价于你原来的s3

# 构建分组sf数据框
df <- tibble(
  group = rep(c(1, 2), each = 3),
  geometry = rep(list(s1, s2, s3), 2) %>% flatten()
) %>% st_sf()
最优解决方案:分组+累积交集

核心思路是利用交集的结合律((A∩B)∩C = A∩(B∩C)),用purrr::accumulate()对每组的多边形做累积交集,最后取最终的交集结果替换原几何列:

df_final <- df %>%
  group_by(group) %>%
  mutate(
    # 对组内的几何对象做累积交集,最后一个元素就是所有多边形的交集
    group_intersection = accumulate(geometry, st_intersection) %>% last()
  ) %>%
  ungroup() %>%
  # 替换原几何列
  select(-geometry) %>%
  rename(geometry = group_intersection)
代码解释
  • group_by(group):按分组字段划分数据,确保每组内的多边形一起处理
  • accumulate(geometry, st_intersection):依次计算多边形的累积交集:先算第1个和第2个的交集,再用这个结果和第3个计算交集,最终得到一个包含每一步结果的列表
  • last():提取列表的最后一个元素,也就是该组所有多边形的共同交集
  • 最后通过select和rename替换原几何列,让每组的所有行都对应该组的交集多边形
注意事项
  • 如果组内存在无交集的多边形,st_intersection会返回空几何,你可以用st_is_empty()来检测并做后续处理(比如过滤这类组)
  • 确保提前加载purrr包,accumulate()是它的核心函数之一
  • 这个方法同样适用于每组有更多多边形的场景,扩展性很强

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.30 20:03:12