Skip to main content

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}