在R中从CSV的FeatureCollection提取LineString坐标求助
提取CSV中FeatureCollection的LineString并转为sf数据框
问题场景
有一份5000行的CSV文件,其中journeyroute列存储FeatureCollection格式的JSON数据,示例如下:
{"type": "FeatureCollection", "features": [{"type": "Feature", "geometry": {"type": "Point", "coordinates": [-4.095772, 50.409393]}, "properties": {"name": "start"}}, {"type": "Feature", "geometry": null, "properties": {"name": "end"}}, {"type": "Feature", "geometry": {"type": "LineString", "coordinates": [[-4.095772, 50.409393], [-4.095781, 50.409397], [-4.095792, 50.409401], [-4.095965, 50.40971], [-4.096064, 50.410069], [-4.09597, 50.410397]]}, "properties": {"distance": 4027.4, "name": "Raw", "times": [1690900467000, 1690900520000, 1690900522000, 1690900539000, 1690900550000, 1690900569000], "duration": 4923.0}}]}
目标是提取其中的LineString数据,生成包含sf LineString几何列的数据框,但尝试的代码报错。
尝试代码
new_df <- df %>% mutate(geo = map(Journey.Route, ~ jsonlite::fromJSON(.))) %>% as.data.frame() %>% unnest(geo) %>% filter(geo != "FeatureCollection") %>% mutate(coord = rep(c("x", "y"))) %>% pivot_wider(names_from = coord, values_from = coordinates)
报错信息
Error in `mutate()`: ℹ In argument: `coord = rep(c("x", "y"))`. Caused by error: ! `coord` must be size 5000 or 1, not 2. Run `rlang::last_trace()` to see where the error occurred.
错误原因
rep(c("x", "y"))未指定重复次数,默认仅生成2个元素,但当前数据框行数远大于2,导致列长度不匹配,触发错误。- 原代码逻辑未正确处理FeatureCollection的结构:
unnest(geo)会把整个JSON列表打散,无法精准定位到features中的LineString几何数据。
解决方案
使用dplyr、purrr、jsonlite和sf包,按以下步骤提取并转换:
完整代码
library(dplyr) library(purrr) library(jsonlite) library(sf) # 读取CSV文件(替换为你的文件路径) df <- read.csv("your_data.csv") # 提取LineString并转为sf数据框 sf_result <- df %>% mutate( # 逐行解析JSON字符串为列表 route_list = map(Journey.Route, ~ fromJSON(.)), # 从features中筛选出LineString类型的几何数据 linestring_coords = map(route_list, ~ { features <- .$features # 筛选geometry类型为LineString的条目,提取坐标数组 filter(features, geometry.type == "LineString") %>% pull(geometry.coordinates) %>% # 确保提取到的是坐标矩阵(处理单条LineString的情况) {if (length(.) > 0) .[[1]] else NULL} }), # 将坐标数组转为sf LineString几何对象,设置坐标系(这里用WGS84) geometry = map(linestring_coords, ~ { if (!is.null(.)) st_linestring(.) %>% st_sfc(crs = 4326) else NULL }) ) %>% # 移除中间辅助列 select(-route_list, -linestring_coords) %>% # 过滤掉没有LineString的行(可选) filter(!map_lgl(geometry, is.null)) %>% # 转为sf数据框 st_as_sf()
代码说明
map(Journey.Route, ~ fromJSON(.)):逐行解析JSON字符串为结构化列表,保留FeatureCollection的层级。- 筛选
features中geometry.type为LineString的条目,提取对应的坐标数组。 st_linestring(.)将二维坐标数组转为LineString几何对象,st_sfc(crs = 4326)为几何对象指定坐标系(WGS84,可根据实际需求调整)。st_as_sf()将普通数据框转为sf数据框,自动识别geometry列为几何列,支持后续空间分析操作。
内容的提问来源于stack exchange,提问作者Tim Binding
相关产品推荐
相关产品推荐

