I am doing this with the map of the counties of the Republic of Ireland found here (direct download).
What I want to do is extend the coast of every county towards the sea for 1500 m, but without moving the borders between counties.
EDIT: I also need to extend the county boundaries of the coastal counties towards the sea, in order to meet the new, extended "coastline" (added as per mrhellmann question)
My code so far:
Load the packages and data
library(tidyverse)
library(sf)
library(ggplot2)
ireland <- st_read("~Census2011_Admin_Counties_generalised20m.shp")
st_crs(ireland) # units are m
Buffer
ireland_buf <- ireland %>%
st_buffer(1500)
Check how borders have moved
ggplot() +
geom_sf(data = ireland_buf, col = "red", fill = "lightgray") +
geom_sf(data = ireland, col = "black", fill = NA) +
theme_bw()
So, basically, the red line corresponds to the buffered map and the black one to the original map. I've obtained the desired effect in the coastline, but then county borders are moved inwards or outwards depending on the county
Using the base shapefile you can create a few other objects along the way by combining, buffering, spatial sampling, and creating voronoi polygons. By joining and intersecting these you can get most of the way there.
Problems with the below example are that it buffers into the adjacent land at the northern border, and some of the islands that are close together may cause very small problems.
library(sf)
library(ggplot2)
library(dplyr)
library(tmap) # for "MAP_COLORS"
path <- 'Census2011_Admin_Counties_generalised20m.shp'
ireland <- read_sf(path)
base_crs <- st_crs(ireland)
#remove county lines, keeps only an outline of the area
ireland_combined <- st_combine(ireland)
# add buffer, fortunately the base CRS is in meters
ireland_buffered <- st_buffer(ireland_combined, 1500)
# polygon(s) of only the buffer
buffer_only <- st_difference(ireland_buffered, ireland_combined)
# sample points inside the buffer for voronoi polygons
# type can be random, hexagonal, or regular.
# increase size for accuracy, decrease for speed.
sampled_points <- st_sample(buffer_only, size = 5000, type = 'hexagonal')
#Create voronoi polygons from sampled points
voronoi <- sampled_points %>%
st_union() %>%
st_voronoi() %>%
st_cast()
# Crop voronoi polygons to buffer area only
# plot 2 below shows voronoi polygons extend much too far for this case
voronoi_buffer <-
st_intersection(
st_make_valid(voronoi),
buffer_only
) %>%
st_as_sf()
# Join polygons by proximity to counties in base shapefile
voronoi_joined <- st_join(
voronoi_buffer,
ireland,
join = st_nearest_feature
)
# join voronoi polygons by countyname
vj_summarized <- voronoi_joined %>%
group_by(COUNTYNAME) %>%
summarize()
#mapview was having trouble with this county name
vj_summarized$COUNTYNAME[6] <- 'Dun Laoghaire-Rathdown'
ireland$COUNTYNAME[20] <- 'Dun Laoghaire-Rathdown'
#rbind sea buffer & land, then join with group_by & summarize
buffer_and_land <- rbind(ireland %>% select(COUNTYNAME), vj_summarized) %>%
group_by(COUNTYNAME) %>%
summarise()
#plots
p1 <- ggplot() +
geom_sf(data = ireland, fill = NA) +
geom_sf(data = ireland_buffered, fill = NA, alpha = .4, color = 'green') +
ggtitle(label = "Ireland counties & 1500m buffer")
p2 <- ggplot() +
geom_sf(data = voronoi, alpha = .2) +
geom_sf(data = voronoi_buffer, alpha = .2, fill = NA, color = 'turquoise') +
ggtitle(label = 'Voronoi & buffer')
# Counties & buffers joined & colored
p4 <- tm_shape(st_geometry(buffer_and_land)) +
tm_polygons(col = "MAP_COLORS") +
tm_shape(st_geometry(ireland)) +
tm_polygons(border.col = 'black', col = NA, alpha = 0)
p1
Green area shows buffer & problem with buffering into bordering land. You can avoid this by using a shapefile of the whole island.
p2
Full voronoi shown. Area of interest in turquoise.
p4
Buffer joined with counties, and filled by countyname. County borders are overlaid in black.
A close-up of one of the messier areas, increasing the number of sample points may help.
Created on 2021-03-22 by the reprex package (v1.0.0)