使用terra::project重投影SpatRaster丢失数值的问题求助
解决terra::project重投影后栅格丢失数值的问题
问题分析
从你提供的栅格信息来看,Pop_moll和sd_pre已经使用相同的坐标系(WGS84/EPSG:4326),此时使用terra::project是错误的选择——project仅用于不同坐标系之间的转换,同一CRS下的栅格分辨率/范围匹配应该使用重采样工具,这是导致数值丢失的核心原因。此外,Pop_moll的范围略小于sd_pre,加上其极高的分辨率(~90米),直接用project可能引发内存或映射逻辑问题。
解决方案
1. 使用resample替代project(推荐)
同一坐标系下,用resample直接匹配sd_pre的栅格模板,根据数据类型选择合适的重采样方法:
- 若要保留人口密度的均值,用
method='bilinear'或'average' - 若要保留人口总量,需先将密度转换为人口数(密度×栅格面积),再用
method='sum'重采样,最后转回密度
# 确认CRS一致(应返回TRUE) crs(Pop_moll) == crs(sd_pre) # 方法1:直接重采样密度(均值) pop_resampled <- terra::resample(Pop_moll, sd_pre, method = "bilinear") # 方法2:保留人口总量的重采样(更严谨) # 计算原始栅格的面积(单位:平方公里) pop_cell_area <- terra::cellSize(Pop_moll, unit = "km") # 转换为人口数量(密度×面积) pop_count <- Pop_moll * pop_cell_area # 重采样到sd_pre的分辨率,求和得到每个粗栅格的总人口 pop_count_resampled <- terra::resample(pop_count, sd_pre, method = "sum") # 转回人口密度(总人口/粗栅格面积) pop_density_resampled <- pop_count_resampled / terra::cellSize(sd_pre, unit = "km")
2. 服务器环境内存优化
由于Pop_moll分辨率极高(21万行×43万列),一次性处理可能触发内存溢出,可分图层处理:
# 遍历每个年份图层,逐个重采样 pop_resampled_list <- lapply(1:nlyr(Pop_moll), function(i) { terra::resample(Pop_moll[[i]], sd_pre, method = "bilinear") }) # 合并为单个SpatRaster pop_resampled <- terra::rast(pop_resampled_list) # 还原图层名称 names(pop_resampled) <- names(Pop_moll)
3. 先聚合再匹配范围
如果不需要实时重采样,可先对Pop_moll进行聚合降低分辨率,再扩展范围匹配sd_pre:
# 计算聚合因子:粗分辨率/细分辨率 = 0.5 / 0.0008333 ≈ 600 agg_factor <- round(res(sd_pre)[1] / res(Pop_moll)[1]) # 聚合图层(用sum保留总量,或mean保留密度) pop_aggregated <- terra::aggregate(Pop_moll, fact = agg_factor, fun = "sum") # 扩展范围至sd_pre的范围,填补NA pop_aligned <- terra::extend(pop_aggregated, ext(sd_pre))
验证结果
处理完成后,检查数值是否正常:
# 查看最小值和最大值 terra::minmax(pop_resampled) # 可视化第一个图层验证 plot(pop_resampled[[1]])
内容的提问来源于stack exchange,提问作者akariozu
相关产品推荐
相关产品推荐

