Skip to content

Commit

Permalink
impl Contains for all geometries
Browse files Browse the repository at this point in the history
  • Loading branch information
michaelkirk committed Jul 28, 2022
1 parent cda3fed commit ffecf0c
Show file tree
Hide file tree
Showing 12 changed files with 362 additions and 247 deletions.
109 changes: 92 additions & 17 deletions geo/src/algorithm/contains/geometry.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,7 @@
use super::Contains;
use crate::geometry::{Coordinate, Geometry, GeometryCollection, Point};
use crate::geometry::*;
use crate::geometry_delegate_impl;
use crate::GeoNum;

// ┌──────────────────────────────┐
// │ Implementations for Geometry │
// └──────────────────────────────┘
use crate::{GeoFloat, GeoNum};

impl<T> Contains<Coordinate<T>> for Geometry<T>
where
Expand All @@ -25,24 +21,103 @@ where
}
}

// ┌────────────────────────────────────────┐
// │ Implementations for GeometryCollection │
// └────────────────────────────────────────┘
impl<T> Contains<Line<T>> for Geometry<T>
where
T: GeoFloat,
{
geometry_delegate_impl! {
fn contains(&self, line: &Line<T>) -> bool;
}
}

impl<T> Contains<Coordinate<T>> for GeometryCollection<T>
impl<T> Contains<LineString<T>> for Geometry<T>
where
T: GeoNum,
T: GeoFloat,
{
fn contains(&self, coord: &Coordinate<T>) -> bool {
self.iter().any(|geometry| geometry.contains(coord))
geometry_delegate_impl! {
fn contains(&self, line_string: &LineString<T>) -> bool;
}
}

impl<T> Contains<Point<T>> for GeometryCollection<T>
impl<T> Contains<Polygon<T>> for Geometry<T>
where
T: GeoNum,
T: GeoFloat,
{
geometry_delegate_impl! {
fn contains(&self, polygon: &Polygon<T>) -> bool;
}
}

impl<T> Contains<MultiPoint<T>> for Geometry<T>
where
T: GeoFloat,
{
geometry_delegate_impl! {
fn contains(&self, multi_point: &MultiPoint<T>) -> bool;
}
}

impl<T> Contains<MultiLineString<T>> for Geometry<T>
where
T: GeoFloat,
{
geometry_delegate_impl! {
fn contains(&self, multi_line_string: &MultiLineString<T>) -> bool;
}
}

impl<T> Contains<MultiPolygon<T>> for Geometry<T>
where
T: GeoFloat,
{
geometry_delegate_impl! {
fn contains(&self, multi_line_string: &MultiPolygon<T>) -> bool;
}
}

impl<T> Contains<GeometryCollection<T>> for Geometry<T>
where
T: GeoFloat,
{
geometry_delegate_impl! {
fn contains(&self, geometry_collection: &GeometryCollection<T>) -> bool;
}
}

impl<T> Contains<Rect<T>> for Geometry<T>
where
T: GeoFloat,
{
geometry_delegate_impl! {
fn contains(&self, rect: &Rect<T>) -> bool;
}
}

impl<T> Contains<Triangle<T>> for Geometry<T>
where
T: GeoFloat,
{
geometry_delegate_impl! {
fn contains(&self, triangle: &Triangle<T>) -> bool;
}
}

impl<T> Contains<Geometry<T>> for Geometry<T>
where
T: GeoFloat,
{
fn contains(&self, point: &Point<T>) -> bool {
self.contains(&point.0)
fn contains(&self, other: &Geometry<T>) -> bool {
match other {
Geometry::Point(geom) => self.contains(geom),
Geometry::Line(geom) => self.contains(geom),
Geometry::LineString(geom) => self.contains(geom),
Geometry::Polygon(geom) => self.contains(geom),
Geometry::MultiPoint(geom) => self.contains(geom),
Geometry::MultiLineString(geom) => self.contains(geom),
Geometry::MultiPolygon(geom) => self.contains(geom),
Geometry::GeometryCollection(geom) => self.contains(geom),
Geometry::Rect(geom) => self.contains(geom),
Geometry::Triangle(geom) => self.contains(geom),
}
}
}
24 changes: 24 additions & 0 deletions geo/src/algorithm/contains/geometry_collection.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
use super::{impl_contains_from_relate, impl_contains_geometry_for, Contains};
use crate::geometry::*;
use crate::{GeoFloat, GeoNum};

impl<T> Contains<Coordinate<T>> for GeometryCollection<T>
where
T: GeoNum,
{
fn contains(&self, coord: &Coordinate<T>) -> bool {
self.iter().any(|geometry| geometry.contains(coord))
}
}

impl<T> Contains<Point<T>> for GeometryCollection<T>
where
T: GeoNum,
{
fn contains(&self, point: &Point<T>) -> bool {
self.contains(&point.0)
}
}

impl_contains_from_relate!(GeometryCollection<T>, [Line<T>, LineString<T>, Polygon<T>, MultiPoint<T>, MultiLineString<T>, MultiPolygon<T>, GeometryCollection<T>, Rect<T>, Triangle<T>]);
impl_contains_geometry_for!(GeometryCollection<T>);
10 changes: 7 additions & 3 deletions geo/src/algorithm/contains/line.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use super::Contains;
use crate::Intersects;
use crate::{Coordinate, GeoNum, Line, LineString, Point};
use super::{impl_contains_from_relate, impl_contains_geometry_for, Contains};
use crate::algorithm::Intersects;
use crate::geometry::*;
use crate::{GeoFloat, GeoNum};

// ┌──────────────────────────┐
// │ Implementations for Line │
Expand Down Expand Up @@ -81,3 +82,6 @@ where
all_intersects && (!all_equal || self.contains(first))
}
}

