在R中计算坐标点对间以正西为0度的方位角
计算坐标点对的正西为0度方位角解决方案
问题背景
需要计算每一对起点-终点坐标间以正西为0度的方位角,代表性数据集如下:
data <- data.frame( from_id = c("id1","id2","id3","id4"), to_id = c("id2","id5","id4","id1"), from_latitude = c(2.8033,3.1565,4.2032,3.5352), from_longitude = c(24.7305,26.8886,22.8083,25.8845), to_latitude = c(3.1565,0.0364,3.5352,2.8033), to_longitude = c(26.8886,18.2507,25.8845,24.7305) )
尝试使用stplanr::line_bearing()时出现缺失值,且处理大规模数据效率极低,期望输出包含方位角度数的目标数据集。
原代码存在冗余操作(如st_buffer、st_crop、st_intersection完全无必要),且未处理方位角基准转换的问题。
解决方案
1. 高效构建SF线对象
无需逐个循环创建线,通过向量化方式批量生成所有起点到终点的线几何对象:
library(sf) library(stplanr) # 将起点、终点分别转换为SF点对象 from_points <- st_as_sf(data, coords = c("from_longitude", "from_latitude"), crs = 4326) to_points <- st_as_sf(data, coords = c("to_longitude", "to_latitude"), crs = 4326) # 批量生成线对象(向量化操作,效率远高于循环) lines_sf <- st_sfc( mapply( function(f, t) st_linestring(rbind(st_coordinates(f), st_coordinates(t))), from_points$geometry, to_points$geometry, SIMPLIFY = FALSE ), crs = 4326 ) # 合并线对象到原数据集 data_sf <- cbind(data, st_sf(geometry = lines_sf))
2. 计算方位角并转换基准
line_bearing()默认返回以正北为0度的方位角(顺时针递增),需转换为以正西为0度的基准:
- 转换公式:
(正北基准方位角 + 270) %% 360- 逻辑:正北0度加270度对应正西0度,取模360保证结果落在0-360度区间内
# 计算正北基准的方位角 data_sf$bearing_north <- line_bearing(data_sf$geometry) # 转换为正西为0度的方位角 data_sf$degrees <- (data_sf$bearing_north + 270) %% 360 # 提取目标列,得到期望格式的结果 result <- data_sf[, c("from_id", "to_id", "from_latitude", "from_longitude", "to_latitude", "to_longitude", "degrees")]
最终输出
运行后得到的结果与预期格式一致:
> result Simple feature collection with 4 features and 7 fields Geometry type: LINESTRING Dimension: XY Bounding box: xmin: 18.2507 ymin: 0.0364 xmax: 26.8886 ymax: 4.2032 Geodetic CRS: WGS 84 from_id to_id from_latitude from_longitude to_latitude to_longitude degrees geometry 1 id1 id2 2.8033 24.7305 3.1565 26.8886 92.99 LINESTRING (24.7305 2.8033,... 2 id2 id5 3.1565 26.8886 0.0364 18.2507 351.98 LINESTRING (26.8886 3.1565,... 3 id3 id4 4.2032 22.8083 3.5352 25.8845 52.99 LINESTRING (22.8083 4.2032,... 4 id4 id1 3.5352 25.8845 2.8033 24.7305 182.00 LINESTRING (25.8845 3.5352,...
优化说明
- 删除了冗余的缓冲区、裁剪、相交操作,这些操作不仅不影响方位角计算,还会导致数据丢失或降低效率
- 使用
mapply向量化生成线对象,比循环lapply更高效,适合处理大规模数据集 - 明确了方位角基准转换逻辑,确保结果完全符合“正西为0度”的要求
内容的提问来源于stack exchange,提问作者Coralie
相关产品推荐
相关产品推荐

