Chr*_*Chr 1 gis r geospatial r-sf
我有一个名为 p_1、p_2、...、p_n 的多边形(和多多边形)列表。我想获得它们相交的区域。由于st_intersection()不接受列表作为参数,我尝试了以下三种方法。它们都没有提供令人满意的解决方案,这就是为什么我正在寻找替代的、更有效的技术。
(i) 我可以遍历列表
for(i in P) p_1 <- st_intersection(p_1, i)
Run Code Online (Sandbox Code Playgroud)
其中 P 是一个包含多边形 p_2 到 p_n 的列表。但这相当缓慢。
(ii) 一种do.call()方法,即
p <- do.call(st_intersection, P)
Run Code Online (Sandbox Code Playgroud)
其中 P 是多边形 p_1 到 p_n 的列表,仅计算列表中前两个多边形之间的交集。
(iii) 我可以将多边形组合成一个 sf 对象,然后运行st_intersection():
p <- do.call(c, P) %>%
st_sf() %>%
st_intersection()
Run Code Online (Sandbox Code Playgroud)
它有效,但速度很慢。大概是因为除了 P 中所有多边形的公共交集之外,它还导出了许多其他多边形。
这三种方法都没有提供令人满意的解决方案。在并行化框架中循环遍历成对比较的层次结构可能会更快。但是,我认为有比这更简单、更有效的解决方案。
欢迎任何意见和建议。
给昨天关闭这个问题的人的注释:不要关闭这个问题。如果您个人有问题,请发表评论或给我发送私信。但不要关闭它。
我不认为遍历列表的开销在这里是一个问题:找到多个多边形的交集只是在计算上很昂贵。但是,可以使用以下方法do.call轻松管理将函数顺序应用于列表成员的方法(实际上是您尝试使用的方法)purrr::accumulate:
您没有可重现的示例供这里的人测试可能的解决方案,并且从头开始创建 sf 多边形涉及一些工作,因此这可能是您之前的问题被关闭的原因 - 我不知道。
无论如何,让我们在列表中创建三个重叠的正方形并绘制它们:
library(sf)
library(purrr)
# create square
s1 <- rbind(c(1, 1), c(10, 1), c(10, 10), c(1, 10), c(1, 1))
p <- list(s1 = s1, s2 = s1 + 4, s3 = s1 - 4)
p <- lapply(p, function(x) st_sfc(st_polygon(list(x))) )
plot(p[[1]], xlim = c(-5, 15), ylim = c(-5, 15))
plot(p[[2]], add = TRUE)
plot(p[[3]], add = TRUE)
Run Code Online (Sandbox Code Playgroud)
我们的目标是找到所有三个正方形的交集,当然也就是中心的小正方形。使用purrr,这很简单:
intersection <- accumulate(p, st_intersection)$s3
Run Code Online (Sandbox Code Playgroud)
因此,当我们添加红色的结果时,我们得到:
plot(intersection, col = "red", add = TRUE)
Run Code Online (Sandbox Code Playgroud)
在性能方面,accumulate仅比原始循环快 10%,因此如果性能是一个大问题,您可能需要对其进行并行化。此外,如果所有多边形之间可能没有交集,您可以找到最小的多边形并用于st_intersects确保所有多边形实际上与它相交。这是一个更快的计算,前提是有相当的机会不存在不明确的交叉点。
| 归档时间: |
|
| 查看次数: |
468 次 |
| 最近记录: |