mc_surface() builds, once, everything that any subsequent analysis needs:
the directed graph of movement costs between adjacent DTM cells, derived from a
user-selected cost function. The returned object is then fed to
mc_accum, mc_paths, mc_corridor,
mc_boundary, mc_alloc, mc_network,
and mc_rank, none of which recomputes the graph.
mc_surface(
dtm = NULL,
funct = "t",
move = 16,
studyplot = NULL,
z = 9,
barrier = NULL,
field = 0,
cogn.slp = FALSE,
topo.dist = FALSE,
N = 1,
sl.crit = 10,
W = 70,
L = 0,
V = 1.2
)An object of class movecost_surface: a list with components
dtm: the input DTM (SpatRaster);
graph: the directed igraph cost graph (one vertex per cell);
cost.raster: SpatRaster storing, for each cell, the
mean value of the cost function over the edges leaving the cell (walking
speed in km/h for speed-based functions, conductance otherwise) - the
analogue of the cost.surface component of movecost <= 2.x;
funct, params, move: metadata describing how
the graph was built (used by downstream functions and plot methods).
The object has print() and plot() methods; plot()
returns a ggplot2 object (see plot.movecost_surface).
Saving to disk: because SpatRaster objects hold external pointers,
use mc_save and mc_load (not bare
saveRDS()) to store movecost objects across sessions.
Digital Terrain Model: a terra SpatRaster, a legacy
RasterLayer, or a file path readable by terra::rast(). If
NULL, elevation data are downloaded for the area defined by
studyplot via mc_dtm (requires the elevatr
package).
character: code of the cost function to be used (default
"t", Tobler's on-path hiking function). Run
mc_cost_functions() for the complete annotated list.
number of directions in which cells are connected: 4 (rook's case), 8 (queen's case), or 16 (knight and one-cell queen moves; default).
polygon (sf, SpatVector, or sp) defining the area for which
online elevation data are downloaded when dtm is NULL.
zoom level (resolution) of the downloaded elevation data (0-15;
default 9); only used when dtm is NULL. See mc_dtm.
lines or polygons (sf, SpatVector, or sp) representing areas where movement is inhibited (see Details).
conductance multiplier applied to edges touching the barrier (0 by default, i.e. movement inhibited).
TRUE or FALSE (default): use the 'cognitive slope' in place of the real slope (see Details).
TRUE or FALSE (default): correct costs for topographic (surface) distance rather than planar distance (see Details).
terrain factor representing ease of movement (1 by default; see
mc_cost_functions for reference values).
critical slope in percent (default 10), used only by the wheeled-vehicle cost function.
walker's body weight in kg (default 70), used by the Pandolf and Van Leusen functions.
carried load in kg (default 0), used by the Pandolf and Van Leusen functions.
walking speed in m/s (default 1.2), used by the Pandolf, Van Leusen, and Ardigo functions; if 0, speed is derived cell-by-cell from the Tobler on-path function.
Why this design: in movecost <= 2.x every analysis function rebuilt
the conductance matrix from scratch at each call (a network between n sites
implied n or more redundant constructions). Building the graph once and
reusing it makes multi-analysis workflows and large location sets dramatically
faster, and makes the package's internal structure modular: one function, one
responsibility.
Cost model: for each pair of adjacent cells (4, 8, or 16 neighbours,
set via move), the terrain slope is computed as rise over run between
cell centres, signed in the direction of travel (positive uphill, negative
downhill), so movement costs are anisotropic. The user-selected cost function
(see mc_cost_functions for all 26 implemented functions, their
formulas, units, and references) maps the slope to either a walking speed or
the reciprocal of a per-metre cost; the edge cost is then the distance between
cell centres divided by speed (yielding seconds) or multiplied by the
per-metre cost. Accumulated costs and least-cost paths are obtained with
Dijkstra's algorithm via the igraph library.
Cognitive slope: if cogn.slp = TRUE, positive slopes are
multiplied by 1.99 and negative slopes by 2.31 before the cost function is
applied, following Pingel T.J. (2013), Modeling Slope as a Contributor to
Route Selection in Mountainous Areas, Cartography and Geographic Information
Science, 37(2), 137-148.
Topographic (surface) distance: if topo.dist = TRUE, costs are
corrected by the factor \(sqrt(1 + slope^2)\), accounting for the actual
distance travelled over sloped terrain rather than its planar projection.
The correction is clearly appropriate for time-based functions; for metabolic
functions, which were empirically derived against planar distance, it should
be used with caution. In gently undulating landscapes the difference is
negligible; it matters in rugged terrain with slopes beyond 20-30 percent.
Barriers: areas where movement is inhibited can be supplied via
barrier (any sf, SpatVector, or legacy sp lines/polygons object).
Edges incident to cells touched by the barrier have their conductance
multiplied by field: 0 (default) makes the barrier impassable, while
intermediate values (e.g. 0.01) penalise but do not forbid crossing. Note
that with move = 16, knight-move connections can "jump" a thin linear
barrier, exactly as in movecost <= 2.x; use move = 8 if that must not
happen.
Irregular DTMs: cells with NoData (for instance, sea around a
coastline) are simply excluded from the graph, so accumulated costs and
least-cost paths can never traverse them. The irregular.dtm workaround
of movecost <= 2.x is therefore no longer needed and has no equivalent here.
Coordinate system: the DTM must use a projected coordinate system with planar units in metres; geographic (lon/lat) rasters are rejected with an informative error.
Alberti (2019) <doi:10.1016/j.softx.2019.100331>.
mc_cost_functions, mc_accum,
mc_paths, mc_corridor, mc_boundary,
mc_alloc, mc_network, mc_rank,
mc_dtm, mc_save;
visualisation: plot.movecost_surface
# load the package sample DTM (Maungawhau volcano) and locations
dtm <- mc_volc()
start <- mc_volc_loc()
destin <- mc_destin_loc()
# build the cost surface once (Tobler's on-path function, 8 directions)
surf <- mc_surface(dtm, funct = "t", move = 8)
# ...and reuse it across analyses without recomputation:
acc <- mc_accum(surf, origin = start, breaks = 0.05)
lcp <- mc_paths(surf, origin = start, destin = destin)
# visualise on demand (no re-running of any computation):
plot(acc)
plot(lcp)
Run the code above in your browser using DataLab