geo/algorithm/within.rs
1use crate::algorithm::Contains;
2
3/// Tests if a geometry is completely within another geometry.
4///
5/// In other words, the [DE-9IM] intersection matrix for (Self, Rhs) is `[T*F**F***]`
6///
7/// # Examples
8///
9/// ```
10/// use geo::{point, line_string};
11/// use geo::algorithm::Within;
12///
13/// let line_string = line_string![(x: 0.0, y: 0.0), (x: 2.0, y: 4.0)];
14///
15/// assert!(point!(x: 1.0, y: 2.0).is_within(&line_string));
16///
17/// // Note that a geometry on only the *boundary* of another geometry is not considered to
18/// // be _within_ that geometry. See [`Relate`] for more information.
19/// assert!(! point!(x: 0.0, y: 0.0).is_within(&line_string));
20/// ```
21///
22/// `Within` is equivalent to [`Contains`] with the arguments swapped.
23///
24/// ```
25/// use geo::{point, line_string};
26/// use geo::algorithm::{Contains, Within};
27///
28/// let line_string = line_string![(x: 0.0, y: 0.0), (x: 2.0, y: 4.0)];
29/// let point = point!(x: 1.0, y: 2.0);
30///
31/// // These two comparisons are completely equivalent
32/// assert!(point.is_within(&line_string));
33/// assert!(line_string.contains(&point));
34/// ```
35///
36/// [DE-9IM]: https://en.wikipedia.org/wiki/DE-9IM
37pub trait Within<Other> {
38 fn is_within(&self, b: &Other) -> bool;
39}
40
41impl<G1, G2> Within<G2> for G1
42where
43 G2: Contains<G1>,
44{
45 fn is_within(&self, b: &G2) -> bool {
46 b.contains(self)
47 }
48}
49
50#[cfg(test)]
51mod tests {
52 use super::*;
53 use crate::{point, Rect};
54 #[test]
55 fn basic() {
56 let a = point!(x: 1.0, y: 2.0);
57 let b = Rect::new((0.0, 0.0), (3.0, 3.0)).to_polygon();
58 assert!(a.is_within(&b));
59 }
60}