如何沿sf包的st_line计算从起点A到路径上点X的距离?
用sf包计算路径起点到路径上点/区域的距离
针对你的需求,分两种场景给出具体实现方案:
场景1:点X在路径A→B上
可以直接用st_project()函数获取点X沿路径到起点A的距离,无需手动拆分路径片段:
library(sf) # 1. 构造示例数据(WGS84坐标系) path <- st_sfc(st_linestring(rbind(c(116, 39), c(117, 40), c(118, 39.5)))) %>% st_set_crs(4326) X <- st_sfc(st_point(c(117, 40))) %>% st_set_crs(4326) # 2. 转换为投影坐标系(如UTM,单位为米,根据实际区域选择对应EPSG) path_proj <- st_transform(path, 32650) X_proj <- st_transform(X, 32650) # 3. 计算A到X的距离 distance_A_to_X <- st_project(path_proj, X_proj)[[1]][1] print(distance_A_to_X)
st_project()返回的第一个值就是沿路径的距离(单位与输入坐标系一致),若X确实在路径上,第二个返回值(点到路径的垂直距离)会为0。
你也可以用熟悉的st_length()结合st_split()实现:
# 拆分路径并取第一段计算长度 split_path <- st_split(path, X) segment_A_to_X <- st_cast(split_path[[1]], "LINESTRING")[1] distance_A_to_X <- st_length(st_transform(segment_A_to_X, 32650))
场景2:X是st_buffer生成的圆形区域
需要先找到路径与缓冲区的交点,再计算起点A到最近交点的距离:
library(sf) # 1. 构造示例数据 path <- st_sfc(st_linestring(rbind(c(116, 39), c(117, 40), c(118, 39.5)))) %>% st_set_crs(4326) center_point <- st_sfc(st_point(c(117.2, 39.8))) %>% st_set_crs(4326) # 生成1000米半径的缓冲区(先转投影再缓冲,保证距离单位准确) buffer <- st_buffer(st_transform(center_point, 32650), dist = 1000) %>% st_transform(4326) # 2. 找到路径与缓冲区的交点 intersections <- st_intersection(path, buffer) # 3. 计算到最近交点的距离 path_proj <- st_transform(path, 32650) if (st_geometry_type(intersections) == "MULTIPOINT") { intersection_points <- st_cast(intersections, "POINT") distances <- sapply(intersection_points, function(p) { st_project(path_proj, st_transform(p, 32650))[[1]][1] }) min_distance <- min(distances) } else if (st_geometry_type(intersections) == "POINT") { min_distance <- st_project(path_proj, st_transform(intersections, 32650))[[1]][1] } else { # 路径完全在缓冲区内时,距离为0 min_distance <- 0 } print(min_distance)
关键注意事项
- 必须转换为投影坐标系(如UTM)计算实际距离,避免用WGS84的度作为距离单位,结果无实际意义。
- 若路径是多段线(
MULTILINESTRING),需先转换为LINESTRING(用st_cast())再进行计算。
内容的提问来源于stack exchange,提问作者Xavier Prudent
相关产品推荐
相关产品推荐

