pub struct IntersectionMatrix(/* private fields */);
Expand description

Models a Dimensionally Extended Nine-Intersection Model (DE-9IM) matrix.

DE-9IM matrix values (such as “212FF1FF2”) specify the topological relationship between two Geometries.

DE-9IM matrices are 3x3 matrices that represent the topological locations that occur in a geometry (Interior, Boundary, Exterior).

The indices are provided by the enum cases CoordPos::Inside, CoordPos::OnBoundary, CoordPos::Outside.

The matrix entries represent the Dimensions of each intersection.

For a description of the DE-9IM and the spatial predicates derived from it, see the following references:

This implementation is heavily based on that from the JTS project.

Implementations§

source§

impl IntersectionMatrix

source

pub fn empty() -> Self

source

pub fn is_disjoint(&self) -> bool

Returns true if geometries a and b are disjoint: they have no point in common, forming a set of disconnected geometries.

§Notes
  • Matches [FF*FF****]
  • This predicate is anti-reflexive
source

pub fn is_intersects(&self) -> bool

Tests if IntersectionMatrix::is_disjoint returns false.

Returns true if the two geometries related by this matrix intersect: they have at least one point in common.

§Notes
  • Matches any of [T********], [*T*******], [***T*****], [****T****]
  • This predicate is reflexive and symmetric
source

pub fn is_within(&self) -> bool

Returns true if the first geometry is within the second: a lies in the interior of b.

§Notes
source

pub fn is_contains(&self) -> bool

Returns true if geometry a contains geometry b.

§Notes
  • Matches [T*****FF*]
  • This predicate is reflexive and transitive
source

pub fn is_equal_topo(&self) -> bool

Returns true if the first geometry is topologically equal to the second.

§Notes
  • Matches [T*F**FFF*]
  • This predicate is reflexive, symmetric, and transitive
source

pub fn is_coveredby(&self) -> bool

Returns true if every point in Geometry a lies inside (i.e. intersects the interior or boundary of) Geometry b.

Equivalently, tests that no point of a lies outside (in the exterior of) b:

  • a is covered by b (extends IntersectionMatrix::is_within): geometry a lies in b. OR
  • At least one point of a lies in b, and no point of a lies in the exterior of b OR
  • Every point of a is a point of (the interior or boundary of) b

returns true if the first geometry is covered by the second.

use geo_types::{Polygon, polygon};
use geo::relate::Relate;

let poly1 = polygon![
    (x: 125., y: 179.),
    (x: 110., y: 150.),
    (x: 160., y: 160.),
    (x: 125., y: 179.),
];
let poly2 = polygon![
    (x: 124., y: 182.),
    (x: 106., y: 146.),
    (x: 162., y: 159.),
    (x: 124., y: 182.),
];

let intersection = poly1.relate(&poly2);
assert_eq!(intersection.is_coveredby(), true);
§Notes
  • Matches any of [T*F**F***], [*TF**F***], [**FT*F***], [**F*TF***]
  • This predicate is reflexive and transitive
source

pub fn is_covers(&self) -> bool

Returns true if every point in Geometry b lies inside (i.e. intersects the interior or boundary of) Geometry a. Equivalently, tests that no point of b lies outside (in the exterior of) a.

§Notes
source

pub fn is_touches(&self) -> bool

Returns true if a touches b: they have at least one point in common, but their interiors do not intersect.

§Notes
  • Matches any of [FT*******], [F**T*****], [F***T****]
  • This predicate is symmetric
source

pub fn is_crosses(&self) -> bool

Compares two geometry objects and returns true if their intersection “spatially crosses”; that is, the geometries have some, but not all interior points in common

use geo_types::{LineString, line_string, polygon};
use geo::relate::Relate;

let line_string: LineString = line_string![(x: 85.0, y: 194.0), (x: 162.0, y: 135.0)];
let poly = polygon![
    (x: 125., y: 179.),
    (x: 110., y: 150.),
    (x: 160., y: 160.),
    (x: 125., y: 179.),
];

let intersection = line_string.relate(&poly);
assert_eq!(intersection.is_crosses(), true);
§Notes
  • If any of the following do not hold, the function will return false:
    • The intersection of the interiors of the geometries must be non-empty
    • The intersection must have dimension less than the maximum dimension of the two input geometries (two polygons cannot cross)
    • The intersection of the two geometries must not equal either geometry (two points cannot cross)
  • Matches one of [T*T******] (a < b), [T*****T**] (a > b), [0********] (dimensions == 1)
  • This predicate is symmetric and irreflexive
source

pub fn is_overlaps(&self) -> bool

Returns true if geometry a and b “spatially overlap”. Two geometries overlap if they have the same dimension, their interiors intersect in that dimension, and each has at least one point inside the other (or equivalently, neither one covers the other)

use geo_types::{Polygon, polygon};
use geo::relate::Relate;

let poly1 = polygon![
    (x: 125., y: 179.),
    (x: 110., y: 150.),
    (x: 160., y: 160.),
    (x: 125., y: 179.),
];
let poly2 = polygon![
    (x: 126., y: 179.),
    (x: 110., y: 150.),
    (x: 161., y: 160.),
    (x: 126., y: 179.),
];

