From b80c2f05e0753a5a00f2d091537dc80080cb3595 Mon Sep 17 00:00:00 2001 From: Matt Battifarano Date: Wed, 12 Oct 2016 08:40:54 -0400 Subject: [PATCH 1/3] Implement `Intersects> for Polygon` Uses `Intersects> for Polygon` to do the work. Also implements `Intersects> for Bbox` --- src/algorithm/intersects.rs | 48 ++++++++++++++++++++++++++++++++++++- 1 file changed, 47 insertions(+), 1 deletion(-) diff --git a/src/algorithm/intersects.rs b/src/algorithm/intersects.rs index 49141a176..a43b6efb0 100644 --- a/src/algorithm/intersects.rs +++ b/src/algorithm/intersects.rs @@ -1,5 +1,5 @@ use num::Float; -use types::{LineString, Polygon, Bbox}; +use types::{LineString, Polygon, Bbox, Point}; use algorithm::contains::Contains; /// Checks if the geometry A intersects the geometry B. @@ -82,6 +82,28 @@ impl Intersects> for Bbox } } +impl Intersects> for Polygon + where T: Float +{ + fn intersects(&self, bbox: &Bbox) -> bool { + let p = Polygon(LineString(vec![Point::new(bbox.xmin, bbox.ymin), + Point::new(bbox.xmin, bbox.ymax), + Point::new(bbox.xmax, bbox.ymax), + Point::new(bbox.xmax, bbox.ymin), + Point::new(bbox.xmin, bbox.ymin)]), + vec![]); + self.intersects(&p) + } +} + +impl Intersects> for Bbox + where T: Float +{ + fn intersects(&self, polygon: &Polygon) -> bool { + polygon.intersects(self) + } +} + impl Intersects> for Polygon where T: Float { @@ -258,6 +280,30 @@ mod test { assert!(p2.intersects(&p1)); } #[test] + fn polygon_intersects_bbox_test() { + let p = |x, y| Point(Coordinate { x: x, y: y }); + let p1 = Polygon(LineString(vec![p(1., 3.), p(4., 3.), p(4., 6.), p(1., 6.), p(1., 3.)]), + Vec::new()); + let b1 = Bbox { xmin: 2.0, xmax: 5.0, ymin: 4.0, ymax: 7.0 }; + let p2 = Polygon(LineString(vec![p(0., 0.), p(0., 4.), p(3., 4.), p(3., 0.), p(0., 0.)]), + vec![LineString(vec![p(1., 1.), p(1., 3.), p(2., 3.), p(2., 1.), p(1., 1.)])]); + let b2 = Bbox { xmin: 1.2, xmax: 1.8, ymin: 1.2, ymax: 2.0 }; + let b3 = Bbox { xmin: 1.4, xmax: 1.6, ymin: 3.5, ymax: 4.5 }; + // overlaps + assert!(p1.intersects(&b1)); + // overlaps with hole + assert!(p2.intersects(&b1)); + // completely contained in the hole + assert!(!p2.intersects(&b2)); + // completely contained in the polygon + assert!(p1.intersects(&b3)); + // conversely, + assert!(b1.intersects(&p1)); + assert!(b1.intersects(&p2)); + assert!(!b2.intersects(&p2)); + assert!(b3.intersects(&p1)); + } + #[test] fn bbox_test() { let bbox_xl = Bbox { xmin: -100., xmax: 100., ymin: -200., ymax: 200.}; let bbox_sm = Bbox { xmin: -10., xmax: 10., ymin: -20., ymax: 20.}; From d1c0951153f76c174bbc31f6f21bb3265df2f0c4 Mon Sep 17 00:00:00 2001 From: Matt Battifarano Date: Wed, 12 Oct 2016 08:45:51 -0400 Subject: [PATCH 2/3] re-order implementations --- src/algorithm/intersects.rs | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/algorithm/intersects.rs b/src/algorithm/intersects.rs index a43b6efb0..4f0b89735 100644 --- a/src/algorithm/intersects.rs +++ b/src/algorithm/intersects.rs @@ -82,6 +82,14 @@ impl Intersects> for Bbox } } +impl Intersects> for Bbox + where T: Float +{ + fn intersects(&self, polygon: &Polygon) -> bool { + polygon.intersects(self) + } +} + impl Intersects> for Polygon where T: Float { @@ -96,14 +104,6 @@ impl Intersects> for Polygon } } -impl Intersects> for Bbox - where T: Float -{ - fn intersects(&self, polygon: &Polygon) -> bool { - polygon.intersects(self) - } -} - impl Intersects> for Polygon where T: Float { From e7e315dd0877105909ddeadbe9c3ca69afdb9374 Mon Sep 17 00:00:00 2001 From: Matt Battifarano Date: Sat, 15 Oct 2016 12:43:42 -0400 Subject: [PATCH 3/3] Annotate and clean up test --- src/algorithm/intersects.rs | 50 +++++++++++++++++++++++++------------ 1 file changed, 34 insertions(+), 16 deletions(-) diff --git a/src/algorithm/intersects.rs b/src/algorithm/intersects.rs index 4f0b89735..2a7f1909e 100644 --- a/src/algorithm/intersects.rs +++ b/src/algorithm/intersects.rs @@ -281,27 +281,45 @@ mod test { } #[test] fn polygon_intersects_bbox_test() { + // Polygon poly = + // + // (0,8) (12,8) + // ┌──────────────────────┐ + // │ (7,7) (11,7) │ + // │ ┌──────┐ │ + // │ │ │ │ + // │ │(hole)│ │ + // │ │ │ │ + // │ │ │ │ + // │ └──────┘ │ + // │ (7,4) (11,4) │ + // │ │ + // │ │ + // │ │ + // │ │ + // │ │ + // └──────────────────────┘ + // (0,0) (12,0) let p = |x, y| Point(Coordinate { x: x, y: y }); - let p1 = Polygon(LineString(vec![p(1., 3.), p(4., 3.), p(4., 6.), p(1., 6.), p(1., 3.)]), - Vec::new()); - let b1 = Bbox { xmin: 2.0, xmax: 5.0, ymin: 4.0, ymax: 7.0 }; - let p2 = Polygon(LineString(vec![p(0., 0.), p(0., 4.), p(3., 4.), p(3., 0.), p(0., 0.)]), - vec![LineString(vec![p(1., 1.), p(1., 3.), p(2., 3.), p(2., 1.), p(1., 1.)])]); - let b2 = Bbox { xmin: 1.2, xmax: 1.8, ymin: 1.2, ymax: 2.0 }; - let b3 = Bbox { xmin: 1.4, xmax: 1.6, ymin: 3.5, ymax: 4.5 }; + let poly = Polygon(LineString(vec![p(0., 0.), p(12., 0.), p(12., 8.), p(0., 8.), p(0., 0.)]), + vec![LineString(vec![p(7., 4.), p(11., 4.), p(11., 7.), p(7., 7.), p(7., 4.)])]); + let b1 = Bbox { xmin: 11.0, xmax: 13.0, ymin: 1.0, ymax: 2.0 }; + let b2 = Bbox { xmin: 2.0, xmax: 8.0, ymin: 2.0, ymax: 5.0 }; + let b3 = Bbox { xmin: 8.0, xmax: 10.0, ymin: 5.0, ymax: 6.0 }; + let b4 = Bbox { xmin: 1.0, xmax: 3.0, ymin: 1.0, ymax: 3.0 }; // overlaps - assert!(p1.intersects(&b1)); - // overlaps with hole - assert!(p2.intersects(&b1)); + assert!(poly.intersects(&b1)); + // contained in exterior, overlaps with hole + assert!(poly.intersects(&b2)); // completely contained in the hole - assert!(!p2.intersects(&b2)); + assert!(!poly.intersects(&b3)); // completely contained in the polygon - assert!(p1.intersects(&b3)); + assert!(poly.intersects(&b4)); // conversely, - assert!(b1.intersects(&p1)); - assert!(b1.intersects(&p2)); - assert!(!b2.intersects(&p2)); - assert!(b3.intersects(&p1)); + assert!(b1.intersects(&poly)); + assert!(b2.intersects(&poly)); + assert!(!b3.intersects(&poly)); + assert!(b4.intersects(&poly)); } #[test] fn bbox_test() {