为什么使用 st_intersection 而不是 st_intersects?

Why use st_intersection rather than st_intersects?

st_intersectionst_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 
p[st_intersects(p, s) %>% lengths > 0,]

答案是,通常这两种方法做不同的事情,但在您的特定情况下(找到点集合和多边形的交集),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)

现在我们将创建一个矩形并在同一个图上用虚线绘制它:

# 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)

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

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

plot(i, add = TRUE, lty = 2, col = "red")

当我们检查对象 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))

然而,如果我们使用 st_intersects,我们只会得到一个逻辑结果,告诉我们 rs 之间是否确实存在交集。如果我们尝试使用它对 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))

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

的子集相同

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