无缝拟合两个 sf 多边形

Posted

技术标签:

【中文标题】无缝拟合两个 sf 多边形【英文标题】:fit two sf polygons seamlessly 【发布时间】:2018-06-29 20:04:42 【问题描述】:

问题

假设我们有两个无缝边界的 shapefile。只是,他们没有。有没有办法强迫他们无缝隙地粘在一起?


具体案例

我有两个 shapefile:一个用于欧洲地区——REG,另一个用于邻国——NEI。两个 shapefile 都取自 Eurostat repository,应该很好地组合在一起;但有一些小的差距。另外,我需要简化多边形,然后差距变得非常明显。


我能想到的最好的

我尝试了几种方法,但都没有成功。实现我看到的预期结果的唯一方法需要以下步骤:

用我的 shapefile 之间的边界创建一条线 sf; 从这条线创建一个足够大的缓冲区多边形以覆盖所有间隙; 将此缓冲区加入并解散到相邻的 shapefile 中 -- NEI; 用REG shapefile 剪掉扩展的NEI

显然,这是一个相当笨拙的解决方法。

有更好的方法吗?


this gist 中的可重现示例


一个最小的例子

# install dev version of ggplot2
devtools::dev_mode()
devtools::install_github("tidyverse/ggplot2")

library(tidyverse)
library(sf)
library(rmapshaper) 
library(ggthemes)


# load data
source(file = url("https://gist.githubusercontent.com/ikashnitsky/4b92f6b9f4bcbd8b2190fb0796fd1ec0/raw/1e281b7bb8ec74c9c9989fe50a87b6021ddbad03/minimal-data.R"))

# test how good they fit together
ggplot() + 
        geom_sf(data = REG, color = "black", size = .2, fill = NA) +
        geom_sf(data = NEI, color = "red", size = .2, fill = NA)+
        coord_sf(datum = NA)+
        theme_map()

ggsave("test-1.pdf", width = 12, height = 10)

# simplify
REGs <- REG %>% ms_simplify(keep = .5, keep_shapes = TRUE)
NEIs <- NEI %>% ms_simplify(keep = .5, keep_shapes = TRUE)


ggplot() + 
        geom_sf(data = REGs, color = "black", size = .2, fill = NA) +
        geom_sf(data = NEIs, color = "red", size = .2, fill = NA)+
        coord_sf(datum = NA)+
        theme_map()

ggsave("test-2.pdf", width = 12, height = 10)

【问题讨论】:

我建议在这里问这个问题:gis.stackexchange.com 另外,我想看看mapshaper::ms_simplify() 是否可以在这里提供帮助。该函数旨在简化多边形,它有一个 snap 参数,当它设置为 TRUE 时可以避免这种情况发生。也许这样可以解决问题? @Phil 感谢您的建议。它似乎不起作用。我想,问题是我人为地合并了两个空间对象,因此即使它们应该在哪里也没有共同的顶点 你能试着减少你的例子吗?这有点笨拙 - 如果您可以将每个数据集中的它减少到一个或两个多边形,以说明问题,那么某人将更容易使用。另外,请不要以rm(list = ls(all = TRUE)) 开头您的示例。如果有人在不仔细查看的情况下运行它,你真的会把他们搞砸。 @andyteucher 感谢您的评论!完成。 这是一个很好的解决方案,pprepair 看起来是非常好的工具,但我认为它超出了 rmapshaper 的范围。 rmapshaper 简单地包装了mapshaper node.js 库,我想保留这个范围。 pprepair 可能是一个很棒的独立包(正如@spacedman 所说)。 【参考方案1】:

ms_simplify 似乎适用于您的最小示例,但您首先需要将 2 个“shapefile”分组为一个“shapefile”。如果需要,可以在简化边界后轻松拆分它们。 (注意:当ms_simplifysf 对象一起使用时,我的rmapshaper 版本返回错误。这就是为什么我将tmp 对象转换为sp 对象与as(tmp, "Spatial")

NEI <- st_transform(NEI, st_crs(REG)$epsg)
tmp <- rbind(REG , NEI)
tmp <- ms_simplify(as(tmp, "Spatial"), keep = .1, keep_shapes = T)
ggplot() + geom_sf(data = st_as_sf(tmp)) + theme_bw()

【讨论】:

这可行,但仅在非常高度简化的情况下。已经在“keep = 0.2”处开始出现漏洞。 很抱歉确认这不是解决方案 我完全同意这充其量只是一个粗略的 hack ......这在现实生活中可能会更糟。但这种解决方案在某些情况下可能有用。也许探索的一个选项是使用 R 中的 Grass GIS 及其 v.clean 命令?

以上是关于无缝拟合两个 sf 多边形的主要内容,如果未能解决你的问题,请参考以下文章

将栅格裁剪为 sf 集合中的多边形 [R sf]

多边形 sf 对象的 gganimate 错误

通过R中的sf将经度和纬度序列转换为多边形

使用 tidyverse + sf R 创建每个多边形的线密度

如何计算多边形之间的所有成对交互以及 R 中 sf 的百分比覆盖率?

ggplot2(和sf)中世界地图的整个地球多边形