Home > other >  How to change SpatRast resolution using res and projectRaster in library(terra) correctly?
How to change SpatRast resolution using res and projectRaster in library(terra) correctly?

Time:06-27

I have a raster file of sea surface temperatures from HadISST at 1x1 resolution. Previously I've re-grid to 0.5 x 0.5 using cdo(csl("remapbil","global_0.5"), inputfile, output file, debug=FALSE) from cdo via climateoperators but I'd like to explore how the workflow would be in terra using projectRaster. Example below using a HadISST nc file and rnaturalearth:

library(tidyverse)
library(ggplot2)
library(tidyterra)
library(terra)
library(tmaptools)
library(sf)
library(rnaturalearth)

### HadISST SST ndcf file (518kb)
if (!file.exists("HadISST_SST.nc.gz")) { 
     download.file("https://www.metoffice.gov.uk/hadobs/hadisst/data/HadISST1_SST_update.nc.gz","HadISST_SST.nc.gz")
     R.utils:::gunzip("HadISST_SST.nc.gz")
}

hadISST <- terra::rast('HadISST_SST.nc') 
hadISST_mean <- mean(hadISST) %>% clamp(lower=5, value=5)
hadISST_outlines <- mean(hadISST) %>% as.polygons(dissolve=FALSE)

### natural earth world coastline
worldrn_m <- ne_coastline(scale = "medium", returnclass = "sf") %>%  st_transform(crs = st_crs(hadISST))

ggplot()   theme_bw()   coord_fixed()   xlim(90,150)    ylim(-20,40)   
  geom_spatraster(data=hadISST_mean,  alpha=0.8)  
  geom_spatvector(data=hadISST_outlines, color="black", size=0.1, fill=NA,  alpha=0.5)   
  scale_fill_continuous(type = "viridis", limits=c(0, 35), breaks=seq(5,35,by=5))  
  geom_sf(data=worldrn_m) 

enter image description here

projectRaster failed without a CRS using the following:

test <- projectRaster(hadISST_mean, res = 0.5, method="bilinear")

Error in rgdal::checkCRSArgs_ng(uprojargs = uprojargs, SRS_string = SRS_string,  : 
  is.character(SRS_string) is not TRUE

the crs I've used with sf previously throws the same error:

target_crs <- st_crs(" proj=longlat  x_0=0  y_0=0  lat_0=0  lon_0=180")
test <- projectRaster(hadISST_mean, res = 0.5, crs=target_crs, method="bilinear")

Error in rgdal::checkCRSArgs_ng(uprojargs = uprojargs, SRS_string = SRS_string,  : 
  is.character(SRS_string) is not TRUE

Can anyone advise where I'm going wrong here?

CodePudding user response:

There is no projectRaster method for a <SpatRaster>. You can use terra::project instead, either by providing a character representation of a coordinate reference system (see below), or (much better) by providing a raster template (see ?terra::project).

library(terra)
r <- rast(system.file("ex/elev.tif", package="terra"))
pr <- project(r, "EPSG:2169", res=100)

And for a SpatVector

v <- vect(system.file("ex/lux.shp", package="terra"))
pv <- project(v, crs(pr))

plot(pr); lines(pv)

But if your goal is to change the resolution (as opposed to the coordinate reference system) project is not the appropriate method, and you should use disaggregate or resample instead. For example:

rr <- disagg(r, 2)  

When asking questions, try to use a minimal, self-contained, example, as I show above; without loading unnecessary packages (never use library(tidyverse) to avoid asking us to install many packages, none of them relevant to the question at hand). Here is a reduced form of your example

library(terra)
library(geodata)
w <- geodata::world(path=".")
h <- rast(res=1) |> init("col") |> mask(w)
crs <- " proj=longlat  x_0=0  y_0=0  lat_0=0  lon_0=180"
test <- project(h, crs, res=0.5, method="bilinear")

I do not know why, but the projection is not working properly (nothing changes). The below does shift the location of the cropped area, but the values are gone.

hcrop <- crop(h, ext(90,150,-20,40)) 
test2 <- project(hcrop, crs, res=0.5, method="bilinear")
#class       : SpatRaster 
#dimensions  : 120, 120, 1  (nrow, ncol, nlyr)
#resolution  : 0.5, 0.5  (x, y)
#extent      : -90, -30, -20, 40  (xmin, xmax, ymin, ymax)
#coord. ref. :  proj=longlat  x_0=0  y_0=0  lat_0=0  lon_0=180 
#source      : memory 
#name        : lyr.1 
#min value   :   NaN 
#max value   :   NaN 

The good news is that it seems that a better way to achieve what you are after goes like this:

x <- rotate(h, FALSE)

And you can change the resolution with:

y <- disagg(x, 2, method="bilinear")
plot(y)
  • Related