Search code examples
rgisrasterspatialterra

Error in mosaic of rasters from different extent using terra package in R?


I have a folder that contains around 191 GeoTIFF files (each file is a different DEM (elevation) tile of a much larger area). I want to merge all the tiles into one raster file. I am using the terra package and was successfully able to load each raster and aggregate them from 2 metre resolution to 30 metre resolution. However, when running the mosaic function to merge them all, I run into an error (see error message below). I have been able to run the mosaic function on a smaller subset of just three tiles, but when I scale up to all the files, this becomes an issue.

By calling the summary of the rasters (see below), the aggregation does slightly change the extent - could this be the issue? resample might be an option, but each individual raster has a different extent and I'm not exactly sure how to implement this fix.

Not sure a sample data set would help since I know the functions work. I am running this code on a high-performance cluster so it's not very efficient to run small batches of code.

library(terra)

files <- as.list(list.files("./DEM_tiles", full.names = TRUE))

raster.list <- lapply(files, rast)
 
for(i in 1:length(raster.list)){
 raster.list[[i]] <- aggregate(raster.list[[i]], fact = 15)
 }

raster.mosaic <- do.call(mosaic, raster.list)

> Error: [mosaic] internal error: extents do not match ()
> Execution halted

Below is an example of what two of the tiles look like:

### Before Aggregation
[[1]]
class       : SpatRaster 
dimensions  : 25000, 25000, 1  (nrow, ncol, nlyr)
resolution  : 2, 2  (x, y)
extent      : -1800000, -1750000, -6e+05, -550000  (xmin, xmax, ymin, ymax)
coord. ref. : +proj=stere +lat_0=90 +lat_ts=70 +lon_0=-45 +x_0=0 +y_0=0 +datum=WGS84 +units=m +no_defs 
source      : 35_23_1_1_2m_v3.0_reg_dem.tif 
name        : 35_23_1_1_2m_v3.0_reg_dem 

[[2]]
class       : SpatRaster 
dimensions  : 25000, 25000, 1  (nrow, ncol, nlyr)
resolution  : 2, 2  (x, y)
extent      : -1800000, -1750000, -550000, -5e+05  (xmin, xmax, ymin, ymax)
coord. ref. : +proj=stere +lat_0=90 +lat_ts=70 +lon_0=-45 +x_0=0 +y_0=0 +datum=WGS84 +units=m +no_defs 
source      : 35_23_1_2_2m_v3.0_reg_dem.tif 
name        : 35_23_1_2_2m_v3.0_reg_dem 


### After Aggregation
[[1]]
class       : SpatRaster 
dimensions  : 1667, 1667, 1  (nrow, ncol, nlyr)
resolution  : 30, 30  (x, y)
extent      : -1800000, -1749990, -600010, -550000  (xmin, xmax, ymin, ymax)
coord. ref. : +proj=stere +lat_0=90 +lat_ts=70 +lon_0=-45 +x_0=0 +y_0=0 +datum=WGS84 +units=m +no_defs 
source      : memory 
name        : 35_23_1_1_2m_v3.0_reg_dem 
min value   :                 -15.62178 
max value   :                  233.6489 

[[2]]
class       : SpatRaster 
dimensions  : 1667, 1667, 1  (nrow, ncol, nlyr)
resolution  : 30, 30  (x, y)
extent      : -1800000, -1749990, -550010, -5e+05  (xmin, xmax, ymin, ymax)
coord. ref. : +proj=stere +lat_0=90 +lat_ts=70 +lon_0=-45 +x_0=0 +y_0=0 +datum=WGS84 +units=m +no_defs 
source      : memory 
name        : 35_23_1_2_2m_v3.0_reg_dem 
min value   :                 -15.27713 
max value   :                  243.0772 

Solution

  • The error was because the rasters were not aligned, and due to a bug. I now get

    library(terra)
    #terra version 1.2.1
    crs <- "+proj=stere +lat_0=90 +lat_ts=70 +lon_0=-45 +x_0=0 +y_0=0 +datum=WGS84 +units=m"
    r1 <- rast(nrow=1667, ncol=1667, ext=c(-1800000, -1749990, -600010, -550000), crs=crs)
    r2 <- rast(nrow=1667, ncol=1667, ext=c(-1800000, -1749990, -550010, -5e+05), crs=crs)
    values(r1) <- 1:ncell(r1)
    values(r2) <- 1:ncell(r2)
    m <- mosaic(r1, r2)
    #Warning message:
    #[mosaic] rasters did not align and were resampled
    
    m
    #class       : SpatRaster 
    #dimensions  : 3334, 1667, 1  (nrow, ncol, nlyr)
    #resolution  : 30, 30  (x, y)
    #extent      : -1800000, -1749990, -600010, -499990  (xmin, xmax, ymin, ymax)
    #coord. ref. : +proj=stere +lat_0=90 +lat_ts=70 +lon_0=-45 +x_0=0 +y_0=0 +datum=WGS84 +units=m +no_defs 
    #source      : memory 
    #name        :   lyr.1 
    #min value   :       1 
    #max value   : 2778889 
    

    Also

    @Elia's suggestion is a good work-around:

    r1 <- writeRaster(r1, "test1.tif", overwrite=TRUE)
    r2 <- writeRaster(r2, "test2.tif", overwrite=TRUE)
    v <- vrt(c("test1.tif", "test2.tif"), "test.vrt", overwrite=TRUE)
    
    v
    #class       : SpatRaster 
    #dimensions  : 3334, 1667, 1  (nrow, ncol, nlyr)
    #resolution  : 30, 30  (x, y)
    #extent      : -1800000, -1749990, -600020, -5e+05  (xmin, xmax, ymin, ymax)
    #coord. ref. : +proj=stere +lat_0=90 +lat_ts=70 +lon_0=-45 +x_0=0 +y_0=0 +datum=WGS84 +units=m +no_defs 
    #source      : test.vrt 
    #name        :    test 
    #min value   :       1 
    #max value   : 2778889