在R中从多边形质心到最大距离边界绘制一条线

Mar*_*rco 2 r geospatial ggplot2 r-sf

我有德国邮政编码的多边形形状数据。对于每个邮政编码,我喜欢计算从质心到其边界的最大距离,并在地图上对其中一些邮政编码进行说明。sf我找到了一篇通过包 andst_cast()计算这个最大值的帖子st_distance()。我的数据为 sf 数据框。

如何使用 SF 包计算质心和多边形边缘之间的最大距离?

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()
Run Code Online (Sandbox Code Playgroud)

找到的最大值(1297.496 [米])到底在哪里?如何在地图上显示连接?

在此输入图像描述

Sam*_*amR 5

您的代码通过将边界投射MULTIPOLYGON到构成该多边形的点集来计算最大距离,然后计算到每个点的距离。

因此,我们可以做的是找到这些点中的哪一个距离最大,创建一个sf包含该点和质心的数据框,并将summarise()它们放入LINESTRINGusing中st_cast()

# create sf object of border points
border_points <- test %>%
    st_cast("POINT")

# compute distances
distances <- border_points |>
    st_distance(st_centroid(test))

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()
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

关于计算质心和投影的说明

您的经/纬度格式的数据。st_crs(GER_postcode)返回4326,即WGS84,一个纬度/经度系统。但是,st_centroid()不能给出纬度/经度数据的准确结果。

您应该将数据转换为投影坐标系,即平面。由于您的数据是德国,您可能需要使用DE_ETRS89。您可以通过以下方式执行此操作:

GER_postcode <- st_transform(GER_postcode, crs = 25831)
Run Code Online (Sandbox Code Playgroud)

如果您选择不同的 CRS,只需确保它st_is_longlat(GER_postcode)FALSE. 这将为您提供更准确的最大距离。在您发布的示例中,差异约为 10 米。但是,根据位置的不同,您可能会得到完全错误的结果(即实际上不是最远距离的线)。有关更多信息,请参阅此处的伦敦预计与地理缓冲区图。