如何将Eurostat世界地图GeoJSON高效转为含全属性的DataFrame?
解决方案:保留所有属性的GeoJSON转DataFrame并正确绘制地图
核心问题分析
你用broom::tidy()转换sp对象时丢失属性,是因为tidy()仅提取地理坐标和分组信息,未保留原GeoJSON的属性列;地图显示异常则是tidy()对复杂几何体(多部分区域、带孔洞的区域)的分组处理存在缺陷,导致绘图时几何体拼接错误。
推荐方案:使用sf包(地理数据处理主流工具)
sf包直接支持GeoJSON读取,返回的对象本身就是带完整属性的类DataFrame结构(sf tibble),且完美兼容ggplot2,无需额外转换即可正确绘制地图。
步骤1:读取GeoJSON并保留所有属性
# 安装并加载sf包 install.packages("sf") library(sf) library(tidyverse) # 读取GeoJSON(本地文件或在线链接均可) geo_df <- st_read("CNTR_BN_20M_2020_4326.geojson") # 替换为你的文件路径/在线链接 # 查看数据结构:包含所有原属性列 + 几何信息列 str(geo_df)
st_read()返回的sf对象中,每一行对应一个地理要素(如国家),同时完整保留了原GeoJSON的所有属性字段,几何信息存储在geometry列中。
步骤2:转换为与get_eurostat_geospatial一致的长格式DataFrame
如果需要完全匹配get_eurostat_geospatial的输出格式(每一行是一个坐标点,重复属性列),可通过以下代码转换:
long_format_df <- geo_df %>% # 提取坐标并转换为long/lat格式的列表列 mutate(coords = st_coordinates(geometry) %>% as_tibble() %>% rename(long = X, lat = Y)) %>% # 将列表列拆分为多行 unnest(coords) %>% # 添加order/piece/group等字段(按需调整分组标识字段) group_by(NAME_LATN) %>% # 替换为你的要素唯一标识字段(如国家代码) mutate(order = row_number(), hole = FALSE, # 如需区分孔洞可通过st_is_empty等判断,此处简化处理 piece = 1, group = paste(cur_group_id(), piece, sep = ".")) %>% ungroup() %>% # 移除几何列(可选) select(-geometry) # 查看转换结果 head(long_format_df)
步骤3:正确绘制地图
使用ggplot2的geom_sf直接绘制sf对象,无需手动处理分组,彻底解决显示异常问题:
ggplot() + geom_sf(data = geo_df, fill = "lightblue", color = "white") + theme_minimal()
方案优势
sf是当前R语言地理数据处理的标准工具,比sp+broom组合更简洁高效- 天然保留所有属性字段,无需手动合并属性与坐标数据
geom_sf自动处理几何体的分组、孔洞等复杂情况,避免地图显示错误
内容的提问来源于stack exchange,提问作者Bruno Guarita
相关产品推荐
相关产品推荐

