2

I've been plotting some global rasters lately using mainly raster and tmap. I'd like to plot the maps in Robinson projection instead of lat-lon. Simple projection to Robinson however duplicates some areas on the edges of the map as you can see from the figures below (Alaska, Siberia, NZ).

Previously, I found a workaround with PROJ.4 code parameter "+over" as outlined in here and here.

With the latest changes to rgdal using GDAL > 3 and PROJ >= 6, this workaround seems to be obsolete. Has anyone found a new way on how to plot global rasters in Robinson/Eckert IV/Mollweide without duplicated areas?

I'm running R 4.0.1, tmap 3.1, stars 0.4-3, raster 3.3-7, rgdal 1.5-12, sp 1.4-2, GDAL 3.1.1 and PROJ 6.3.1 on a macOS Catalina 10.15.4

require(stars)
require(raster)
require(tmap)
require(dplyr)

# data
worldclim_prec = getData(name = "worldclim", var = "prec", res = 10)
jan_prec <- worldclim_prec$prec1

# to Robinson and plot - projection outputs a warning
jp_rob <- jan_prec %>%
  projectRaster(crs = "+proj=robin +over")
tm_shape(jp_rob) + tm_raster(style = "fisher")
Warning messages:
1: In showSRID(uprojargs, format = "PROJ", multiline = "NO") :
  Discarded ellps WGS 84 in CRS definition: +proj=robin +over
2: In showSRID(uprojargs, format = "PROJ", multiline = "NO") :
  Discarded datum WGS_1984 in CRS definition

enter image description here

I tried to do the same with stars instead of raster but no resolution was found, supposedly since tmap uses stars since version 3.0.

# new grid for warping stars objects
newgrid <- st_as_stars(jan_prec) %>%
  st_transform("+proj=robin +over") %>%
  st_bbox() %>%
  st_as_stars()

# to stars object - projection outputs no warning
jp_rob_stars <- st_as_stars(jan_prec) %>%
  st_warp(newgrid)

tm_shape(jp_rob_stars) + tm_raster(style = "fisher")

Thanks for any insights - hoping someone else is thinking about this issue!

vdoe
  • 33
  • 4

1 Answers1

1

With raster you can do

library(raster)
prec <- getData(name = "worldclim", var = "prec", res = 10)[[1]]
crs <- "+proj=robin +lon_0=0 +x_0=0 +y_0=0 +datum=WGS84 +units=m"
rrob <- projectRaster(prec, crs=crs)

Create a mask

library(geosphere)
e <- as(extent(prec), "SpatialPolygons")
crs(e) <- crs(prec)
e <- makePoly(e)  # add additional vertices
re <- spTransform(e, crs)

And use it

mrob <- mask(rrob, re)

The new package terra has a mask argument for that (you need version >= 0.8.3 for this, available from github)

prec <- getData(name = "worldclim", var = "prec", res = 10)[[1]]
jp <- rast(prec$prec1) 
jp <- jp * 1 # to deal with NAs in this datasaet
rob <- project(jp, crs, mask=TRUE)
Robert Hijmans
  • 40,301
  • 4
  • 55
  • 63
  • Thanks Robert for your answer; much appreciated! Solution via masking works very well. Perhaps I should consider migrating to terra as well if it's going to replace raster at some point. – vdoe Jul 16 '20 at 05:46