sf分组点边界框生成、绘图问题及与ArcGIS Pro对比咨询
sf分组点边界框生成与绘图问题解答
问题1:更简便的分组边界框生成方法
直接使用dplyr分组结合st_bbox和st_as_sfc即可,无需自定义函数,代码简洁易维护:
# 生成带分组ID的轴对齐边界框sf对象 bound_boxes <- Example %>% group_by(ID) %>% summarise( geometry = st_as_sfc(st_bbox(geometry)), # 将分组点的边界框转为几何对象 area = st_area(st_as_sfc(st_bbox(geometry))), # 直接计算面积 .groups = "drop" ) %>% st_set_crs(26917) # 确保CRS与原数据一致
问题2:geom_sf报错原因分析
报错核心是额外的sfc列丢失了CRS信息:
- 自定义的
st_bbox_by_feature函数中,st_as_sfc(st_bbox(y))生成的边界框sfc对象没有继承原数据的CRS; - sf对象仅允许一个活跃几何列,将无CRS的sfc列
BoundBox追加到原sf对象中,会导致ggplot处理数据时尝试转换所有sfc列,无CRS的列无法完成转换,从而抛出错误。
问题3:保留分组ID的边界框生成方法
在分组汇总时直接保留ID列,生成的边界框sf对象自带分组标识,无需额外处理:
# 生成带ID的边界框 bound_boxes <- Example %>% group_by(ID) %>% summarise( geometry = st_as_sfc(st_bbox(geometry)), area = st_area(geometry), .groups = "drop" ) %>% st_set_crs(26917)
后续绘图时直接调用该对象,即可按ID着色:
ggplot() + geom_sf(data = NC, fill = "lightgray", color = "white") + geom_sf(data = Example, aes(color = factor(ID))) + geom_sf(data = bound_boxes, aes(fill = factor(ID)), alpha = 0.3, color = NA)
问题4:st_bbox与ArcGIS Minimum Bounding Geometry的差异及对齐方法
- st_bbox默认生成轴对齐边界框(AABB):矩形边与坐标轴平行,仅取x、y的最大最小值;
- ArcGIS默认生成最小旋转矩形(MRR):能包围所有点的面积最小矩形,允许旋转,与坐标轴不一定平行。
要生成和ArcGIS一致的最小旋转矩形,需使用lwgeom包的st_minimum_bounding_rectangle函数:
# 安装并加载lwgeom install.packages("lwgeom") library(lwgeom) # 生成最小旋转矩形(与ArcGIS默认结果一致) rotated_boxes <- Example %>% group_by(ID) %>% summarise( geometry = st_minimum_bounding_rectangle(geometry), area = st_area(geometry), .groups = "drop" ) %>% st_set_crs(26917)
完整修正代码
library(tidyverse) library(sf) library(lwgeom) # 用于生成最小旋转矩形 # 模拟数据 ID <- rep(seq(1:4), each = 4) NC <- st_read(system.file("shape/nc.shp", package = "sf"), quiet = TRUE) %>% filter(FIPS == c("37007", "37123", "37167", "37179")) %>% st_transform(crs = 26917) points <- st_sample(NC, size = c(4,4), type = "random") %>% st_transform(crs = 26917) Example <- bind_rows(list(geometry = points)) %>% mutate(ID = ID) %>% st_as_sf(crs = 26917) # 1. 生成轴对齐边界框(st_bbox) axis_aligned_boxes <- Example %>% group_by(ID) %>% summarise( geometry = st_as_sfc(st_bbox(geometry)), area = st_area(geometry), .groups = "drop" ) %>% st_set_crs(26917) # 2. 生成最小旋转矩形(与ArcGIS默认一致) rotated_boxes <- Example %>% group_by(ID) %>% summarise( geometry = st_minimum_bounding_rectangle(geometry), area = st_area(geometry), .groups = "drop" ) %>% st_set_crs(26917) # 轴对齐边界框绘图 ggplot() + geom_sf(data = NC, fill = "lightgray", color = "white") + geom_sf(data = Example, aes(color = factor(ID)), size = 2) + geom_sf(data = axis_aligned_boxes, aes(fill = factor(ID)), alpha = 0.3, color = "black") + labs(title = "轴对齐分组边界框", color = "分组ID", fill = "分组ID") + theme_minimal() # 最小旋转矩形绘图 ggplot() + geom_sf(data = NC, fill = "lightgray", color = "white") + geom_sf(data = Example, aes(color = factor(ID)), size = 2) + geom_sf(data = rotated_boxes, aes(fill = factor(ID)), alpha = 0.3, color = "black") + labs(title = "最小旋转分组边界框(与ArcGIS一致)", color = "分组ID", fill = "分组ID") + theme_minimal()
内容的提问来源于stack exchange,提问作者Jeffrey Beauvais
相关产品推荐
相关产品推荐

