Per-cell 3D volume overlap between two rasterized domains
Source:R/AllGenerics.R, R/volume.R
calc_volume_overlap.RdComputes the depth interval and volume of each domain and of their
intersection, cell by cell. The intersection is intersect_3d(); this
function measures it. Accepts any combination of SpatEnvelope and
SpatVoxel; when the two differ, the envelope is discretized onto
the voxel's depth levels with envelope_to_voxel() rather than the voxel
being collapsed, because voxel_to_envelope() fills interior gaps and
would overstate the overlap.
Usage
calc_volume_overlap(x, y, ...)
# S4 method for class 'SpatEnvelope,SpatEnvelope'
calc_volume_overlap(x, y, ...)
# S4 method for class 'SpatVoxel,SpatVoxel'
calc_volume_overlap(x, y, bounds = c("top", "midpoint"))
# S4 method for class 'SpatEnvelope,SpatVoxel'
calc_volume_overlap(x, y, bounds = c("top", "midpoint"), ...)
# S4 method for class 'SpatVoxel,SpatEnvelope'
calc_volume_overlap(x, y, bounds = c("top", "midpoint"), ...)
# S4 method for class 'SpatRaster,SpatRaster'
calc_volume_overlap(x, y, ...)Arguments
- x, y
The two domains, each a SpatEnvelope or SpatVoxel.
- ...
Arguments for the voxel methods, which are an error for a pair of envelopes.
- bounds
Voxel methods only. See
volume(). Also governs how an envelope is discretized when the two inputs differ.
Value
Multi-layer SpatRaster with 9 layers:
- depth_min_a, depth_max_a
Depth limits of
x(m)- depth_min_b, depth_max_b
Depth limits of
y(m)- depth_min_overlap, depth_max_overlap
Depth limits of the intersection (m). NA where the domains do not overlap in depth.
- volume_a, volume_b
Per-cell volume of each domain (km³)
- volume_overlap
Per-cell overlap volume (km³).
0where both are present but their depths do not intersect, NA where either is absent.
For voxel inputs the depth layers are summary bounds — the shallowest and deepest occupied level. A voxel with an interior gap is not solid between them, so read the volume layers, not the depth layers, for occupied volume. The result is a plain SpatRaster: it is neither an envelope nor a voxel.
Details
Two voxels must be sampled at the same depth levels, and all inputs must be
on the same grid. To ask only whether two domains overlap, use
intersects_3d(); it computes no volumes.
See also
intersect_3d() for the shared domain itself, and volume() for
its total volume; intersects_3d() when only the presence of overlap is
needed.
Examples
fp <- terra::rast(nrows = 1, ncols = 2, xmin = 0, xmax = 2000,
ymin = 0, ymax = 1000,
crs = "+proj=laea +lat_0=0 +lon_0=0 +datum=WGS84 +units=m")
terra::values(fp) <- c(1, 1)
a <- as_envelope(fp, depth_min = 0, depth_max = 100)
b <- as_envelope(fp, depth_min = 50, depth_max = 200)
ov <- calc_volume_overlap(a, b)
names(ov)
#> [1] "depth_min_a" "depth_max_a" "depth_min_b"
#> [4] "depth_max_b" "depth_min_overlap" "depth_max_overlap"
#> [7] "volume_a" "volume_b" "volume_overlap"
terra::global(ov[[c("volume_a", "volume_b", "volume_overlap")]], "sum",
na.rm = TRUE)
#> sum
#> volume_a 0.2
#> volume_b 0.3
#> volume_overlap 0.1
# Mixed input: the envelope is discretized onto the voxel's levels.
bv <- envelope_to_voxel(b, depths = c(0, 50, 100, 150, 200))
terra::global(calc_volume_overlap(a, bv)[["volume_overlap"]], "sum",
na.rm = TRUE)
#> sum
#> volume_overlap 0.1