保留整数格式的栅格数学运算(R- Raster math)

3
我有一些大型栅格图像(每个约110 MB),我想对其执行一些栅格计算。在本示例中,我想对SNDPPT_M_sl1_1km_ll.tifSNDPPT_M_sl2_1km_ll.tif进行求平均值,可在此网站上下载。实际上,数学运算会更加复杂(需要对多个栅格进行乘法和除法)。
两个输入栅格都是整数(INT1U)数据,我希望输出也是INT1U。但是,每当我尝试进行栅格计算时,它就会创建浮点格式的临时文件,这些文件非常大。我的笔记本电脑只有约7 GB的可用硬盘空间,在计算完成之前就会被填满。
# load packages
require(raster)

## script control
# which property?
prop <- "SNDPPT"

# load layers
r.1 <- raster(paste0("1raw/", prop, "_M_sl1_1km_ll.tif"))
r.2 <- raster(paste0("1raw/", prop, "_M_sl2_1km_ll.tif"))

# allocate space for output raster - this is about 100 MB (same size as input files)
r.out <- writeRaster(r.1, 
                     filename=paste0("2derived/", prop, "_M_meanTop200cm_1km_ll.tif"), 
                     datatype="INT1U")

# perform raster math calculation
r.out <- integer(round((r.out+r.2)/2))  

# at this point, my hard drive fills due to temporary files > 7 GB in size

请问有没有办法在R中进行光栅运算,同时使用整数输入和输出文件,并在最小化或避免非常大的中间文件的情况下进行操作?


1
我不熟悉raster包,但你可以试试看r.out <- (r.out+r.2) %/% 2)是否可行?(虽然不完全符合你的要求,但很接近) - Stefan F
1个回答

2
这里的技巧可能是使用raster::overlay进行计算,并同时将结果保存为压缩tiff格式。类似这样的代码应该可以工作:
library(raster)
#> Loading required package: sp
# load layers
r.1 <- raster("C:/Users/LB_laptop/Downloads/SNDPPT_M_sl1_1km_ll.tif")
r.2 <- raster("C:/Users/LB_laptop/Downloads/SNDPPT_M_sl1_1km_ll.tif")

out <- raster::overlay(r.1, r.2,
                       fun = function(x, y) (round((x + y) / 2)),
                       filename = "C:/Users/LB_laptop/Downloads/SNDPPT_out.tif", 
                       datatype = "INT1U", 
                       options  = "COMPRESS=DEFLATE")
> out
class       : RasterLayer 
dimensions  : 16800, 43200, 725760000  (nrow, ncol, ncell)
resolution  : 0.008333333, 0.008333333  (x, y)
extent      : -180, 180, -56.00083, 83.99917  (xmin, xmax, ymin, ymax)
coord. ref. : +proj=longlat +datum=WGS84 +no_defs +ellps=WGS84 +towgs84=0,0,0 
data source : C:\Users\LB_laptop\Downloads\SNDPPT_out.tif 
names       : SNDPPT_out 
values      : 0, 242  (min, max)

HTH.


感谢@LoBu - 关于结果大于255的好建议。在我的情况下,所有值都是百分比(0-100),我正在对它们进行平均,因此我知道结果永远不会大于100,这就是为什么我在所有情况下都可以使用INT1U格式的原因。因此,一旦我将函数设置为function(x, y) (round((x+y) / 2)),这个解决方案对我非常有效,产生了一个与输入大小相同的输出栅格(约120 MB)。 - Sam Zipper
1
好的。请注意,我刚刚编辑了答案,因为“压缩”选项的语法是错误的。 - lbusett
啊,现在我明白了!我使用的是乘法而不是加法。我更正了答案以反映这一点。 - lbusett

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接