Reduce a SpatVoxel to the SpatEnvelope that bounds it. A
predicate fun is applied to the cell values at each depth; for every cell,
the shallowest depth at which the predicate is TRUE becomes depth_min
and the deepest becomes depth_max. Cells where the predicate is never
TRUE are NA in both layers.
Usage
voxel_to_envelope(v, fun = function(x) !is.na(x))Value
A SpatEnvelope with layers depth_min and depth_max, on
the same grid as v.
Details
The default predicate, \(x) !is.na(x), gives the plain vertical extent of
the data: the shallowest and deepest depths at which the cell has any value.
Pass a different predicate to bound a subset of the values instead, e.g.
\(x) x > 15 for the depths over which a cell exceeds 15 degrees.
This conversion is lossy. An envelope stores a single continuous
interval per cell, so any interior gap in the voxel is filled in: a cell that
satisfies fun at 0 m and 200 m but not at 100 m still yields the envelope
[0, 200]. Use SpatVoxel directly where interior gaps matter.
See also
envelope_to_voxel(), the reverse expansion.
Examples
# Two cells sampled at four standard depths.
r <- terra::rast(nrows = 1, ncols = 2, xmin = 0, xmax = 2, ymin = 0, ymax = 1,
nlyrs = 4)
terra::values(r) <- cbind(c(12, NA), c(11, NA), c(NA, 8), c(6, NA))
v <- as_voxel(r, depths = c(0, 50, 100, 200), varname = "temp")
# Default predicate: the vertical extent of the data. Cell 1 has values at
# 0, 50 and 200 m, so it comes back as [0, 200] — the gap at 100 m is filled,
# because an envelope stores one continuous interval per cell.
terra::values(voxel_to_envelope(v))
#> depth_min depth_max
#> [1,] 0 200
#> [2,] 100 100
# Another predicate bounds a subset of the values instead: here the depths
# over which a cell is warmer than 10 degrees. Cell 2 never qualifies, so it
# is NA in both layers.
terra::values(voxel_to_envelope(v, fun = function(x) x > 10))
#> depth_min depth_max
#> [1,] 0 50
#> [2,] NA NA