let intersection = poly1.relate(&poly2);
assert_eq!(intersection.is_overlaps(), true);
§Notes
  • Matches one of [1*T***T**] (dimensions == 1), [T*T***T**] (dimensions == 0 OR 2)
  • This predicate is symmetric
source

pub fn get(&self, lhs: CoordPos, rhs: CoordPos) -> Dimensions

Directly accesses this matrix

use geo_types::{LineString, Rect, line_string};
use geo::{coordinate_position::CoordPos, dimensions::Dimensions, relate::Relate};

let line_string: LineString = line_string![(x: 0.0, y: 0.0), (x: 10.0, y: 0.0), (x: 5.0, y: 5.0)];
let rect = Rect::new((0.0, 0.0), (5.0, 5.0));

let intersection = line_string.relate(&rect);

// The intersection of the two interiors is empty, because no part of the string is inside the rect
assert_eq!(intersection.get(CoordPos::Inside, CoordPos::Inside), Dimensions::Empty);

// The intersection of the line string's interior with the rect's boundary is one-dimensional, because part of the first line overlaps one of the rect's edges
assert_eq!(intersection.get(CoordPos::Inside, CoordPos::OnBoundary), Dimensions::OneDimensional);

// The intersection of the line string's interior with the rect's exterior is one-dimensional, because part of the string is outside the rect
assert_eq!(intersection.get(CoordPos::Inside, CoordPos::Outside), Dimensions::OneDimensional);

// The intersection of the line string's boundary with the rect's interior is empty, because neither of its end points are inside the rect
assert_eq!(intersection.get(CoordPos::OnBoundary, CoordPos::Inside), Dimensions::Empty);

// The intersection of the line string's boundary with the rect's boundary is zero-dimensional, because the string's start and end points are on the rect's edges
assert_eq!(intersection.get(CoordPos::OnBoundary, CoordPos::OnBoundary), Dimensions::ZeroDimensional);

// The intersection of the line string's boundary with the rect's exterior is empty, because neither of its end points are outside the rect
assert_eq!(intersection.get(CoordPos::OnBoundary, CoordPos::Outside), Dimensions::Empty);

// The intersection of the the line's exterior with the rect's interior is two-dimensional, because it's simply the rect's interior
assert_eq!(intersection.get(CoordPos::Outside, CoordPos::Inside), Dimensions::TwoDimensional);

// The intersection of the line's exterior with the rect's boundary is one-dimensional, because it's the rect's edges (minus where the string overlaps it)
assert_eq!(intersection.get(CoordPos::Outside, CoordPos::OnBoundary), Dimensions::OneDimensional);

// The intersection of the two exteriors is two-dimensional, because it's the whole plane around the two shapes
assert_eq!(intersection.get(CoordPos::Outside, CoordPos::Outside), Dimensions::TwoDimensional);
source

pub fn matches(&self, spec: &str) -> Result<bool, InvalidInputError>

Does the intersection matrix match the provided DE-9IM specification string?

A DE-9IM spec string must be 9 characters long, and each character must be one of the following:

  • 0: matches a 0-dimensional (point) intersection
  • 1: matches a 1-dimensional (line) intersection
  • 2: matches a 2-dimensional (area) intersection
  • f or F: matches only empty dimensions
  • t or T: matches anything non-empty
  • *: matches anything
use geo::algorithm::Relate;
use geo::geometry::Polygon;
use wkt::TryFromWkt;

let a = Polygon::<f64>::try_from_wkt_str("POLYGON((0 0,4 0,4 4,0 4,0 0))").expect("valid WKT");
let b = Polygon::<f64>::try_from_wkt_str("POLYGON((1 1,4 0,4 4,0 4,1 1))").expect("valid WKT");
let im = a.relate(&b);
assert!(im.matches("212F11FF2").expect("valid DE-9IM spec"));
assert!(im.matches("TTT***FF2").expect("valid DE-9IM spec"));
assert!(!im.matches("TTT***FFF").expect("valid DE-9IM spec"));

Trait Implementations§

source§

impl Clone for IntersectionMatrix

source§

fn clone(&self) -> IntersectionMatrix

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for IntersectionMatrix

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl FromStr for IntersectionMatrix

Build an IntersectionMatrix based on a string specification.

use geo::algorithm::relate::IntersectionMatrix;
use std::str::FromStr;

let intersection_matrix = IntersectionMatrix::from_str("212101212").expect("valid DE-9IM specification");
assert!(intersection_matrix.is_intersects());
assert!(!intersection_matrix.is_contains());
§

type Err = InvalidInputError

The associated error which can be returned from parsing.
source§

fn from_str(str: &str) -> Result<Self, Self::Err>

Parses a string s to return a value of this type. Read more
source§

impl PartialEq for IntersectionMatrix

source§

fn eq(&self, other: &IntersectionMatrix) -> bool

This method tests for self and other values to be equal, and is used by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
source§

impl Eq for IntersectionMatrix

source§

impl StructuralPartialEq for IntersectionMatrix

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<Q, K> Equivalent<K> for Q
where Q: Eq + ?Sized, K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

source§

impl<T, U> Into<U> for T
where U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

source§

impl<T> ToOwned for T
where T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
source§

impl<G1, G2> Within<G2> for G1
where G2: Contains<G1>,

source§

fn is_within(&self, b: &G2) -> bool