1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
//! Validate and repair invalid OGC GIS geometries in Rust.
//!
//! Detects and fixes geometry defects — self-intersections, unclosed rings,
//! degenerate shapes, NaN coordinates, and more — using algorithms selected
//! by geometry type. The **Structure** strategy (default) mirrors GEOS's
//! ST_MakeValid algorithm; the **Arrange** strategy uses CDT-based repair
//! as a robust fallback for complex topologies. Passes 2490/2490 GEOS XML
//! validation tests, with parallel batch performance **0.30× GEOS** (3.3×
//! faster) on 1.58M data set polygons.
//!
//! # Quick start
//!
//! ```toml
//! [dependencies]
//! geo-repair = "0.12"
//! ```
//!
//! ```rust
//! # use geo::{Geometry, Point};
//! # let geometry = Geometry::Point(Point::new(0.0, 0.0));
//! use geo_repair::{is_valid, validate, MakeValid, ValidateAndFix};
//! use geo_repair::{read_wkb, write_wkb, read_wkt, write_wkt};
//!
//! // Check validity
//! let result = validate(&geometry);
//! if !result.valid {
//! for err in &result.errors {
//! eprintln!(" {err}");
//! }
//! }
//!
//! // Fix invalid geometry
//! let fixed = geometry.make_valid();
//!
//! // Combined validate-and-fix
//! let (result, fixed) = geometry.validate_and_fix();
//!
//! // WKB roundtrip
//! let bytes: Vec<u8> = write_wkb(&geometry);
//! let geom = read_wkb(&bytes).unwrap();
//!
//! // WKT roundtrip
//! let text: String = write_wkt(&geometry);
//! let geom = read_wkt(&text).unwrap();
//! ```
//!
//! ## With method selection
//!
//! ```rust
//! # use geo::{Geometry, Point};
//! # let geometry = Geometry::Point(Point::new(0.0, 0.0));
//! use geo_repair::{MakeValid, MakeValidConfig, PolyMethod};
//!
//! let config = MakeValidConfig {
//! poly_method: PolyMethod::Arrange,
//! keep_collapsed: false,
//! ..Default::default()
//! };
//! let fixed = geometry.make_valid_with_config(&config);
//! ```
//!
//! ## WKB I/O (built-in, no dependencies)
//!
//! ```rust
//! # use geo::{Geometry, Point};
//! # let geom = Geometry::Point(Point::new(0.0, 0.0));
//! # let concat_buffer = vec![];
//! use geo_repair::{read_wkb, write_wkb, read_wkb_concat};
//!
//! let wkb: Vec<u8> = write_wkb(&geom);
//! let geom = read_wkb(&wkb).unwrap();
//! let geoms: Vec<Geometry<f64>> = read_wkb_concat(&concat_buffer).unwrap();
//! ```
//!
//! ## WKT I/O (built-in, no dependencies)
//!
//! ```rust
//! # use geo::{Geometry, Point};
//! # let geom = Geometry::Point(Point::new(0.0, 0.0));
//! use geo_repair::{read_wkt, write_wkt};
//!
//! let wkt: String = write_wkt(&geom);
//! let geom = read_wkt(&wkt).unwrap();
//! ```
//!
//! ## Binary format loading (custom `.bin` format, fast bulk I/O)
//!
//! ```rust,no_run
//! use geo_repair::load_bin;
//!
//! let polys: Vec<geo::Polygon<f64>> = load_bin("dataset.bin").unwrap();
//! ```
//!
//! # Feature flags
//!
//! | Feature | Description | Default |
//! |---------|-------------|---------|
//! | `std` | Standard library + file I/O. Disable for no_std builds. | yes |
//! | `arrange` | CDT-based polygon repair (requires `spade`) | yes |
//! | `structure` | Structure-based fast-path repair | yes |
//! | `parallel` | Rayon parallel processing (non-WASM) | yes |
//! | `simd` | AVX2-accelerated orientation tests (x86_64) | yes |
//! | `simd-portable` | Portable SIMD via `core::simd` (nightly) | no |
//! | `validate` | OGC validation predicates | yes |
//! | `memmap` | Memory-mapped binary file loading | no* |
//! | `wasm` | WASM browser fetch (synchronous XHR) | no |
//! | `mimalloc` | Use mimalloc global allocator | yes |
//! | `io-shp` | Shapefile format backend | no |
//! | `io-wkb` | No-op (WKB is always compiled in) | — |
//! | `io-wkt` | No-op (WKT is always compiled in) | — |
//! | `io-csv` | CSV format backend | no |
//! | `io-gml` | GML/XML format backend | no |
//! | `io-gpkg` | GeoPackage format backend (not WASM) | no |
//! | `io-all` | All opt-in backends except gpkg | no |
//! | `io-all-native` | All opt-in backends including gpkg | no |
//! | `ffi` | C-compatible FFI bindings | no |
//! | `python` | Python bindings via PyO3 | no |
//! | `proj` | CRS transformation via PROJ | no |
//! | `serde` | Geometry serde support | no |
//! | `bench-geos` | GEOS comparison benchmarks (static — MSVC, no LTO) | no |
//! | `bench-geos-system` | GEOS comparison benchmarks (system — conda LLVM, full LTO) | no |
//!
//! *`memmap` was default in 0.10 but moved to opt-in in 0.11.
//!
//! # Platform support
//!
//! | Platform | Core | SIMD | I/O | Parallel | Python |
//! |----------|------|------|-----|----------|--------|
//! | x86_64 Windows/Linux/macOS | Yes | Yes (AVX2) | Yes | Yes | Yes |
//! | aarch64 macOS/Linux | Yes | Scalar | Yes | Yes | Yes |
//! | WASM32 | Yes | Scalar | In-memory only | No | No |
//! | no_std (embedded) | Yes | Scalar | No | No | No |
//!
//! AVX2 requires `RUSTFLAGS="-C target-cpu=native"` at build time. Falls
//! back to scalar on CPUs without AVX2 or non-x86_64 targets.
//!
//! # no_std
//!
//! Disable the `std` feature for no_std builds. Core validation, repair,
//! and WKB parsing work without std. File I/O, parallel processing, and
//! Python/FFI bindings require std:
//!
//! ```shell
//! cargo check --no-default-features --features arrange,structure,simd
//! ```
//!
//! # Validation
//!
//! The [`GeoValidation`] trait checks 18 OGC validity rules using Shewchuk
//! adaptive-precision orientation tests (via the `robust` crate):
//!
//! | Rule | Applies to |
//! |------|-----------|
//! | Coordinate finiteness | All geometries |
//! | Ring closure | Polygon rings |
//! | Ring minimum vertices (≥4) | Polygon rings |
//! | Ring self-intersection | Polygon rings |
//! | Pinch points (non-consecutive duplicates) | Rings |
//! | Hole containment (inside shell) | Polygon |
//! | No nested holes | Polygon |
//! | Interior ring connectivity | Polygon |
//! | Ring orientation (exterior CCW, interior CW) | Polygon |
//! | Non-collinear rings | Polygon |
//! | Consecutive duplicates | Lines/rings |
//! | Duplicate rings | Polygon |
//! | Duplicate points | MultiPoint |
//! | Duplicate lines | MultiLineString |
//! | Non-zero-length lines | Line |
//! | Non-degenerate exterior | Polygon |
//! | Simplicity (no interior intersections) | LineString, MultiLineString |
//! | Nesting depth limit | GeometryCollection |
//!
//! ```rust
//! # use geo::{Geometry, Point};
//! # let geom = Geometry::Point(Point::new(0.0, 0.0));
//! use geo_repair::{is_valid, validate, validate_reason, GeoValidation, ValidationResult};
//!
//! let ok: bool = geom.is_valid();
//! let ok2: bool = is_valid(&geom);
//!
//! let result: ValidationResult = validate(&geom);
//! let reason: String = validate_reason(&geom);
//! ```
//!
//! # Polygon repair strategies
//!
//! | Strategy | Approach | Strengths | Weaknesses |
//! |----------|----------|-----------|------------|
//! | **Arrange** (CDT) | Constrained Delaunay triangulation → face labeling → ring extraction | Handles any topology. No self-intersection limit. | Slower, especially on large rings. Requires `spade`. |
//! | **Structure** (fast path) | Planar graph extraction → face walking → winding-number assembly | 10-100× faster for valid/simple inputs. No external deps. | Falls back on complex topologies (many holes, nested self-intersections). |
//!
//! **Auto** (default) tries Structure first and falls back to Arrange.
//! The repair pipeline enforces OGC-correct winding order (CCW exterior,
//! CW interior) on all output.
//!
//! # CRS support
//!
//! The [`Crs`] type stores EPSG codes and provides CRS-aware tolerance heuristics:
//! - Geographic (lon/lat): `1e-10` degrees
//! - Projected (metres): `1e-6` metres
//! - Unknown: `1e-12`
//!
//! CRS is set directly on [`MakeValidConfig`]:
//!
//! ```rust
//! use geo_repair::{Crs, MakeValidConfig};
//!
//! let config = MakeValidConfig {
//! crs: Some(Crs::from_epsg(4326)),
//! ..Default::default()
//! };
//! ```
//!
//! # I/O
//!
//! GeoRepair provides format-agnostic dispatch and individual backends:
//!
//! ```rust,no_run
//! # use geo::{Geometry, Point};
//! # let geom = Geometry::Point(Point::new(0.0, 0.0));
//! # let concat_buffer = vec![];
//! use geo_repair::{
//! diagnose_file, load, load_bin, read_wkb, read_wkb_concat, read_wkb_from,
//! read_ewkb, write_ewkb, EwkbGeometry, EwkbDims,
//! read_wkt, read_wkt_from, write_wkt, write_wkt_to, infer_wkt_type,
//! write_wkb, write_wkb_to, write_wkb_with_opts, Endianness, WriteOptions,
//! repair_file, save, MakeValidConfig,
//! };
//!
//! let geoms = load("input.wkb").unwrap();
//! let geoms = read_wkb_concat(&concat_buffer).unwrap();
//!
//! for result in diagnose_file("input.bin").unwrap() {
//! println!("{}", result.reason());
//! }
//!
//! repair_file("invalid.wkb", "fixed.wkb", &MakeValidConfig::default()).unwrap();
//! save("output.wkt", &geoms[0]).unwrap();
//!
//! // Standard LE WKB
//! let wkb: Vec<u8> = write_wkb(&geom);
//! // Big-endian WKB
//! let be_wkb: Vec<u8> = write_wkb_with_opts(&geom, &WriteOptions { endianness: Endianness::BigEndian });
//! // Write to any io::Write target
//! write_wkb_to(&geom, &mut std::io::stdout()).unwrap();
//! // Read from any io::Read source
//! let geom = read_wkb_from(&wkb[..]).unwrap();
//!
//! // EWKB with SRID and Z/M preservation
//! let ewkb = EwkbGeometry {
//! geometry: geom.clone(),
//! srid: Some(4326),
//! dims: EwkbDims::XYZ,
//! extra_coords: vec![100.0],
//! };
//! let ewkb_bytes = write_ewkb(&ewkb);
//! let back = read_ewkb(&ewkb_bytes).unwrap();
//!
//! // WKT with streaming I/O
//! let wkt: String = write_wkt(&geom);
//! let geom = read_wkt(&wkt).unwrap();
//! write_wkt_to(&geom, &mut std::io::stdout()).unwrap();
//! let geom = read_wkt_from(wkt.as_bytes()).unwrap();
//!
//! // Peek at WKT type without parsing
//! let (type_name, _dims) = infer_wkt_type("POLYGON ((0 0, 1 0, 1 1, 0 1, 0 0))").unwrap();
//!
//! let polys = load_bin("dataset.bin").unwrap();
//! ```
//!
//! | Extension | Format | Backend |
//! |-----------|--------|---------|
//! | `.wkb` / `.wks` | WKB (LE/BE, EWKB SRID, Z/M variants, io::Read/Write) | Zero-dep built-in |
//! | `.bin` | Custom binary bulk polygon format | Zero-dep built-in |
//! | `.shp` | Shapefile | `io-shp` feature |
//! | `.wkt` | WKT (io::Read/Write, type inference) | Zero-dep built-in |
//! | `.csv` | CSV with WKT geometry | `io-csv` feature |
//! | `.gml` | GML/XML | `io-gml` feature |
//! | `.gpkg` | GeoPackage (SQLite) | `io-gpkg` feature |
//!
//! # Geometry type coverage
//!
//! | Geometry | Repair approach |
//! |----------|----------------|
//! | `Polygon` / `MultiPolygon` | Structure fast path or Arrange CDT fallback |
//! | `LineString` / `MultiLineString` | NaN filtering, duplicate removal, self-intersection noding |
//! | `Line` | Zero-length and NaN detection |
//! | `Point` / `MultiPoint` | NaN/Inf filtering, deduplication |
//! | `Rect` / `Triangle` | Basic degeneracy checks |
//! | `GeometryCollection` | Recursive repair of children |
//!
//! # Known limitations
//!
//! - **CDT arranger may panic** on certain degenerate inputs (all-collinear
//! exterior rings, coordinates near f64::MAX). This is a known limitation
//! of `spade`.
//! - **OGC compliance** is a key goal but not yet formally certified. The
//! validation module checks 18 OGC predicates and passes 2490/2490 GEOS XML
//! tests.
//! - **GeometryCollection cross-component intersection** is not validated.
//! - **Z/M coordinate consistency** is not validated.
//!
//! # License
//!
//! Apache-2.0
/// Compile-time guard: ensures `cfg(feature = "rstar")` is active when any
/// rstar-dependent feature is enabled. Prevents silent O(n²) regression when
/// `dep:rstar` is used in Cargo.toml feature lists instead of the explicit
/// `rstar = ["dep:rstar"]` feature alias.
const _: = ;
/// Core configuration types for geometry repair.
/// Coordinate reference system (CRS) handling and transformation.
/// Double-double arithmetic for robust geometric computations.
/// Feature metadata associated with geometries.
/// Geometry I/O: WKB, binary format, and format-dispatch helpers.
/// Geometry repair implementation via the [`MakeValid`] trait.
/// Ring orientation utilities (CW/CCW winding).
/// Coordinate snapping to a precision grid.
pub
/// OGC Simple Features geometry validation predicates.
/// Z/M coordinate value preservation through the repair pipeline.
/// CDT-based polygon repair for complex topologies (Arrange strategy).
/// Segment noding: intersection detection, snap-rounding, and validation.
/// Geometry precision reduction with topology preservation.
/// GEOS-compatible fast-path polygon repair via planar graph extraction.
/// C-compatible FFI bindings for geo-repair.
/// Rayon-based parallel batch geometry repair.
/// Python bindings via PyO3.
/// AVX2-accelerated geometric predicates (x86_64).
/// Repair configuration, error types, and polygon method selection.
pub use ;
/// Coordinate reference system wrapper.
pub use Crs;
/// A feature combining geometry with optional attributes and CRS.
pub use Feature;
pub use ;
/// Trait for repairing invalid geometries.
pub use MakeValid;
/// Combines validation and repair in a single step, returning errors for
/// violations that could not be automatically repaired.
pub use ValidateAndFix;
/// Coordinate snapping functions.
pub use ;
/// OGC validation predicates and result types.
pub use ;
static GLOBAL: MiMalloc = MiMalloc;
/// Profile each step of the structure fast path on a sample of polygons.
/// Prints timing breakdown and pass rates to stderr.