use arrow_buffer::OffsetBuffer;
use geo_traits::MultiPolygonTrait;
use geoarrow_schema::Dimension;
use crate::array::CoordBuffer;
use crate::eq::multi_polygon_eq;
use crate::scalar::Polygon;
use crate::util::OffsetBufferUtils;
#[derive(Debug, Clone)]
pub struct MultiPolygon<'a> {
pub(crate) coords: &'a CoordBuffer,
pub(crate) geom_offsets: &'a OffsetBuffer<i32>,
pub(crate) polygon_offsets: &'a OffsetBuffer<i32>,
pub(crate) ring_offsets: &'a OffsetBuffer<i32>,
pub(crate) geom_index: usize,
start_offset: usize,
}
impl<'a> MultiPolygon<'a> {
pub(crate) fn new(
coords: &'a CoordBuffer,
geom_offsets: &'a OffsetBuffer<i32>,
polygon_offsets: &'a OffsetBuffer<i32>,
ring_offsets: &'a OffsetBuffer<i32>,
geom_index: usize,
) -> Self {
let (start_offset, _) = geom_offsets.start_end(geom_index);
Self {
coords,
geom_offsets,
polygon_offsets,
ring_offsets,
geom_index,
start_offset,
}
}
pub(crate) fn native_dim(&self) -> Dimension {
self.coords.dim()
}
}
impl<'a> MultiPolygonTrait for MultiPolygon<'a> {
type InnerPolygonType<'b>
= Polygon<'a>
where
Self: 'b;
fn num_polygons(&self) -> usize {
let (start, end) = self.geom_offsets.start_end(self.geom_index);
end - start
}
unsafe fn polygon_unchecked(&self, i: usize) -> Self::InnerPolygonType<'_> {
Polygon::new(
self.coords,
self.polygon_offsets,
self.ring_offsets,
self.start_offset + i,
)
}
}
impl<'a> MultiPolygonTrait for &'a MultiPolygon<'a> {
type InnerPolygonType<'b>
= Polygon<'a>
where
Self: 'b;
fn num_polygons(&self) -> usize {
let (start, end) = self.geom_offsets.start_end(self.geom_index);
end - start
}
unsafe fn polygon_unchecked(&self, i: usize) -> Self::InnerPolygonType<'_> {
Polygon::new(
self.coords,
self.polygon_offsets,
self.ring_offsets,
self.start_offset + i,
)
}
}
impl<G: MultiPolygonTrait<T = f64>> PartialEq<G> for MultiPolygon<'_> {
fn eq(&self, other: &G) -> bool {
multi_polygon_eq(self, other)
}
}