GeoRepair
This crate is experimental. The API is actively evolving — expect breaking changes between 0.x releases. Core algorithms, I/O backends, and feature flags are all subject to change as we improve correctness and performance.
OGC geometry repair and validation for Rust. Built-in I/O for WKB, WKT, and a custom binary batch format — no extra dependencies required. Detects and fixes invalid GIS geometries (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: planar graph extraction, face walking, and winding-number assembly. 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 roughly on par with GEOS on 1.58M data set polygons (full dataset 0.92×, validation 3.3×).
See the full documentation for quick-start examples, validation rules, CRS support, I/O backends, Python bindings, C FFI, and known limitations.
Performance
Real-world dataset (1,578,988 polygons)
Structure batch on a production GIS dataset. GEOS linked via conda-forge (MSVC, serial internally, no LTO). i5-12400F (6C/12T), mimalloc. All columns are parallel batch (Rayon 12 threads); serial included for reference.
| Dataset | GeoRepair (ser) | GeoRepair (par) | GEOS (par batch) | vs GEOS |
|---|---|---|---|---|
| Validation (1.58M) | 3.14 s | 1.13 s | 3.78 s | 3.3× |
| Invalid subset (1855 polys) | 5.78 s | 1.96 s | 1.88 s | 1.04× |
| Full dataset (1.58M polys) | 9.40 s | 3.34 s | 3.61 s | 0.92× |
Synthetic benchmarks (CoordSeq direct — no WKT overhead)
Structure strategy, i5-12400F (6C/12T). GEOS benchmark uses CoordSeq direct construction, NOT WKT — this is a fair comparison. Serial column is single-threaded; parallel column uses Rayon 12-thread batch.
Stars indicate improvement: *** ≥100× · ** 10–100× · * 1–10× · (blank) <1× (GEOS faster)
Arrange pipeline (CDT fallback):
| Benchmark | GeoRepair (par) | GEOS (par batch) | Ratio |
|---|---|---|---|
| Valid polygon 4v | 0.09 µs | 1.49 µs | 17× |
| Valid polygon 50v | 1.65 µs | 3.84 µs | 2.3× |
| Invalid bowtie 4v | 0.65 µs | 17.4 µs | 27× |
| Star-burst 10sp | 0.09 µs | 0.35 µs | 3.9× |
| Star-burst 50sp | 0.51 µs | 0.87 µs | 1.7× |
Notes:
- conda-forge
libgeoson Windows is MSVC, serial per-call, no LTO. "par batch" = many GEOS C calls run concurrently via Rayon (12 threads). - Synthetic benchmarks use CoordSeq direct GEOS construction (no WKT). WKT round-trip inflated earlier GEOS numbers by 10-120×. Real-world benchmark always used CoordSeq (fair).
- GeoRepair parallel speedup is limited on sub-5µs geometries (Rayon overhead dominates). Real-world batches of 1.58M polygons show better throughput scaling (2-3× vs serial).
- GeoRepair wins big on invalid polygon repair and MultiPolygon unification (C++ quadratic algorithms hit their worst case). GEOS wins on large valid polygons where C++ optimization and mature JTS codebase dominate.
Run benchmarks
# Real-world dataset benchmark (system GEOS — conda-forge)
cargo bench --features bench-geos-system,arrange,structure,parallel,simd,io-shp --bench real_world
# Real-world dataset benchmark (static GEOS — built from source)
cargo bench --features bench-geos,arrange,structure,parallel,simd,io-shp --bench real_world
# Synthetic benchmarks with serial + parallel columns (no GEOS)
cargo bench --features arrange,structure,parallel,simd --bench bench
# Synthetic benchmarks with GEOS comparison
cargo bench --features bench-geos-system,arrange,structure,parallel,simd --bench bench
# Criterion microbenchmarks
cargo bench --features bench-criterion --bench criterion
Features
| Feature | Description | Default |
|---|---|---|
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 |
validate |
OGC validation predicates | yes |
mimalloc |
Use mimalloc global allocator | yes |
std |
Standard library + file I/O. Disable for no_std builds. | yes |
simd-portable |
Portable SIMD via core::simd (nightly only) |
no |
memmap |
Memory-mapped binary file loading | no |
wasm |
WASM browser fetch (synchronous XHR) | no |
proj |
CRS transformation (placeholder) | no |
serde |
Geometry serde support (geo/serde) |
no |
ffi |
C-compatible FFI bindings | no |
python |
Python bindings via PyO3 | no |
io-shp |
Shapefile format backend | no |
io-wkt |
No-op (WKT is built-in, kept for CI compatibility) | no |
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 |
bench-geos |
GEOS comparison benchmarks (build from source — MSVC, no LTO) | no |
bench-geos-system |
GEOS comparison benchmarks (link against system GEOS — conda-forge MSVC) | no |
bench-criterion |
Criterion benchmark harness | no |
License
Apache-2.0