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 raster;
210pub mod resampling;
211pub mod vector;
212
213#[cfg(feature = "simd")]
214pub mod simd;
215
216#[cfg(feature = "parallel")]
217pub mod parallel;
218
219#[cfg(feature = "dsl")]
220pub mod dsl;
221
222// Tutorial documentation
223pub mod tutorials;
224
225// Re-export commonly used items
226pub use error::{AlgorithmError, Result};
227pub use resampling::{Resampler, ResamplingMethod};
228
229// Re-export bytecode compiler + VM for band-math expressions
230pub use raster::{
231    CompiledProgram, OpCode, RasterCalculator, RasterExpression, estimate_stack_depth,
232    eval_bytecode,
233};
234
235// Re-export streaming raster abstraction (out-of-core chunked processing)
236pub use raster::streaming::{
237    Chunk, ChunkIterator, ChunkedRaster, InMemoryRasterSource, RasterError, RasterSource,
238    extract_inner, process_streaming, streaming_focal_mean, streaming_hillshade, streaming_slope,
239};
240
241// Re-export compound morphological operators (slice-based API)
242pub use raster::{
243    BorderMode, MorphologyOptions, black_hat, black_hat_with, closing, closing_with, opening,
244    opening_with, top_hat, top_hat_with,
245};
246
247// Re-export TIN (Triangulated Irregular Network) interpolation
248pub use raster::{
249    Tin, TinInterpMethod, TinPoint, build_tin, interpolate_idw_tin, interpolate_natural_neighbor,
250    rasterize_tin,
251};
252
253// Re-export point-cloud thinning (grid/random/Poisson-disk)
254pub use raster::{
255    ThinPoint3, ThinningMethod, ThinningStats, thin_grid, thin_poisson_disk, thin_random,
256    thin_with_stats,
257};
258
259// Re-export vector operations for convenience
260pub use vector::{
261    AreaMethod,
262
263    BufferCapStyle,
264    BufferJoinStyle,
265    BufferOptions,
266
267    // Minimum bounding geometry
268    Circle,
269    // Clipping operations
270    ClipOperation,
271    // Map generalization operators (ICA taxonomy: collapse, exaggerate, displace)
272    CollapseOptions,
273    ContainsPredicate,
274    // Geometric types (from oxigdal-core)
275    Coordinate,
276    DisplaceOptions,
277    DisplaceStats,
278    DistanceMethod,
279
280    ExaggerateAnchor,
281    ExaggerateOptions,
282    IntersectsPredicate,
283    IssueType,
284    // Line offset (parallel curves)
285    JoinStyle,
286    LineString,
287    MultiPolygon,
288    OffsetOptions,
289    OffsetResult,
290    Point,
291    Polygon,
292
293    // Power diagram (weighted Voronoi)
294    PowerCell,
295    PowerDiagram,
296    PowerDiagramOptions,
297    // Robust location estimators (geometric median, L1 median, spatial mean)
298    RobustLocationOptions,
299    RotatedRect,
300    SegmentIntersection,
301
302    Severity,
303    SimplifyMethod,
304
305    SnapRoundingOptions,
306    SnapRoundingResult,
307    SnappedSegment,
308    TopologySimplifyOptions,
309    TouchesPredicate,
310
311    ValidationIssue,
312    WeightedPoint,
313    aabb,
314    // Area operations
315    area,
316    area_multipolygon,
317    area_polygon,
318    // Buffer operations
319    buffer_linestring,
320    buffer_point,
321    buffer_polygon,
322    // Union operations
323    cascaded_union,
324    // Centroid operations
325    centroid,
326    centroid_collection,
327    centroid_linestring,
328    centroid_multilinestring,
329    centroid_multipoint,
330    centroid_multipolygon,
331    centroid_point,
332    centroid_polygon,
333
334    clip_multi,
335    clip_polygons,
336    // Difference operations
337    clip_to_box,
338    // Advanced modules
339    clustering,
340    collapse_linestring_to_point,
341    collapse_polygon_to_point,
342    // Spatial predicates (contains, intersects, etc.)
343    contains,
344    convex_hull,
345    delaunay,
346    difference_polygon,
347    difference_polygons,
348    // Distance operations
349    directed_hausdorff,
350    discrete_frechet_distance,
351    disjoint,
352    displace_points,
353    displace_polygons_by_centroid,
354    distance_point_to_linestring,
355    distance_point_to_point,
356    distance_point_to_polygon,
357    erase_small_holes,
358    exaggerate_coord,
359    exaggerate_linestring,
360    exaggerate_polygon,
361    geometric_median,
362    geometric_median_3d,
363    geometric_median_with_options,
364    hausdorff_distance,
365    hausdorff_distance_to_segments,
366    // Intersection operations
367    intersect_linestrings,
368    intersect_linestrings_sweep,
369    intersect_polygons,
370    intersect_segment_segment,
371    intersects,
372    is_clockwise,
373    is_counter_clockwise,
374    l1_median,
375    merge_polygons,
376    min_area_rotated_rect,
377    network,
378    offset_linestring,
379    offset_polygon_rings,
380    point_in_polygon,
381    point_in_polygon_or_boundary,
382    point_on_polygon_boundary,
383    point_strictly_inside_polygon,
384    power_diagram,
385    should_collapse_polygon,
386    // Simplification operations
387    simplify_linestring,
388    simplify_linestring_dp,
389    simplify_polygon,
390    // Topology-preserving simplification
391    simplify_topology,
392    simplify_topology_with_options,
393    smallest_enclosing_circle,
394    // Snap rounding operations
395    snap_coordinate,
396    snap_linestring,
397    snap_round,
398    spatial_join,
399    spatial_mean,
400    symmetric_difference,
401
402    topology,
403    touches,
404    union_polygon,
405    union_polygons,
406
407    // Validation operations
408    validate_geometry,
409    validate_linestring,
410    validate_polygon,
411    voronoi,
412    weighted_bisector,
413    weighted_geometric_median,
414
415    within,
416};
417
418/// Crate version
419pub const VERSION: &str = env!("CARGO_PKG_VERSION");
420
421/// Crate name
422pub const NAME: &str = env!("CARGO_PKG_NAME");
423
424#[cfg(test)]
425mod tests {
426    use super::*;
427
428    #[test]
429    fn test_version() {
430        assert!(!VERSION.is_empty());
431        assert_eq!(NAME, "oxigdal-algorithms");
432    }
433}