Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: implement Validify repair trait #1120

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions geo/src/algorithm/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,10 @@ pub mod triangulate_spade;
#[cfg(feature = "spade")]
pub use triangulate_spade::TriangulateSpade;

/// Operations on invalid polygons to make them valid
mod validity;
pub use validity::Validify;

/// Vector Operations for 2D coordinates
mod vector_ops;
pub use vector_ops::Vector2DOps;
Expand Down
32 changes: 32 additions & 0 deletions geo/src/algorithm/validity/impls.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
use super::*;

use geo_types::{MultiPolygon, Polygon};

use crate::GeoFloat;

/// Splits self intersecting polygons into individual valid polygons
///
/// Self intersecting here includes banana polygons
///
/// There are no real guarantees in terms of minimality we can give since the algorithms is a
/// heuristic. In practice it turned out to work quiet well though.
///
/// # Validity
///
/// The algo will return non-sense if the input is non-sense. This mainly means:
///
/// - a polygon including a weird, disconnected linestring
impl<F: GeoFloat> Validify for Polygon<F> {
type ValidResult = MultiPolygon<F>;
fn split_into_valid(&self) -> Self::ValidResult {
let mp = MultiPolygon::new(vec![self.clone()]);
split::split_invalid_multipolygon(&mp)
}
}

impl<F: GeoFloat> Validify for MultiPolygon<F> {
type ValidResult = MultiPolygon<F>;
fn split_into_valid(&self) -> Self::ValidResult {
split::split_invalid_multipolygon(self)
}
}
20 changes: 20 additions & 0 deletions geo/src/algorithm/validity/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
mod impls;
mod split;

/// Trait which includes a bunch of methods for dealing with invalid polygons.
///
/// There are a few implicit assumptions that are made when dealing with geo's types. You can read
/// more about the specific assumptions of a kind of geometry in it's own documentation.
///
/// Some of geo's algorithms act in unexpected ways if those validity assumptions are not
/// respected. An example of this is `.make_ccw_winding()` on [`LineStrings`] which might fail if
/// the linestring doesn't include unique points.
pub trait Validify {
type ValidResult;

/// splits invalid geometries into valid ones
fn split_into_valid(&self) -> Self::ValidResult;
}

#[cfg(test)]
mod split_tests;
Loading
Loading