无缝拟合两个SF多边形

23

问题

假设我们有两个形状文件,它们应该无缝连接。但是实际上,它们之间存在缝隙。有没有一种方法可以强制它们彼此粘合而不留下空白?

enter image description here


具体情况

我有两个形状文件:一个是欧洲地区的文件--REG,另一个是邻国的文件--NEI。这两个形状文件都来自欧盟统计局的资料库,并且应该能够拼合在一起;但是它们之间存在小缝隙。此外,我需要简化多边形,然后这些缝隙变得非常明显。


我所能想到的最好办法

我尝试了几种方法,但都没有成功。我唯一看到可以实现期望结果的方式包含以下步骤:

  • 创建一个只包含两个形状文件边界的线sf;
  • 从这条线创建一个缓冲区多边形,使其足够大覆盖所有缝隙;
  • 将此缓冲区与邻居的形状文件--NEI连接并融合;
  • 使用REG形状文件剪裁扩展的NEI

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

是否有更好的方法?


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

1
我建议在这里提出问题:https://gis.stackexchange.com/ 另外,我会看看是否可以使用 mapshaper::ms_simplify()。该函数旨在简化多边形,并且它有一个 snap 参数,当设置为 TRUE 时,可以避免出现这种情况。也许那样就可以解决问题了? - Phil
@Phil 谢谢你的建议。看起来并没有起作用。我猜问题在于我人为地合并了这两个空间对象,因此即使它们应该存在共同的顶点,也不存在。 - ikashnitsky
2
你可以试着简化你的示例吗?它有点笨重-如果你能将每个数据集中的多边形减少到只有一个或两个来说明问题,那么对于其他人来说就更容易处理了。此外,请不要以rm(list = ls(all = TRUE))开始你的示例。如果有人不仔细看就运行它,会导致很大的麻烦。 - andyteucher
@ikashnitsky,你能提供从Eurostat获取数据的URL吗?你的示例数据(NEI、REG)需要将单个几何文件与多个几何文件合并。 - Technophobe01
1
这是一个很好的解决方案,pprepair 看起来像是非常好的工具,但我认为它超出了 rmapshaper 的范围。rmapshaper 只是包装了 mapshaper node.js 库,我想保持这个范围。pprepair 可以作为一个很棒的独立包存在(正如 @spacedman 所说)。 - andyteucher
显示剩余3条评论
1个回答

1

ms_simplify 在您的最小示例中似乎有效,但您需要先将2个“shapefiles”分组成一个“shapefile”。 如果需要,在边界简化后拆分它们很容易。
(注意:我的 rmapshaper 版本在 sf 对象上使用 ms_simplify 时返回错误。这就是为什么我用 as(tmp, "Spatial") 将我的tmp对象转换为 sp 对象的原因)

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

enter image description here


1
这个可以工作,但只适用于非常高的简化级别。在“keep = 0.2”时就开始出现漏洞了。 - lbusett
1
很抱歉确认这不是一个解决方案。 - ikashnitsky
3
我完全同意这只能算是一个大致的 hack……在实际例子中可能会更糟糕。但是在某些情况下,这个解决方案可能会有用。也许可以考虑使用 R 中的 Grass GIS 和其 v.clean 命令? - Gilles San Martin

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接