diff --git a/src/algorithm/geo/simplify.rs b/src/algorithm/geo/simplify.rs index f765050c0..f023d76c4 100644 --- a/src/algorithm/geo/simplify.rs +++ b/src/algorithm/geo/simplify.rs @@ -4,9 +4,11 @@ use crate::array::*; use crate::chunked_array::ChunkedGeometryArray; use crate::datatypes::GeoDataType; use crate::error::{GeoArrowError, Result}; +use crate::scalar::linestring::scalar::TakeLineString; +use crate::trait_::GeometryScalarTrait; use crate::GeometryArrayTrait; use arrow_array::OffsetSizeTrait; -use geo::Simplify as _Simplify; +use geo::{Simplify as _Simplify, SimplifyIdx}; /// Simplifies a geometry. /// @@ -96,7 +98,26 @@ macro_rules! iter_geo_impl { }; } -iter_geo_impl!(LineStringArray, geo::LineString); +impl Simplify for LineStringArray { + type Output = Self; + + fn simplify(&self, epsilon: &f64) -> Self { + let geoms = self + .iter() + .map(|maybe_g| { + if let Some(geom) = maybe_g { + let idxs = geom.to_geo().simplify_idx(epsilon); + Some(TakeLineString::new(geom, idxs)) + } else { + None + } + }) + .collect::>(); + LineStringBuilder::from_nullable_line_strings(geoms.as_slice(), Default::default()).finish() + } +} + +// iter_geo_impl!(LineStringArray, geo::LineString); iter_geo_impl!(PolygonArray, geo::Polygon); iter_geo_impl!(MultiLineStringArray, geo::MultiLineString); iter_geo_impl!(MultiPolygonArray, geo::MultiPolygon); diff --git a/src/array/linestring/capacity.rs b/src/array/linestring/capacity.rs index 8129e84c3..7774af859 100644 --- a/src/array/linestring/capacity.rs +++ b/src/array/linestring/capacity.rs @@ -1,4 +1,4 @@ -use std::ops::Add; +use std::ops::{Add, AddAssign}; use arrow_array::OffsetSizeTrait; @@ -52,6 +52,12 @@ impl LineStringCapacity { }; Ok(()) } + + #[inline] + pub fn add_null(&mut self) { + self.geom_capacity += 1; + } + pub fn coord_capacity(&self) -> usize { self.coord_capacity } @@ -94,3 +100,10 @@ impl Add for LineStringCapacity { Self::new(coord_capacity, geom_capacity) } } + +impl AddAssign for LineStringCapacity { + fn add_assign(&mut self, rhs: Self) { + self.coord_capacity += rhs.coord_capacity; + self.geom_capacity += rhs.geom_capacity; + } +} diff --git a/src/scalar/linestring/mod.rs b/src/scalar/linestring/mod.rs index 31c1a9f02..b16698413 100644 --- a/src/scalar/linestring/mod.rs +++ b/src/scalar/linestring/mod.rs @@ -1,6 +1,6 @@ pub mod iterator; mod owned; -mod scalar; +pub(crate) mod scalar; pub use iterator::LineStringIterator; pub use owned::OwnedLineString; diff --git a/src/scalar/linestring/scalar.rs b/src/scalar/linestring/scalar.rs index 5da7056dc..cc74044fd 100644 --- a/src/scalar/linestring/scalar.rs +++ b/src/scalar/linestring/scalar.rs @@ -180,6 +180,42 @@ impl PartialEq for LineString<'_, O> { } } +/// A LineString where specific indices of the geometry are selected +/// +/// Primarily used in the Simplify trait +pub(crate) struct TakeLineString<'a, O: OffsetSizeTrait> { + line_string: LineString<'a, O>, + idxs: Vec, +} + +impl<'a, O: OffsetSizeTrait> TakeLineString<'a, O> { + pub fn new(line_string: LineString<'a, O>, idxs: Vec) -> Self { + Self { line_string, idxs } + } +} + +impl<'a, O: OffsetSizeTrait> LineStringTrait for TakeLineString<'a, O> { + type T = f64; + type ItemType<'b> = Point<'a> where Self: 'b; + type Iter<'b> = LineStringIterator<'a, O> where Self: 'b; + + fn coords(&self) -> Self::Iter<'_> { + todo!() + } + + fn num_coords(&self) -> usize { + self.idxs.len() + } + + fn coord(&self, i: usize) -> Option> { + if i > self.num_coords() { + return None; + } + + self.line_string.coord(self.idxs[i]) + } +} + #[cfg(test)] mod test { use crate::array::LineStringArray; diff --git a/src/scalar/mod.rs b/src/scalar/mod.rs index 77825f8a0..58b0cc827 100644 --- a/src/scalar/mod.rs +++ b/src/scalar/mod.rs @@ -5,7 +5,7 @@ pub use binary::WKB; pub use coord::{Coord, InterleavedCoord, SeparatedCoord}; pub use geometry::Geometry; pub use geometrycollection::GeometryCollection; -pub use linestring::{LineString, OwnedLineString}; +pub use linestring::{LineString, LineStringIterator, OwnedLineString}; pub use multilinestring::{MultiLineString, OwnedMultiLineString}; pub use multipoint::{MultiPoint, OwnedMultiPoint}; pub use multipolygon::{MultiPolygon, OwnedMultiPolygon}; @@ -17,7 +17,7 @@ mod binary; mod coord; mod geometry; mod geometrycollection; -mod linestring; +pub(crate) mod linestring; mod multilinestring; mod multipoint; mod multipolygon;