为什么使用 st_intersection 而不是 st_intersects?

syr*_*yre 6 r topology geospatial r-sf

st_intersection与 相比非常慢st_intersects。那么为什么不使用后者而不是前者呢?这是一个带有小型玩具数据集的示例,但对于与实际地理区域边界相交的仅 62,020 个点的实际集合而言,执行时间的差异是巨大的。我有 24Gb 的 RAM 并且st_intersects代码需要几秒钟,而st_intersection代码需要超过 15 分钟(可能更多,我没有耐心等待......)。st_intersection做任何我不喜欢的事情st_intersects吗?

下面的代码处理sfc对象,但我相信对sf对象同样有效。

library(sf)
library(dplyr)

# create square
s <- rbind(c(1, 1), c(10, 1), c(10, 10), c(1, 10), c(1, 1)) %>% list %>% st_polygon %>% st_sfc
# create random points
p <- runif(50, 0, 11) %>% cbind(runif(50, 0, 11)) %>% st_multipoint %>% st_sfc %>% st_cast("POINT")

# intersect points and square with st_intersection
st_intersection(p, s)

# intersect points and square with st_intersects (courtesy of /sf/answers/3451330641/)
p[st_intersects(p, s) %>% lengths > 0,]
Run Code Online (Sandbox Code Playgroud)

All*_*ron 16

答案是,通常这两种方法做不同的事情,但在您的特定情况下(找到点集合和多边形的交集),st_intersects可用于有效地完成相同的工作。

我们可以通过一个从您自己修改的简单示例来展示差异。我们从一个正方形开始:

library(sf)
library(dplyr)

# create square
s <- rbind(c(1, 1), c(10, 1), c(10, 10), c(1, 10), c(1, 1)) %>% 
  list %>% 
  st_polygon %>% 
  st_sfc

plot(s)
Run Code Online (Sandbox Code Playgroud)

在此处输入图片说明

现在我们将创建一个矩形并将其绘制在同一个带有虚线轮廓的图上:

# create rectangle
r <- rbind(c(-1, 2), c(11, 2), c(11, 4), c(-1, 4), c(-1, 2)) %>% 
  list %>% 
  st_polygon %>% 
  st_sfc

plot(r, add= TRUE, lty = 2)
Run Code Online (Sandbox Code Playgroud)

在此处输入图片说明

现在我们找到两个多边形的交点并将其绘制为红色:

# intersect points and square with st_intersection
i <- st_intersection(s, r)

plot(i, add = TRUE, lty = 2, col = "red")
Run Code Online (Sandbox Code Playgroud)

在此处输入图片说明

当我们检查 object 时i,我们会看到它是一个新的多边形:

i
#> Geometry set for 1 feature 
#> geometry type:  POLYGON
#> dimension:      XY
#> bbox:           xmin: 1 ymin: 2 xmax: 10 ymax: 4
#> epsg (SRID):    NA
#> proj4string:    NA
#> POLYGON ((10 4, 10 2, 1 2, 1 4, 10 4))
Run Code Online (Sandbox Code Playgroud)

然而,如果我们使用st_intersects,我们只会得到一个逻辑结果,告诉我们r和之间是否确实存在交集s。如果我们尝试使用它来子集r来找到交点,我们不会得到相交的形状,我们只会得到我们原来的矩形:

r[which(unlist(st_intersects(s, r)) == 1)]
#> Geometry set for 1 feature 
#> geometry type:  POLYGON
#> dimension:      XY
#> bbox:           xmin: -1 ymin: 2 xmax: 11 ymax: 4
#> epsg (SRID):    NA
#> proj4string:    NA
#> POLYGON ((-1 2, 11 2, 11 4, -1 4, -1 2))
Run Code Online (Sandbox Code Playgroud)

您遇到的情况有所不同,因为您正在尝试找到与多边形相交的点的子集。这种情况下,一组点与一个多边形的交集与满足条件的子集相同st_intersects

所以很高兴您找到了一种有效的方法来获得更快的交叉路口。请注意,这仅适用于与多边形相交的点集合。