oxigdal_analytics/lib.rs
1//! OxiGDAL Analytics - Advanced Geospatial Analytics
2//!
3//! This crate provides advanced analytics capabilities for geospatial data processing,
4//! including time series analysis, spatial clustering, hotspot detection, change detection,
5//! interpolation, and advanced zonal statistics.
6//!
7//! # Features
8//!
9//! ## Time Series Analysis
10//!
11//! Analyze temporal patterns in geospatial data:
12//! - Trend detection (Mann-Kendall test, linear regression)
13//! - Anomaly detection (Z-score, IQR, Modified Z-score)
14//! - Seasonal decomposition
15//! - Gap filling and smoothing
16//!
17//! ```
18//! use oxigdal_analytics::timeseries::{TrendDetector, TrendMethod};
19//! use scirs2_core::ndarray::array;
20//!
21//! let values = array![1.0, 2.0, 3.0, 4.0, 5.0];
22//! let detector = TrendDetector::new(TrendMethod::MannKendall, 0.05);
23//! let result = detector.detect(&values.view()).expect("Failed to detect trend");
24//!
25//! assert_eq!(result.direction, 1); // Positive trend
26//! assert!(result.significant);
27//! ```
28//!
29//! ## Spatial Clustering
30//!
31//! Identify clusters and outliers in spatial data:
32//! - K-means clustering for image classification
33//! - DBSCAN for spatial outlier detection
34//! - Cluster validation metrics
35//!
36//! ```
37//! use oxigdal_analytics::clustering::{KMeansClusterer, DbscanClusterer};
38//! use scirs2_core::ndarray::array;
39//!
40//! let data = array![
41//! [0.0, 0.0],
42//! [0.1, 0.1],
43//! [10.0, 10.0],
44//! [10.1, 10.1],
45//! ];
46//!
47//! // K-means clustering
48//! let kmeans = KMeansClusterer::new(2, 100, 1e-4);
49//! let result = kmeans.fit(&data.view()).expect("Failed to fit K-means clustering");
50//! assert_eq!(result.centers.nrows(), 2);
51//! ```
52//!
53//! ## Hotspot Analysis
54//!
55//! Detect spatial clusters of high or low values:
56//! - Getis-Ord Gi* statistic (hot spot analysis)
57//! - Moran's I (global and local spatial autocorrelation)
58//! - LISA (Local Indicators of Spatial Association)
59//!
60//! ```
61//! use oxigdal_analytics::hotspot::{GetisOrdGiStar, SpatialWeights};
62//! use scirs2_core::ndarray::array;
63//!
64//! let values = array![1.0, 1.0, 10.0, 10.0];
65//! let adj = array![
66//! [1.0, 1.0, 0.0, 0.0],
67//! [1.0, 1.0, 1.0, 0.0],
68//! [0.0, 1.0, 1.0, 1.0],
69//! [0.0, 0.0, 1.0, 1.0],
70//! ];
71//!
72//! let weights = SpatialWeights::from_adjacency(adj).expect("Failed to create spatial weights from adjacency matrix");
73//! let gi_star = GetisOrdGiStar::new(0.05);
74//! let result = gi_star.calculate(&values.view(), &weights).expect("Failed to calculate Getis-Ord Gi* statistic");
75//! ```
76//!
77//! ## Change Detection
78//!
79//! Detect changes between multi-temporal images:
80//! - Image differencing
81//! - Change Vector Analysis (CVA)
82//! - Principal Component Analysis (PCA)
83//! - Automatic threshold optimization (Otsu's method)
84//!
85//! ```
86//! use oxigdal_analytics::change::{ChangeDetector, ChangeMethod};
87//! use scirs2_core::ndarray::Array;
88//!
89//! let before = Array::from_shape_vec((2, 2, 1), vec![1.0, 2.0, 3.0, 4.0]).expect("Failed to create before array");
90//! let after = Array::from_shape_vec((2, 2, 1), vec![2.0, 3.0, 4.0, 5.0]).expect("Failed to create after array");
91//!
92//! let detector = ChangeDetector::new(ChangeMethod::CVA);
93//! let result = detector.detect(&before.view(), &after.view()).expect("Failed to detect changes");
94//!
95//! assert_eq!(result.magnitude.dim(), (2, 2));
96//! ```
97//!
98//! ## Interpolation
99//!
100//! Create continuous surfaces from point data:
101//! - Inverse Distance Weighting (IDW)
102//! - Kriging (Ordinary and Universal)
103//! - Variogram modeling
104//! - Cross-validation
105//!
106//! ```
107//! use oxigdal_analytics::interpolation::{IdwInterpolator, KrigingInterpolator, KrigingType, Variogram, VariogramModel};
108//! use scirs2_core::ndarray::array;
109//!
110//! let points = array![[0.0, 0.0], [1.0, 0.0], [0.0, 1.0]];
111//! let values = array![1.0, 2.0, 3.0];
112//! let targets = array![[0.5, 0.5]];
113//!
114//! // IDW interpolation
115//! let idw = IdwInterpolator::new(2.0);
116//! let result = idw.interpolate(&points, &values.view(), &targets).expect("Failed to perform IDW interpolation");
117//! ```
118//!
119//! ## Advanced Zonal Statistics
120//!
121//! Calculate statistics for regions:
122//! - Multiple statistics (mean, median, min, max, std, etc.)
123//! - Weighted statistics
124//! - Multi-band support
125//! - Custom aggregation functions
126//!
127//! ```
128//! use oxigdal_analytics::zonal::{ZonalCalculator, ZonalStatistic};
129//! use scirs2_core::ndarray::array;
130//!
131//! let values = array![[1.0, 2.0], [3.0, 4.0]];
132//! let zones = array![[1, 1], [1, 1]];
133//!
134//! let calculator = ZonalCalculator::new();
135//! let result = calculator.calculate(&values.view(), &zones.view()).expect("Failed to calculate zonal statistics");
136//!
137//! let zone1_stats = &result.zones[&1];
138//! assert!(zone1_stats.contains_key(&ZonalStatistic::Mean));
139//! ```
140//!
141//! # COOLJAPAN Policy Compliance
142//!
143//! This crate adheres to COOLJAPAN ecosystem policies:
144//!
145//! - **Pure Rust**: 100% Pure Rust implementation, no C/Fortran dependencies
146//! - **No unwrap()**: All error cases are properly handled with `Result<T, E>`
147//! - **SciRS2 Integration**: Uses `scirs2-core` for scientific computing instead of ndarray directly
148//! - **Comprehensive Error Handling**: Custom error types for all failure modes
149//! - **File Size Policy**: All source files are kept under 2000 lines
150//! - **Latest Crates**: Uses latest versions from crates.io
151//! - **Workspace Policy**: Follows workspace dependency management
152//!
153//! # Performance
154//!
155//! All algorithms are optimized for production use with:
156//! - Efficient memory usage
157//! - Vectorized operations where possible
158//! - Optional parallel processing (enable `parallel` feature)
159//! - Numerical stability checks
160//!
161//! # Safety
162//!
163//! This crate is designed with safety in mind:
164//! - No unsafe code (except what's in dependencies)
165//! - Comprehensive input validation
166//! - Proper handling of edge cases (empty data, singular matrices, etc.)
167//! - Clear error messages for debugging
168
169#![warn(clippy::all)]
170// Pedantic disabled to reduce noise - default clippy::all is sufficient
171// #![warn(clippy::pedantic)]
172#![deny(clippy::unwrap_used)]
173#![deny(clippy::panic)]
174#![allow(clippy::module_name_repetitions)]
175#![allow(clippy::cast_precision_loss)]
176#![allow(clippy::cast_possible_truncation)]
177#![allow(clippy::cast_sign_loss)]
178#![allow(clippy::similar_names)]
179#![allow(clippy::too_many_lines)] // Analytics functions can be complex
180// Allow partial documentation during development
181#![allow(missing_docs)]
182// Allow dead code for internal structures
183#![allow(dead_code)]
184// Allow needless range loop for explicit indexing
185#![allow(clippy::needless_range_loop)]
186// Allow unused imports in analytics modules
187#![allow(unused_imports)]
188
189pub mod change;
190pub mod clustering;
191pub mod error;
192pub mod hotspot;
193pub mod interpolation;
194pub mod timeseries;
195pub mod zonal;
196
197// Re-export commonly used items
198pub use error::{AnalyticsError, Result};
199
200/// Crate version
201pub const VERSION: &str = env!("CARGO_PKG_VERSION");
202
203/// Crate name
204pub const NAME: &str = env!("CARGO_PKG_NAME");
205
206#[cfg(test)]
207mod tests {
208 use super::*;
209
210 #[test]
211 fn test_version() {
212 assert!(!VERSION.is_empty());
213 assert_eq!(NAME, "oxigdal-analytics");
214 }
215}