-
Notifications
You must be signed in to change notification settings - Fork 199
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
cp -r ../geo-validity-check/src/* geo/src/algorithm/validation/
325ec00e5a1207308eecfb1d8fb5456cd5d5d121 from https://github.com/michaelkirk/geo-validity-check
- Loading branch information
1 parent
3da9289
commit 92d8bfc
Showing
14 changed files
with
1,824 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
use crate::{utils, Problem, ProblemAtPosition, ProblemPosition, ProblemReport, Valid}; | ||
use geo::{Coord, GeoFloat}; | ||
|
||
impl<F: GeoFloat> Valid for Coord<F> { | ||
fn is_valid(&self) -> bool { | ||
if utils::check_coord_is_not_finite(self) { | ||
return false; | ||
} | ||
true | ||
} | ||
fn explain_invalidity(&self) -> Option<ProblemReport> { | ||
let mut reason = Vec::new(); | ||
|
||
if utils::check_coord_is_not_finite(self) { | ||
reason.push(ProblemAtPosition( | ||
Problem::NotFinite, | ||
ProblemPosition::Point, | ||
)); | ||
} | ||
|
||
// Return the reason(s) of invalidity, or None if valid | ||
if reason.is_empty() { | ||
None | ||
} else { | ||
Some(ProblemReport(reason)) | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
use crate::{ProblemReport, Valid}; | ||
use geo::{GeoFloat, Geometry}; | ||
|
||
impl<F: GeoFloat> Valid for Geometry<F> { | ||
fn is_valid(&self) -> bool { | ||
match self { | ||
Geometry::Point(e) => e.is_valid(), | ||
Geometry::Line(e) => e.is_valid(), | ||
Geometry::Rect(e) => e.is_valid(), | ||
Geometry::Triangle(e) => e.is_valid(), | ||
Geometry::LineString(e) => e.is_valid(), | ||
Geometry::Polygon(e) => e.is_valid(), | ||
Geometry::MultiPoint(e) => e.is_valid(), | ||
Geometry::MultiLineString(e) => e.is_valid(), | ||
Geometry::MultiPolygon(e) => e.is_valid(), | ||
Geometry::GeometryCollection(e) => e.is_valid(), | ||
} | ||
} | ||
fn explain_invalidity(&self) -> Option<ProblemReport> { | ||
match self { | ||
Geometry::Point(e) => e.explain_invalidity(), | ||
Geometry::Line(e) => e.explain_invalidity(), | ||
Geometry::Rect(e) => e.explain_invalidity(), | ||
Geometry::Triangle(e) => e.explain_invalidity(), | ||
Geometry::LineString(e) => e.explain_invalidity(), | ||
Geometry::Polygon(e) => e.explain_invalidity(), | ||
Geometry::MultiPoint(e) => e.explain_invalidity(), | ||
Geometry::MultiLineString(e) => e.explain_invalidity(), | ||
Geometry::MultiPolygon(e) => e.explain_invalidity(), | ||
Geometry::GeometryCollection(e) => e.explain_invalidity(), | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
use crate::{GeometryPosition, ProblemAtPosition, ProblemPosition, ProblemReport, Valid}; | ||
use geo::{GeoFloat, GeometryCollection}; | ||
|
||
/// GeometryCollection is valid if all its elements are valid | ||
impl<F: GeoFloat> Valid for GeometryCollection<F> { | ||
fn is_valid(&self) -> bool { | ||
for geometry in self.0.iter() { | ||
if !geometry.is_valid() { | ||
return false; | ||
} | ||
} | ||
true | ||
} | ||
fn explain_invalidity(&self) -> Option<ProblemReport> { | ||
let mut reason = Vec::new(); | ||
|
||
// Loop over all the geometries, collect the reasons of invalidity | ||
// and change the ProblemPosition to reflect the GeometryCollection | ||
for (i, geometry) in self.0.iter().enumerate() { | ||
let temp_reason = geometry.explain_invalidity(); | ||
if let Some(temp_reason) = temp_reason { | ||
for ProblemAtPosition(problem, position) in temp_reason.0 { | ||
reason.push(ProblemAtPosition( | ||
problem, | ||
ProblemPosition::GeometryCollection( | ||
GeometryPosition(i), | ||
Box::new(position), | ||
), | ||
)); | ||
} | ||
} | ||
} | ||
// Return the reason(s) of invalidity, or None if valid | ||
if reason.is_empty() { | ||
None | ||
} else { | ||
Some(ProblemReport(reason)) | ||
} | ||
} | ||
} | ||
|
||
#[cfg(test)] | ||
mod tests { | ||
use crate::{ | ||
CoordinatePosition, GeometryPosition, Problem, ProblemAtPosition, ProblemPosition, | ||
ProblemReport, Valid, | ||
}; | ||
use geo::{Coord, Geometry, GeometryCollection, LineString, Point}; | ||
use geos::Geom; | ||
|
||
#[test] | ||
fn test_geometrycollection_contain_invalid_element() { | ||
let gc = GeometryCollection(vec![ | ||
Geometry::Point(Point::new(0., 0.)), | ||
Geometry::LineString(LineString(vec![ | ||
Coord { x: 0., y: 0. }, | ||
Coord { x: 1., y: 1. }, | ||
])), | ||
Geometry::LineString(LineString(vec![ | ||
Coord { x: 0., y: 0. }, | ||
Coord { x: 0., y: 0. }, | ||
])), | ||
]); | ||
assert!(!gc.is_valid()); | ||
assert_eq!( | ||
gc.explain_invalidity(), | ||
Some(ProblemReport(vec![ProblemAtPosition( | ||
Problem::TooFewPoints, | ||
ProblemPosition::GeometryCollection( | ||
GeometryPosition(2), | ||
Box::new(ProblemPosition::LineString(CoordinatePosition(0))) | ||
) | ||
)])) | ||
); | ||
|
||
let geoms = | ||
gc.0.iter() | ||
.map(|geometry| match geometry { | ||
Geometry::Point(pt) => { | ||
let geos_point: geos::Geometry = pt.try_into().unwrap(); | ||
geos_point | ||
} | ||
Geometry::LineString(ls) => { | ||
let geos_linestring: geos::Geometry = ls.try_into().unwrap(); | ||
geos_linestring | ||
} | ||
_ => unreachable!(), | ||
}) | ||
.collect::<Vec<_>>(); | ||
let geometrycollection_geos: geos::Geometry = | ||
geos::Geometry::create_geometry_collection(geoms).unwrap(); | ||
assert_eq!(gc.is_valid(), geometrycollection_geos.is_valid()); | ||
} | ||
} |
Oops, something went wrong.