3

Copied from my SO question

The problem

Suppose we have two shapefiles that should border seamlessly. Only, they don't. Is there a way to force them to stick to one another without gaps?

enter image description here


The specific case

I have two shapefiles: one for European regions -- REG, the other for the neighbouring countries -- NEI. Both shapefiles are taken from Eurostat repository and should fit together nicely; but there are small gaps. Also, I need to simplify the polygons, and then the gaps become really notable.


The best I can think of

I've tried several approaches but with no success. The only way to achieve the desired result that I see requires following steps:

  • create a line sf with just the border between my shapefiles;
  • from this line create a buffer polygon just big enough to cover all gaps;
  • join and dissolve this buffer to the shapefile for neighbours -- NEI;
  • clip off the expanded NEI with the REG shapefile.

Obviously, this is a rather clumsy workaround.

Is there a better way to go?


Reproducible example in this gist


A minimal example

# 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)
  • would you mind not just downvote but rather leave a comment – ikashnitsky Jan 22 '18 at 22:58
  • 1
    Yeah wow, nice example. It is a bit hard to follow though, so I wonder if you could split it - have an example that clearly plots and identifies the slight gaps, as well as your more comprehensive code that seems to solve (?) it. Are the gaps present prior to using ms_simplify? That's a part that's slightly unclear to me, and that's where I'd start from if so. It's a good reprex, you could add checks to not re-download the files, and also should remove the rm() call at the top. – mdsumner Jan 23 '18 at 0:02
  • FWIW, this is the kind of example where I'd just fire up Manifold and use its editing and tracing tools, it's great to see an example where that's not even considered :) – mdsumner Jan 23 '18 at 0:03
  • 1
    Try feeding it into pprepair: github.com/tudelft3d/pprepair "pprepair (planar partition repair) takes a set of polygons and ensures that they form a valid planar partition, made of valid polygons and having no gaps or overlaps" - its an external tool you need to run on your shapefile, not an R function though. – Spacedman Jan 23 '18 at 8:17
  • 1
    Your sample data are in two different coordinate systems at the moment! A quick st_transform for REG to st_crs(NEI) sorts that out though. – Spacedman Jan 23 '18 at 11:49
5

After reading in your sample data, transform REG to the same coords as NEI. Combine the two objects, and save as a shapefile:

REG = st_transform(REG, st_crs(NEI))
d = rbind(NEI, REG)
st_write(d,"NEIREG.shp")

Then in the shell, run pprepair:

pprepair -i NEIREG.shp -o FIX.shp -fix

Back in R, load the new shapefile:

fix = st_read("FIX.shp")

Here's the "before":

enter image description here

and "after":

enter image description here

Knowing the sensitivity of the border in this part of the world, I'd put a big big disclaimer on any map using this.

  • Amazing! Thanks a lot! Do you know if pprepair might ever become an R package? – ikashnitsky Jan 23 '18 at 12:05
  • Not sure - its something I've pondered doing but my C++ skills are lacking. Maybe something for a Google Summer of Code project with a capable supervisor (not me). – Spacedman Jan 23 '18 at 14:24
  • do you think it's correct to open a github issue at rmapshaper to propose including the method? Unfortunately, my own C++ skills are non-existent, so I cannot offer help in this issue. – ikashnitsky Jan 24 '18 at 5:09
  • Dear @Spacedman, if you copy this answer to the SO version of my question (today) I'll gladly allocate the +100 bounty to it – ikashnitsky Jan 30 '18 at 1:18

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.