我尝试使用sf::st_union
在三个多边形之间进行并集。下图显示了ArcGIS“ Overlay,Union,All”的结果,我希望通过使用R中的sf包获得与“ OUTPUT”中五个不同多边形相似的结果。
library(sf)
a1 <- st_polygon(list(rbind(c(0, 10), c(45, 10), c(45, 90), c(0, 90), c(0, 10))))
a2 <- st_polygon(list(rbind(c(45, 10), c(90,10), c(90, 90), c(45, 90), c(45, 10))))
b <- st_polygon(list(rbind(c(15, 5), c(75, 5), c(75, 50), c(15, 50), c(15, 5))))
a <- st_sf(c(st_sfc(a1), st_sfc(a2)))
b <- st_sf(st_sfc(b))
a$station <- c(1, 2)
b$type <- "A"
ab_union <- st_union(a, b)
在此简单示例中,生成的SF对象'ab_union'将仅包含两个多边形,而不是预期的五个。通过使用sf
包中的函数,能否通过上图中的五个对象获得所需的结果?
答案 0 :(得分:1)
我没有找到一个可以一步一步完成的功能,但这是解决问题的一种方法:
library(sf)
#> Linking to GEOS 3.6.1, GDAL 2.2.3, PROJ 4.9.3
library(tidyverse)
a1 <- st_polygon(list(rbind(c(0, 10), c(45, 10), c(45, 90), c(0, 90), c(0, 10))))
a2 <- st_polygon(list(rbind(c(45, 10), c(90,10), c(90, 90), c(45, 90), c(45, 10))))
b1 <- st_polygon(list(rbind(c(15, 5), c(75, 5), c(75, 50), c(15, 50), c(15, 5))))
a <- st_sf(station=c(1, 2), geometry=st_sfc(a1, a2))
b <- st_sf(type="A", geometry=st_sfc(b1))
st_agr(a) = "constant" #to avoid warnings, but see https://github.com/r-spatial/sf/issues/406
st_agr(b) = "constant"
#Operations
plot(st_geometry(st_union(a,b)))
op1 <- st_difference(a,st_union(b)) #notice the use of st_union()
plot(st_geometry(op1), border="red", add=TRUE)
op2 <- st_difference(b, st_union(a)) #notice the order of b and a and st_union()
plot(st_geometry(op2), border="green", add=TRUE)
op3 <- st_intersection(b, a) #notice the order of b and a
plot(st_geometry(op3), border="blue", add=TRUE)
union <- rbind(op1, op2, op3) #Error because op1 (op2) doesn't have the column "type" ("station")
#> Error in match.names(clabs, names(xi)): names do not match previous names
op11 <- dplyr::mutate(op1, type=NA)
op22 <- dplyr::mutate(op2, station=NA)
union <- rbind(op11, op22, op3)
(as.data.frame(union)) #The row names must be ordered.
#> station type geometry
#> 1 1 <NA> POLYGON ((15 10, 0 10, 0 90...
#> 2 2 <NA> POLYGON ((45 50, 45 90, 90 ...
#> 3 NA A POLYGON ((75 10, 75 5, 15 5...
#> 11 1 A POLYGON ((15 10, 15 50, 45 ...
#> 1.1 2 A POLYGON ((45 50, 75 50, 75 ...
plot(union)
#Other approach for avoid create the new columns would be:
union2 <- dplyr::bind_rows(op1, op2, op3) #But see discusion here: https://github.com/r-spatial/sf/issues/49
#> Warning in bind_rows_(x, .id): Vectorizing 'sfc_POLYGON' elements may not
#> preserve their attributes
#> Warning in bind_rows_(x, .id): Vectorizing 'sfc_POLYGON' elements may not
#> preserve their attributes
#> Warning in bind_rows_(x, .id): Vectorizing 'sfc_POLYGON' elements may not
#> preserve their attributes
由reprex package(v0.2.1)于2019-04-06创建
答案 1 :(得分:0)
我也需要这样一个函数,所以这是我的任意 sf 对象的版本,避免显式添加缺失的列。它还需要“plyr”库(函数 rbind.fill):
my_union <- function(a,b) {
#
# function doing a real GIS union operation such as in QGIS or ArcGIS
#
# a - the first sf
# b - the second sf
#
st_agr(a) = "constant"
st_agr(b) = "constant"
op1 <- st_difference(a,st_union(b))
op2 <- st_difference(b, st_union(a))
op3 <- st_intersection(b, a)
union <- rbind.fill(op1, op2, op3)
}