oxigeo_algorithms/lib.rs
1//! OxiGeo 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 oxigeo_algorithms::resampling::{ResamplingMethod, Resampler};
63//! use oxigeo_core::buffer::RasterBuffer;
64//! use oxigeo_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 oxigeo_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 ClipResult,
274 // Map generalization operators (ICA taxonomy: collapse, exaggerate, displace)
275 CollapseOptions,
276 ContainsPredicate,
277 // Geometric types (from oxigeo-core)
278 Coordinate,
279 DisplaceOptions,
280 DisplaceStats,
281 DistanceMethod,
282
283 ExaggerateAnchor,
284 ExaggerateOptions,
285 IntersectsPredicate,
286 IssueType,
287 // Line offset (parallel curves)
288 JoinStyle,
289 LineString,
290 MultiPolygon,
291 OffsetOptions,
292 OffsetResult,
293 Point,
294 Polygon,
295
296 // Power diagram (weighted Voronoi)
297 PowerCell,
298 PowerDiagram,
299 PowerDiagramOptions,
300 // Robust location estimators (geometric median, L1 median, spatial mean)
301 RobustLocationOptions,
302 RotatedRect,
303 SegmentIntersection,
304
305 Severity,
306 SimplifyMethod,
307
308 SnapRoundingOptions,
309 SnapRoundingResult,
310 SnappedSegment,
311 TopologySimplifyOptions,
312 TouchesPredicate,
313
314 ValidationIssue,
315 WeightedPoint,
316 aabb,
317 // Area operations
318 area,
319 area_multipolygon,
320 area_polygon,
321 // Buffer operations
322 buffer_linestring,
323 buffer_point,
324 buffer_polygon,
325 // Union operations
326 cascaded_union,
327 // Centroid operations
328 centroid,
329 centroid_collection,
330 centroid_linestring,
331 centroid_multilinestring,
332 centroid_multipoint,
333 centroid_multipolygon,
334 centroid_point,
335 centroid_polygon,
336
337 clip_multi,
338 clip_polygons,
339 clip_polygons_detailed,
340 // Difference operations
341 clip_to_box,
342 // Advanced modules
343 clustering,
344 collapse_linestring_to_point,
345 collapse_polygon_to_point,
346 // Spatial predicates (contains, intersects, etc.)
347 contains,
348 convex_hull,
349 delaunay,
350 difference_polygon,
351 difference_polygons,
352 // Distance operations
353 directed_hausdorff,
354 discrete_frechet_distance,
355 disjoint,
356 displace_points,
357 displace_polygons_by_centroid,
358 distance_point_to_linestring,
359 distance_point_to_point,
360 distance_point_to_polygon,
361 erase_small_holes,
362 exaggerate_coord,
363 exaggerate_linestring,
364 exaggerate_polygon,
365 geometric_median,
366 geometric_median_3d,
367 geometric_median_with_options,
368 hausdorff_distance,
369 hausdorff_distance_to_segments,
370 // Intersection operations
371 intersect_linestrings,
372 intersect_linestrings_sweep,
373 intersect_polygons,
374 intersect_segment_segment,
375 intersects,
376 is_clockwise,
377 is_counter_clockwise,
378 l1_median,
379 merge_polygons,
380 min_area_rotated_rect,
381 network,
382 offset_linestring,
383 offset_polygon_rings,
384 point_in_polygon,
385 point_in_polygon_or_boundary,
386 point_on_polygon_boundary,
387 point_strictly_inside_polygon,
388 power_diagram,
389 should_collapse_polygon,
390 // Simplification operations
391 simplify_linestring,
392 simplify_linestring_dp,
393 simplify_polygon,
394 // Topology-preserving simplification
395 simplify_topology,
396 simplify_topology_with_options,
397 smallest_enclosing_circle,
398 // Snap rounding operations
399 snap_coordinate,
400 snap_linestring,
401 snap_round,
402 spatial_join,
403 spatial_mean,
404 symmetric_difference,
405
406 topology,
407 touches,
408 union_polygon,
409 union_polygons,
410
411 // Validation operations
412 validate_geometry,
413 validate_linestring,
414 validate_polygon,
415 voronoi,
416 weighted_bisector,
417 weighted_geometric_median,
418
419 within,
420};
421
422/// Crate version
423pub const VERSION: &str = env!("CARGO_PKG_VERSION");
424
425/// Crate name
426pub const NAME: &str = env!("CARGO_PKG_NAME");
427
428#[cfg(test)]
429mod tests {
430 use super::*;
431
432 #[test]
433 fn test_version() {
434 assert!(!VERSION.is_empty());
435 assert_eq!(NAME, "oxigeo-algorithms");
436 }
437}