Skip to main content

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}