Skip to main content

oxigdal_algorithms/vector/
mod.rs

1//! Vector operations and geometric algorithms
2//!
3//! This module provides comprehensive geometric operations for vector data:
4//!
5//! ## Core Operations
6//! - Buffer generation (fixed and variable distance)
7//! - Intersection operations
8//! - Union operations
9//! - Difference operations
10//!
11//! ## Topology Operations
12//! - Overlay analysis (intersection, union, difference, symmetric difference)
13//! - Erase operations (cookie-cutter)
14//! - Split operations (geometry splitting)
15//!
16//! ## Network Analysis
17//! - Graph structures and building
18//! - Shortest path algorithms (Dijkstra, A*, bidirectional)
19//! - Service area calculation (isochrones)
20//! - Advanced routing with constraints
21//!
22//! ## Spatial Clustering
23//! - DBSCAN (density-based clustering)
24//! - K-means clustering
25//! - Hierarchical clustering
26//!
27//! ## Triangulation
28//! - Delaunay triangulation
29//! - Voronoi diagrams
30//! - Constrained Delaunay
31//!
32//! ## Spatial Joins
33//! - R-tree spatial index
34//! - Nearest neighbor search
35//! - K-nearest neighbors
36//! - Range queries
37//!
38//! ## Simplification
39//! - Douglas-Peucker algorithm
40//! - Visvalingam-Whyatt algorithm
41//! - Topology-preserving simplification
42//!
43//! ## Geometric Analysis
44//! - Centroid calculation (geometric and area-weighted)
45//! - Area calculation (planar and geodetic)
46//! - Length measurement (planar and geodetic)
47//! - Distance measurement (Euclidean, Haversine, Vincenty)
48//! - Convex hull computation
49//!
50//! ## Spatial Predicates
51//! - Contains, Within
52//! - Intersects, Disjoint
53//! - Touches, Overlaps, Crosses
54//!
55//! ## Validation & Repair
56//! - Geometry validation
57//! - Self-intersection detection
58//! - Duplicate vertex detection
59//! - Spike detection
60//! - Geometry repair (fix orientation, remove duplicates, close rings)
61//!
62//! ## Coordinate Transformation
63//! - CRS transformation (WGS84, Web Mercator, UTM, etc.)
64//! - Geometry reprojection
65//!
66//! ## Object Pooling
67//! - Thread-local object pools for Point, LineString, Polygon
68//! - Pooled versions of buffer, union, difference, intersection operations
69//! - Reduces allocations by 2-3x for batch operations
70//! - Automatic return to pool via RAII guards
71//!
72//! ### Using Object Pooling
73//!
74//! ```
75//! use oxigdal_algorithms::vector::{buffer_point_pooled, Point, BufferOptions};
76//!
77//! let point = Point::new(0.0, 0.0);
78//! let options = BufferOptions::default();
79//!
80//! // Get a pooled polygon - automatically returned to pool when dropped
81//! let buffered = buffer_point_pooled(&point, 10.0, &options)?;
82//! // Use buffered geometry...
83//! // Polygon returned to pool when `buffered` goes out of scope
84//! # Ok::<(), oxigdal_algorithms::error::AlgorithmError>(())
85//! ```
86//!
87//! All operations use geometry types from `oxigdal-core::vector`.
88
89mod area;
90mod buffer;
91mod centroid;
92pub mod clipping;
93pub mod clustering;
94mod contains;
95pub mod de9im;
96pub mod delaunay;
97mod difference;
98mod distance;
99mod douglas_peucker;
100mod envelope;
101pub mod geodesic;
102mod intersection;
103mod length;
104pub mod network;
105pub mod pool;
106mod repair;
107mod simplify;
108pub mod spatial_join;
109pub mod topology;
110mod topology_simplify;
111mod transform;
112mod union_ops;
113mod valid;
114pub mod voronoi;
115
116// Re-export from core
117pub use oxigdal_core::vector::{Coordinate, LineString, MultiPolygon, Point, Polygon};
118
119// Re-export area operations
120pub use area::{
121    AreaMethod, area, area_multipolygon, area_polygon, is_clockwise, is_counter_clockwise,
122};
123
124// Re-export buffer operations
125pub use buffer::{
126    BufferCapStyle, BufferJoinStyle, BufferOptions, buffer_linestring, buffer_linestring_pooled,
127    buffer_point, buffer_point_pooled, buffer_polygon, buffer_polygon_pooled,
128};
129
130// Re-export centroid operations
131pub use centroid::{
132    centroid, centroid_collection, centroid_linestring, centroid_multilinestring,
133    centroid_multipoint, centroid_multipolygon, centroid_point, centroid_polygon,
134};
135
136// Re-export spatial predicates
137pub use contains::{
138    ContainsPredicate, CrossesPredicate, IntersectsPredicate, OverlapsPredicate, TouchesPredicate,
139    contains, crosses, disjoint, intersects, overlaps, point_in_polygon_or_boundary,
140    point_on_polygon_boundary, point_strictly_inside_polygon, touches, within,
141};
142
143// Re-export DE-9IM types and predicates
144pub use de9im::{
145    CoveredByPredicate, CoversPredicate, De9im, Dimension, EqualsPredicate, relate,
146    relate_line_polygon, relate_point_polygon, relate_polygons,
147};
148
149// Re-export difference operations
150pub use difference::{
151    clip_to_box, difference_polygon, difference_polygon_pooled, difference_polygons,
152    difference_polygons_pooled, erase_small_holes, symmetric_difference,
153    symmetric_difference_pooled,
154};
155
156// Re-export distance operations
157pub use distance::{
158    DistanceMethod, distance_point_to_linestring, distance_point_to_point,
159    distance_point_to_polygon,
160};
161
162// Re-export Douglas-Peucker
163pub use douglas_peucker::simplify_linestring as simplify_linestring_dp;
164
165// Re-export envelope operations
166pub use envelope::{
167    envelope, envelope_collection, envelope_contains_point, envelope_intersection,
168    envelope_linestring, envelope_multilinestring, envelope_multipoint, envelope_multipolygon,
169    envelope_point, envelope_polygon, envelope_union, envelope_with_buffer, envelopes_intersect,
170};
171
172// Re-export intersection operations
173pub use intersection::{
174    SegmentIntersection, intersect_linestrings, intersect_linestrings_sweep, intersect_polygons,
175    intersect_polygons_pooled, intersect_segment_segment, point_in_polygon,
176};
177
178// Re-export length operations
179pub use length::{
180    LengthMethod, length, length_linestring, length_linestring_3d, length_multilinestring,
181};
182
183// Re-export simplification operations
184pub use simplify::{SimplifyMethod, simplify_linestring, simplify_polygon};
185
186// Re-export topology-preserving simplification
187pub use topology_simplify::{
188    TopologySimplifyOptions, simplify_topology, simplify_topology_with_options,
189};
190
191// Re-export union operations
192pub use union_ops::{
193    cascaded_union, cascaded_union_pooled, convex_hull, convex_hull_pooled, merge_polygons,
194    union_polygon, union_polygon_pooled, union_polygons, union_polygons_pooled,
195};
196
197// Re-export pool types and utilities
198pub use pool::{
199    Pool, PoolGuard, PoolStats, clear_all_pools, get_pool_stats, get_pooled_coordinate_vec,
200    get_pooled_linestring, get_pooled_point, get_pooled_polygon,
201};
202
203// Re-export validation
204pub use valid::{
205    IssueType, Severity, ValidationIssue, validate_geometry, validate_linestring, validate_polygon,
206};
207
208// Re-export repair operations
209pub use repair::{
210    RepairOptions, close_ring, fix_self_intersection, remove_collinear_vertices,
211    remove_duplicate_vertices, remove_spikes, repair_linestring, repair_linestring_with_options,
212    repair_polygon, repair_polygon_with_options, reverse_ring,
213};
214
215// Re-export clipping operations
216pub use clipping::{ClipOperation, clip_multi, clip_polygons};
217
218// Re-export coordinate transformations
219pub use transform::{
220    CommonCrs, CrsTransformer, transform_geometry, transform_linestring, transform_point,
221    transform_polygon,
222};
223
224#[cfg(test)]
225mod tests {
226    use super::*;
227
228    #[test]
229    fn test_point_distance() {
230        let p1 = Coordinate::new_2d(0.0, 0.0);
231        let p2 = Coordinate::new_2d(3.0, 4.0);
232        let dx = p1.x - p2.x;
233        let dy = p1.y - p2.y;
234        let dist = (dx * dx + dy * dy).sqrt();
235        assert!((dist - 5.0).abs() < 1e-10);
236    }
237
238    #[test]
239    fn test_linestring_construction() {
240        let coords = vec![
241            Coordinate::new_2d(0.0, 0.0),
242            Coordinate::new_2d(3.0, 0.0),
243            Coordinate::new_2d(3.0, 4.0),
244        ];
245        let result = LineString::new(coords);
246        assert!(result.is_ok());
247        if let Ok(line) = result {
248            assert_eq!(line.len(), 3);
249        }
250    }
251
252    #[test]
253    fn test_polygon_construction() {
254        // Square with side length 10
255        let coords = vec![
256            Coordinate::new_2d(0.0, 0.0),
257            Coordinate::new_2d(10.0, 0.0),
258            Coordinate::new_2d(10.0, 10.0),
259            Coordinate::new_2d(0.0, 10.0),
260            Coordinate::new_2d(0.0, 0.0),
261        ];
262        let exterior = LineString::new(coords);
263        assert!(exterior.is_ok());
264        if let Ok(ext) = exterior {
265            let poly = Polygon::new(ext, vec![]);
266            assert!(poly.is_ok());
267        }
268    }
269}