The method for GIS objects (terra Spat* & sf classes) will
crop, reproject, and mask, in that order.
This is a wrapper for cropTo(), fixErrorsIn(),
projectTo(), maskTo() and writeTo(),
with a required amount of data manipulation between these calls so that the crs match.
postProcess(x, ...)
# S3 method for class 'list'
postProcess(x, ...)
# Default S3 method
postProcess(x, ...)A GIS object of postProcessing,
e.g., Spat* or sf*. This can be provided as a
rlang::quosure or a normal R object.
Additional arguments passed to methods. For spatialClasses,
these are: cropTo(), fixErrorsIn(),
projectTo(), maskTo(),
determineFilename(), and writeTo().
Each of these may also pass ... into other functions, like
writeTo().
This might include potentially important arguments like datatype,
format. Also passed to terra::project,
with likely important arguments such as method = "bilinear".
See details.
A GIS file (e.g., RasterLayer, SpatRaster etc.) that has been
appropriately cropped, reprojected, masked, depending on the inputs.
If the rasterToMatch or studyArea are passed, then
the following sequence will occur:
Fix errors fixErrorsIn(). Currently only errors fixed are for
SpatialPolygons using buffer(..., width = 0).
Crop using cropTo()
Project using projectTo()
Mask using maskTo()
Determine file name determineFilename()
Write that file name to disk, optionally writeTo()
NOTE: checksumming does not occur during the post-processing stage, as
there are no file downloads. To achieve fast results, wrap
prepInputs with Cache
rasterToMatch and/or studyArea argumentsFor backwards compatibility, postProcess will continue to allow passing
rasterToMatch and/or studyArea arguments. Depending on which of these
are passed, different things will happen to the targetFile located at filename1.
See Use cases section in postProcessTo() for post processing behaviour with
the new from and to arguments.
targetFile is a raster (Raster*, or SpatRaster) object:rasterToMatch | studyArea | Both | |
extent | Yes | Yes | rasterToMatch |
resolution | Yes | No | rasterToMatch |
projection | Yes | No* | rasterToMatch* |
alignment | Yes | No | rasterToMatch |
mask | No** | Yes | studyArea** |
*Can be overridden with useSAcrs.
**Will mask with NAs from rasterToMatch if maskWithRTM.
prepInputs
if (requireNamespace("terra", quietly = TRUE) &&
requireNamespace("withr", quietly = TRUE)) {
library(reproducible)
withr::local_dir(withr::local_tempdir())
withr::local_options(reproducible.inputPaths = NULL)
# od <- setwd(tempdir2())
# download a (spatial) file from remote url (which often is an archive) load into R
# need 3 files for this example; 1 from remote, 2 local
dPath <- file.path(tempdir2())
# the `CRAN` tag tracks terra's current CRAN release; `master` moves and is flakier
remoteTifUrl <- "https://github.com/rspatial/terra/raw/CRAN/inst/ex/elev.tif"
localFileLuxSm <- system.file("ex/luxSmall/luxSmall.shp", package = "reproducible")
localFileLux <- system.file("ex/lux.shp", package = "terra")
# 1 step for each layer
# 1st step -- get study area
studyArea <- prepInputs(localFileLuxSm, fun = "terra::vect") # default is sf::st_read
# Requires internet -- gated on NOT_CRAN so CRAN's machines are never asked to
# reach a third-party server, and wrapped in try() for when the server is down
if (identical(Sys.getenv("NOT_CRAN"), "true")) {
# 2nd step: make the input data layer like the studyArea map
elevForStudy <- try(prepInputs(url = remoteTifUrl, to = studyArea, res = 250,
destinationPath = dPath, useCache = FALSE))
}
## The single call above is equivalent to all the steps below, which must be known and
## repeated for every layer. Left commented out: it is an explanation, not a test.
##
## dir.create(dPath, recursive = TRUE, showWarnings = FALSE)
## file.copy(localFileLuxSm, file.path(dPath, basename(localFileLuxSm)))
## studyArea2 <- terra::vect(localFileLuxSm)
## if (!all(terra::is.valid(studyArea2))) studyArea2 <- terra::makeValid(studyArea2)
## tf <- tempfile(fileext = ".tif")
## download.file(url = remoteTifUrl, destfile = tf, mode = "wb", quiet = TRUE)
## Checksums(dPath, write = TRUE, files = tf)
## elevOrig <- terra::rast(tf)
## studyAreaCrs <- terra::crs(studyArea)
## # Build an explicit target raster (same CRS as studyArea, res = 250) and project to
## # it. Avoids the recursive `terra::project(x, char_crs, res = N)` shorthand that
## # recent terra (~1.9) regressed with `[write] unknown option(s): xscale,yscale`.
## elevTarget <- terra::project(terra::rast(elevOrig), studyAreaCrs)
## elevTarget <- terra::rast(terra::ext(elevTarget),
## crs = terra::crs(elevTarget),
## resolution = 250)
## elevForStudy2 <- terra::project(elevOrig, elevTarget) |>
## terra::mask(studyArea2) |>
## terra::crop(studyArea2)
##
## isTRUE(all.equal(elevForStudy, elevForStudy2)) # TRUE!
# sf class
if (requireNamespace("sf", quietly = TRUE)) {
studyAreaSmall <- prepInputs(localFileLuxSm, fun = "sf::st_read")
studyAreas <- list()
studyAreas[["orig"]] <- prepInputs(localFileLux)
studyAreas[["reprojected"]] <- projectTo(studyAreas[["orig"]], studyAreaSmall)
studyAreas[["cropped"]] <- suppressWarnings(cropTo(studyAreas[["orig"]], studyAreaSmall))
studyAreas[["masked"]] <- suppressWarnings(maskTo(studyAreas[["orig"]], studyAreaSmall))
}
# SpatVector-- note: doesn't matter what class the "to" object is, only the "from"
studyAreas <- list()
studyAreaSmall <- prepInputs(localFileLuxSm)
studyAreas[["orig"]] <- prepInputs(localFileLux)
studyAreas[["reprojected"]] <- projectTo(studyAreas[["orig"]], studyAreaSmall)
studyAreas[["cropped"]] <- suppressWarnings(cropTo(studyAreas[["orig"]], studyAreaSmall))
studyAreas[["masked"]] <- suppressWarnings(maskTo(studyAreas[["orig"]], studyAreaSmall))
if (interactive()) {
par(mfrow = c(2,2));
out <- lapply(studyAreas, function(x) terra::plot(x))
}
withr::deferred_run()
# setwd(od)
}
#> Running prepInputs
#> Running `preProcess`
#> Preparing: /home/runner/work/_temp/Library/reproducible/ex/luxSmall/luxSmall.shp
#> Running `process` (i.e., loading file into R)
#> targetFile located at:
#> /home/runner/work/_temp/Library/reproducible/ex/luxSmall/luxSmall.shp
#> Loading object into R
#> Recording data-source URLs from prepInputs/preProcess. View with
#> prepInputsLog() or showCache(userTags = 'reproducible.url'); disable with
#> options(reproducible.urlLog = FALSE).
#> Running prepInputs
#>
|---------|---------|---------|---------|
=========================================
#> prepInputsCOG: windowed remote read complete (tiled GeoTiff); full postProcess
#> will follow
#> Running `postProcessTo`
#> cropping...
#> projecting...
#>
#> projectTo is a Vector dataset, which does not define all metadata required.
#> Using the origin and extent from `ext(from)` in the projection from
#> `crs(projectTo)`.
#> If this is not correct, create a template gridded object and pass that to
#> `projectTo`...
#>
#> done! took: 0.0889 secs
#> masking...
#> done! took: 0.0258 secs
#> cropping...
#> done! took: 0.0264 secs
#> postProcessTo done! took: 0.205 secs
#> Running prepInputs
#> Running `preProcess`
#> Preparing: /home/runner/work/_temp/Library/reproducible/ex/luxSmall/luxSmall.shp
#> Running `process` (i.e., loading file into R)
#> targetFile located at:
#> /home/runner/work/_temp/Library/reproducible/ex/luxSmall/luxSmall.shp
#> Loading object into R
#> Reading layer `luxSmall' from data source
#> `/home/runner/work/_temp/Library/reproducible/ex/luxSmall/luxSmall.shp'
#> using driver `ESRI Shapefile'
#> Simple feature collection with 4 features and 6 fields
#> Geometry type: POLYGON
#> Dimension: XY
#> Bounding box: xmin: 4522355 ymin: 11299040 xmax: 4575913 ymax: 11339850
#> Projected CRS: +proj=lcc +lat_0=0 +lon_0=-95 +lat_1=49 +lat_2=77 +x_0=0 +y_0=0 +ellps=GRS80 +units=m +no_defs
#> Saved! Cache file: 95ea45dd354daafe.rds; fn: sf::st_read
#> Running prepInputs
#> Running `preProcess`
#> Preparing: /home/runner/work/_temp/Library/terra/ex/lux.shp
#> Using sf::st_read on shapefile because sf package is available; to force old
#> behaviour with 'raster::shapefile' use fun = 'raster::shapefile' or
#> options('reproducible.shapefileRead' = 'raster::shapefile')
#> Running `process` (i.e., loading file into R)
#> targetFile located at:
#> /home/runner/work/_temp/Library/terra/ex/lux.shp
#> Loading object into R
#> Object to retrieve (fn: sf::st_read, d598abd965f6e371.rds) ...
#> Loaded! Cached result from previous sf::st_read call
#> projecting...
#> done! took: 0.0341 secs
#> cropping...
#> done! took: 0.0256 secs
#> masking...
#> done! took: 0.0394 secs
#> Running prepInputs
#> Running `preProcess`
#> Preparing: /home/runner/work/_temp/Library/reproducible/ex/luxSmall/luxSmall.shp
#> Using sf::st_read on shapefile because sf package is available; to force old
#> behaviour with 'raster::shapefile' use fun = 'raster::shapefile' or
#> options('reproducible.shapefileRead' = 'raster::shapefile')
#> Running `process` (i.e., loading file into R)
#> targetFile located at:
#> /home/runner/work/_temp/Library/reproducible/ex/luxSmall/luxSmall.shp
#> Loading object into R
#> Object to retrieve (fn: sf::st_read, 95ea45dd354daafe.rds) ...
#> Loaded! Cached result from previous sf::st_read call
#> Running prepInputs
#> Running `preProcess`
#> Preparing: /home/runner/work/_temp/Library/terra/ex/lux.shp
#> Using sf::st_read on shapefile because sf package is available; to force old
#> behaviour with 'raster::shapefile' use fun = 'raster::shapefile' or
#> options('reproducible.shapefileRead' = 'raster::shapefile')
#> Running `process` (i.e., loading file into R)
#> targetFile located at:
#> /home/runner/work/_temp/Library/terra/ex/lux.shp
#> Loading object into R
#> Object to retrieve (fn: sf::st_read, d598abd965f6e371.rds) ...
#> Loaded! Cached result from previous sf::st_read call
#> projecting...
#> done! took: 0.0337 secs
#> cropping...
#> done! took: 0.0253 secs
#> masking...
#> done! took: 0.0395 secs
#> Ran 3/3 deferred expressions