R中stars::st_as_sf(merge=TRUE)未完全合并同值栅格点问题
大栅格转面内存溢出,stars包merge参数无法合并为单个要素的解决方法
问题描述
处理大栅格时,raster::rasterToPolygons(..., dissolve = TRUE)会因内存占用过高崩溃。改用stars包转sf对象时,sf::st_as_sf(..., merge = TRUE)仅能将相邻的相同值栅格单元合并,得到5908个要素,而非预期的单个多面体(所有有效栅格值均为242)。同时无法直接调用stars::st_as_sf,只能使用sf::st_as_sf。
环境配置
- Ubuntu 22.04.1 LTS
- R 4.2.1 (2022-06-23) -- "Funny-Looking Kid"
- RStudio 2022.07.2+576 "Spotted Wakerobin"
- 包版本:CropScapeR 1.1.4、httr 1.4.4、raster 3.6-3、sf 1.0-8、stars 0.5-6
可复现代码
library(CropScapeR) library(httr) library(stars) library(raster) library(sf) # Linux系统下载USDA CDL数据需跳过SSL校验 httr::set_config(httr::config(ssl_verifypeer = 0L)) tif_file <- tempfile(fileext = '.tif') ST_CDL1 <- GetCDLData(aoi = '34001', year = 2021, type = 'f', save_path = tif_file) writeRaster(ST_CDL1, "ST_CDL1.tif", overwrite=TRUE) ST_CDL1 = raster("ST_CDL1.tif") # 创建仅保留蓝莓区域(值为242)的栅格,其余设为NA ST_CDL_blueberries1 <- raster::reclassify(ST_CDL1, c(-0.1,241.9,NA, 242.1,255.1,NA), progress="text") # 转为stars对象后转sf ST_CDL_blueberries1 <- stars::st_as_stars(ST_CDL_blueberries1) # 不合并得到52260个要素 ST_CDL_blueberries1false <- sf::st_as_sf(ST_CDL_blueberries1, as_points = FALSE, merge = FALSE) # 合并后仅得到5908个要素,未达预期 ST_CDL_blueberries1true <- sf::st_as_sf(ST_CDL_blueberries1, as_points = FALSE, merge = TRUE)
可行但内存不足的代码
# 重新分类保留蓝莓区域 ST_CDL_blueberries1 <- raster::reclassify(ST_CDL, c(-0.1,241.9,NA, 242.1,255.1,NA), progress="text") # 栅格转面并合并为单个要素,但大栅格下内存溢出 ST_CDL_blueberries1 <- rasterToPolygons(ST_CDL_blueberries1, dissolve = TRUE) ST_CDL_blueberries1 <- st_as_sf(ST_CDL_blueberries1)
解决方案
核心原因
raster::rasterToPolygons(dissolve = TRUE)会将所有相同值的栅格单元合并为一个多面体(无论是否空间相邻),而sf::st_as_sf(..., merge = TRUE)仅合并空间相邻的相同值单元。因此当有效区域由多个不连续斑块组成时,stars方法会得到多个要素,而非单个。
解决步骤
利用stars包低内存的优势完成栅格转面后,使用sf::st_union()合并所有要素,得到单个多面体:
# 转为stars对象后转sf(合并相邻单元) ST_CDL_blueberries_stars <- stars::st_as_stars(ST_CDL_blueberries1) ST_CDL_blueberries_sf <- sf::st_as_sf(ST_CDL_blueberries_stars, as_points = FALSE, merge = TRUE) # 合并所有要素为单个多面体 ST_CDL_blueberries_union <- sf::st_union(ST_CDL_blueberries_sf) # 转为sf对象(可选,方便后续操作) ST_CDL_blueberries_final <- sf::st_sf(geometry = ST_CDL_blueberries_union)
额外优化
如果栅格极大,可考虑分块处理后再合并,但对于多数场景,上述方法已能解决内存问题,同时得到预期的单个多面体。
内容的提问来源于stack exchange,提问作者RobertoAS
相关产品推荐
相关产品推荐

