6

I have about 1,000 rasters which are around 10km x 10km and partially overlap to cover a whole country.

I would like to convert these into a single national raster, and where raster overlap, add the cell values together.

Currently, I am using ArcGIS's workspace to new raster tool, but I would like to replicate the process in the R language.

I've tried a couple of things but usually end up with only the intersection of the rasters. Many of the solutions on StackExchange advocate cropping to a common area, which is the exact opposite of what I want.

IS there a general solution for aligning two rasters and then making a mosaic which has the combined extent of both rasters?

Can this method be scaled to work for thousands of rasters?

EDIT

> sessionInfo()
R version 3.3.2 (2016-10-31)
Platform: x86_64-w64-mingw32/x64 (64-bit)
Running under: Windows 7 x64 (build 7601) Service Pack 1

locale:
[1] LC_COLLATE=English_United Kingdom.1252  LC_CTYPE=English_United Kingdom.1252    LC_MONETARY=English_United Kingdom.1252
[4] LC_NUMERIC=C                            LC_TIME=English_United Kingdom.1252    

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base     

other attached packages:
[1] rgdal_1.2-5  raster_2.5-8 sp_1.2-4    

loaded via a namespace (and not attached):
[1] tools_3.3.2     Rcpp_0.12.9     grid_3.3.2      lattice_0.20-34

> rasterOptions()
format        : raster 
datatype      : FLT8S 
overwrite     : FALSE 
progress      : none 
timer         : FALSE 
chunksize     : 1e+07 
maxmemory     : 1e+08 
tmpdir        : D:/RTemp\RtmpgzISfL/raster/ 
tmptime       : 168 
setfileext    : TRUE 
tolerance     : 0.5 
standardnames : TRUE 
warn depracat.: TRUE 
header        : none

2 Answers 2

7

The best solution to this is making a list of the rasters, then passing this to a function based on the apply family

The following code was pulled from a similar question wrapped into a function and should work for you

mosaicList <- function(rasList){

#Internal function to make a list of raster objects from list of files.
  ListRasters <- function(list_names) {
    raster_list <- list() # initialise the list of rasters
    for (i in 1:(length(list_names))){ 
      grd_name <- list_names[i] # list_names contains all the names of the images in .grd format
      raster_file <- raster::raster(grd_name)
    }
    raster_list <- append(raster_list, raster_file) # update raster_list at each iteration
  }

  #convert every raster path to a raster object and create list of the results
  raster.list <-sapply(rasList, FUN = ListRasters)

  # edit settings of the raster list for use in do.call and mosaic
  names(raster.list) <- NULL
  #####This function deals with overlapping areas
  raster.list$fun <- sum

  #run do call to implement mosaic over the list of raster objects.
  mos <- do.call(raster::mosaic, raster.list)

  #set crs of output
  crs(mos) <- crs(x = raster(rasList[1]))
  return(mos)
}

To use this do something along the lines of:'

raster_files <- list.files(path ="folder_with_files",pattern = ".tif$",full.names = TRUE )

national_layer <- mosaicList(raster_files )
8
  • 1
    This looks like the kind of solution I need but I get an error "Error in compareRaster(x, extent = FALSE, rowcol = FALSE, orig = TRUE, : different origin" with my data.
    – falcs
    Commented Jan 30, 2017 at 15:05
  • Hmmmm ok, this question on mosaicing is probably the same error. So i would try the following: 1) update R and raster to most recent versions, 2) increase the tollerence, gis.stackexchange.com/questions/167445/… Commented Jan 30, 2017 at 15:08
  • 1
    I've updated R from 3.3.1 to 3.3.2 and reinstalled raster package, but get the same error.
    – falcs
    Commented Jan 30, 2017 at 15:28
  • 1
    I also increase the tolerance to rasterOptions(tolerance = 0.5)
    – falcs
    Commented Jan 30, 2017 at 15:31
  • 1
    Try specifying the tollerence within mosaic, it might not be using the global option within the functions. 'raster.list$tolerance <- 0.1'. Otherwise i'm really not sure. Commented Jan 30, 2017 at 15:49
5

Full credit to @Tom Higginbottom who answered the hard part but a small modification I made to fix the

Error in compareRaster(x, extent = FALSE, rowcol = FALSE, orig = TRUE, : different origin

Just added a raster_file <- projectRaster(raster_file, snap, method = "ngb") into the loop and created a snap raster, with a large extent that covers the whole set of rasters

snap <- raster(resolution = c(10,10), xmn = 180000, xmx = 300000, ymn = 60000, ymx = 100000, crs = "+init=epsg:27700")

Full Code

    mosaicList <- function(rasList){

  #Internal function to make a list of raster objects from list of files.
  ListRasters <- function(list_names) {
    raster_list <- list() # initialise the list of rasters
    for (i in 1:(length(list_names))){ 
      grd_name <- list_names[i] # list_names contains all the names of the images in .grd format
      raster_file <- raster::raster(grd_name)
      raster_file <- projectRaster(raster_file, snap, method = "ngb")
          }
    raster_list <- append(raster_list, raster_file) # update raster_list at each iteration
  }

  #convert every raster path to a raster object and create list of the results
  raster.list <-sapply(rasList, FUN = ListRasters)

  # edit settings of the raster list for use in do.call and mosaic
  names(raster.list) <- NULL
  #####This function deals with overlapping areas
  raster.list$fun <- sum
  #raster.list$tolerance <- 0.1

  #run do call to implement mosaic over the list of raster objects.
  mos <- do.call(raster::mosaic, raster.list)

  #set crs of output
  crs(mos) <- crs(x = raster(rasList[1]))
  return(mos)
}

raster_files <- list.files(path ="D:/results/gov-4p/stackoverflow",pattern = ".tif$",full.names = TRUE )
snap <- raster(resolution = c(10,10), xmn = 180000, xmx = 300000, ymn = 60000, ymx = 100000, crs = "+init=epsg:27700") 
national_layer <- mosaicList(raster_files )

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.