-
Notifications
You must be signed in to change notification settings - Fork 202
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
511: Robust Intersect and Contains r=michaelkirk a=rmanoka Use robust predicates in Intersects and Contains traits + use robust preds (doesn't need Float anymore) + define interior, boundary, and exterior of geometry types (similar to geos/jts) + define Intersect and Contains using DE-9IM model + fix contains logic in a few corner cases Future work: The polygon contains line / polygon logic is not yet fully correct. I've added a few TODO comments, and an ignored test for cases where our predicate doesn't match the DE-9IM definition. Unfortunately, it doesn't seem to be a simple change to fix these corner cases. For instance, geos seems to use a concept called `GeometryGraph` for these cases which I'm yet to understand. Co-authored-by: Rajsekar Manokaran <[email protected]> Co-authored-by: rmanoka <[email protected]>
- Loading branch information
Showing
38 changed files
with
1,124 additions
and
825 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
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
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
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
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
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
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
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
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
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
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,58 @@ | ||
use super::Contains; | ||
use crate::kernels::*; | ||
use crate::*; | ||
|
||
// ┌──────────────────────────────┐ | ||
// │ Implementations for Geometry │ | ||
// └──────────────────────────────┘ | ||
|
||
impl<T> Contains<Coordinate<T>> for Geometry<T> | ||
where | ||
T: HasKernel, | ||
{ | ||
fn contains(&self, coord: &Coordinate<T>) -> bool { | ||
match self { | ||
Geometry::Point(g) => g.contains(coord), | ||
Geometry::Line(g) => g.contains(coord), | ||
Geometry::LineString(g) => g.contains(coord), | ||
Geometry::Polygon(g) => g.contains(coord), | ||
Geometry::MultiPoint(g) => g.contains(coord), | ||
Geometry::MultiLineString(g) => g.contains(coord), | ||
Geometry::MultiPolygon(g) => g.contains(coord), | ||
Geometry::GeometryCollection(g) => g.contains(coord), | ||
Geometry::Rect(g) => g.contains(coord), | ||
Geometry::Triangle(g) => g.contains(coord), | ||
} | ||
} | ||
} | ||
|
||
impl<T> Contains<Point<T>> for Geometry<T> | ||
where | ||
T: HasKernel, | ||
{ | ||
fn contains(&self, point: &Point<T>) -> bool { | ||
self.contains(&point.0) | ||
} | ||
} | ||
|
||
// ┌────────────────────────────────────────┐ | ||
// │ Implementations for GeometryCollection │ | ||
// └────────────────────────────────────────┘ | ||
|
||
impl<T> Contains<Coordinate<T>> for GeometryCollection<T> | ||
where | ||
T: HasKernel, | ||
{ | ||
fn contains(&self, coord: &Coordinate<T>) -> bool { | ||
self.0.iter().any(|geometry| geometry.contains(coord)) | ||
} | ||
} | ||
|
||
impl<T> Contains<Point<T>> for GeometryCollection<T> | ||
where | ||
T: HasKernel, | ||
{ | ||
fn contains(&self, point: &Point<T>) -> bool { | ||
self.contains(&point.0) | ||
} | ||
} |
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,84 @@ | ||
use super::Contains; | ||
use crate::intersects::Intersects; | ||
use crate::kernels::*; | ||
use crate::*; | ||
|
||
// ┌──────────────────────────┐ | ||
// │ Implementations for Line │ | ||
// └──────────────────────────┘ | ||
|
||
impl<T> Contains<Coordinate<T>> for Line<T> | ||
where | ||
T: HasKernel, | ||
{ | ||
fn contains(&self, coord: &Coordinate<T>) -> bool { | ||
if self.start == self.end { | ||
&self.start == coord | ||
} else { | ||
coord != &self.start && coord != &self.end && self.intersects(coord) | ||
} | ||
} | ||
} | ||
|
||
impl<T> Contains<Point<T>> for Line<T> | ||
where | ||
T: HasKernel, | ||
{ | ||
fn contains(&self, p: &Point<T>) -> bool { | ||
self.contains(&p.0) | ||
} | ||
} | ||
|
||
impl<T> Contains<Line<T>> for Line<T> | ||
where | ||
T: HasKernel, | ||
{ | ||
fn contains(&self, line: &Line<T>) -> bool { | ||
if line.start == line.end { | ||
self.contains(&line.start) | ||
} else { | ||
self.intersects(&line.start) && self.intersects(&line.end) | ||
} | ||
} | ||
} | ||
|
||
impl<T> Contains<LineString<T>> for Line<T> | ||
where | ||
T: HasKernel, | ||
{ | ||
fn contains(&self, linestring: &LineString<T>) -> bool { | ||
// Empty linestring has no interior, and not | ||
// contained in anything. | ||
if linestring.0.is_empty() { | ||
return false; | ||
} | ||
|
||
// The interior of the linestring should have some | ||
// intersection with the interior of self. Two cases | ||
// arise: | ||
// | ||
// 1. There are at least two distinct points in the | ||
// linestring. Then, if both intersect, the interior | ||
// between these two must have non-empty intersection. | ||
// | ||
// 2. Otherwise, all the points on the linestring | ||
// are the same. In this case, the interior is this | ||
// specific point, and it should be contained in the | ||
// line. | ||
let first = linestring.0.first().unwrap(); | ||
let mut all_equal = true; | ||
|
||
// If all the vertices of the linestring intersect | ||
// self, then the interior or boundary of the | ||
// linestring cannot have non-empty intersection | ||
// with the exterior. | ||
let all_intersects = linestring.0.iter().all(|c| { | ||
if c != first { | ||
all_equal = false; | ||
} | ||
self.intersects(c) | ||
}); | ||
|
||
all_intersects && (!all_equal || self.contains(first)) | ||
} | ||
} |
Oops, something went wrong.