基于sf包与Voronoi法提取河道中心线的技术求助
用sf实现Voronoi法提取河道中心线
核心逻辑
Voronoi法提取河道中心线的关键是:对河道边界的密集采样点生成Voronoi图,筛选出位于河道多边形内部的Voronoi边,这些边经合并简化后即为河道中心线。
完整代码示例
假设你已拥有sf格式的河道多边形对象(命名为river_poly),以下是从采样到生成中心线的完整流程:
1. 对河道边界密集采样
library(sf) # 提取河道边界线 river_boundary <- st_cast(river_poly, "MULTILINESTRING") %>% st_cast("LINESTRING") # 对边界线密集采样(density为采样密度,单位与数据CRS一致,可根据河道宽度调整) sample_points <- st_line_sample(river_boundary, density = 10) %>% st_cast("POINT")
2. 生成Voronoi图并提取边
# 基于采样点生成Voronoi图 voronoi_tess <- st_voronoi(st_union(sample_points)) %>% st_cast("POLYGON") %>% st_sf() # 提取Voronoi图的所有边并转换为线要素 voronoi_edges <- st_boundary(voronoi_tess) %>% st_cast("LINESTRING") %>% st_sf()
3. 筛选河道内部的Voronoi边
# 先筛选完全位于河道内部的边 center_edges <- voronoi_edges[st_within(voronoi_edges, river_poly, sparse = FALSE), ] # 若存在跨边界的边,裁剪至河道内部 center_edges <- st_intersection(center_edges, river_poly)
4. 合并边并简化中心线
# 合并所有有效边为单一线要素 center_line <- st_union(center_edges) %>% st_cast("MULTILINESTRING") %>% st_sf() # 简化中心线(dTolerance为简化阈值,单位与CRS一致,按需调整) center_line_simplified <- st_simplify(center_line, dTolerance = 5)
注意事项
- 采样密度:河道越窄,
density需设得越高,保证中心线精度;宽河道可适当降低密度提升效率。 - CRS匹配:所有要素必须使用同一投影坐标系(建议用UTM等米制CRS,避免经纬度单位带来的计算误差)。
- 筛选逻辑:若
st_within筛选结果过少,可改用st_intersects保留所有与河道相交的边,再裁剪至内部。
内容的提问来源于stack exchange,提问作者Jane
相关产品推荐
相关产品推荐

