如何为sfnetwork构建的空间网络添加原始shp的Simple Features属性
解决方案
问题原因
你丢失属性的核心是调用了st_combine(),该函数会将所有线要素合并为单个MULTILINESTRING几何对象,直接丢弃了原始属性表的所有字段,导致后续生成的网络边没有关联属性。
推荐方案(属性留存率最高)
直接使用sfnetwork内置的to_spatial_subdivision转换函数,该函数会自动识别线交叉点、拆分线段、生成新节点,同时完整保留原始边的所有属性,无需额外关联操作:
# 加载依赖包 library(sf) library(sfnetwork) library(dplyr) # 读入原始shp shp_file <- st_read("myfile.shp") # 直接构建网络并做空间拆分 graph <- as_sfnetwork(shp_file, directed = FALSE) %>% convert(to_spatial_subdivision, .clean = TRUE)
运行后查看边数据,即可看到原始的39个字段都完整保存在边属性表中,实现和SpatialLineDataframe一致的属性关联效果。
兼容原代码逻辑的方案
如果你需要沿用原来的st_node处理流程,可以对拆分后的线段做空间关联匹配,挂载原始属性:
# 生成拆分后的线段集合 split_edges <- st_sf(shp_file) %>% st_combine() %>% st_node() %>% st_cast('LINESTRING') %>% st_sf() %>% rename(geometry = x) # 空间关联原始属性,设置微小容差避免浮点精度误差导致匹配失败 edges_with_attr <- st_join( x = split_edges, y = shp_file, join = st_within, tolerance = 1e-8 ) # 转换为sfnetwork graph <- as_sfnetwork(edges_with_attr, directed = FALSE)
注意事项
- 容差参数可根据你的数据精度调整,当前数据为UTM投影(单位米),1e-8的容差不会影响匹配准确性
- 如果存在线重叠场景,拆分后的线段可能匹配到多条原始线,可通过
group_by(geometry) %>% slice(1)保留第一条匹配的属性即可
内容的提问来源于stack exchange,提问作者mrR
相关产品推荐
相关产品推荐

