use core::{iter::Map, slice::Iter};
use rstar::{AABB, Envelope, RTreeNum, primitives::Rectangle};
pub trait Rings<K> {
type RingIter<'a>: Iterator<Item = &'a [[K; 2]]>
where
Self: 'a,
K: 'a;
fn exterior(&self) -> &[[K; 2]];
fn interiors<'a>(&'a self) -> Self::RingIter<'a>;
}
pub(crate) fn rectangle_from_polygon<K: RTreeNum, P: Rings<K>>(polygon: &P) -> Rectangle<[K; 2]> {
Rectangle::from_aabb(
polygon
.exterior()
.iter()
.fold(AABB::new_empty(), |aabb, vertex| {
aabb.merged(&AABB::from_point([vertex[0], vertex[1]]))
}),
)
}
#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
pub struct PolygonId(usize);
impl PolygonId {
#[inline]
pub fn new(id: usize) -> Self {
Self(id)
}
#[inline]
pub fn index(self) -> usize {
self.0
}
}
#[derive(Clone, Debug)]
pub struct Polygon<K> {
pub exterior: Vec<[K; 2]>,
pub interiors: Vec<Vec<[K; 2]>>,
}
impl<K> Rings<K> for Polygon<K> {
type RingIter<'a>
= Map<Iter<'a, Vec<[K; 2]>>, fn(&'a Vec<[K; 2]>) -> &'a [[K; 2]]>
where
K: 'a;
fn exterior(&self) -> &[[K; 2]] {
self.exterior.as_slice()
}
fn interiors<'a>(&'a self) -> Self::RingIter<'a> {
self.interiors.iter().map(Vec::as_slice)
}
}
#[derive(Clone, Debug)]
pub struct PolygonWithData<K, W = ()> {
pub exterior: Vec<[K; 2]>,
pub interiors: Vec<Vec<[K; 2]>>,
pub data: W,
}
impl<K, W> Rings<K> for PolygonWithData<K, W> {
type RingIter<'a>
= Map<Iter<'a, Vec<[K; 2]>>, fn(&'a Vec<[K; 2]>) -> &'a [[K; 2]]>
where
K: 'a,
W: 'a;
fn exterior(&self) -> &[[K; 2]] {
self.exterior.as_slice()
}
fn interiors<'a>(&'a self) -> Self::RingIter<'a> {
self.interiors.iter().map(Vec::as_slice)
}
}