Skip to main content

oxigdal_algorithms/raster/terrain/
mod.rs

1//! Advanced terrain analysis algorithms
2//!
3//! This module provides comprehensive terrain analysis metrics beyond basic
4//! slope and aspect calculations. These metrics are essential for geomorphology,
5//! hydrology, and landscape ecology studies.
6//!
7//! # Terrain Metrics
8//!
9//! ## Topographic Position Index (TPI)
10//!
11//! TPI compares the elevation of a point to the mean elevation of its neighborhood.
12//! Positive values indicate ridges/peaks, negative values indicate valleys, and
13//! values near zero indicate flat areas or mid-slope positions.
14//! Supports both rectangular and annular (ring) neighborhoods.
15//!
16//! ## Terrain Ruggedness Index (TRI)
17//!
18//! TRI quantifies topographic heterogeneity by calculating the difference between
19//! a center cell and its neighbors. Supports both Riley et al. (1999) method
20//! (square root of sum of squared differences) and the simple mean absolute
21//! difference method.
22//!
23//! ## Surface Roughness
24//!
25//! Roughness measures the variability in elevation within a neighborhood, using
26//! either standard deviation or range (max - min) methods.
27//!
28//! ## Curvature
29//!
30//! Curvature describes the shape of the terrain surface:
31//! - **Profile curvature**: Rate of change of slope (affects flow acceleration)
32//! - **Planform curvature**: Curvature perpendicular to slope (affects flow convergence)
33//! - **Total curvature**: Combined measure of surface curvature (Laplacian)
34//! - **Mean curvature**: Average of principal curvatures
35//! - **Gaussian curvature**: Product of principal curvatures
36//! - **Tangential curvature**: Curvature in direction perpendicular to slope
37//! - **Convergence index**: Measure of flow convergence/divergence
38//!
39//! ## Vector Ruggedness Measure (VRM)
40//!
41//! VRM calculates terrain ruggedness as the dispersion of normal vectors
42//! to the surface, providing a scale-independent measure of roughness.
43//!
44//! ## Terrain Classification
45//!
46//! Landform classification using TPI at multiple scales following Weiss (2001)
47//! and Jenness (2006) methodologies, classifying terrain into categories such
48//! as valley bottoms, ridges, plains, upper/lower slopes, etc.
49//!
50//! ## Topographic Wetness Index (TWI)
51//!
52//! TWI = ln(a / tan(beta)) where a is specific catchment area and beta is slope.
53//! Used in hydrological modeling to predict soil moisture distribution.
54//!
55//! ## Stream Power Index (SPI)
56//!
57//! SPI = a * tan(beta) where a is specific catchment area and beta is slope.
58//! Measures erosive power of flowing water.
59//!
60//! # References
61//!
62//! - Burrough, P.A. & McDonnell, R.A. (1998). Principles of GIS.
63//! - Riley, S.J. et al. (1999). A terrain ruggedness index.
64//! - Weiss, A. (2001). Topographic Position and Landforms Analysis.
65//! - Jenness, J. (2006). Topographic Position Index extension for ArcView.
66//! - Zevenbergen, L.W. & Thorne, C.R. (1987). Quantitative analysis of land surface topography.
67//! - Sappington, J.M. et al. (2007). Quantifying landscape ruggedness (VRM).
68
69use crate::error::{AlgorithmError, Result};
70use oxigdal_core::buffer::RasterBuffer;
71use oxigdal_core::types::RasterDataType;
72
73#[cfg(feature = "parallel")]
74use rayon::prelude::*;
75
76// ---------------------------------------------------------------------------
77// TRI method variants
78// ---------------------------------------------------------------------------
79
80/// Method for computing Terrain Ruggedness Index
81#[derive(Debug, Clone, Copy, PartialEq, Eq)]
82pub enum TriMethod {
83    /// Riley et al. (1999): sqrt(sum of squared differences)
84    Riley,
85    /// Simple mean absolute difference
86    MeanAbsoluteDifference,
87    /// Wilson et al. (2007): root mean square difference
88    RootMeanSquare,
89}
90
91// ---------------------------------------------------------------------------
92// Roughness method variants
93// ---------------------------------------------------------------------------
94
95/// Method for computing surface roughness
96#[derive(Debug, Clone, Copy, PartialEq, Eq)]
97pub enum RoughnessMethod {
98    /// Standard deviation of elevations
99    StandardDeviation,
100    /// Range (max - min) of elevations
101    Range,
102    /// Coefficient of variation (stddev / mean)
103    CoefficientOfVariation,
104}
105
106// ---------------------------------------------------------------------------
107// Curvature types
108// ---------------------------------------------------------------------------
109
110/// Curvature types
111#[derive(Debug, Clone, Copy, PartialEq, Eq)]
112pub enum CurvatureType {
113    /// Profile curvature (in direction of slope)
114    Profile,
115    /// Planform curvature (perpendicular to slope)
116    Planform,
117    /// Total curvature (Laplacian)
118    Total,
119    /// Mean curvature
120    Mean,
121    /// Gaussian curvature
122    Gaussian,
123    /// Tangential curvature (perpendicular to slope direction on surface)
124    Tangential,
125}
126
127// ---------------------------------------------------------------------------
128// Landform classification
129// ---------------------------------------------------------------------------
130
131/// Landform classes following Weiss (2001) TPI-based classification
132#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
133#[repr(u8)]
134pub enum LandformClass {
135    /// Deep valley / canyon
136    Valley = 1,
137    /// Lower slope / footslope
138    LowerSlope = 2,
139    /// Flat area / plain
140    Flat = 3,
141    /// Middle slope
142    MiddleSlope = 4,
143    /// Upper slope / shoulder
144    UpperSlope = 5,
145    /// Ridge / hilltop
146    Ridge = 6,
147}
148
149impl LandformClass {
150    /// Returns a human-readable name for the landform class
151    #[must_use]
152    pub fn name(self) -> &'static str {
153        match self {
154            Self::Valley => "Valley",
155            Self::LowerSlope => "Lower Slope",
156            Self::Flat => "Flat",
157            Self::MiddleSlope => "Middle Slope",
158            Self::UpperSlope => "Upper Slope",
159            Self::Ridge => "Ridge",
160        }
161    }
162}
163
164// ---------------------------------------------------------------------------
165// TPI Neighborhood configuration
166// ---------------------------------------------------------------------------
167
168/// Neighborhood shape for TPI computation
169#[derive(Debug, Clone, Copy)]
170pub enum TpiNeighborhood {
171    /// Rectangular neighborhood with given odd size
172    Rectangular(usize),
173    /// Annular (ring) neighborhood with inner and outer radii (in cells)
174    Annular {
175        /// Inner radius (cells excluded closer than this)
176        inner_radius: f64,
177        /// Outer radius (cells beyond this are excluded)
178        outer_radius: f64,
179    },
180}
181
182// ===========================================================================
183// TPI
184// ===========================================================================
185
186mod curvature;
187mod landform;
188mod roughness;
189/// Computes Topographic Position Index (TPI) with configurable neighborhood
190///
191/// TPI = elevation - mean(neighborhood elevation)
192///
193/// Supports rectangular and annular (ring) neighborhoods.
194/// Annular neighborhoods are particularly useful for multi-scale analysis
195/// (Weiss, 2001; Jenness, 2006).
196///
197/// # Arguments
198///
199/// * `dem` - Digital elevation model
200/// * `neighborhood_size` - Size of neighborhood (must be odd)
201/// * `cell_size` - Size of each cell (for scaling)
202///
203/// # Errors
204///
205/// Returns an error if the operation fails
206// Submodules
207mod slope_aspect;
208
209// Re-exports
210pub use curvature::compute_curvature;
211pub use landform::{
212    classify_landforms, classify_landforms_multiscale, compute_spi, compute_terrain_shape_index,
213    compute_twi,
214};
215pub use roughness::{
216    compute_convergence_index, compute_roughness, compute_roughness_advanced, compute_tpi,
217    compute_tpi_advanced, compute_tri, compute_tri_advanced, compute_vrm,
218};
219pub use slope_aspect::{compute_aspect_degrees, compute_slope_degrees};
220
221#[cfg(test)]
222mod tests;