Skip to contents

This function computes any number of indices from an input raster via terra::predict(). By default, this function is designed to work with subsets of spectral_indices(), but it will work with any data frame with a formula, bands, and short_name column.

Usage

calculate_indices(
  raster,
  indices,
  output_filename,
  ...,
  cores = 1L,
  wopt = list(),
  overwrite = FALSE,
  extra_objects = list(),
  names_suffix = NULL
)

Arguments

raster

The raster (either as a SpatRaster or object readable by terra::rast()) to compute indices from.

indices

A data frame of indices to compute. The intent is for this function to work with subsets of spectral_indices, but any data frame with columns formula (containing a string representation of the equation used to calculate the index), bands (a list column containing character vectors of the necessary bands) and short_name (which will be used as the band name) will work.

output_filename

The filename to write the computed metrics to.

...

These dots are for future extensions and must be empty.

cores

positive integer. If cores > 1, a 'parallel' package cluster with that many cores is created and used

wopt

list with named options for writing files as in writeRaster

overwrite

logical. If TRUE, filename is overwritten

extra_objects

A named list of additional objects to pass to the minimal environment that formulas are executed in. For instance, if you need to use the pmax function in order to calculate an index, you can make it available in the environment by setting extra_objects = list("pmax" = pmax). Providing extra functionality is inherently less safe than the default minimal environment, and as such always emits a warning, which you can suppress with suppressWarnings().

names_suffix

If not NULL, will be used (with paste()) to add a suffix to each of the band names returned.

Value

output_filename, unchanged.

Security

Note that this function is running code from the formula column of the spectral indices data frame, which is derived from a JSON file downloaded off the internet. It's not impossible that an attacker could take advantage of this to run arbitrary code on your computer. To mitigate this, indices are calculated in a minimal environment that contains very few functions or symbols (preventing an attacker from accessing, for example, system()).

Still, it's good practice to inspect your formula column to make sure there's nothing nasty hiding in any of the formulas you're going to run. Additionally, consider using pre-saved indices tables or spectral_indices(download_indices = FALSE) if using this in an unsupervised workload.

Examples

our_raster <- system.file("rasters/example_sentinel1.tif", package = "rsi")
calculate_indices(
  our_raster,
  filter_bands(bands = names(terra::rast(our_raster))),
  tempfile(fileext = ".tif"),
  names_suffix = "sentinel1"
)
#> Warning: No cache file present and `download_indices` set to `FALSE`.
#>  Returning (likely outdated) package data instead.
#> [1] "/tmp/RtmpopigZF/file1a424ebfb334.tif"

# Formulas aren't able to access most R functions or operators,
# in order to try and keep formulas from doing something bad:
example_indices <- filter_platforms(platforms = "Sentinel-1 (Dual Polarisation VV-VH)")[1, ]
example_indices$formula <- 'system("echo something bad")'
# So this will error:
try(
  calculate_indices(
    system.file("rasters/example_sentinel1.tif", package = "rsi"),
    example_indices,
    tempfile(fileext = ".tif")
  )
)
#> Error in system("echo something bad") : could not find function "system"

# Because of this, formulas which try to use most R functions
# will wind up erroring as well:
example_indices$formula <- "pmax(VH, VV)"
try(
  calculate_indices(
    system.file("rasters/example_sentinel1.tif", package = "rsi"),
    example_indices,
    tempfile(fileext = ".tif")
  )
)
#> Error in pmax(VH, VV) : could not find function "pmax"

# To fix this, pass the objects you want to use to `extra_objects`
calculate_indices(
  system.file("rasters/example_sentinel1.tif", package = "rsi"),
  example_indices,
  tempfile(fileext = ".tif"),
  extra_objects = list(pmax = pmax)
) |>
  suppressWarnings(classes = "rsi_extra_objects")
#> [1] "/tmp/RtmpopigZF/file1a421f40d005.tif"