impl_contains_from_relate!(Line<T>, [Polygon<T>, MultiPoint<T>, MultiLineString<T>, MultiPolygon<T>, GeometryCollection<T>, Rect<T>, Triangle<T>]);
impl_contains_geometry_for!(Line<T>);
22 changes: 15 additions & 7 deletions geo/src/algorithm/contains/line_string.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use super::Contains;
use crate::Intersects;
use crate::{CoordNum, Coordinate, GeoNum, Line, LineString, MultiLineString, Point};
use super::{impl_contains_from_relate, impl_contains_geometry_for, Contains};
use crate::algorithm::Intersects;
use crate::geometry::*;
use crate::{CoordNum, GeoFloat, GeoNum};

// ┌────────────────────────────────┐
// │ Implementations for LineString │
Expand Down Expand Up @@ -113,15 +114,22 @@ where
}
}

impl_contains_from_relate!(LineString<T>, [Polygon<T>, MultiPoint<T>, MultiLineString<T>, MultiPolygon<T>, GeometryCollection<T>, Rect<T>, Triangle<T>]);
impl_contains_geometry_for!(LineString<T>);

// ┌─────────────────────────────────────┐
// │ Implementations for MultiLineString │
// └─────────────────────────────────────┘
impl<G, T> Contains<G> for MultiLineString<T>

impl_contains_from_relate!(MultiLineString<T>, [Line<T>, LineString<T>, Polygon<T>, MultiPoint<T>, MultiLineString<T>, MultiPolygon<T>, GeometryCollection<T>, Rect<T>, Triangle<T>]);
impl_contains_geometry_for!(MultiLineString<T>);

impl<T> Contains<Point<T>> for MultiLineString<T>
where
T: CoordNum,
LineString<T>: Contains<G>,
LineString<T>: Contains<Point<T>>,
{
fn contains(&self, rhs: &G) -> bool {
self.iter().any(|p| p.contains(rhs))
fn contains(&self, rhs: &Point<T>) -> bool {
self.iter().any(|ls| ls.contains(rhs))
}
}
43 changes: 43 additions & 0 deletions geo/src/algorithm/contains/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,13 +37,56 @@ pub trait Contains<Rhs = Self> {
}

mod geometry;
mod geometry_collection;
mod line;
mod line_string;
mod point;
mod polygon;
mod rect;
mod triangle;

macro_rules! impl_contains_from_relate {
($for:ty, [$($target:ty),*]) => {
$(
impl<T> Contains<$target> for $for
where
T: GeoFloat
{
fn contains(&self, target: &$target) -> bool {
use $crate::algorithm::Relate;
self.relate(target).is_contains()
}
}
)*
};
}
pub(crate) use impl_contains_from_relate;

macro_rules! impl_contains_geometry_for {
($geom_type: ty) => {
impl<T> Contains<Geometry<T>> for $geom_type
where
T: GeoFloat,
{
fn contains(&self, geometry: &Geometry<T>) -> bool {
match geometry {
Geometry::Point(g) => self.contains(g),
Geometry::Line(g) => self.contains(g),
Geometry::LineString(g) => self.contains(g),
Geometry::Polygon(g) => self.contains(g),
Geometry::MultiPoint(g) => self.contains(g),
Geometry::MultiLineString(g) => self.contains(g),
Geometry::MultiPolygon(g) => self.contains(g),
Geometry::GeometryCollection(g) => self.contains(g),
Geometry::Rect(g) => self.contains(g),
Geometry::Triangle(g) => self.contains(g),
}
}
}
};
}
pub(crate) use impl_contains_geometry_for;

// ┌───────┐
// │ Tests │
// └───────┘
Expand Down
Loading

0 comments on commit ffecf0c

Please sign in to comment.