Skip to content

Commit

Permalink
WIP: add support for multipolygon
Browse files Browse the repository at this point in the history
  • Loading branch information
michaelkirk committed Nov 2, 2024
1 parent 11193b6 commit 39a2f62
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 7 deletions.
39 changes: 39 additions & 0 deletions geo-types/src/geometry/multi_polygon.rs
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,45 @@ where
}
}

#[cfg(any(
feature = "rstar_0_8",
feature = "rstar_0_9",
feature = "rstar_0_10",
feature = "rstar_0_11",
feature = "rstar_0_12"
))]
macro_rules! impl_rstar_multi_polygon {
($rstar:ident) => {
impl<T> $rstar::RTreeObject for MultiPolygon<T>
where
T: ::num_traits::Float + ::$rstar::RTreeNum,
{
type Envelope = ::$rstar::AABB<$crate::Point<T>>;

fn envelope(&self) -> Self::Envelope {
use ::$rstar::Envelope;
self.iter()
.map(|p| p.envelope())
.fold(::$rstar::AABB::new_empty(), |a, b| a.merged(&b))
}
}
};
}
#[cfg(feature = "rstar_0_8")]
impl_rstar_multi_polygon!(rstar_0_8);

#[cfg(feature = "rstar_0_9")]
impl_rstar_multi_polygon!(rstar_0_9);

#[cfg(feature = "rstar_0_10")]
impl_rstar_multi_polygon!(rstar_0_10);

#[cfg(feature = "rstar_0_11")]
impl_rstar_multi_polygon!(rstar_0_11);

#[cfg(feature = "rstar_0_12")]
impl_rstar_multi_polygon!(rstar_0_12);

#[cfg(test)]
mod test {
use super::*;
Expand Down
8 changes: 4 additions & 4 deletions geo/src/algorithm/bool_ops/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -226,18 +226,18 @@ impl<T: BoolOpsNum> BooleanOps for MultiPolygon<T> {
}

/// Allows the unary union operation to be performed on any container which can produce items of type `Polygon<T>`
impl<T, Container> UnaryUnion for Container
impl<T, Boppable, BoppableCollection> UnaryUnion for BoppableCollection
where
T: BoolOpsNum,
Container: IntoIterator<Item = Polygon<T>> + Clone,
Polygon<T>: RTreeObject,
Boppable: BooleanOps<Scalar = T> + RTreeObject,
BoppableCollection: IntoIterator<Item = Boppable> + Clone,
{
type Scalar = T;

fn unary_union(&self) -> MultiPolygon<Self::Scalar> {
// these three functions drive the union operation
let init = || MultiPolygon::<T>::new(vec![]);
let fold = |mut accum: MultiPolygon<T>, poly: &Polygon<T>| -> MultiPolygon<T> {
let fold = |mut accum: MultiPolygon<T>, poly: &Boppable| -> MultiPolygon<T> {
accum = accum.union(poly);
accum
};
Expand Down
14 changes: 11 additions & 3 deletions geo/src/algorithm/bool_ops/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,17 @@ fn test_unary_union() {
let poly2: Polygon = wkt!(POLYGON((210.0 290.0,204.07584923592933 288.2701221108328,212.24082541367974 285.47846008552216,210.0 290.0)));
let poly3: Polygon = wkt!(POLYGON((211.0 292.0,204.07584923592933 288.2701221108328,212.24082541367974 285.47846008552216,210.0 290.0)));

let polys = vec![poly1, poly2, poly3];
let res = polys.unary_union();
assert_eq!(res.0.len(), 1);
let polys = vec![poly1.clone(), poly2.clone(), poly3.clone()];
let poly_union = polys.unary_union();
assert_eq!(poly_union.0.len(), 1);

let multi_poly_1 = MultiPolygon::new(vec![poly1, poly2]);
let multi_poly_2 = MultiPolygon::new(vec![poly3]);
let multi_polys = vec![multi_poly_1, multi_poly_2];
let multi_poly_union = multi_polys.unary_union();
// FIXME: This should be 1, same as poly_union, right?
assert_eq!(multi_poly_union.0.len(), 1);
assert_eq!(poly_union, multi_poly_union);
}

#[test]
Expand Down

0 comments on commit 39a2f62

Please sign in to comment.