Skip to content

Commit

Permalink
Leverage geometry graph to fix contains.
Browse files Browse the repository at this point in the history
Unfortunately this entails a `clone` of the geometry. I'm not sure yet
how easy this will be to avoid, since GeomGraph works on Geometry...

This also adds a bunch of undesirable 'static constraints. I think this
is ultimately because of the Box'd LineIntersector. We should try to get
rid of those constraints.
  • Loading branch information
michaelkirk committed Jan 26, 2021
1 parent f36196a commit 484f87e
Show file tree
Hide file tree
Showing 5 changed files with 18 additions and 17 deletions.
1 change: 1 addition & 0 deletions geo/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ proj-network = ["use-proj", "proj/network"]
use-serde = ["serde", "geo-types/serde"]

[dev-dependencies]
env_logger = "*"
approx = "0.4.0"
criterion = { version = "0.3" }
rand = "0.8.0"
Expand Down
3 changes: 1 addition & 2 deletions geo/src/algorithm/contains/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -394,8 +394,7 @@ mod test {
fn line_in_polygon_edgecases_test() {
// Some DE-9IM edge cases for checking line is
// inside polygon The end points of the line can be
// on the boundary of the polygon but we don't allow
// that yet.
// on the boundary of the polygon.
let c = |x, y| Coordinate { x, y };
// A non-convex polygon
let linestring0 = line_string![
Expand Down
19 changes: 10 additions & 9 deletions geo/src/algorithm/contains/polygon.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
use super::Contains;
use crate::intersects::Intersects;
use crate::{CoordNum, Coordinate, GeoFloat, Line, LineString, MultiPolygon, Point, Polygon};
use crate::{
CoordNum, Coordinate, GeoFloat, Geometry, Line, LineString, MultiPolygon, Point, Polygon,
};

// ┌─────────────────────────────┐
// │ Implementations for Polygon │
Expand Down Expand Up @@ -29,22 +31,21 @@ where
// line.start and line.end is on the boundaries
impl<T> Contains<Line<T>> for Polygon<T>
where
T: GeoFloat,
T: 'static + GeoFloat,
{
fn contains(&self, line: &Line<T>) -> bool {
// both endpoints are contained in the polygon and the line
// does NOT intersect the exterior or any of the interior boundaries
self.contains(&line.start)
&& self.contains(&line.end)
&& !self.exterior().intersects(line)
&& !self.interiors().iter().any(|inner| inner.intersects(line))
use crate::algorithm::relate::Relate;
// These clones are unfortunate. Can we get something like a GeometryRef type?
let polygon = Geometry::Polygon(self.clone());
let line = Geometry::Line(line.clone());
polygon.relate(&line).is_contains()
}
}

// TODO: also check interiors
impl<T> Contains<Polygon<T>> for Polygon<T>
where
T: GeoFloat,
T: 'static + GeoFloat,
{
fn contains(&self, poly: &Polygon<T>) -> bool {
// decompose poly's exterior ring into Lines, and check each for containment
Expand Down
8 changes: 4 additions & 4 deletions geo/src/algorithm/euclidean_distance.rs
Original file line number Diff line number Diff line change
Expand Up @@ -294,7 +294,7 @@ where
// Line to Polygon distance
impl<T> EuclideanDistance<T, Polygon<T>> for Line<T>
where
T: GeoFloat + Signed + RTreeNum + FloatConst,
T: 'static + GeoFloat + Signed + RTreeNum + FloatConst,
{
fn euclidean_distance(&self, other: &Polygon<T>) -> T {
if other.contains(self) || self.intersects(other) {
Expand Down Expand Up @@ -328,7 +328,7 @@ where
/// Line to MultiPolygon distance
impl<T> EuclideanDistance<T, MultiPolygon<T>> for Line<T>
where
T: GeoFloat + FloatConst + Signed + RTreeNum,
T: 'static + GeoFloat + FloatConst + Signed + RTreeNum,
{
fn euclidean_distance(&self, mpolygon: &MultiPolygon<T>) -> T {
mpolygon
Expand Down Expand Up @@ -431,7 +431,7 @@ where
// Polygon to Line distance
impl<T> EuclideanDistance<T, Line<T>> for Polygon<T>
where
T: GeoFloat + FloatConst + Signed + RTreeNum,
T: 'static + GeoFloat + FloatConst + Signed + RTreeNum,
{
fn euclidean_distance(&self, other: &Line<T>) -> T {
other.euclidean_distance(self)
Expand Down Expand Up @@ -504,7 +504,7 @@ where
/// MultiPolygon to Line distance
impl<T> EuclideanDistance<T, Line<T>> for MultiPolygon<T>
where
T: GeoFloat + FloatConst + Signed + RTreeNum,
T: 'static + GeoFloat + FloatConst + Signed + RTreeNum,
{
fn euclidean_distance(&self, other: &Line<T>) -> T {
other.euclidean_distance(self)
Expand Down
4 changes: 2 additions & 2 deletions geo/src/algorithm/relate/intersection_matrix.rs
Original file line number Diff line number Diff line change
Expand Up @@ -518,8 +518,8 @@ impl IntersectionMatrix {
// JTS: }
pub fn is_contains(&self) -> bool {
self.0[Location::Interior as usize][Location::Interior as usize] != Dimensions::Empty
&& self.0[Location::Interior as usize][Location::Exterior as usize] == Dimensions::Empty
&& self.0[Location::Boundary as usize][Location::Exterior as usize] == Dimensions::Empty
&& self.0[Location::Exterior as usize][Location::Interior as usize] == Dimensions::Empty
&& self.0[Location::Exterior as usize][Location::Boundary as usize] == Dimensions::Empty
}
// JTS:
// JTS: /**
Expand Down

0 comments on commit 484f87e

Please sign in to comment.