This is a generalized version of a notion of a viewshed. The main difference is that there can be many "viewpoints".
spokes(
landscape,
coords,
loci,
maxRadius = ncol(landscape)/4,
minRadius = maxRadius,
allowOverlap = TRUE,
stopRule = NULL,
includeBehavior = "includePixels",
returnDistances = FALSE,
angles = NA_real_,
nAngles = NA_real_,
returnAngles = FALSE,
returnIndices = TRUE,
...
)
Raster on which the circles are built.
Either a matrix with 2 (or 3) columns, x
and y
(and id
), representing the
coordinates (and an associated id, like cell index),
or a SpatialPoints*
object around which to make circles. Must be same
coordinate system as the landscape
argument. Default is missing,
meaning it uses the default to loci
.
Numeric. An alternative to coords
.
These are the indices on landscape
to initiate this function (see coords
).
Default is one point in centre of landscape
.
Numeric vector of length 1 or same length as coords
Numeric vector of length 1 or same length as coords
. Default is
maxRadius
, meaning return all cells that are touched
by the narrow ring at that exact radius. If smaller than maxRadius
,
then this will create a buffer or doughnut or ring.
Logical. Should duplicates across id be removed or kept. Default TRUE.
A function. If the spokes are to stop. This can be a function
of landscape
, fromCell
, toCell
, x
(distance from coords cell), or any other named argument passed
into the ...
of this function. See examples.
Character string. Currently accepts only "includePixels"
, the default,
and "excludePixels"
. See details.
Logical. If TRUE
, then a column will be added to the returned
data.table that reports the distance from coords
to every
point that was in the circle/doughnut surrounding coords
.
Default FALSE
, which is faster.
Numeric. Optional vector of angles, in radians, to use. This will create
"spokes" outward from coords.
Default is NA
, meaning, use internally
derived angles that will "fill" the circle.
Numeric, length one. Alternative to angles. If provided, the function
will create a sequence of angles from 0
to 2*pi
,
with a length nAngles
, and not including 2*pi
.
Will not be used if angles
is provided, and will show
warning of both are given.
Logical. If TRUE
, then a column will be added to the returned
data.table that reports the angle from coords
to every
point that was in the circle/doughnut surrounding coords
. Default FALSE.
Logical or numeric. If 1
or TRUE
, will return a data.table
with indices and values of successful spread events.
If 2
, it will simply return a vector of pixel indices of
all cells that were touched. This will be the fastest option.
If FALSE
, then it will return a raster with values.
See Details.
Objects to be used by stopRule()
. See examples.
A matrix containing columns id (representing the row numbers of coords
),
angles (from coords
to each point along the spokes), x and y coordinates
of each point along the spokes, the corresponding indices on the landscape
Raster, dists (the distances between each coords
and each point along the
spokes), and stop, indicating if it was a point that caused a spoke to stop
going outwards due to stopRule
.
library(data.table)
library(terra)
origDTThreads <- data.table::setDTthreads(2L)
origNcpus <- options(Ncpus = 2L)
set.seed(1234)
ras <- terra::rast(terra::ext(0, 10, 0, 10), res = 1, val = 0)
rp <- randomPolygons(ras, numTypes = 10)
if (interactive())
terra::plot(rp)
angles <- seq(0, pi * 2, length.out = 17)
angles <- angles[-length(angles)]
n <- 2
loci <- sample(terra::ncell(rp), n)
coords <- terra::vect(terra::xyFromCell(rp, loci))
stopRule <- function(landscape) landscape < 3
d2 <- spokes(rp, coords = coords, stopRule = stopRule,
minRadius = 0, maxRadius = 50,
returnAngles = TRUE, returnDistances = TRUE,
allowOverlap = TRUE, angles = angles, returnIndices = TRUE)
#> This function is very experimental and may not behave as expected
# Assign values to the "patches" that were in the viewshed of a ray
rasB <- terra::rast(ras)
rasB[] <- 0
rasB[d2[d2[, "stop"] == 1, "indices"]] <- 1
if (interactive()) {
rasB[rasB == 0] <- NA
terra::plot(rasB, add = TRUE, col = "red", legend = FALSE)
}
if (NROW(d2) > 0) {
sp1 <- terra::vect(d2[, c("x", "y")])
if (interactive())
terra::plot(sp1, add = TRUE, pch = 19)
}
if (interactive())
terra::plot(coords, add = TRUE, pch = 19, col = "blue")
# clean up
data.table::setDTthreads(origDTThreads)
options(Ncpus = origNcpus)