#' Identify watershed basins and direction and accumulation of flow
#'
#' @description The `flow()` function uses a raster representing elevation to compute other rasters representing:
#' * Flow accumulation;
#' * Direction of flow;
#' * Watershed basins;
#' * Flooded areas; and/or
#' * Topographic convergence (log of flow accumulation divided by local slope).
#'
#' More details about the computations can be found at the help page for the **GRASS** module `r.terraflow`] (see `grassHelp("r.terraflow")`)
#'
#' @param x A `GRaster` with a single layer, typically representing elevation.
#'
#' @param direction Character: Either `"single"` or `"multi"`. This indicates whether a single-direction flow or multi-direction flow model is used. The default is `"multi"`. Partial matching is used and case is ignored.
#'
#' @param dirThreshold Numeric (default is `Inf`): For the multi-direction flow model, this indicates the amount of accumulated flow above which the single-direction flow rule is used to locate the egress of water from a cell. This is the `d8cut` parameter in `r.stream.extract`.
#'
#' @param return Character vector: Indicates what rasters to return. Partial matching is used and case is ignored. Options include:
#' * `"accumulation"` (default): Flow accumulation raster.
#' * `"basins"`: Watershed basins
#' * `"direction"`: Flow direction
#' * `"flooded"`: Flooded areas
#' * `"TCI"`: Topographic convergence index
#' * `"*"`: All of the above
#'
#' @seealso [flowPath()], [streams()], the **GRASS** module `r.terraflow` (see `grassHelp("r.terraflow")`)
#'
#' @param scratchDir Character or `NULL` (default): Directory in which to store temporary files. The **GRASS** module `r.terraflow` makes a lot of temporary files. If this is `NULL`, then a temporary folder in the user's working directory will be used (see [getwd()]).
#'
#' @returns A `GRaster`.
#'
#' @example man/examples/ex_flow.r
#'
#' @aliases flow
#' @rdname flow
#' @exportMethod flow
methods::setMethod(
f = "flow",
signature = c(x = "GRaster"),
function(
x,
direction = "multi",
return = "accumulation",
dirThreshold = Inf,
scratchDir = NULL
) {
if (nlyr(x) > 1L) stop("This function can only use a single-layered GRaster as input.")
returns <- c("accumulation", "basins", "direction", "flooded", "TCI")
if (any(return == "*")) return <- returns
return <- omnibus::pmatchSafe(return, returns)
return <- unique(return)
direction <- omnibus::pmatchSafe(direction, c("single", "multi"), nmax = 1L)
.locationRestore(x)
.region(x)
if (is.null(scratchDir)) {
scratchDir <- paste0(getwd(), "/flow_temporary_files")
omnibus::dirCreate(scratchDir)
on.exit(unlink(scratchDir, recursive = TRUE, force = TRUE))
}
args <- list(
cmd = "r.terraflow",
elevation = sources(x),
memory = faster("memory"),
directory = scratchDir,
flags = c(.quiet(), "overwrite")
)
if (direction == "single") args$flags <- c(args$flags, "s")
if (direction == "multi" & !is.infinite(dirThreshold)) args$d8cut <- dirThreshold
if (any(return == "accumulation")) args$accumulation <- .makeSourceName("r_flow_accumulation", "raster")
if (any(return == "direction")) args$direction <- .makeSourceName("r_flow_direction", "raster")
if (any(return == "basins")) args$swatershed <- .makeSourceName("r_flow_swatershed", "raster")
if (any(return == "flooded")) args$filled <- .makeSourceName("r_flow_filled", "raster")
if (any(return == "TCI")) args$tci <- .makeSourceName("r_flow_tci", "raster")
if (is.null(scratchDir)) {
scratchDir <- getwd()
scratchDir <- paste0(scratchDir, '/flow_temp_files')
omnibus::dirCreate(scratchDir)
on.exit(unlink(scratchDir, recursive = TRUE, force = TRUE, expand = TRUE), add = TRUE)
}
do.call(rgrass::execGRASS, args = args)
names <- srcs <- character()
if (any(return == "accumulation")) {
srcs <- args$accumulation
names <- "accumulation"
}
if (any(return == "direction")) {
srcs <- c(srcs, args$direction)
names <- c(names, "direction")
}
if (any(return == "basins")) {
srcs <- c(srcs, args$swatershed)
names <- c(names, "basins")
}
if (any(return == "flooded")) {
srcs <- c(srcs, args$filled)
names <- c(names, "flooded")
}
if (any(return == "TCI")) {
srcs <- c(srcs, args$tci)
names <- c(names, "TCI")
}
order <- match(return, names)
srcs <- srcs[order]
names <- names[order]
.makeGRaster(srcs, names)
} # EOF
)
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.