Site icon R-bloggers

Automatically center a projection on the plotted map

[This article was first published on modTools, and kindly contributed to R-bloggers]. (You can report issue about the content on this page here)
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.

Following this previous post and this discussion on Mastodon, I wrote a function that wraps a combination of functions from the ‘terra’ package to project a SpatRaster or SpatVector layer while automatically centering the projection on that layer, to minimize visual distortion:

projectCentered <- function(x,  # SpatRaster or SpatVector                            proj = "laea"  # +proj parameter for PROJ.4 string                            ) {  # version 1.0, by A. Marcia Barbosa  stopifnot(inherits(x, "SpatRaster") || inherits(x, "SpatVector"))  if (terra::crs(x) == "" || is.na(terra::crs(x))) {    stop("'x' does not have a CRS to project")  }  if (inherits(x, "SpatRaster")) {    a <- terra::as.polygons(x * 0)  }  if (inherits(x, "SpatVector") && length(x) > 1) {    a <- terra::aggregate(x)  } else {    a <- x  }  if (!isTRUE(terra::is.lonlat(a))) {    a <- terra::project(a, "EPSG:4326")  }  centr <- terra::crds(terra::centroids(a))  proj <- tolower(proj)  proj <- sub("+proj=", "", proj, fixed = TRUE)  # in case user input prefix  CRS <- paste(    paste0("+proj=", proj),    paste0("+lat_0=", centr[2]),    paste0("+lon_0=", centr[1])  )  tryCatch(terra::project(x, CRS),           error = function(e)             stop("'proj' is invalid"))}

Here is a use case (compared with the default behaviour), using e.g. Lambert Azimuthal Equal-Area projection:

library(terra)library(geodata)countries <- geodata::world(path = tempdir())map <- subset(countries, countries$NAME_0 %in% c("New Zealand", "Australia"))par(mfrow = c(1, 3))plot(map, main = "Unprojected")plot(project(map, "+proj=laea"), main = "Projected, default-centered")plot(projectCentered(map, "laea"), main = "Projected, map-centered")

This is meant to be used for visualization purposes. For computing e.g. areas or distances, it is better to use unprojected layers, with longitude-latitude coordinates in degrees (making sure that spherical geometry or geodesic algorithms are being used), so that the Earth’s curvature is taken into account.

Note that I just plotted the bare minimum to illustrate what the ‘projectCentered’ function does. Maps can be made to look much nicer — even with just terra + base R plots, with no added package dependencies!

To leave a comment for the author, please follow the link and comment on their blog: modTools.

R-bloggers.com offers daily e-mail updates about R news and tutorials about learning R and many other topics. Click here if you're looking to post or find an R/data-science job.
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.
Exit mobile version