geo/algorithm/contains/
rect.rs

1use geo_types::CoordFloat;
2
3use super::{impl_contains_from_relate, impl_contains_geometry_for, Contains};
4use crate::{geometry::*, Area, CoordsIter, HasDimensions, Intersects};
5use crate::{CoordNum, GeoFloat};
6
7// ┌──────────────────────────┐
8// │ Implementations for Rect │
9// └──────────────────────────┘
10
11impl<T> Contains<Coord<T>> for Rect<T>
12where
13    T: CoordNum,
14{
15    fn contains(&self, coord: &Coord<T>) -> bool {
16        coord.x > self.min().x
17            && coord.x < self.max().x
18            && coord.y > self.min().y
19            && coord.y < self.max().y
20    }
21}
22
23impl<T> Contains<Point<T>> for Rect<T>
24where
25    T: CoordNum,
26{
27    fn contains(&self, p: &Point<T>) -> bool {
28        self.contains(&p.0)
29    }
30}
31
32impl<T> Contains<Rect<T>> for Rect<T>
33where
34    T: CoordNum,
35{
36    fn contains(&self, other: &Rect<T>) -> bool {
37        // TODO: check for degenerate rectangle (which is a line or a point)
38        // All points of LineString must be in the polygon ?
39        self.min().x <= other.min().x
40            && self.max().x >= other.max().x
41            && self.min().y <= other.min().y
42            && self.max().y >= other.max().y
43    }
44}
45
46impl<T> Contains<Polygon<T>> for Rect<T>
47where
48    T: CoordFloat,
49{
50    fn contains(&self, rhs: &Polygon<T>) -> bool {
51        // the polygon must not be empty
52        if rhs.is_empty() {
53            return false;
54        }
55
56        // none of the polygon's points may lie outside the rectangle
57        let mut points_inside = 0;
58        for c in rhs.exterior_coords_iter() {
59            if !self.intersects(&c) {
60                return false;
61            }
62            if self.contains(&c) {
63                points_inside += 1;
64            }
65        }
66
67        // The polygon must not lie completely inside the rectangle's boundary.
68        // In other words: at least one point of the interior of the polygon
69        // must lie in the interior of the rectangle. Since we know that the
70        // rectangle is convex, we just need make sure that either at least
71        // one point of the polygon lies inside the rectangle's interior or
72        // that the polygon's interior is not empty, in which case it will
73        // definitely intersect with the rectangle's interior.
74        if points_inside == 0 && rhs.signed_area().is_zero() {
75            return false;
76        }
77
78        true
79    }
80}
81
82impl_contains_from_relate!(Rect<T>, [Line<T>, LineString<T>, MultiPoint<T>, MultiLineString<T>, MultiPolygon<T>, GeometryCollection<T>, Triangle<T>]);
83impl_contains_geometry_for!(Rect<T>);