21
votes

I have several high resolution raster layers in R that I am working with. The level of detail is excessive for some of the analyses I am running, so I would like to speed things up by reducing the resolution.

The coordinate system is UTM so the units are meters. The resolution says it is 30, 30 (x, y). So it seems that the resolution here is 30m.

Could someone please advise me on how to change the resolution to 120m instead? I have read the help for the resample() and projectRaster() functions but they seem to require a template raster with the desired resolution, which I don't have.

Here is an example of one of my raster layers:

alt.utm
class : RasterLayer
dimensions : 4572, 2495, 11407140 (nrow, ncol, ncell)
resolution : 30, 30 (x, y)
extent : 421661, 496511, 4402939, 4540099 (xmin, xmax, ymin, ymax)
coord. ref. : +proj=utm +zone=13 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs
data source : in memory
names : layer
values : 1485.127, 4275.202 (min, max)

4

4 Answers

42
votes

You can use aggregate or disaggregate.

library(raster)

#get some sample data
data(meuse.grid)
gridded(meuse.grid) <- ~x+y
meuse.raster <- raster(meuse.grid)
res(meuse.raster)
#[1] 40 40

#aggregate from 40x40 resolution to 120x120 (factor = 3)
meuse.raster.aggregate <- aggregate(meuse.raster, fact=3)
res(meuse.raster.aggregate)
#[1] 120 120

#disaggregate from 40x40 resolution to 10x10 (factor = 4)
meuse.raster.disaggregate <- disaggregate(meuse.raster, fact=4)
res(meuse.raster.disaggregate)
#[1] 10 10
8
votes

I've tried 3 different options for upscaling a DEM file. First I used gdal_translate like this:

from CMD:
gdal_translate -tr 0.1 0.1 "C:\dem.tif" "C:\dem_0.1.tif"

In R:

