在R中读取4GB左右GeoJSON文件遇到内存不足问题如何解决
方案1:分批次读取数据,避免一次性加载全量
- 首先确认你已经安装了最新版的
sf包,底层绑定GDAL版本≥3.0即可支持该操作 - 第一步先读取元数据,确认数据集字段,不需要加载全量内容:
library(sf) # 仅读取结构信息,无内存压力 data_meta <- st_read("你的意大利GeoJSON文件路径.geojson", query = "SELECT * FROM layer LIMIT 0") # 查看字段列表,筛选你实际需要用到的字段,无用字段不要加载 colnames(data_meta)
- 循环分批次读取数据,每次读取后及时释放内存:
# 单次读取行数,内存不足可往下调整,比如改为5万 batch_size <- 100000 offset <- 0 result_list <- list() while(TRUE) { batch <- st_read( "你的意大利GeoJSON文件路径.geojson", # 仅选择你需要的字段,不要写SELECT * query = glue::glue("SELECT 字段1, 字段2, geometry FROM layer LIMIT {batch_size} OFFSET {offset}") ) if(nrow(batch) == 0) break result_list[[length(result_list)+1]] <- batch offset <- offset + batch_size # 手动释放内存 rm(batch) gc() } # 合并所有批次得到全量数据 full_data <- do.call(rbind, result_list)
注意:如果合并全量数据时还是内存不足,可改为边读取边处理业务逻辑,不需要保留全量数据在内存中
方案2:转成高压缩率的列式存储格式后读取(推荐优先使用该方案)
GeoJSON是文本格式,读入内存后体积会膨胀35倍,转成GeoParquet格式后文件体积通常只有原GeoJSON的1/31/5,内存占用会大幅降低,转换过程是GDAL底层流式处理,不会占用过多内存:
library(sf) # 格式转换,不需要把全量数据读入内存 gdal_utils( util = "vectortranslate", source = "你的意大利GeoJSON文件路径.geojson", destination = "意大利地址数据.parquet", options = c("-f", "Parquet") ) # 转换完成后直接读取parquet文件即可 italy_data <- st_read("意大利地址数据.parquet")
如果熟悉命令行操作,也可以直接用GDAL的ogr2ogr命令转换,速度更快:ogr2ogr -f Parquet 意大利地址数据.parquet 你的意大利GeoJSON文件路径.geojson
方案3:提前过滤不需要的内容,减少加载数据量
如果你不需要全量意大利地址数据,只需要特定区域或特定属性的内容,可以在读取时直接过滤,不需要加载全量数据:
按空间范围过滤
library(sf) # 先拿到你需要的目标区域边界 target_boundary <- st_read("你的目标区域边界文件路径.geojson") # 读取时直接做空间裁剪,仅返回落在目标区域内的要素 target_address <- st_read( "你的意大利GeoJSON文件路径.geojson", wkt_filter = st_as_text(st_geometry(target_boundary)) )
按属性过滤
如果你只需要符合特定属性条件的数据,可以直接在query参数中写过滤条件:
# 比如仅读取城市为罗马的地址 roma_data <- st_read( "你的意大利GeoJSON文件路径.geojson", query = "SELECT * FROM layer WHERE city = 'Roma'" )
优化建议
- 读取数据前关闭其他占用内存的软件,保证R可用内存≥6GB
- 不需要的字段一定不要加载,文本类字段是内存占用的大头
- 如果后续需要频繁操作该数据集,建议长期存储为GeoParquet或FlatGeobuf格式,读写效率和内存占用都远优于GeoJSON
内容的提问来源于stack exchange,提问作者Giovanni
相关产品推荐
相关产品推荐

