r gis: identify inner borders between polygons with sf

独自空忆成欢 提交于 2019-12-12 11:23:34

问题


This is an update of my previous similar question, the same task only I need to do it within sf framework.


I need to identify the inner boundaries between polygons, red lines in this map.


Within sp framework I used to utilize a self written function that wrapped @Spacedman's answer. Here it is:

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

Alternatively one may use raster::boundaries().


Code to get the spatial data and replicate the map

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

回答1:


rmapshaper uses javascript, that is cheating! I tried:

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)




回答2:


It turned out that rmapshaper has precisely the desired function and works with sf objects nicely -- ms_innerlines(). The only difficulty (possibly a bug) is that ms_innerlines() returns a list rather than an sf object. But this odd behavior is easily fixed. Below is the solution code. Note that I simplify the initial polygons to see the difference. The new inner borders that are created from an sf object are plotted in navy color.

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



来源:https://stackoverflow.com/questions/47760033/r-gis-identify-inner-borders-between-polygons-with-sf

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!