I have polygon shape data for German postcodes. For each postcode I like to calculate the maximum distance from centroid to its border and illustrate this on a map for some of them. I found a post which calculates this maximum via sf package and st_cast() and st_distance(). My data comes as sf dataframe.
library(sf)
library(tidyverse)
# Get German postcode shape polygons
URL <- "https://downloads.suche-postleitzahl.org/v2/public/plz-5stellig.shp.zip"
# use GDAL virtual file systems to load zipped shapefile from remote url
GER_postcode <- paste0("/vsizip//vsicurl/", URL) %>% read_sf()
# convert numeric
GER_postcode$plz <- as.numeric(GER_postcode$plz)
# filter a specific postcode
test <- GER_postcode %>% filter(plz == 15232)
# compute distances
distances <- test %>%
st_cast("POINT") %>%
st_distance(st_centroid(test))
# maximum dist:
max_dist <- max(distances)
max_dist
ggplot() +
geom_sf(data = test, size = 1, shape = 16, alpha = 0.1) + # shape
geom_sf(data = st_centroid(test)) + # centroid
theme_bw()
Where exactly is the found maximum (1297.496 [m]) and how can I show the connection on the map?
>Solution :
This should do the trick. This code continues after your line test <- GER_postcode %>% filter(plz == 15232).
Your code calculates the maximum distance by casting the border to an sf object of points around the border, then calculating the distance to each of those points.
So what we can do is find which of those points is the maximum distance away, create an sf data frame which contains that point and the centroid and summarise() them into a LINESTRING using st_cast().
# create sf object of border points
border_points <- test %>%
st_cast("POINT")
# compute distances
distances <- border_points |>
st_distance(st_centroid(test))
# maximum dist:
max_dist <- max(distances)
max_dist_linestring <- border_points |>
filter(as.logical(distances == max(distances))) |>
bind_rows(st_centroid(test)) |>
summarise() |>
st_cast("LINESTRING")
ggplot() +
geom_sf(data = test, size = 1, shape = 16, alpha = 0.1) + # shape
geom_sf(data = st_centroid(test)) + # centroid
geom_sf(data = max_dist_linestring) +
theme_bw()

