在R中定位多边形质心最远边界点并绘制连线
解决德国邮编区域质心到边界最远点的连线绘制问题
步骤1:提取边界点并匹配最远点
假设你已拥有sf格式的邮编数据框postal_sf,先确保数据为多边形类型,执行以下操作:
- 计算每个区域的质心:
postal_sf$centroid <- st_centroid(postal_sf) - 将多边形转换为边界点集合:
postal_sf$boundary_points <- st_cast(postal_sf, "POINT") - 遍历每个区域,找到质心到边界的最远点:
for (i in 1:nrow(postal_sf)) { # 获取当前区域的质心与边界点 cent <- postal_sf$centroid[i] bounds <- postal_sf$boundary_points[i] # 计算质心到所有边界点的距离 dists <- st_distance(cent, bounds) # 定位最大距离对应的边界点并保存 max_idx <- which.max(dists) postal_sf$farthest_point[i] <- bounds[max_idx,] }
步骤2:生成质心到最远点的连线
将质心与最远点组合为线要素,绑定到原数据框:
# 批量生成连线的sf线对象 lines_list <- lapply(1:nrow(postal_sf), function(i) { st_sfc(st_linestring(rbind(st_coordinates(postal_sf$centroid[i]), st_coordinates(postal_sf$farthest_point[i]))), crs = st_crs(postal_sf)) }) postal_sf$distance_line <- st_sfc(lines_list, crs = st_crs(postal_sf))
步骤3:绘制可视化地图
以tmap包为例,实现区域、质心、最远点及连线的叠加展示:
library(tmap) tm_shape(postal_sf) + tm_polygons(col = "lightgray", alpha = 0.5) + # 绘制邮编区域底色 tm_shape(postal_sf) + tm_symbols(shape = 21, size = 0.1, col = "red", border.col = "black") + # 标记质心 tm_shape(postal_sf) + tm_symbols(shape = 21, size = 0.1, col = "blue", border.col = "black") + # 标记最远点 tm_shape(postal_sf) + tm_lines(col = "darkred", lwd = 0.5) # 绘制质心到最远点的连线
优化提示
- 若数据为多部分多边形(MULTIPOLYGON),
st_cast会自动提取所有部分的边界点,无需额外处理 - 确保所有要素的CRS一致,避免距离计算偏差
- 处理全德国邮编这类大数据时,用
purrr替代循环提升效率:
library(purrr) postal_sf <- postal_sf %>% mutate( centroid = st_centroid(geometry), boundary_points = st_cast(geometry, "POINT"), farthest_point = map2(centroid, boundary_points, function(c, b) { dists <- st_distance(c, b) b[which.max(dists),] }), distance_line = map2(centroid, farthest_point, function(c, fp) { st_linestring(rbind(st_coordinates(c), st_coordinates(fp))) }) %>% st_sfc(crs = st_crs(.)) )
内容的提问来源于stack exchange,提问作者Marco
相关产品推荐
相关产品推荐

