我想根据(1)它们是否在空间中与列表中的其他多边形相交以及(2)描述时间的多边形属性(例如,创建多边形的时间)对多边形列表进行子集化。例如,考虑三个部分重叠的多边形,分别在时间
a
创建的 b
、c
和 t=c(1, 3, 5)
。如下图,a
和b
相交,b
和c
相交,a
和c
不相交
我想对这些多边形进行子集化,以便仅保留与较早时间的另一个多边形相交的多边形。因此,对于这三个多边形,我会排除
a
,因为它与 b
相交,并且 b
的时间更晚。我会排除 b
,因为它与 c
相交,并且 c
的时间较晚(它与 a
相交,但 a
的时间较早;这不是排除它的理由)。我会保留 c
,因为它与 b
相交,但 a
的时间更早。
如何使用空间几何和多边形的属性来创建逻辑表达式来完成此子集化?我已经使用下面的三个多边形和时间属性设置了示例问题。
library(sf)
# create polygons
vertices <- rbind(c(1, 1), c(8, 1), c(8, 8), c(1, 8), c(1, 1))
listOfSquares <- list(a = vertices - 4, b = vertices + 4, c = vertices)
listOfSquares <- lapply(listOfSquares, function(x) st_sfc(st_polygon(list(x))) )
# plot polygons
plot(listOfSquares[[1]], xlim = c(-5, 15), ylim = c(-5, 15))
plot(listOfSquares[[2]], add = TRUE)
plot(listOfSquares[[3]], add = TRUE)
text(x=-2.5,y=4.75,"a, t=1")
text(x=-2.5+4,y=4.75+4,"b, t=3")
text(x=-2.5+8,y=4.75+8,"c, t=5")
# add time attribute
listOfSquares[[1]]$time <- 1
listOfSquares[[2]]$time <- 3
listOfSquares[[3]]$time <- 5
改编自此问题的代码:R sf:多边形列表上的 st_intersection
如果将多边形组织为
sf
对象,则可以使用 st_intersection()
获得交叉点并结合使用 dplyr::filter()
dplyr::group_by()
筛选出您想要的结果。
library(sf)
#> Linking to GEOS 3.11.1, GDAL 3.6.2, PROJ 9.1.1; sf_use_s2() is TRUE
library(tidyverse)
vertices <- rbind(c(1, 1), c(8, 1), c(8, 8), c(1, 8), c(1, 1))
# The squares b and c are switched in your code. The follwing line corrects that.
listOfSquares <-
list(a = vertices - 4, b = vertices, c = vertices + 4)
# Create sf object.
sq_sf <-
lapply(listOfSquares, function(x)
st_polygon(list(x))) |>
st_sfc() |>
st_sf() |>
mutate(name = letters[1:3],
time = c(1, 3, 5))
# Plot with ggplot() to make sure that labels are associated with correct squares.
ggplot(sq_sf) +
geom_sf() +
geom_sf_label(aes(label = paste(name, time, sep = ", t=")))
# Get intersections and apply filter rules.
res <-
st_intersection(sq_sf, sq_sf) |>
filter(name != name.1) |>
group_by(name) |>
filter(all(time.1 < time))
#> Warning: attribute variables are assumed to be spatially constant throughout
#> all geometries
res
#> Simple feature collection with 1 feature and 4 fields
#> Geometry type: POLYGON
#> Dimension: XY
#> Bounding box: xmin: 5 ymin: 5 xmax: 8 ymax: 8
#> CRS: NA
#> # A tibble: 1 × 5
#> # Groups: name [1]
#> name time name.1 time.1 st_sfc.lapply.listOfSquares..function.x..st_polygo…¹
#> * <chr> <dbl> <chr> <dbl> <POLYGON>
#> 1 c 5 b 3 ((5 5, 5 8, 8 8, 8 5, 5 5))
#> # ℹ abbreviated name:
#> # ¹st_sfc.lapply.listOfSquares..function.x..st_polygon.list.x....
# Filter original set to only include the desired squares.
sq_sf |>
filter(name %in% res$name)
#> Simple feature collection with 1 feature and 2 fields
#> Geometry type: POLYGON
#> Dimension: XY
#> Bounding box: xmin: 5 ymin: 5 xmax: 12 ymax: 12
#> CRS: NA
#> st_sfc.lapply.listOfSquares..function.x..st_polygon.list.x.... name time
#> 1 POLYGON ((5 5, 12 5, 12 12,... c 5