简化 R 中的二进制光栅化

Streamlining binary rasterization in R

我有一些非常小的国家级多边形和点形状文件,我想在 R 中对其进行栅格化。最终产品应该是 一个 全局二进制栅格(表示网格是否细胞中心被多边形覆盖/点是否位于细胞内)。我的方法是遍历 shapefile 并对每个 shapefile 执行以下操作:

  # load shapefile  
  shp       = sf::read_sf(shapefile_path)
  
  # create a global raster template with resolution 0.0083
  ext       = extent(-180.0042, 180.0042, -65.00417, 75.00417)
  gridsize  = 0.008333333
  r         = raster(ext, res = gridsize)
  
  # rasterize polygon or point shapefile to raster
  rr        = rasterize(shp, r, background = 0) #all grid cells that are not covered get 0

  # convert to binary raster
  values(rr)[values(rr)>0] = 1

这里,rr 是栅格文件,其中 shp 中的多边形/点编码为 1,所有其他网格单元编码为 0。之后,我对所有 rr 得到一个包含所有多边形/点的全局二进制光栅文件。

最后两步非常慢。此外,当我尝试用 1 替换 rr 中的所有正值时,我遇到了 RAM 问题,因为由于分辨率高,单元格计数非常大。我想知道是否有可能为我想要实现的目标提出一个更智能的解决方案。

我已经找到了 fasterize 包,它可以快速实现 rasterize,效果很好。我认为如果有人有 rasterize 直接 returns 二进制栅格的解决方案,那将很有帮助。

似乎在计算上有效并显着缩短计算时间的方法是

  1. 创建一个大的 shapefile shp 而不是使用单独的栅格化 shapefile。

  2. 使用 fasterize 包对合并后的 shapefile 进行栅格化。

  3. 使用raster::calc避免内存问题。

 ext       = extent(-180.0042, 180.0042, -65.00417, 75.00417)
 gridsize  = 0.008333333
 r         = raster(ext, res=gridsize)
 rr        = fasterize(shp, r, background = 0) #all not covered cells get 0, others get sum

# convert to binary raster
  fun       =  function(x) {x[x>0] <- 1; return(x) }
  r2        =  raster::calc(rr, fun)

这是您可以使用 raster 更好地完成此操作的方法。请注意 value=1 参数,以及我更改了您对范围的说明——因为您所做的可能不正确。

library(raster)
v <- shapefile(shapefile_path)
ext <- extent(-180, 180, -65, 75)
r <- raster(ext, res = 1/120)
rr <- rasterize(v, r, value=1, background = 0)

您的最后一步不需要,但您可以完成

rr <- clamp(rr, 0, 1)
# or 
rr <- rr > 0
# or
rr <- reclassify(rr, cbind(1, Inf, 1))

raster::calc 对于像这样的简单算术运算效率不是很高

一步光栅化所有矢量数据应该比循环光栅化快得多,尤其是对于像这样的大型光栅(程序可能需要为每次迭代编写一个临时文件)。

用示例数据说明此解决方案

library(raster)
cds1 <- rbind(c(-180,-20), c(-140,55), c(10, 0), c(-140,-60))
cds2 <- rbind(c(-10,0), c(140,60), c(160,0), c(140,-55))
cds3 <- rbind(c(-125,0), c(0,60), c(40,5), c(15,-45))
v <- spLines(cds1, cds2, cds3)   
r <- raster(ncols=90, nrows=45)

r <- rasterize(v, r, field=1)

为了加快速度,您可以使用 terra(光栅的替代品)

library(raster)
f <- system.file("ex/lux.shp", package="terra")
v <- as.lines(vect(f))
r <- rast(v, ncol=75, nrow=100)
x <- rasterize(v, r, field=1)