res(raster('C:\dem_0.1.tif')
[1] 0.1 0.1

Then I tried both aggregate and resample commands from raster package in R:

#
r <- raster("dem.tif")
> res(r)
[1] 0.0002777778 0.0002777778 # original dem resolution
#
r_up_0.1 <- aggregate(r, fact = 0.1/res(r)) # aggregate output
> res(r_up_0.1)
[1] 0.1 0.1
#
s <- raster(nrow = 10, ncol = 10)
extent(s) <- extent(r)
s <- resample(r, s, method = 'bilinear') # resample output
> res(s)
[1] 0.1000278 0.1000278

These are the outputs: The 3 outputs were upscaled to a res = 0.1x0.1 and there are some differences between them but I intend to use the gdal output.

Hope this helps.

5
votes

Here is an example of how to do this. (link to original)

  #########################################################################
# SubsampleImageRaster.r
#  
# This function demonstrates resampling of raster images to a new
# spatial resolution using the R raster package.
# 
# Author: Rick Reeves
# Date created: 6-October- 2010
# Date modified:                                                             
# NCEAS
#
#########################################################################
#
SubsampleImageRaster <- function()
{
   library(raster)

   sOutFile <- ""
   resampleFactor <- 4  # For test, subsample incoming image by factor of 10

# Read the mosaic components, stored in a subfolder, into a raster object list.
# Within the same loop, obtain the (geographic) extent of each component.
# Note: these images do not have same spatial extent, so they cant be stored
# in a rasterStack. Instead, use a list of rasterLayers.

   setwd("./ForUseCase")
   inFiles <- list.files(pattern="*.tif")
   nFiles <-  length(inFiles)
   inputRaster <- raster()
   CoarseResampRaster <- raster()   
   FineResampRaster <- raster()   
   for (iCtr in 1 : nFiles)
   {
      message(sprintf("resampling file: %s",inFiles[iCtr]))
      inputRaster <- raster(inFiles[iCtr])

# The aggregate() / disaggregate methods resample rasters to COARSER (bigger cells)
# and FINER (smaller cells) resolutions, respectively

      CoarseResampRaster <- aggregate(inputRaster,fact=resampleFactor,fun=mean) 
      sOutFile <- sprintf("CoarseSubsamp%s",inFiles[iCtr]) 
      writeRaster(CoarseResampRaster,filename=sOutFile,format="GTiff",datatype="INT1U",overwrite=TRUE)      
      FineResampRaster <- disaggregate(inputRaster,fact=resampleFactor,fun=mean) 
      sOutFile <- sprintf("FineSubsamp%s",inFiles[iCtr]) 
      writeRaster(FineResampRaster,filename=sOutFile,format="GTiff",datatype="INT1U",overwrite=TRUE)            
   }   

   message("resample demo")
   browser()

# second method: use the resample() method from raster package

# Simple example:
# This code produces a resampled raster, 's',
# with correct resampled values. e.g.; 
# s[] prints a vector of resampled cell values.

   r <- raster(nrow=3, ncol=3)
   r[] <- 1:ncell(r)
   s <- raster(nrow=10, ncol=10)
   s <- resample(r, s, method='bilinear')

# Useful example:
# Resample a satellite image, stored in a GeoTiff file
# into a NEW raster with 2x spatial resolution in 
# both dimensions (four times the number of cells)
# Here is the technique: 
#  1) Create a new raster object with the correct 'resampled' number of cells.
#  2) Set the extent (geographic 'bounding box') of the new raster 
#     to the extent of the original raster
#  3) Generate the resampled raster.

   resampleFactor <- .5  # reduce the cell size by 50% and double the number of rows and columns.      
   inputRaster <- raster("TmB50MosaicImg1.tif")      
   inCols <- ncol(inputRaster)
   inRows <- nrow(inputRaster)
   resampledRaster <- raster(ncol=(inCols / resampleFactor), nrow=(inRows / resampleFactor))
   extent(resampledRaster) <- extent(inputRaster)

# The resample method will write the resampled raster image to a NEW disk file..

   resampledRaster <- resample(inputRaster,resampledRaster,datatype="INT1U",method='bilinear',filename="testOutResamp.tif",overwrite=TRUE)

# Or, use writeRaster method to create the output file.

   writeRaster(resampledRaster,filename="ResampleProduct.tif",format="GTiff",datatype="INT1U",overwrite=TRUE)   


# end
}
-1
votes

I recently had a requirement to reduce the resolution of a ggmap object. This involves extracting and transforming the ggmap raster (using Robin Lovelace's ggmap_rast()), aggregating the raster as discussed in this thread, and then replacing the ggmap high resolution raster with the lower resolution raster below. Hope this is useful:

original_map <- get_map("New York", scale = 1) #download a map at lowest resolution
#ggmap_rast function courtesy of Robin Lovelace
original_map.rast1 <- ggmap_rast(original_map) #extract RasterStack from ggmap object

original_map.rast2 <- aggregate(original_map.rast, 2) #compress raster

rast2_length <- sqrt(length(original_map.rast2)/3)  ## find the number of cells in compressed raster

map <- ggmap::ggmap(original_map) 
# from https://stackguides.com/questions/44225063/plot-ggmap-image-over-raster
r <- map$layers[[2]]$geom_params$raster #pull hex raster pixel values from ggmap object
#x <- r[,] #assign values to a variable (probably unnecessary)

xx <- r[1:rast2_length,1:rast2_length] #filler values for raster to be created

rgb_map <- original_map.rast2

for(i in 1:rast2_length){
  for(j in 1:rast2_length){
    k=i*rast2_length+j
    #many rgv values are non-integers; rgb2hex requires integer
    red = as.integer(round(rgb_map$layer.1[k],0))
    green = as.integer(round(rgb_map$layer.2[k],0))
    blue = as.integer(round(rgb_map$layer.3[k],0))
    #rgb2hex from ggtern package
    xx[i,j] <- rgb2hex(red,green,blue)
    #rgb2hex is slow; export, calculate in excel, import is faster, sadly
    #xx[i,j] <- as.character(rgb_from_excel$V1[k])
  }
}

map$layers[[2]]$geom_params$raster <- xx
map