oxigdal_algorithms/lib.rs
1//! OxiGDAL Algorithms - High-Performance Raster and Vector Operations
2//!
3//! This crate provides production-ready geospatial algorithms for raster and vector processing,
4//! with a focus on performance, correctness, and Pure Rust implementation.
5//!
6//! # Features
7//!
8//! ## Resampling Algorithms
9//!
10//! - Nearest neighbor (fast, preserves exact values)
11//! - Bilinear interpolation (smooth, good for continuous data)
12//! - Bicubic interpolation (high quality, slower)
13//! - Lanczos resampling (highest quality, expensive)
14//!
15//! ## Raster Operations
16//!
17//! - Raster calculator (map algebra with expression evaluation)
18//! - Hillshade generation (3D terrain visualization)
19//! - Slope and aspect calculation (terrain analysis)
20//! - Reclassification (value mapping and binning)
21//! - Zonal statistics (aggregate statistics by zones)
22//!
23//! ## Vector Operations
24//!
25//! ### Geometric Operations
26//! - Buffer generation (fixed and variable distance, multiple cap/join styles)
27//! - Intersection (geometric intersection with sweep line algorithm)
28//! - Union (geometric union, cascaded union, convex hull)
29//! - Difference (geometric difference, symmetric difference, clip to box)
30//!
31//! ### Simplification
32//! - Douglas-Peucker simplification (perpendicular distance based)
33//! - Visvalingam-Whyatt simplification (area based)
34//! - Topology-preserving simplification
35//!
36//! ### Geometric Analysis
37//! - Centroid calculation (geometric and area-weighted, all geometry types)
38//! - Area calculation (planar and geodetic methods)
39//! - Distance measurement (Euclidean, Haversine, Vincenty)
40//!
41//! ### Spatial Predicates
42//! - Contains, Within (point-in-polygon tests)
43//! - Intersects, Disjoint (intersection tests)
44//! - Touches, Overlaps (boundary relationships)
45//!
46//! ### Validation
47//! - Geometry validation (OGC Simple Features compliance)
48//! - Self-intersection detection
49//! - Duplicate vertex detection
50//! - Ring orientation and closure checks
51//!
52//! ## SIMD Optimizations
53//!
54//! Many algorithms use SIMD instructions (when enabled) for maximum performance.
55//! Enable the `simd` feature for best performance.
56//!
57//! # Examples
58//!
59//! ## Raster Resampling
60//!
61//! ```
62//! use oxigdal_algorithms::resampling::{ResamplingMethod, Resampler};
63//! use oxigdal_core::buffer::RasterBuffer;
64//! use oxigdal_core::types::RasterDataType;
65//!
66//! # fn main() -> Result<(), Box<dyn std::error::Error>> {
67//! // Create source raster
68//! let src = RasterBuffer::zeros(1000, 1000, RasterDataType::Float32);
69//!
70//! // Resample to half size using bilinear interpolation
71//! let resampler = Resampler::new(ResamplingMethod::Bilinear);
72//! let dst = resampler.resample(&src, 500, 500)?;
73//! # Ok(())
74//! # }
75//! ```
76//!
77//! ## Vector Operations
78//!
79//! ```
80//! use oxigdal_algorithms::{
81//! Coordinate, LineString, Point, Polygon,
82//! buffer_point, BufferOptions,
83//! area, area_polygon, AreaMethod,
84//! centroid_polygon, simplify_linestring, SimplifyMethod,
85//! validate_polygon,
86//! };
87//!
88//! # fn main() -> Result<(), Box<dyn std::error::Error>> {
89//! // Create a point and buffer it
90//! let point = Point::new(0.0, 0.0);
91//! let options = BufferOptions::default();
92//! let buffered = buffer_point(&point, 10.0, &options)?;
93//!
94//! // Calculate area of a polygon
95//! let coords = vec![
96//! Coordinate::new_2d(0.0, 0.0),
97//! Coordinate::new_2d(10.0, 0.0),
98//! Coordinate::new_2d(10.0, 10.0),
99//! Coordinate::new_2d(0.0, 10.0),
100//! Coordinate::new_2d(0.0, 0.0),
101//! ];
102//! let exterior = LineString::new(coords)?;
103//! let polygon = Polygon::new(exterior, vec![])?;
104//! let area_value = area_polygon(&polygon, AreaMethod::Planar)?;
105//! # assert!((area_value - 100.0).abs() < 1e-10);
106//!
107//! // Simplify a linestring
108//! let line_coords = vec![
109//! Coordinate::new_2d(0.0, 0.0),
110//! Coordinate::new_2d(1.0, 0.1),
111//! Coordinate::new_2d(2.0, -0.05),
112//! Coordinate::new_2d(3.0, 0.0),
113//! ];
114//! let linestring = LineString::new(line_coords)?;
115//! let simplified = simplify_linestring(&linestring, 0.15, SimplifyMethod::DouglasPeucker)?;
116//!
117//! // Validate a polygon
118//! let issues = validate_polygon(&polygon)?;
119//! assert!(issues.is_empty()); // Valid square has no issues
120//! # Ok(())
121//! # }
122//! ```
123//!
124//! # Performance
125//!
126//! All algorithms are designed for production use with:
127//!
128//! - Zero-copy operations where possible
129//! - SIMD vectorization (x86_64 AVX2, ARM NEON)
130//! - Cache-friendly memory access patterns
131//! - Optional parallel processing via `rayon`
132//!
133//! # COOLJAPAN Policy Compliance
134//!
135//! - Pure Rust (no C/Fortran dependencies)
136//! - No `unwrap()` or `expect()` in production code
137//! - Comprehensive error handling
138//! - no_std compatible core algorithms (with `alloc`)
139
140#![cfg_attr(not(feature = "std"), no_std)]
141#![warn(clippy::all)]
142// Pedantic disabled to reduce noise - default clippy::all is sufficient
143// #![warn(clippy::pedantic)]
144#![deny(clippy::unwrap_used)]
145#![deny(clippy::panic)]
146#![allow(clippy::module_name_repetitions)]
147// Allow loop indexing patterns common in geospatial algorithms
148#![allow(clippy::needless_range_loop)]
149// Allow expect() for internal invariants that shouldn't fail
150#![allow(clippy::expect_used)]
151// Allow more arguments for complex geospatial operations
152#![allow(clippy::too_many_arguments)]
153// Allow manual implementations for clarity in algorithms
154#![allow(clippy::manual_memcpy)]
155#![allow(clippy::manual_div_ceil)]
156#![allow(clippy::manual_clamp)]
157// Allow dead code for internal algorithm structures
158#![allow(dead_code)]
159// Allow partial documentation for complex algorithm modules
160#![allow(missing_docs)]
161// Allow non-canonical partial_cmp for custom ordering
162#![allow(clippy::non_canonical_partial_ord_impl)]
163// Allow unused variables in algorithm code
164#![allow(unused_variables)]
165#![allow(unused_imports)]
166// Allow collapsible match for algorithm clarity
167#![allow(clippy::collapsible_match)]
168#![allow(clippy::collapsible_if)]
169// Allow manual_strip for path handling
170#![allow(clippy::manual_strip)]
171// Allow should_implement_trait for builder patterns
172#![allow(clippy::should_implement_trait)]
173// Allow method names that match trait names but with different signatures
174#![allow(clippy::wrong_self_convention)]
175// Allow iter_with_drain for performance patterns
176#![allow(clippy::iter_with_drain)]
177// Allow map_values for explicit iteration
178#![allow(clippy::iter_kv_map)]
179// Allow loop over option for clarity in algorithm code
180#![allow(for_loops_over_fallibles)]
181// Allow first element access with get(0)
182#![allow(clippy::get_first)]
183// Allow redundant closure for clarity
184#![allow(clippy::redundant_closure)]
185// Allow field assignment outside initializer
186#![allow(clippy::field_reassign_with_default)]
187// Allow manual iterator find implementations
188#![allow(clippy::manual_find)]
189// Allow identical blocks in if statements for algorithm clarity
190#![allow(clippy::if_same_then_else)]
191// Allow elided lifetime confusion
192#![allow(clippy::needless_lifetimes)]
193// Allow unused assignments for algorithm control flow
194#![allow(unused_assignments)]
195// Allow impls that can be derived (explicit implementations preferred)
196#![allow(clippy::derivable_impls)]
197// Allow explicit counter loop for clarity
198#![allow(clippy::explicit_counter_loop)]
199// Allow clone where from_ref could be used
200#![allow(clippy::clone_on_ref_ptr)]
201// Allow doc list item overindentation in complex formulas
202#![allow(clippy::doc_overindented_list_items)]
203// Allow useless vec for clarity in algorithm tests
204#![allow(clippy::useless_vec)]
205// Allow slice from ref pattern for geometry operations
206#![allow(clippy::assigning_clones)]
207
208pub mod error;
209pub mod expr_depth;
210pub mod raster;
211pub mod resampling;
212pub mod vector;
213
214#[cfg(feature = "simd")]
215pub mod simd;
216
217#[cfg(feature = "parallel")]
218pub mod parallel;
219
220#[cfg(feature = "dsl")]
221pub mod dsl;
222
223// Tutorial documentation
224pub mod tutorials;
225
226// Re-export commonly used items
227pub use error::{AlgorithmError, Result};
228pub use expr_depth::MAX_EXPRESSION_DEPTH;
229pub use resampling::{Resampler, ResamplingMethod};
230
231// Re-export bytecode compiler + VM for band-math expressions
232pub use raster::{
233 CompiledProgram, OpCode, RasterCalculator, RasterExpression, estimate_stack_depth,
234 eval_bytecode,
235};
236
237// Re-export streaming raster abstraction (out-of-core chunked processing)
238pub use raster::streaming::{
239 Chunk, ChunkIterator, ChunkedRaster, InMemoryRasterSource, RasterError, RasterSource,
240 extract_inner, process_streaming, streaming_focal_mean, streaming_hillshade, streaming_slope,
241};
242
243// Re-export compound morphological operators (slice-based API)
244pub use raster::{
245 BorderMode, MorphologyOptions, black_hat, black_hat_with, closing, closing_with, opening,
246 opening_with, top_hat, top_hat_with,
247};
248
249// Re-export TIN (Triangulated Irregular Network) interpolation
250pub use raster::{
251 Tin, TinInterpMethod, TinPoint, build_tin, interpolate_idw_tin, interpolate_natural_neighbor,
252 rasterize_tin,
253};
254
255// Re-export point-cloud thinning (grid/random/Poisson-disk)
256pub use raster::{
257 ThinPoint3, ThinningMethod, ThinningStats, thin_grid, thin_poisson_disk, thin_random,
258 thin_with_stats,
259};
260
261// Re-export vector operations for convenience
262pub use vector::{
263 AreaMethod,
264
265 BufferCapStyle,
266 BufferJoinStyle,
267 BufferOptions,
268
269 // Minimum bounding geometry
270 Circle,
271 // Clipping operations
272 ClipOperation,
273 // Map generalization operators (ICA taxonomy: collapse, exaggerate, displace)
274 CollapseOptions,
275 ContainsPredicate,
276 // Geometric types (from oxigdal-core)
277 Coordinate,
278 DisplaceOptions,
279 DisplaceStats,
280 DistanceMethod,
281
282 ExaggerateAnchor,
283 ExaggerateOptions,
284 IntersectsPredicate,
285 IssueType,
286 // Line offset (parallel curves)
287 JoinStyle,
288 LineString,
289 MultiPolygon,
290 OffsetOptions,
291 OffsetResult,
292 Point,
293 Polygon,
294
295 // Power diagram (weighted Voronoi)
296 PowerCell,
297 PowerDiagram,
298 PowerDiagramOptions,
299 // Robust location estimators (geometric median, L1 median, spatial mean)
300 RobustLocationOptions,
301 RotatedRect,
302 SegmentIntersection,
303
304 Severity,
305 SimplifyMethod,
306
307 SnapRoundingOptions,
308 SnapRoundingResult,
309 SnappedSegment,
310 TopologySimplifyOptions,
311 TouchesPredicate,
312
313 ValidationIssue,
314 WeightedPoint,
315 aabb,
316 // Area operations
317 area,
318 area_multipolygon,
319 area_polygon,
320 // Buffer operations
321 buffer_linestring,
322 buffer_point,
323 buffer_polygon,
324 // Union operations
325 cascaded_union,
326 // Centroid operations
327 centroid,
328 centroid_collection,
329 centroid_linestring,
330 centroid_multilinestring,
331 centroid_multipoint,
332 centroid_multipolygon,
333 centroid_point,
334 centroid_polygon,
335
336 clip_multi,
337 clip_polygons,
338 // Difference operations
339 clip_to_box,
340 // Advanced modules
341 clustering,
342 collapse_linestring_to_point,
343 collapse_polygon_to_point,
344 // Spatial predicates (contains, intersects, etc.)
345 contains,
346 convex_hull,
347 delaunay,
348 difference_polygon,
349 difference_polygons,
350 // Distance operations
351 directed_hausdorff,
352 discrete_frechet_distance,
353 disjoint,
354 displace_points,
355 displace_polygons_by_centroid,
356 distance_point_to_linestring,
357 distance_point_to_point,
358 distance_point_to_polygon,
359 erase_small_holes,
360 exaggerate_coord,
361 exaggerate_linestring,
362 exaggerate_polygon,
363 geometric_median,
364 geometric_median_3d,
365 geometric_median_with_options,
366 hausdorff_distance,
367 hausdorff_distance_to_segments,
368 // Intersection operations
369 intersect_linestrings,
370 intersect_linestrings_sweep,
371 intersect_polygons,
372 intersect_segment_segment,
373 intersects,
374 is_clockwise,
375 is_counter_clockwise,
376 l1_median,
377 merge_polygons,
378 min_area_rotated_rect,
379 network,
380 offset_linestring,
381 offset_polygon_rings,
382 point_in_polygon,
383 point_in_polygon_or_boundary,
384 point_on_polygon_boundary,
385 point_strictly_inside_polygon,
386 power_diagram,
387 should_collapse_polygon,
388 // Simplification operations
389 simplify_linestring,
390 simplify_linestring_dp,
391 simplify_polygon,
392 // Topology-preserving simplification
393 simplify_topology,
394 simplify_topology_with_options,
395 smallest_enclosing_circle,
396 // Snap rounding operations
397 snap_coordinate,
398 snap_linestring,
399 snap_round,
400 spatial_join,
401 spatial_mean,
402 symmetric_difference,
403
404 topology,
405 touches,
406 union_polygon,
407 union_polygons,
408
409 // Validation operations
410 validate_geometry,
411 validate_linestring,
412 validate_polygon,
413 voronoi,
414 weighted_bisector,
415 weighted_geometric_median,
416
417 within,
418};
419
420/// Crate version
421pub const VERSION: &str = env!("CARGO_PKG_VERSION");
422
423/// Crate name
424pub const NAME: &str = env!("CARGO_PKG_NAME");
425
426#[cfg(test)]
427mod tests {
428 use super::*;
429
430 #[test]
431 fn test_version() {
432 assert!(!VERSION.is_empty());
433 assert_eq!(NAME, "oxigdal-algorithms");
434 }
435}