Expand description
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
[dependencies]
geo-repair = "0.12"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
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)
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)
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)
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:
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 |
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-10degrees - Projected (metres):
1e-6metres - Unknown:
1e-12
CRS is set directly on MakeValidConfig:
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:
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
Re-exports§
pub use core::MakeValidConfig;pub use core::MakeValidError;pub use core::PolyMethod;pub use crs::Crs;pub use feature::Feature;pub use io::diagnose_file;pub use io::infer_wkt_type;pub use io::load;pub use io::load_bin;pub use io::load_bin_stream;pub use io::read_ewkb;pub use io::read_wkb;pub use io::read_wkb_concat;pub use io::read_wkb_from;pub use io::read_wkt;pub use io::read_wkt_from;pub use io::repair_file;pub use io::save;pub use io::write_ewkb;pub use io::write_wkb;pub use io::write_wkb_to;pub use io::write_wkb_with_opts;pub use io::write_wkt;pub use io::write_wkt_to;pub use io::Endianness;pub use io::EwkbDims;pub use io::EwkbGeometry;pub use io::WkbError;pub use io::WktError;pub use io::WriteOptions;pub use make_valid::MakeValid;pub use make_valid::ValidateAndFix;pub use snap::snap_coord;pub use snap::snap_coord_default;pub use snap::snap_line;pub use snap::snap_lines;pub use snap::DEFAULT_GRID;pub use validation::is_valid;pub use validation::validate;pub use validation::validate_reason;pub use validation::GeoValidation;pub use validation::GeometryValidationError;pub use validation::ValidationResult;
Modules§
- arrange
- CDT-based polygon repair for complex topologies (Arrange strategy). CDT-based polygon repair for complex topologies (LEDOUX et al. 2014).
- core
- Core configuration types for geometry repair. Core configuration, error types, and numeric constants for geometry repair.
- crs
- Coordinate reference system (CRS) handling and transformation. Coordinate Reference System (CRS) metadata and transformation.
- dd
- Double-double arithmetic for robust geometric computations. Double-double arithmetic for robust geometric constructions.
- feature
- Feature metadata associated with geometries. GIS feature container with attribute, CRS, and Z/M preservation.
- io
- Geometry I/O: WKB, binary format, and format-dispatch helpers. Format-agnostic geometry I/O: WKB, WKT, and binary format backends.
- make_
valid - Geometry repair implementation via the
MakeValidtrait. Geometry repair implementations via the MakeValid and ValidateAndFix traits. - noding
- Segment noding: intersection detection, snap-rounding, and validation. Noding utilities for linear geometry repair.
- orient
- Ring orientation utilities (CW/CCW winding). Adaptive-precision orientation predicates (Shewchuk’s algorithm).
- parallel
- Rayon-based parallel batch geometry repair. Rayon-based parallel batch geometry repair.
- reduce
- Geometry precision reduction with topology preservation. Geometry precision reduction with topology preservation.
- simd
- AVX2-accelerated geometric predicates (x86_64). SIMD-accelerated orientation predicates.
- snap
- Coordinate snapping to a precision grid. Coordinate snap-rounding utilities.
- structure
- GEOS-compatible fast-path polygon repair via planar graph extraction. GEOS-compatible fast-path polygon repair via planar graph extraction.
- validation
- OGC Simple Features geometry validation predicates. OGC Simple Features geometry validation predicates.
- zm
- Z/M coordinate value preservation through the repair pipeline. Z/M coordinate value preservation and querying.
Functions§
- profile_
structure_ fastpath - Profile each step of the structure fast path on a sample of polygons. Prints timing breakdown and pass rates to stderr.