This function calculates the least-cost distances from a point to all (or some) of the cells in a surrounding raster
object, returning a raster
. This is the least-cost distance equivalent of distanceFromPoints
.
lcp_from_point(
origin,
surface,
destination = NULL,
cost = NULL,
graph = NULL,
use_all_cores = FALSE,
verbose = TRUE
)
A matrix which defines the coordinates (x, y) of the point from which to calculate least-cost distances. Unlike distanceFromPoints
, only a single point is expected.
A raster
across which to implement least-cost distance calculations. If the cost
matrix is derived from lcp_costs
(see below), there are some constraints on the form of this surface
; namely, equal resolution in x and y directions and a Universal Transverse Mercator coordinate reference system with units of metres. The surface
defines the properties of the returned raster
(see Value).
(optional) An matrix of destination coordinates; an integer vector of cell IDs; or function that defines a subset of destination cells, given their surface
value, for which to implement calculations. For example destination = function(x) x > 0
would restrict least-cost distance calculations to cells of the surface
that have a value of more than zero. Other cells are set to NA. This can improve computational efficiency.
(optional) A sparse dsCMatrix-class
matrix that defines the cost of movement between connected cells (see lcp_costs
). If unsupplied, if the graph
is also unsupplied (see below), a matrix of distances from lcp_costs
is computed internally and taken to define the cost surface. For this to be appropriate, the surface
should have a Universal Transverse Mercator projection, with equal resolution in the x and y directions and units of metres (see surface
, above). If a graph
is supplied, cost
is unnecessary.
(optional) A graph object that defines cell nodes and edge costs for connected cells within the surface
(see lcp_graph_surface
). If supplied, the calculation of the cost surface and the construction of the graph stages in the computation of least-cost distances are skipped (see Details), which is desirable in iterative applications.
A logical input that defines whether or not to parallelise least-cost distance calculations across all cores. This is passed to get_distance_matrix
which implements calculations.
A logical input that defines whether or not to print messages to the console to relay function progress.
The function returns a raster
in which each cell represents the least-cost distance from a specified origin
to that cell. The origin
is assigned a value of zero. Any cells excluded by the destination
filter have a value of NA.
This function implements routines provided via flapper
and the cppRouting
package to calculate least-cost distances. The main steps are:
The calculation of distances between adjacent cells (i.e., cost
, if not supplied, via lcp_costs
);
The construction of a graph that defines cell connections from the origin
to surrounding cells on the surface
as a network (via makegraph
);
The calculation of shortest distances between the origin
and surrounding cells from the graph (via get_distance_matrix
);
The expression of shortest distances as a raster
which is returned.
This function is similar to distanceFromPoints
, which returns a Raster* of Euclidean distances. For iterative applications across the same surface, lcp_costs
and lcp_graph_surface
can be implemented to define the cost matrix and the graph object outside of this function. These can be passed to lcp_from_point
, skipping the need to recompute these objects. For shortest-distances and/or paths between specific origin and destination coordinates, the lcp_over_surface
can be used. The particle filtering movement algorithms in flapper
(i.e., pf
) can implement this approach to ensure that movement paths are biologically realistic.
#### Step (1): Define example origin
proj <- sp::CRS(SRS_string = "EPSG:4326")
proj_utm <- sp::CRS(SRS_string = "EPSG:32629")
origin <- matrix(c(-5.616, 56.388), ncol = 2)
origin <- sp::SpatialPoints(origin, proj)
origin <- sp::spTransform(origin, proj_utm)
#### Step (2): Select and process surface
# We will focus on an area within the dat_gebco bathymetry raster
boundaries <- raster::extent(707884.6, 709884.6, 6253404, 6255404)
blank <- raster::raster(boundaries, res = c(5, 5))
r <- raster::resample(dat_gebco, blank)
#> Warning: aggregation factor is larger than the number of columns
#> Warning: aggregation factor is larger than the number of rows
#> Error in .intersectExtent(x, y, validate = TRUE): Objects do not intersect
#### Example (1): Implement function using default options
lcp_dist <- lcp_from_point(origin = origin, surface = r)
#> flapper::lcp_from_point() called (@ 2023-08-29 15:43:56)...
#> Error in h(simpleError(msg, call)): error in evaluating the argument 'x' in selecting a method for function 'ncell': object 'r' not found
## Visualise outputs
pp <- par(mfrow = c(2, 2))
# Plot surface
raster::plot(r)
#> Error in h(simpleError(msg, call)): error in evaluating the argument 'x' in selecting a method for function 'plot': object 'r' not found
# Examine Euclidean distances from point
raster::plot(raster::distanceFromPoints(r, origin))
#> Error in h(simpleError(msg, call)): error in evaluating the argument 'x' in selecting a method for function 'plot': error in evaluating the argument 'x' in selecting a method for function 'couldBeLonLat': object 'r' not found
# Compare to shortest distances
raster::plot(lcp_dist)
#> Error in h(simpleError(msg, call)): error in evaluating the argument 'x' in selecting a method for function 'plot': object 'lcp_dist' not found
par(pp)
if (flapper_run_slow) {
#### Example (2): Implement function across specific destinations
## Supply destination cell coordinates/IDs directly
# E.g., consider distances to cells shallower than 125 m
destination_cells <- raster::Which(r < 125, cells = TRUE, na.rm = TRUE)
lcp_dist <- lcp_from_point(
origin = origin,
surface = r,
destination = destination_cells
)
raster::plot(lcp_dist)
## Use a function instead to consider distances to cells shallower than 125 m
filter_destination_cells <- function(x) x < 125
lcp_dist <- lcp_from_point(
origin = origin,
surface = r,
destination = filter_destination_cells
)
raster::plot(lcp_dist)
#### Example (3): Define cost surfaces for LCP calculations outside of function
# This can be implemented internally, but we compute it here via lcp_costs().
# Note this imposes restrictions on the nature of the surface, such as equal
# ... resolution, which we have forced above.
costs <- lcp_costs(r)
cost <- costs$dist_total
lcp_dist <- lcp_from_point(
origin = origin,
surface = r,
destination = filter_destination_cells,
cost = cost
)
#### Example (4): Supply a graph object
graph <- lcp_graph_surface(surface = r, cost = cost)
lcp_dist <- lcp_from_point(origin = origin, surface = r, graph = graph)
#### Example (5): Implement algorithm in parallel via use_all_cores
lcp_dist <- lcp_from_point(origin = origin, surface = r, use_all_cores = TRUE)
}
#> Error in h(simpleError(msg, call)): error in evaluating the argument 'x' in selecting a method for function 'Which': object 'r' not found