r gis:用 sf 识别多边形之间的内部边界
r gis: identify inner borders between polygons with sf
这是 的更新,相同的任务只需要在 sf
框架内完成即可。
我需要识别多边形之间的内部边界,这张地图中的红线。
在 sp
框架中,我曾经使用一个自写的函数来包装@Spacedman 的 。在这里:
identify_borders <- function(SPolyDF){
require(rgeos)
require(sp)
borders <- gDifference(
as(SPolyDF,"SpatialLines"),
as(gUnaryUnion(SPolyDF),"SpatialLines"),
byid=TRUE)
df <- data.frame(len = sapply(1:length(borders),
function(i) gLength(borders[i, ])))
rownames(df) <- sapply(1:length(borders),
function(i) borders@lines[[i]]@ID)
SLDF <- SpatialLinesDataFrame(borders, data = df)
return(SLDF)
}
或者可以使用 raster::boundaries()
。
获取空间数据和复制地图的代码
# dev version of ggplot2 for geom_sf()
devtools::install_github("tidyverse/ggplot2")
library(tidyverse)
library(sf)
load(url("https://ikashnitsky.github.io/share/1712-so-q-identify-borders/geodata.Rdata"))
ggplot() +
geom_sf(data = gd_nuts0) +
geom_sf(data = gd_borders, color = "red") +
coord_sf(datum = NA) +
theme_void()
事实证明,rmapshaper
恰好具有所需的功能,并且可以很好地与 sf
对象一起使用 -- ms_innerlines()
。唯一的困难(可能是错误)是 ms_innerlines()
returns 列表而不是 sf
对象。但这种奇怪的行为很容易解决。下面是解决代码。请注意,我简化了初始多边形以查看差异。从 sf
对象创建的新内部边框以海军色绘制。
# dev version of ggplot2 for geom_sf()
devtools::install_github("tidyverse/ggplot2")
library(tidyverse)
library(sf)
library(rmapshaper)
load(url("https://ikashnitsky.github.io/misc/171211-so-question-identify-borders/geodata.Rdata"))
sf_poly_simp <- gd_nuts0 %>%
ms_simplify(keep = .2, keep_shapes = TRUE)
sf_bord_simp <- sf_poly_simp %>%
ms_innerlines() %>%
as_tibble() %>%
st_as_sf()
ggplot() +
geom_sf(data = sf_poly_simp) +
geom_sf(data = sf_bord_simp, color = "navy", size = 1) +
geom_sf(data = gd_borders, color = "red", size = .1) +
coord_sf(datum = NA) +
theme_void()
rmapshaper 使用javascript,那是作弊!我试过了:
i = st_intersection(gd_nuts0, gd_nuts0)
i2 <- i[i$nuts_id != i$nuts_id.1,]
plot(gd_nuts0[1])
plot(i2, add = TRUE, col ='red', lwd = 2)
这是 sf
框架内完成即可。
我需要识别多边形之间的内部边界,这张地图中的红线。
在 sp
框架中,我曾经使用一个自写的函数来包装@Spacedman 的
identify_borders <- function(SPolyDF){
require(rgeos)
require(sp)
borders <- gDifference(
as(SPolyDF,"SpatialLines"),
as(gUnaryUnion(SPolyDF),"SpatialLines"),
byid=TRUE)
df <- data.frame(len = sapply(1:length(borders),
function(i) gLength(borders[i, ])))
rownames(df) <- sapply(1:length(borders),
function(i) borders@lines[[i]]@ID)
SLDF <- SpatialLinesDataFrame(borders, data = df)
return(SLDF)
}
或者可以使用 raster::boundaries()
。
获取空间数据和复制地图的代码
# dev version of ggplot2 for geom_sf()
devtools::install_github("tidyverse/ggplot2")
library(tidyverse)
library(sf)
load(url("https://ikashnitsky.github.io/share/1712-so-q-identify-borders/geodata.Rdata"))
ggplot() +
geom_sf(data = gd_nuts0) +
geom_sf(data = gd_borders, color = "red") +
coord_sf(datum = NA) +
theme_void()
事实证明,rmapshaper
恰好具有所需的功能,并且可以很好地与 sf
对象一起使用 -- ms_innerlines()
。唯一的困难(可能是错误)是 ms_innerlines()
returns 列表而不是 sf
对象。但这种奇怪的行为很容易解决。下面是解决代码。请注意,我简化了初始多边形以查看差异。从 sf
对象创建的新内部边框以海军色绘制。
# dev version of ggplot2 for geom_sf()
devtools::install_github("tidyverse/ggplot2")
library(tidyverse)
library(sf)
library(rmapshaper)
load(url("https://ikashnitsky.github.io/misc/171211-so-question-identify-borders/geodata.Rdata"))
sf_poly_simp <- gd_nuts0 %>%
ms_simplify(keep = .2, keep_shapes = TRUE)
sf_bord_simp <- sf_poly_simp %>%
ms_innerlines() %>%
as_tibble() %>%
st_as_sf()
ggplot() +
geom_sf(data = sf_poly_simp) +
geom_sf(data = sf_bord_simp, color = "navy", size = 1) +
geom_sf(data = gd_borders, color = "red", size = .1) +
coord_sf(datum = NA) +
theme_void()
rmapshaper 使用javascript,那是作弊!我试过了:
i = st_intersection(gd_nuts0, gd_nuts0)
i2 <- i[i$nuts_id != i$nuts_id.1,]
plot(gd_nuts0[1])
plot(i2, add = TRUE, col ='red', lwd = 2)