diff --git a/js/src/algorithm/geo/area.rs b/js/src/algorithm/geo/area.rs index f4ed0ab5..5761e4bb 100644 --- a/js/src/algorithm/geo/area.rs +++ b/js/src/algorithm/geo/area.rs @@ -28,4 +28,3 @@ impl_area!(PolygonArray); impl_area!(MultiPointArray); impl_area!(MultiLineStringArray); impl_area!(MultiPolygonArray); -impl_area!(GeometryArray); diff --git a/js/src/algorithm/geo/bounding_rect.rs b/js/src/algorithm/geo/bounding_rect.rs index 8aa6ecd0..687b65d9 100644 --- a/js/src/algorithm/geo/bounding_rect.rs +++ b/js/src/algorithm/geo/bounding_rect.rs @@ -21,4 +21,3 @@ impl_bounding_rect!(PolygonArray); impl_bounding_rect!(MultiPointArray); impl_bounding_rect!(MultiLineStringArray); impl_bounding_rect!(MultiPolygonArray); -impl_bounding_rect!(GeometryArray); diff --git a/js/src/algorithm/geo/center.rs b/js/src/algorithm/geo/center.rs index 809d91ed..4e9cc5ee 100644 --- a/js/src/algorithm/geo/center.rs +++ b/js/src/algorithm/geo/center.rs @@ -24,4 +24,3 @@ impl_center!(PolygonArray); impl_center!(MultiPointArray); impl_center!(MultiLineStringArray); impl_center!(MultiPolygonArray); -impl_center!(GeometryArray); diff --git a/js/src/algorithm/geo/centroid.rs b/js/src/algorithm/geo/centroid.rs index ef200f97..196eb8f3 100644 --- a/js/src/algorithm/geo/centroid.rs +++ b/js/src/algorithm/geo/centroid.rs @@ -28,4 +28,3 @@ impl_centroid!(PolygonArray); impl_centroid!(MultiPointArray); impl_centroid!(MultiLineStringArray); impl_centroid!(MultiPolygonArray); -impl_centroid!(GeometryArray); diff --git a/js/src/algorithm/geo/chamberlain_duquette_area.rs b/js/src/algorithm/geo/chamberlain_duquette_area.rs index c0d73801..1882d81b 100644 --- a/js/src/algorithm/geo/chamberlain_duquette_area.rs +++ b/js/src/algorithm/geo/chamberlain_duquette_area.rs @@ -32,4 +32,3 @@ impl_alg!(PolygonArray); impl_alg!(MultiPointArray); impl_alg!(MultiLineStringArray); impl_alg!(MultiPolygonArray); -impl_alg!(GeometryArray); diff --git a/js/src/algorithm/geo/convex_hull.rs b/js/src/algorithm/geo/convex_hull.rs index 8b72218d..0191b987 100644 --- a/js/src/algorithm/geo/convex_hull.rs +++ b/js/src/algorithm/geo/convex_hull.rs @@ -27,4 +27,3 @@ impl_alg!(PolygonArray); impl_alg!(MultiPointArray); impl_alg!(MultiLineStringArray); impl_alg!(MultiPolygonArray); -impl_alg!(GeometryArray); diff --git a/js/src/algorithm/geo/dimensions.rs b/js/src/algorithm/geo/dimensions.rs index d59cea63..9fa16dea 100644 --- a/js/src/algorithm/geo/dimensions.rs +++ b/js/src/algorithm/geo/dimensions.rs @@ -25,4 +25,3 @@ impl_alg!(PolygonArray); impl_alg!(MultiPointArray); impl_alg!(MultiLineStringArray); impl_alg!(MultiPolygonArray); -impl_alg!(GeometryArray); diff --git a/js/src/algorithm/geo/geodesic_area.rs b/js/src/algorithm/geo/geodesic_area.rs index 624dc6da..562e91fb 100644 --- a/js/src/algorithm/geo/geodesic_area.rs +++ b/js/src/algorithm/geo/geodesic_area.rs @@ -139,4 +139,3 @@ impl_geodesic_area!(PolygonArray); impl_geodesic_area!(MultiPointArray); impl_geodesic_area!(MultiLineStringArray); impl_geodesic_area!(MultiPolygonArray); -impl_geodesic_area!(GeometryArray); diff --git a/js/src/algorithm/geoarrow/coord_format.rs b/js/src/algorithm/geoarrow/coord_format.rs index 3b4a27e2..db680421 100644 --- a/js/src/algorithm/geoarrow/coord_format.rs +++ b/js/src/algorithm/geoarrow/coord_format.rs @@ -66,4 +66,3 @@ impl_coord_type!(PolygonArray); impl_coord_type!(MultiPointArray); impl_coord_type!(MultiLineStringArray); impl_coord_type!(MultiPolygonArray); -impl_coord_type!(GeometryArray); diff --git a/js/src/array/geometry.rs b/js/src/array/geometry.rs deleted file mode 100644 index 34739a32..00000000 --- a/js/src/array/geometry.rs +++ /dev/null @@ -1,84 +0,0 @@ -use crate::array::polygon::PolygonArray; -use crate::array::{ - LineStringArray, MultiLineStringArray, MultiPointArray, MultiPolygonArray, PointArray, -}; -use crate::error::WasmResult; -use crate::impl_geometry_array; -#[cfg(feature = "geodesy")] -use crate::reproject::ReprojectDirection; -use wasm_bindgen::prelude::*; - -/// An enum of geometry types -#[wasm_bindgen] -pub enum GeometryType { - Point = 0, - LineString = 1, - Polygon = 3, - MultiPoint = 4, - MultiLineString = 5, - MultiPolygon = 6, -} - -/// A GeometryArray that can be any of various underlying geometry types -#[wasm_bindgen] -pub struct GeometryArray(pub(crate) geoarrow::array::GeometryArray); - -impl_geometry_array!(GeometryArray); - -#[wasm_bindgen] -impl GeometryArray { - #[wasm_bindgen(js_name = fromPointArray)] - pub fn from_point_array(arr: PointArray) -> Self { - Self(geoarrow::array::GeometryArray::Point(arr.0)) - } - - #[wasm_bindgen(js_name = fromLineStringArray)] - pub fn from_line_string_array(arr: LineStringArray) -> Self { - Self(geoarrow::array::GeometryArray::LineString(arr.0)) - } - - #[wasm_bindgen(js_name = fromPolygonArray)] - pub fn from_polygon_array(arr: PolygonArray) -> Self { - Self(geoarrow::array::GeometryArray::Polygon(arr.0)) - } - - #[wasm_bindgen(js_name = fromMultiPointArray)] - pub fn from_multi_point_array(arr: MultiPointArray) -> Self { - Self(geoarrow::array::GeometryArray::MultiPoint(arr.0)) - } - - #[wasm_bindgen(js_name = fromMultiLineStringArray)] - pub fn from_multi_line_string_array(arr: MultiLineStringArray) -> Self { - Self(geoarrow::array::GeometryArray::MultiLineString(arr.0)) - } - - #[wasm_bindgen(js_name = fromMultiPolygonArray)] - pub fn from_multi_polygon_array(arr: MultiPolygonArray) -> Self { - Self(geoarrow::array::GeometryArray::MultiPolygon(arr.0)) - } - - #[wasm_bindgen(js_name = geometryType)] - pub fn geometry_type(&self) -> GeometryType { - match self.0 { - geoarrow::array::GeometryArray::Point(_) => GeometryType::Point, - geoarrow::array::GeometryArray::LineString(_) => GeometryType::LineString, - geoarrow::array::GeometryArray::Polygon(_) => GeometryType::Polygon, - geoarrow::array::GeometryArray::MultiPoint(_) => GeometryType::MultiPoint, - geoarrow::array::GeometryArray::MultiLineString(_) => GeometryType::MultiLineString, - geoarrow::array::GeometryArray::MultiPolygon(_) => GeometryType::MultiPolygon, - geoarrow::array::GeometryArray::Rect(_) => unimplemented!(), - } - } -} - -impl From<&GeometryArray> for geoarrow::array::GeometryArray { - fn from(value: &GeometryArray) -> Self { - value.0.clone() - } -} - -impl From> for GeometryArray { - fn from(value: geoarrow::array::GeometryArray) -> Self { - Self(value) - } -} diff --git a/js/src/array/linestring.rs b/js/src/array/linestring.rs index b9a0c26d..d28cdf4b 100644 --- a/js/src/array/linestring.rs +++ b/js/src/array/linestring.rs @@ -1,9 +1,7 @@ use crate::array::CoordBuffer; -use crate::array::GeometryArray; -use crate::error::WasmResult; -use crate::impl_geometry_array; -#[cfg(feature = "geodesy")] -use crate::reproject::ReprojectDirection; +// use crate::error::WasmResult; +// #[cfg(feature = "geodesy")] +// use crate::reproject::ReprojectDirection; use crate::utils::vec_to_offsets; use wasm_bindgen::prelude::*; @@ -12,8 +10,6 @@ use wasm_bindgen::prelude::*; #[wasm_bindgen] pub struct LineStringArray(pub(crate) geoarrow::array::LineStringArray); -impl_geometry_array!(LineStringArray); - #[wasm_bindgen] impl LineStringArray { #[wasm_bindgen(constructor)] @@ -26,12 +22,6 @@ impl LineStringArray { } } -impl From<&LineStringArray> for geoarrow::array::GeometryArray { - fn from(value: &LineStringArray) -> Self { - geoarrow::array::GeometryArray::LineString(value.0.clone()) - } -} - impl From> for LineStringArray { fn from(value: geoarrow::array::LineStringArray) -> Self { Self(value) diff --git a/js/src/array/macro.rs b/js/src/array/macro.rs deleted file mode 100644 index e889bacb..00000000 --- a/js/src/array/macro.rs +++ /dev/null @@ -1,24 +0,0 @@ -// TODO: better to not export at the top level? -// https://stackoverflow.com/a/31749071 -#[macro_export] -macro_rules! impl_geometry_array { - ($struct_name:ident) => { - #[wasm_bindgen] - impl $struct_name { - #[cfg(feature = "geodesy")] - #[wasm_bindgen(js_name = reprojectRs)] - pub fn reproject_rs( - &self, - definition: &str, - direction: ReprojectDirection, - ) -> WasmResult { - use geoarrow::algorithm::geodesy::reproject; - Ok(GeometryArray(reproject( - &self.into(), - definition, - direction.into(), - )?)) - } - } - }; -} diff --git a/js/src/array/mod.rs b/js/src/array/mod.rs index 0cb310fa..8ba73080 100644 --- a/js/src/array/mod.rs +++ b/js/src/array/mod.rs @@ -1,8 +1,6 @@ pub mod binary; pub mod coord; -pub mod geometry; pub mod linestring; -pub mod r#macro; pub mod multilinestring; pub mod multipoint; pub mod multipolygon; @@ -13,7 +11,6 @@ pub mod rect; pub use binary::WKBArray; pub use coord::{CoordBuffer, InterleavedCoordBuffer, SeparatedCoordBuffer}; -pub use geometry::GeometryArray; pub use linestring::LineStringArray; pub use multilinestring::MultiLineStringArray; pub use multipoint::MultiPointArray; diff --git a/js/src/array/multilinestring.rs b/js/src/array/multilinestring.rs index da537900..6ee5f5f0 100644 --- a/js/src/array/multilinestring.rs +++ b/js/src/array/multilinestring.rs @@ -1,9 +1,7 @@ use crate::array::CoordBuffer; -use crate::array::GeometryArray; -use crate::error::WasmResult; -use crate::impl_geometry_array; -#[cfg(feature = "geodesy")] -use crate::reproject::ReprojectDirection; +// use crate::error::WasmResult; +// #[cfg(feature = "geodesy")] +// use crate::reproject::ReprojectDirection; use crate::utils::vec_to_offsets; use wasm_bindgen::prelude::*; @@ -12,8 +10,6 @@ use wasm_bindgen::prelude::*; #[wasm_bindgen] pub struct MultiLineStringArray(pub(crate) geoarrow::array::MultiLineStringArray); -impl_geometry_array!(MultiLineStringArray); - #[wasm_bindgen] impl MultiLineStringArray { #[wasm_bindgen(constructor)] @@ -26,11 +22,6 @@ impl MultiLineStringArray { )) } } -impl From<&MultiLineStringArray> for geoarrow::array::GeometryArray { - fn from(value: &MultiLineStringArray) -> Self { - geoarrow::array::GeometryArray::MultiLineString(value.0.clone()) - } -} impl From> for MultiLineStringArray { fn from(value: geoarrow::array::MultiLineStringArray) -> Self { diff --git a/js/src/array/multipoint.rs b/js/src/array/multipoint.rs index 9988b54a..79c066dd 100644 --- a/js/src/array/multipoint.rs +++ b/js/src/array/multipoint.rs @@ -1,9 +1,7 @@ use crate::array::CoordBuffer; -use crate::array::GeometryArray; -use crate::error::WasmResult; -use crate::impl_geometry_array; -#[cfg(feature = "geodesy")] -use crate::reproject::ReprojectDirection; +// use crate::error::WasmResult; +// #[cfg(feature = "geodesy")] +// use crate::reproject::ReprojectDirection; use crate::utils::vec_to_offsets; use wasm_bindgen::prelude::*; @@ -12,8 +10,6 @@ use wasm_bindgen::prelude::*; #[wasm_bindgen] pub struct MultiPointArray(pub(crate) geoarrow::array::MultiPointArray); -impl_geometry_array!(MultiPointArray); - #[wasm_bindgen] impl MultiPointArray { #[wasm_bindgen(constructor)] @@ -26,12 +22,6 @@ impl MultiPointArray { } } -impl From<&MultiPointArray> for geoarrow::array::GeometryArray { - fn from(value: &MultiPointArray) -> Self { - geoarrow::array::GeometryArray::MultiPoint(value.0.clone()) - } -} - impl From> for MultiPointArray { fn from(value: geoarrow::array::MultiPointArray) -> Self { Self(value) diff --git a/js/src/array/multipolygon.rs b/js/src/array/multipolygon.rs index 911e645f..fc801b3e 100644 --- a/js/src/array/multipolygon.rs +++ b/js/src/array/multipolygon.rs @@ -1,9 +1,7 @@ use crate::array::CoordBuffer; -use crate::array::GeometryArray; -use crate::error::WasmResult; -use crate::impl_geometry_array; -#[cfg(feature = "geodesy")] -use crate::reproject::ReprojectDirection; +// use crate::error::WasmResult; +// #[cfg(feature = "geodesy")] +// use crate::reproject::ReprojectDirection; use crate::utils::vec_to_offsets; use wasm_bindgen::prelude::*; @@ -12,8 +10,6 @@ use wasm_bindgen::prelude::*; #[wasm_bindgen] pub struct MultiPolygonArray(pub(crate) geoarrow::array::MultiPolygonArray); -impl_geometry_array!(MultiPolygonArray); - #[wasm_bindgen] impl MultiPolygonArray { #[wasm_bindgen(constructor)] @@ -32,11 +28,6 @@ impl MultiPolygonArray { )) } } -impl From<&MultiPolygonArray> for geoarrow::array::GeometryArray { - fn from(value: &MultiPolygonArray) -> Self { - geoarrow::array::GeometryArray::MultiPolygon(value.0.clone()) - } -} impl From> for MultiPolygonArray { fn from(value: geoarrow::array::MultiPolygonArray) -> Self { diff --git a/js/src/array/point.rs b/js/src/array/point.rs index 42cad661..a4c2f845 100644 --- a/js/src/array/point.rs +++ b/js/src/array/point.rs @@ -1,9 +1,7 @@ use crate::array::CoordBuffer; -use crate::array::GeometryArray; -use crate::error::WasmResult; -use crate::impl_geometry_array; -#[cfg(feature = "geodesy")] -use crate::reproject::ReprojectDirection; +// use crate::error::WasmResult; +// #[cfg(feature = "geodesy")] +// use crate::reproject::ReprojectDirection; use wasm_bindgen::prelude::*; /// An immutable array of Point geometries in WebAssembly memory using GeoArrow's in-memory @@ -11,8 +9,6 @@ use wasm_bindgen::prelude::*; #[wasm_bindgen] pub struct PointArray(pub(crate) geoarrow::array::PointArray); -impl_geometry_array!(PointArray); - #[wasm_bindgen] impl PointArray { #[wasm_bindgen(constructor)] @@ -21,12 +17,6 @@ impl PointArray { } } -impl From<&PointArray> for geoarrow::array::GeometryArray { - fn from(value: &PointArray) -> Self { - geoarrow::array::GeometryArray::Point(value.0.clone()) - } -} - impl From for PointArray { fn from(value: geoarrow::array::PointArray) -> Self { Self(value) diff --git a/js/src/array/polygon.rs b/js/src/array/polygon.rs index c56da5a2..76bf1d28 100644 --- a/js/src/array/polygon.rs +++ b/js/src/array/polygon.rs @@ -1,9 +1,7 @@ use crate::array::CoordBuffer; -use crate::array::GeometryArray; -use crate::error::WasmResult; -use crate::impl_geometry_array; -#[cfg(feature = "geodesy")] -use crate::reproject::ReprojectDirection; +// use crate::error::WasmResult; +// #[cfg(feature = "geodesy")] +// use crate::reproject::ReprojectDirection; use crate::utils::vec_to_offsets; use wasm_bindgen::prelude::*; @@ -12,8 +10,6 @@ use wasm_bindgen::prelude::*; #[wasm_bindgen] pub struct PolygonArray(pub(crate) geoarrow::array::PolygonArray); -impl_geometry_array!(PolygonArray); - #[wasm_bindgen] impl PolygonArray { #[wasm_bindgen(constructor)] @@ -32,12 +28,6 @@ impl PolygonArray { } } -impl From<&PolygonArray> for geoarrow::array::GeometryArray { - fn from(value: &PolygonArray) -> Self { - geoarrow::array::GeometryArray::Polygon(value.0.clone()) - } -} - impl From> for PolygonArray { fn from(value: geoarrow::array::PolygonArray) -> Self { Self(value) diff --git a/js/src/array/rect.rs b/js/src/array/rect.rs index 23fe9399..abcbe991 100644 --- a/js/src/array/rect.rs +++ b/js/src/array/rect.rs @@ -1,8 +1,6 @@ -use crate::array::GeometryArray; -use crate::error::WasmResult; -use crate::impl_geometry_array; -#[cfg(feature = "geodesy")] -use crate::reproject::ReprojectDirection; +// use crate::error::WasmResult; +// #[cfg(feature = "geodesy")] +// use crate::reproject::ReprojectDirection; use wasm_bindgen::prelude::*; /// An immutable array of Rect geometries in WebAssembly memory using GeoArrow's in-memory @@ -10,14 +8,6 @@ use wasm_bindgen::prelude::*; #[wasm_bindgen] pub struct RectArray(pub(crate) geoarrow::array::RectArray); -impl_geometry_array!(RectArray); - -impl From<&RectArray> for geoarrow::array::GeometryArray { - fn from(value: &RectArray) -> Self { - geoarrow::array::GeometryArray::Rect(value.0.clone()) - } -} - impl From for RectArray { fn from(value: geoarrow::array::RectArray) -> Self { Self(value) diff --git a/src/algorithm/geo/affine_ops.rs b/src/algorithm/geo/affine_ops.rs index 28f6c966..8741f671 100644 --- a/src/algorithm/geo/affine_ops.rs +++ b/src/algorithm/geo/affine_ops.rs @@ -97,12 +97,6 @@ impl AffineOps for MultiPointArray { } } -impl AffineOps for GeometryArray { - crate::geometry_array_delegate_impl! { - fn affine_transform(&self, transform: &AffineTransform) -> Self; - } -} - // ┌────────────────────────────────┐ // │ Implementations for RHS arrays │ // └────────────────────────────────┘ @@ -160,9 +154,3 @@ impl AffineOps> for MultiPointArray output_geoms.into() } } - -impl AffineOps> for GeometryArray { - crate::geometry_array_delegate_impl! { - fn affine_transform(&self, transform: &Vec) -> Self; - } -} diff --git a/src/algorithm/geo/area.rs b/src/algorithm/geo/area.rs index fa20f84c..0961ac10 100644 --- a/src/algorithm/geo/area.rs +++ b/src/algorithm/geo/area.rs @@ -1,7 +1,7 @@ use crate::algorithm::geo::utils::zeroes; use crate::array::{ - GeometryArray, LineStringArray, MultiLineStringArray, MultiPointArray, MultiPolygonArray, - PointArray, PolygonArray, WKBArray, + LineStringArray, MultiLineStringArray, MultiPointArray, MultiPolygonArray, PointArray, + PolygonArray, WKBArray, }; use crate::GeometryArrayTrait; use arrow_array::builder::Float64Builder; @@ -102,14 +102,6 @@ iter_geo_impl!(PolygonArray); iter_geo_impl!(MultiPolygonArray); iter_geo_impl!(WKBArray); -impl Area for GeometryArray { - crate::geometry_array_delegate_impl! { - fn signed_area(&self) -> Float64Array; - - fn unsigned_area(&self) -> Float64Array; - } -} - #[cfg(test)] mod test { use super::*; diff --git a/src/algorithm/geo/bounding_rect.rs b/src/algorithm/geo/bounding_rect.rs index 18c2462a..58a837b0 100644 --- a/src/algorithm/geo/bounding_rect.rs +++ b/src/algorithm/geo/bounding_rect.rs @@ -1,4 +1,7 @@ +use crate::array::dyn_geometry_array::{as_line_string_array, as_point_array}; use crate::array::*; +use crate::datatypes::GeoDataType; +use crate::GeometryArrayTrait; use arrow_array::OffsetSizeTrait; use geo::algorithm::bounding_rect::BoundingRect as GeoBoundingRect; use geo::Rect; @@ -29,6 +32,33 @@ pub trait BoundingRect { fn bounding_rect(&self) -> RectArray; } +// TODO: just an example to show how to impl algorithms for dyn GeometryArrayTrait +impl BoundingRect for dyn GeometryArrayTrait { + fn bounding_rect(&self) -> RectArray { + match self.data_type() { + GeoDataType::Point(_) => { + let array = as_point_array(self); + let output_geoms: Vec> = array + .iter_geo() + .map(|maybe_g| maybe_g.map(|geom| geom.bounding_rect())) + .collect(); + + RectArray::from(output_geoms) + } + GeoDataType::LineString(_) => { + let array = as_line_string_array::(self); + let output_geoms: Vec> = array + .iter_geo() + .map(|maybe_g| maybe_g.and_then(|geom| geom.bounding_rect())) + .collect(); + + RectArray::from(output_geoms) + } + _ => unimplemented!(), + } + } +} + impl BoundingRect for PointArray { fn bounding_rect(&self) -> RectArray { let output_geoms: Vec> = self @@ -62,9 +92,3 @@ iter_geo_impl!(MultiPointArray); iter_geo_impl!(MultiLineStringArray); iter_geo_impl!(MultiPolygonArray); iter_geo_impl!(WKBArray); - -impl BoundingRect for GeometryArray { - crate::geometry_array_delegate_impl! { - fn bounding_rect(&self) -> RectArray; - } -} diff --git a/src/algorithm/geo/center.rs b/src/algorithm/geo/center.rs index 5e7cc75c..170db9e4 100644 --- a/src/algorithm/geo/center.rs +++ b/src/algorithm/geo/center.rs @@ -1,6 +1,6 @@ use crate::array::{ - GeometryArray, LineStringArray, MultiLineStringArray, MultiPointArray, MultiPolygonArray, - PointArray, PointBuilder, PolygonArray, WKBArray, + LineStringArray, MultiLineStringArray, MultiPointArray, MultiPolygonArray, PointArray, + PointBuilder, PolygonArray, WKBArray, }; use crate::GeometryArrayTrait; use arrow_array::OffsetSizeTrait; @@ -44,9 +44,3 @@ iter_geo_impl!(MultiPointArray); iter_geo_impl!(MultiLineStringArray); iter_geo_impl!(MultiPolygonArray); iter_geo_impl!(WKBArray); - -impl Center for GeometryArray { - crate::geometry_array_delegate_impl! { - fn center(&self) -> PointArray; - } -} diff --git a/src/algorithm/geo/centroid.rs b/src/algorithm/geo/centroid.rs index ef4aca17..3b59031c 100644 --- a/src/algorithm/geo/centroid.rs +++ b/src/algorithm/geo/centroid.rs @@ -1,6 +1,6 @@ use crate::array::{ - GeometryArray, LineStringArray, MultiLineStringArray, MultiPointArray, MultiPolygonArray, - PointArray, PointBuilder, PolygonArray, WKBArray, + LineStringArray, MultiLineStringArray, MultiPointArray, MultiPolygonArray, PointArray, + PointBuilder, PolygonArray, WKBArray, }; use crate::GeometryArrayTrait; use arrow_array::OffsetSizeTrait; @@ -88,9 +88,3 @@ iter_geo_impl!(MultiPointArray); iter_geo_impl!(MultiLineStringArray); iter_geo_impl!(MultiPolygonArray); iter_geo_impl!(WKBArray); - -impl Centroid for GeometryArray { - crate::geometry_array_delegate_impl! { - fn centroid(&self) -> PointArray; - } -} diff --git a/src/algorithm/geo/chamberlain_duquette_area.rs b/src/algorithm/geo/chamberlain_duquette_area.rs index d36a2fe9..c7abc8d2 100644 --- a/src/algorithm/geo/chamberlain_duquette_area.rs +++ b/src/algorithm/geo/chamberlain_duquette_area.rs @@ -1,7 +1,7 @@ use crate::algorithm::geo::utils::zeroes; use crate::array::{ - GeometryArray, LineStringArray, MultiLineStringArray, MultiPointArray, MultiPolygonArray, - PointArray, PolygonArray, WKBArray, + LineStringArray, MultiLineStringArray, MultiPointArray, MultiPolygonArray, PointArray, + PolygonArray, WKBArray, }; use crate::GeometryArrayTrait; use arrow_array::builder::Float64Builder; @@ -120,10 +120,3 @@ macro_rules! iter_geo_impl { iter_geo_impl!(PolygonArray); iter_geo_impl!(MultiPolygonArray); iter_geo_impl!(WKBArray); - -impl ChamberlainDuquetteArea for GeometryArray { - crate::geometry_array_delegate_impl! { - fn chamberlain_duquette_signed_area(&self) -> Float64Array; - fn chamberlain_duquette_unsigned_area(&self) -> Float64Array; - } -} diff --git a/src/algorithm/geo/convex_hull.rs b/src/algorithm/geo/convex_hull.rs index d89a8d61..19eac53b 100644 --- a/src/algorithm/geo/convex_hull.rs +++ b/src/algorithm/geo/convex_hull.rs @@ -1,6 +1,6 @@ use crate::array::{ - GeometryArray, LineStringArray, MultiLineStringArray, MultiPointArray, MultiPolygonArray, - PointArray, PolygonArray, WKBArray, + LineStringArray, MultiLineStringArray, MultiPointArray, MultiPolygonArray, PointArray, + PolygonArray, WKBArray, }; use arrow_array::OffsetSizeTrait; use geo::algorithm::convex_hull::ConvexHull as GeoConvexHull; @@ -70,12 +70,6 @@ iter_geo_impl!(MultiLineStringArray); iter_geo_impl!(MultiPolygonArray); iter_geo_impl!(WKBArray); -impl ConvexHull for GeometryArray { - crate::geometry_array_delegate_impl! { - fn convex_hull(&self) -> PolygonArray; - } -} - #[cfg(test)] mod tests { use super::ConvexHull; diff --git a/src/algorithm/geo/dimensions.rs b/src/algorithm/geo/dimensions.rs index 9e7729e9..e1d71ab2 100644 --- a/src/algorithm/geo/dimensions.rs +++ b/src/algorithm/geo/dimensions.rs @@ -59,17 +59,3 @@ iter_geo_impl!(MultiPointArray); iter_geo_impl!(MultiLineStringArray); iter_geo_impl!(MultiPolygonArray); iter_geo_impl!(WKBArray); - -impl HasDimensions for GeometryArray { - fn is_empty(&self) -> BooleanArray { - match self { - GeometryArray::Point(arr) => HasDimensions::is_empty(arr), - GeometryArray::LineString(arr) => HasDimensions::is_empty(arr), - GeometryArray::Polygon(arr) => HasDimensions::is_empty(arr), - GeometryArray::MultiPoint(arr) => HasDimensions::is_empty(arr), - GeometryArray::MultiLineString(arr) => HasDimensions::is_empty(arr), - GeometryArray::MultiPolygon(arr) => HasDimensions::is_empty(arr), - _ => todo!(), - } - } -} diff --git a/src/algorithm/geo/geodesic_area.rs b/src/algorithm/geo/geodesic_area.rs index 47a53eb3..9ccd1345 100644 --- a/src/algorithm/geo/geodesic_area.rs +++ b/src/algorithm/geo/geodesic_area.rs @@ -310,13 +310,3 @@ macro_rules! iter_geo_impl { iter_geo_impl!(PolygonArray); iter_geo_impl!(MultiPolygonArray); iter_geo_impl!(WKBArray); - -impl GeodesicArea for GeometryArray { - crate::geometry_array_delegate_impl! { - fn geodesic_area_signed(&self) -> Float64Array; - fn geodesic_area_unsigned(&self) -> Float64Array; - fn geodesic_perimeter(&self) -> Float64Array; - fn geodesic_perimeter_area_signed(&self) -> (Float64Array, Float64Array); - fn geodesic_perimeter_area_unsigned(&self) -> (Float64Array, Float64Array); - } -} diff --git a/src/algorithm/geo/minimum_rotated_rect.rs b/src/algorithm/geo/minimum_rotated_rect.rs index 8b9bbbbe..872c2c74 100644 --- a/src/algorithm/geo/minimum_rotated_rect.rs +++ b/src/algorithm/geo/minimum_rotated_rect.rs @@ -123,15 +123,3 @@ iter_geo_impl!(MultiLineStringArray, i64); iter_geo_impl!(MultiPolygonArray, i32); iter_geo_impl!(MultiPolygonArray, i64); - -impl MinimumRotatedRect for GeometryArray { - crate::geometry_array_delegate_impl! { - fn minimum_rotated_rect(&self) -> PolygonArray; - } -} - -// impl MinimumRotatedRect for GeometryArray { -// crate::geometry_array_delegate_impl! { -// fn minimum_rotated_rect(&self) -> PolygonArray; -// } -// } diff --git a/src/algorithm/geo/remove_repeated_points.rs b/src/algorithm/geo/remove_repeated_points.rs index 4a88e019..e53d0da6 100644 --- a/src/algorithm/geo/remove_repeated_points.rs +++ b/src/algorithm/geo/remove_repeated_points.rs @@ -45,19 +45,3 @@ iter_geo_impl!(LineStringArray, geo::LineString); iter_geo_impl!(PolygonArray, geo::Polygon); iter_geo_impl!(MultiLineStringArray, geo::MultiLineString); iter_geo_impl!(MultiPolygonArray, geo::MultiPolygon); - -impl RemoveRepeatedPoints for GeometryArray { - fn remove_repeated_points(&self) -> Self { - use GeometryArray::*; - - match self { - Point(arr) => Point(arr.remove_repeated_points()), - LineString(arr) => LineString(arr.remove_repeated_points()), - Polygon(arr) => Polygon(arr.remove_repeated_points()), - MultiPoint(arr) => MultiPoint(arr.remove_repeated_points()), - MultiLineString(arr) => MultiLineString(arr.remove_repeated_points()), - MultiPolygon(arr) => MultiPolygon(arr.remove_repeated_points()), - Rect(arr) => Rect(arr.clone()), - } - } -} diff --git a/src/algorithm/geo/rotate.rs b/src/algorithm/geo/rotate.rs index 9990a34e..2d655826 100644 --- a/src/algorithm/geo/rotate.rs +++ b/src/algorithm/geo/rotate.rs @@ -173,14 +173,6 @@ iter_geo_impl!(MultiLineStringArray); iter_geo_impl!(MultiPolygonArray); iter_geo_impl!(WKBArray); -impl Rotate for GeometryArray { - crate::geometry_array_delegate_impl! { - fn rotate_around_centroid(&self, degrees: &Float64Array) -> Self; - fn rotate_around_center(&self, degrees: &Float64Array) -> Self; - fn rotate_around_point(&self, degrees: &Float64Array, point: geo::Point) -> Self; - } -} - // ┌─────────────────────────────────┐ // │ Implementations for RHS scalars │ // └─────────────────────────────────┘ @@ -247,11 +239,3 @@ iter_geo_impl_scalar!(MultiPointArray); iter_geo_impl_scalar!(MultiLineStringArray); iter_geo_impl_scalar!(MultiPolygonArray); iter_geo_impl_scalar!(WKBArray); - -impl Rotate for GeometryArray { - crate::geometry_array_delegate_impl! { - fn rotate_around_centroid(&self, degrees: &f64) -> Self; - fn rotate_around_center(&self, degrees: &f64) -> Self; - fn rotate_around_point(&self, degrees: &f64, point: geo::Point) -> Self; - } -} diff --git a/src/algorithm/geo/scale.rs b/src/algorithm/geo/scale.rs index 83895325..ffb42c35 100644 --- a/src/algorithm/geo/scale.rs +++ b/src/algorithm/geo/scale.rs @@ -211,22 +211,3 @@ iter_geo_impl!(MultiPointArray, geo::MultiPoint); iter_geo_impl!(MultiLineStringArray, geo::MultiLineString); iter_geo_impl!(MultiPolygonArray, geo::MultiPolygon); iter_geo_impl!(WKBArray, geo::Geometry); - -impl Scale for GeometryArray { - crate::geometry_array_delegate_impl! { - fn scale(&self, scale_factor: BroadcastablePrimitive) -> Self; - - fn scale_xy( - &self, - x_factor: BroadcastablePrimitive, - y_factor: BroadcastablePrimitive - ) -> Self; - - fn scale_around_point( - &self, - x_factor: BroadcastablePrimitive, - y_factor: BroadcastablePrimitive, - origin: geo::Point - ) -> Self; - } -} diff --git a/src/algorithm/geo/simplify.rs b/src/algorithm/geo/simplify.rs index 465beed8..9fc7805f 100644 --- a/src/algorithm/geo/simplify.rs +++ b/src/algorithm/geo/simplify.rs @@ -87,22 +87,6 @@ iter_geo_impl!(PolygonArray, geo::Polygon); iter_geo_impl!(MultiLineStringArray, geo::MultiLineString); iter_geo_impl!(MultiPolygonArray, geo::MultiPolygon); -impl Simplify for GeometryArray { - fn simplify(&self, epsilon: &f64) -> Self { - use GeometryArray::*; - - match self { - Point(arr) => Point(arr.simplify(epsilon)), - LineString(arr) => LineString(arr.simplify(epsilon)), - Polygon(arr) => Polygon(arr.simplify(epsilon)), - MultiPoint(arr) => MultiPoint(arr.simplify(epsilon)), - MultiLineString(arr) => MultiLineString(arr.simplify(epsilon)), - MultiPolygon(arr) => MultiPolygon(arr.simplify(epsilon)), - Rect(arr) => Rect(arr.clone()), - } - } -} - #[cfg(test)] mod tests { use super::*; diff --git a/src/algorithm/geo/simplify_vw.rs b/src/algorithm/geo/simplify_vw.rs index 2c3b5c1f..c4c2b649 100644 --- a/src/algorithm/geo/simplify_vw.rs +++ b/src/algorithm/geo/simplify_vw.rs @@ -84,19 +84,3 @@ iter_geo_impl!(LineStringArray, geo::LineString); iter_geo_impl!(PolygonArray, geo::Polygon); iter_geo_impl!(MultiLineStringArray, geo::MultiLineString); iter_geo_impl!(MultiPolygonArray, geo::MultiPolygon); - -impl SimplifyVw for GeometryArray { - fn simplify_vw(&self, epsilon: &f64) -> Self { - use GeometryArray::*; - - match self { - Point(arr) => Point(arr.simplify_vw(epsilon)), - LineString(arr) => LineString(arr.simplify_vw(epsilon)), - Polygon(arr) => Polygon(arr.simplify_vw(epsilon)), - MultiPoint(arr) => MultiPoint(arr.simplify_vw(epsilon)), - MultiLineString(arr) => MultiLineString(arr.simplify_vw(epsilon)), - MultiPolygon(arr) => MultiPolygon(arr.simplify_vw(epsilon)), - Rect(arr) => Rect(arr.clone()), - } - } -} diff --git a/src/algorithm/geo/skew.rs b/src/algorithm/geo/skew.rs index 3918f6a8..760564f5 100644 --- a/src/algorithm/geo/skew.rs +++ b/src/algorithm/geo/skew.rs @@ -246,22 +246,3 @@ iter_geo_impl!(MultiPointArray, geo::MultiPoint); iter_geo_impl!(MultiLineStringArray, geo::MultiLineString); iter_geo_impl!(MultiPolygonArray, geo::MultiPolygon); iter_geo_impl!(WKBArray, geo::Geometry); - -impl Skew for GeometryArray { - crate::geometry_array_delegate_impl! { - fn skew(&self, scale_factor: BroadcastablePrimitive) -> Self; - - fn skew_xy( - &self, - x_factor: BroadcastablePrimitive, - y_factor: BroadcastablePrimitive - ) -> Self; - - fn skew_around_point( - &self, - x_factor: BroadcastablePrimitive, - y_factor: BroadcastablePrimitive, - origin: geo::Point - ) -> Self; - } -} diff --git a/src/algorithm/geo/translate.rs b/src/algorithm/geo/translate.rs index a9faed5f..14ac98ea 100644 --- a/src/algorithm/geo/translate.rs +++ b/src/algorithm/geo/translate.rs @@ -97,13 +97,3 @@ iter_geo_impl!(MultiPointArray, geo::MultiPoint); iter_geo_impl!(MultiLineStringArray, geo::MultiLineString); iter_geo_impl!(MultiPolygonArray, geo::MultiPolygon); iter_geo_impl!(WKBArray, geo::Geometry); - -impl Translate for GeometryArray { - crate::geometry_array_delegate_impl! { - fn translate( - &self, - x_offset: BroadcastablePrimitive, - y_offset: BroadcastablePrimitive - ) -> Self; - } -} diff --git a/src/algorithm/geo/utils.rs b/src/algorithm/geo/utils.rs index 09ba0e73..c5135705 100644 --- a/src/algorithm/geo/utils.rs +++ b/src/algorithm/geo/utils.rs @@ -5,43 +5,3 @@ pub(crate) fn zeroes(len: usize, nulls: Option<&NullBuffer>) -> Float64Array { let values = vec![0.0f64; len]; Float64Array::new(values.into(), nulls.cloned()) } - -/// Implements the common pattern where a [`GeometryArray`][crate::array::GeometryArray] enum -/// simply delegates its trait impl to it's inner type. -/// -// This is derived from geo https://github.com/georust/geo/blob/d4c858308ba910f69beab175e08af263b17c5f9f/geo/src/types.rs#L119-L158 -#[macro_export] -macro_rules! geometry_array_delegate_impl { - ($($a:tt)*) => { $crate::__geometry_array_delegate_impl_helper!{ GeometryArray, $($a)* } } -} - -#[doc(hidden)] -#[macro_export] -macro_rules! __geometry_array_delegate_impl_helper { - ( - $enum:ident, - $( - $(#[$outer:meta])* - fn $func_name: ident(&$($self_life:lifetime)?self $(, $arg_name: ident: $arg_type: ty)*) -> $return: ty; - )+ - ) => { - $( - $(#[$outer])* - fn $func_name(&$($self_life)? self, $($arg_name: $arg_type),*) -> $return { - match self { - $enum::Point(g) => g.$func_name($($arg_name),*).into(), - // $enum::Line(g) => g.$func_name($($arg_name),*).into(), - $enum::LineString(g) => g.$func_name($($arg_name),*).into(), - $enum::Polygon(g) => g.$func_name($($arg_name),*).into(), - $enum::MultiPoint(g) => g.$func_name($($arg_name),*).into(), - $enum::MultiLineString(g) => g.$func_name($($arg_name),*).into(), - $enum::MultiPolygon(g) => g.$func_name($($arg_name),*).into(), - // $enum::GeometryCollection(g) => g.$func_name($($arg_name),*).into(), - $enum::Rect(_g) => todo!(), - // $enum::Rect(g) => g.$func_name($($arg_name),*).into(), - // $enum::Triangle(g) => g.$func_name($($arg_name),*).into(), - } - } - )+ - }; -} diff --git a/src/algorithm/geodesy/mod.rs b/src/algorithm/geodesy/mod.rs index 6b82c879..28c30bd5 100644 --- a/src/algorithm/geodesy/mod.rs +++ b/src/algorithm/geodesy/mod.rs @@ -7,4 +7,3 @@ mod reproject; pub use geodesy::Direction; -pub use reproject::reproject; diff --git a/src/algorithm/geodesy/reproject.rs b/src/algorithm/geodesy/reproject.rs index 0cfb1f29..1fe5cce5 100644 --- a/src/algorithm/geodesy/reproject.rs +++ b/src/algorithm/geodesy/reproject.rs @@ -1,7 +1,5 @@ -use crate::array::{CoordBuffer, GeometryArray, InterleavedCoordBuffer, SeparatedCoordBuffer}; +use crate::array::{CoordBuffer, InterleavedCoordBuffer, SeparatedCoordBuffer}; use crate::error::Result; -use crate::trait_::GeometryArraySelfMethods; -use arrow_array::OffsetSizeTrait; use geodesy::prelude::*; use geodesy::Coor4D; use geodesy::Direction; @@ -47,6 +45,7 @@ impl CoordinateSet for SeparatedCoordsGeodesy<'_> { } } +#[allow(dead_code)] fn reproject_coords( coords: &CoordBuffer, definition: &str, @@ -84,49 +83,3 @@ fn reproject_coords( Ok(new_coords) } - -/// Reproject coordinates -/// - -// NOTE: In the future this should probably take care to _not_ reproject coordinates that are set to null via the arrow validity bitmask. That could probably lead to -pub fn reproject( - array: &GeometryArray, - definition: &str, - direction: Direction, -) -> Result> { - match array { - GeometryArray::Point(arr) => { - let new_coords = reproject_coords(&arr.coords, definition, direction)?; - Ok(GeometryArray::Point(arr.clone().with_coords(new_coords))) - } - GeometryArray::LineString(arr) => { - let new_coords = reproject_coords(&arr.coords, definition, direction)?; - Ok(GeometryArray::LineString( - arr.clone().with_coords(new_coords), - )) - } - GeometryArray::Polygon(arr) => { - let new_coords = reproject_coords(&arr.coords, definition, direction)?; - Ok(GeometryArray::Polygon(arr.clone().with_coords(new_coords))) - } - GeometryArray::MultiPoint(arr) => { - let new_coords = reproject_coords(&arr.coords, definition, direction)?; - Ok(GeometryArray::MultiPoint( - arr.clone().with_coords(new_coords), - )) - } - GeometryArray::MultiLineString(arr) => { - let new_coords = reproject_coords(&arr.coords, definition, direction)?; - Ok(GeometryArray::MultiLineString( - arr.clone().with_coords(new_coords), - )) - } - GeometryArray::MultiPolygon(arr) => { - let new_coords = reproject_coords(&arr.coords, definition, direction)?; - Ok(GeometryArray::MultiPolygon( - arr.clone().with_coords(new_coords), - )) - } - GeometryArray::Rect(_arr) => todo!(), - } -} diff --git a/src/algorithm/geos/area.rs b/src/algorithm/geos/area.rs index b12050cf..fb16e024 100644 --- a/src/algorithm/geos/area.rs +++ b/src/algorithm/geos/area.rs @@ -1,7 +1,7 @@ use crate::algorithm::geo::utils::zeroes; use crate::array::{ - GeometryArray, LineStringArray, MultiLineStringArray, MultiPointArray, MultiPolygonArray, - PointArray, PolygonArray, WKBArray, + LineStringArray, MultiLineStringArray, MultiPointArray, MultiPolygonArray, PointArray, + PolygonArray, WKBArray, }; use crate::error::Result; use crate::GeometryArrayTrait; @@ -61,12 +61,6 @@ iter_geos_impl!(PolygonArray); iter_geos_impl!(MultiPolygonArray); iter_geos_impl!(WKBArray); -impl Area for GeometryArray { - crate::geometry_array_delegate_impl! { - fn area(&self) -> Result; - } -} - #[cfg(test)] mod test { use super::*; diff --git a/src/algorithm/geos/buffer.rs b/src/algorithm/geos/buffer.rs index fc12edce..334fe7c4 100644 --- a/src/algorithm/geos/buffer.rs +++ b/src/algorithm/geos/buffer.rs @@ -68,12 +68,6 @@ impl Buffer for PointArray { // iter_geos_impl!(MultiPolygonArray); // iter_geos_impl!(WKBArray); -// impl Area for GeometryArray { -// crate::geometry_array_delegate_impl! { -// fn area(&self) -> Result>; -// } -// } - #[cfg(test)] mod test { use super::*; diff --git a/src/array/dyn_geometry_array.rs b/src/array/dyn_geometry_array.rs new file mode 100644 index 00000000..ff0df4d0 --- /dev/null +++ b/src/array/dyn_geometry_array.rs @@ -0,0 +1,310 @@ +use crate::array::zip_validity::ZipValidity; +use crate::array::{ + GeometryCollectionArray, LineStringArray, MixedGeometryArray, MultiLineStringArray, + MultiPointArray, MultiPolygonArray, PointArray, PolygonArray, RectArray, WKBArray, +}; +use crate::datatypes::GeoDataType; +use crate::error::GeoArrowError; +use crate::scalar::Geometry; +use crate::trait_::GeometryArrayAccessor; +use crate::GeometryArrayTrait; +use arrow_array::{Array, OffsetSizeTrait}; +use arrow_buffer::bit_iterator::BitIterator; +use arrow_schema::Field; + +impl dyn GeometryArrayTrait { + pub fn value(&self, i: usize) -> Geometry { + match self.data_type() { + GeoDataType::Point(_) => Geometry::Point(as_point_array(self).value(i)), + GeoDataType::LineString(_) | GeoDataType::LargeLineString(_) => { + Geometry::LineString(as_line_string_array::(self).value(i)) + } + GeoDataType::Polygon(_) | GeoDataType::LargePolygon(_) => { + Geometry::Polygon(as_polygon_array::(self).value(i)) + } + GeoDataType::MultiPoint(_) | GeoDataType::LargeMultiPoint(_) => { + Geometry::MultiPoint(as_multi_point_array::(self).value(i)) + } + GeoDataType::MultiLineString(_) | GeoDataType::LargeMultiLineString(_) => { + Geometry::MultiLineString(as_multi_line_string_array::(self).value(i)) + } + GeoDataType::MultiPolygon(_) | GeoDataType::LargeMultiPolygon(_) => { + Geometry::MultiPolygon(as_multi_polygon_array::(self).value(i)) + } + GeoDataType::Mixed(_) | GeoDataType::LargeMixed(_) => { + as_mixed_array::(self).value(i) + } + // GeoDataType::GeometryCollection(_) | GeoDataType::LargeGeometryCollection(_) => + // as_geometry_collection_array::(self).value(i), + // GeoDataType::WKB | GeoDataType::LargeWKB => as_wkb_array::(self).value(i), + GeoDataType::Rect => Geometry::Rect(as_rect_array(self).value(i)), + _ => unimplemented!(), + } + } + pub fn value_as_geo(&self, i: usize) -> geo::Geometry { + match self.data_type() { + GeoDataType::Point(_) => geo::Geometry::Point(as_point_array(self).value_as_geo(i)), + GeoDataType::LineString(_) => { + geo::Geometry::LineString(as_line_string_array::(self).value_as_geo(i)) + } + GeoDataType::LargeLineString(_) => { + geo::Geometry::LineString(as_line_string_array::(self).value_as_geo(i)) + } + GeoDataType::Polygon(_) => { + geo::Geometry::Polygon(as_polygon_array::(self).value_as_geo(i)) + } + GeoDataType::LargePolygon(_) => { + geo::Geometry::Polygon(as_polygon_array::(self).value_as_geo(i)) + } + GeoDataType::MultiPoint(_) => { + geo::Geometry::MultiPoint(as_multi_point_array::(self).value_as_geo(i)) + } + GeoDataType::LargeMultiPoint(_) => { + geo::Geometry::MultiPoint(as_multi_point_array::(self).value_as_geo(i)) + } + GeoDataType::MultiLineString(_) => geo::Geometry::MultiLineString( + as_multi_line_string_array::(self).value_as_geo(i), + ), + GeoDataType::LargeMultiLineString(_) => geo::Geometry::MultiLineString( + as_multi_line_string_array::(self).value_as_geo(i), + ), + GeoDataType::MultiPolygon(_) => { + geo::Geometry::MultiPolygon(as_multi_polygon_array::(self).value_as_geo(i)) + } + GeoDataType::LargeMultiPolygon(_) => { + geo::Geometry::MultiPolygon(as_multi_polygon_array::(self).value_as_geo(i)) + } + GeoDataType::Mixed(_) => as_mixed_array::(self).value_as_geo(i), + GeoDataType::LargeMixed(_) => as_mixed_array::(self).value_as_geo(i), + GeoDataType::GeometryCollection(_) => geo::Geometry::GeometryCollection( + as_geometry_collection_array::(self).value_as_geo(i), + ), + GeoDataType::LargeGeometryCollection(_) => geo::Geometry::GeometryCollection( + as_geometry_collection_array::(self).value_as_geo(i), + ), + GeoDataType::WKB => as_wkb_array::(self).value_as_geo(i), + GeoDataType::LargeWKB => as_wkb_array::(self).value_as_geo(i), + GeoDataType::Rect => geo::Geometry::Rect(as_rect_array(self).value_as_geo(i)), + } + } + + /// Iterator over geo Geometry objects, not looking at validity + pub fn iter_geo_values(&self) -> impl Iterator + '_ { + (0..self.len()).map(|i| self.value_as_geo(i)) + } + + /// Iterator over geo Geometry objects, taking into account validity + pub fn iter_geo( + &self, + ) -> ZipValidity + '_, BitIterator> { + ZipValidity::new_with_validity(self.iter_geo_values(), self.nulls()) + } + + /// Returns the value at slot `i` as a GEOS geometry. + #[cfg(feature = "geos")] + pub fn value_as_geos(&self, i: usize) -> geos::Geometry { + match self.data_type() { + GeoDataType::Point(_) => as_point_array(self).value_as_geos(i), + GeoDataType::LineString(_) => as_line_string_array::(self).value_as_geos(i), + GeoDataType::LargeLineString(_) => as_line_string_array::(self).value_as_geos(i), + GeoDataType::Polygon(_) => as_polygon_array::(self).value_as_geos(i), + GeoDataType::LargePolygon(_) => as_polygon_array::(self).value_as_geos(i), + GeoDataType::MultiPoint(_) => as_multi_point_array::(self).value_as_geos(i), + GeoDataType::LargeMultiPoint(_) => as_multi_point_array::(self).value_as_geos(i), + GeoDataType::MultiLineString(_) => { + as_multi_line_string_array::(self).value_as_geos(i) + } + GeoDataType::LargeMultiLineString(_) => { + as_multi_line_string_array::(self).value_as_geos(i) + } + GeoDataType::MultiPolygon(_) => as_multi_polygon_array::(self).value_as_geos(i), + GeoDataType::LargeMultiPolygon(_) => { + as_multi_polygon_array::(self).value_as_geos(i) + } + GeoDataType::Mixed(_) => as_mixed_array::(self).value_as_geos(i), + GeoDataType::LargeMixed(_) => as_mixed_array::(self).value_as_geos(i), + GeoDataType::GeometryCollection(_) => { + as_geometry_collection_array::(self).value_as_geos(i) + } + GeoDataType::LargeGeometryCollection(_) => { + as_geometry_collection_array::(self).value_as_geos(i) + } + GeoDataType::WKB => as_wkb_array::(self).value_as_geos(i), + GeoDataType::LargeWKB => as_wkb_array::(self).value_as_geos(i), + GeoDataType::Rect => todo!(), + } + } + + /// Gets the value at slot `i` as a GEOS geometry, additionally checking the validity bitmap + #[cfg(feature = "geos")] + pub fn get_as_geos(&self, i: usize) -> Option { + if self.is_null(i) { + return None; + } + + Some(self.value_as_geos(i)) + } + + /// Iterator over GEOS geometry objects + #[cfg(feature = "geos")] + pub fn iter_geos_values(&self) -> impl Iterator + '_ { + (0..self.len()).map(|i| self.value_as_geos(i)) + } + + /// Iterator over GEOS geometry objects, taking validity into account + #[cfg(feature = "geos")] + pub fn iter_geos( + &self, + ) -> ZipValidity + '_, BitIterator> { + ZipValidity::new_with_validity(self.iter_geos_values(), self.nulls()) + } +} + +#[inline] +pub fn as_point_array(arr: &dyn GeometryArrayTrait) -> &PointArray { + arr.as_any() + .downcast_ref::() + .expect("Unable to downcast to point array") +} + +#[inline] +pub fn as_line_string_array( + arr: &dyn GeometryArrayTrait, +) -> &LineStringArray { + arr.as_any() + .downcast_ref::>() + .expect("Unable to downcast to line string array") +} + +#[inline] +pub fn as_polygon_array(arr: &dyn GeometryArrayTrait) -> &PolygonArray { + arr.as_any() + .downcast_ref::>() + .expect("Unable to downcast to polygon array") +} + +#[inline] +pub fn as_multi_point_array( + arr: &dyn GeometryArrayTrait, +) -> &MultiPointArray { + arr.as_any() + .downcast_ref::>() + .expect("Unable to downcast to multi point array") +} + +#[inline] +pub fn as_multi_line_string_array( + arr: &dyn GeometryArrayTrait, +) -> &MultiLineStringArray { + arr.as_any() + .downcast_ref::>() + .expect("Unable to downcast to multi line string array") +} + +#[inline] +pub fn as_multi_polygon_array( + arr: &dyn GeometryArrayTrait, +) -> &MultiPolygonArray { + arr.as_any() + .downcast_ref::>() + .expect("Unable to downcast to multi polygon array") +} + +#[inline] +pub fn as_rect_array(arr: &dyn GeometryArrayTrait) -> &RectArray { + arr.as_any() + .downcast_ref::() + .expect("Unable to downcast to rect array") +} + +#[inline] +pub fn as_wkb_array(arr: &dyn GeometryArrayTrait) -> &WKBArray { + arr.as_any() + .downcast_ref::>() + .expect("Unable to downcast to wkb array") +} + +#[inline] +pub fn as_mixed_array(arr: &dyn GeometryArrayTrait) -> &MixedGeometryArray { + arr.as_any() + .downcast_ref::>() + .expect("Unable to downcast to mixed array") +} + +#[inline] +pub fn as_geometry_collection_array( + arr: &dyn GeometryArrayTrait, +) -> &GeometryCollectionArray { + arr.as_any() + .downcast_ref::>() + .expect("Unable to downcast to geometry collection array") +} + +impl TryFrom<(&Field, &dyn Array, bool)> for Box { + type Error = GeoArrowError; + + fn try_from((field, array, is_large): (&Field, &dyn Array, bool)) -> Result { + if is_large { + if let Some(extension_name) = field.metadata().get("ARROW:extension:name") { + let geom_arr: Result, GeoArrowError> = + match extension_name.as_str() { + "geoarrow.point" => Ok(Box::new(PointArray::try_from(array)?)), + "geoarrow.linestring" => { + Ok(Box::new(LineStringArray::::try_from(array)?)) + } + "geoarrow.polygon" => Ok(Box::new(PolygonArray::::try_from(array)?)), + "geoarrow.multipoint" => { + Ok(Box::new(MultiPointArray::::try_from(array)?)) + } + "geoarrow.multilinestring" => { + Ok(Box::new(MultiLineStringArray::::try_from(array)?)) + } + "geoarrow.multipolygon" => { + Ok(Box::new(MultiPolygonArray::::try_from(array)?)) + } + // TODO: create a top-level API that parses any named geoarrow array? + // "geoarrow.wkb" => Ok(GeometryArray::WKB(array.try_into()?)), + _ => Err(GeoArrowError::General(format!( + "Unknown geoarrow type {}", + extension_name + ))), + }; + geom_arr + } else { + // TODO: better error here, and document that arrays without geoarrow extension + // metadata should use TryFrom for a specific geometry type directly, instead of using + // GeometryArray + Err(GeoArrowError::General( + "Can only construct an array with an extension type name.".to_string(), + )) + } + } else if let Some(extension_name) = field.metadata().get("ARROW:extension:name") { + let geom_arr: Result, GeoArrowError> = match extension_name + .as_str() + { + "geoarrow.point" => Ok(Box::new(PointArray::try_from(array)?)), + "geoarrow.linestring" => Ok(Box::new(LineStringArray::::try_from(array)?)), + "geoarrow.polygon" => Ok(Box::new(PolygonArray::::try_from(array)?)), + "geoarrow.multipoint" => Ok(Box::new(MultiPointArray::::try_from(array)?)), + "geoarrow.multilinestring" => { + Ok(Box::new(MultiLineStringArray::::try_from(array)?)) + } + "geoarrow.multipolygon" => Ok(Box::new(MultiPolygonArray::::try_from(array)?)), + // TODO: create a top-level API that parses any named geoarrow array? + // "geoarrow.wkb" => Ok(GeometryArray::WKB(array.try_into()?)), + _ => Err(GeoArrowError::General(format!( + "Unknown geoarrow type {}", + extension_name + ))), + }; + geom_arr + } else { + // TODO: better error here, and document that arrays without geoarrow extension + // metadata should use TryFrom for a specific geometry type directly, instead of using + // GeometryArray + Err(GeoArrowError::General( + "Can only construct an array with an extension type name.".to_string(), + )) + } + } +} diff --git a/src/array/geometry/array.rs b/src/array/geometry/array.rs deleted file mode 100644 index 7fb442f8..00000000 --- a/src/array/geometry/array.rs +++ /dev/null @@ -1,456 +0,0 @@ -use std::sync::Arc; - -use arrow_array::{Array, OffsetSizeTrait}; -use arrow_buffer::NullBuffer; -use arrow_schema::{DataType, Field}; - -use crate::algorithm::native::type_id::TypeIds; -// use crate::algorithm::native::type_id::TypeIds; -use crate::array::{ - LineStringArray, MultiLineStringArray, MultiPointArray, MultiPolygonArray, PointArray, - PolygonArray, RectArray, WKBArray, -}; -use crate::datatypes::GeoDataType; -use crate::error::GeoArrowError; -use crate::scalar::Geometry; -use crate::trait_::{GeometryArrayAccessor, GeometryArraySelfMethods, IntoArrow}; -use crate::GeometryArrayTrait; - -/// A GeometryArray is an enum over the various underlying _zero copy_ GeoArrow array types. -/// -/// Notably this does _not_ include [`WKBArray`] as a variant, because that is not zero-copy to -/// parse. -#[derive(Debug, Clone)] -// #[derive(Debug, Clone, PartialEq)] -pub enum GeometryArray { - Point(PointArray), - LineString(LineStringArray), - Polygon(PolygonArray), - MultiPoint(MultiPointArray), - MultiLineString(MultiLineStringArray), - MultiPolygon(MultiPolygonArray), - Rect(RectArray), -} - -impl GeometryArrayTrait for GeometryArray { - fn as_any(&self) -> &dyn std::any::Any { - // Note: I don't think this will work because you presumably can't downcast past the - // enum...? - match self { - GeometryArray::Point(arr) => arr.as_any(), - GeometryArray::LineString(arr) => arr.as_any(), - GeometryArray::Polygon(arr) => arr.as_any(), - GeometryArray::MultiPoint(arr) => arr.as_any(), - GeometryArray::MultiLineString(arr) => arr.as_any(), - GeometryArray::MultiPolygon(arr) => arr.as_any(), - GeometryArray::Rect(arr) => arr.as_any(), - } - } - - fn data_type(&self) -> &GeoDataType { - match self { - GeometryArray::Point(arr) => arr.data_type(), - GeometryArray::LineString(arr) => arr.data_type(), - GeometryArray::Polygon(arr) => arr.data_type(), - GeometryArray::MultiPoint(arr) => arr.data_type(), - GeometryArray::MultiLineString(arr) => arr.data_type(), - GeometryArray::MultiPolygon(arr) => arr.data_type(), - GeometryArray::Rect(arr) => arr.data_type(), - } - } - - fn storage_type(&self) -> DataType { - match self { - GeometryArray::Point(arr) => arr.storage_type(), - GeometryArray::LineString(arr) => arr.storage_type(), - GeometryArray::Polygon(arr) => arr.storage_type(), - GeometryArray::MultiPoint(arr) => arr.storage_type(), - GeometryArray::MultiLineString(arr) => arr.storage_type(), - GeometryArray::MultiPolygon(arr) => arr.storage_type(), - GeometryArray::Rect(arr) => arr.storage_type(), - } - } - - fn extension_field(&self) -> Arc { - match self { - GeometryArray::Point(arr) => arr.extension_field(), - GeometryArray::LineString(arr) => arr.extension_field(), - GeometryArray::Polygon(arr) => arr.extension_field(), - GeometryArray::MultiPoint(arr) => arr.extension_field(), - GeometryArray::MultiLineString(arr) => arr.extension_field(), - GeometryArray::MultiPolygon(arr) => arr.extension_field(), - GeometryArray::Rect(arr) => arr.extension_field(), - } - } - - fn extension_name(&self) -> &str { - match self { - GeometryArray::Point(arr) => arr.extension_name(), - GeometryArray::LineString(arr) => arr.extension_name(), - GeometryArray::Polygon(arr) => arr.extension_name(), - GeometryArray::MultiPoint(arr) => arr.extension_name(), - GeometryArray::MultiLineString(arr) => arr.extension_name(), - GeometryArray::MultiPolygon(arr) => arr.extension_name(), - GeometryArray::Rect(arr) => arr.extension_name(), - } - } - - fn into_array_ref(self) -> Arc { - match self { - GeometryArray::Point(arr) => arr.into_array_ref(), - GeometryArray::LineString(arr) => arr.into_array_ref(), - GeometryArray::Polygon(arr) => arr.into_array_ref(), - GeometryArray::MultiPoint(arr) => arr.into_array_ref(), - GeometryArray::MultiLineString(arr) => arr.into_array_ref(), - GeometryArray::MultiPolygon(arr) => arr.into_array_ref(), - GeometryArray::Rect(arr) => arr.into_array_ref(), - } - } - - fn coord_type(&self) -> crate::array::CoordType { - match self { - GeometryArray::Point(arr) => arr.coord_type(), - GeometryArray::LineString(arr) => arr.coord_type(), - GeometryArray::Polygon(arr) => arr.coord_type(), - GeometryArray::MultiPoint(arr) => arr.coord_type(), - GeometryArray::MultiLineString(arr) => arr.coord_type(), - GeometryArray::MultiPolygon(arr) => arr.coord_type(), - GeometryArray::Rect(arr) => arr.coord_type(), - } - } - - /// The length of the [`GeometryArray`]. Every array has a length corresponding to the number - /// of geometries it contains. - fn len(&self) -> usize { - match self { - GeometryArray::Point(arr) => arr.len(), - GeometryArray::LineString(arr) => arr.len(), - GeometryArray::Polygon(arr) => arr.len(), - GeometryArray::MultiPoint(arr) => arr.len(), - GeometryArray::MultiLineString(arr) => arr.len(), - GeometryArray::MultiPolygon(arr) => arr.len(), - GeometryArray::Rect(arr) => arr.len(), - } - } - - /// The validity of the [`GeometryArray`]: every array has an optional [`Bitmap`] that, when - /// available specifies whether the geometry at a given slot is valid or not (null). When the - /// validity is [`None`], all slots are valid. - fn validity(&self) -> Option<&NullBuffer> { - match self { - GeometryArray::Point(arr) => arr.nulls(), - GeometryArray::LineString(arr) => arr.nulls(), - GeometryArray::Polygon(arr) => arr.nulls(), - GeometryArray::MultiPoint(arr) => arr.nulls(), - GeometryArray::MultiLineString(arr) => arr.nulls(), - GeometryArray::MultiPolygon(arr) => arr.nulls(), - GeometryArray::Rect(arr) => arr.nulls(), - } - } - - // /// Clones this [`GeometryArray`] with a new assigned bitmap. - // /// # Panic - // /// This function panics iff `validity.len() != self.len()`. - // pub fn with_validity(&self, validity: Option) -> Box; -} - -impl GeometryArraySelfMethods for GeometryArray { - fn with_coords(self, coords: crate::array::CoordBuffer) -> Self { - match self { - GeometryArray::Point(arr) => GeometryArray::Point(arr.with_coords(coords)), - GeometryArray::LineString(arr) => GeometryArray::LineString(arr.with_coords(coords)), - GeometryArray::Polygon(arr) => GeometryArray::Polygon(arr.with_coords(coords)), - GeometryArray::MultiPoint(arr) => GeometryArray::MultiPoint(arr.with_coords(coords)), - GeometryArray::MultiLineString(arr) => { - GeometryArray::MultiLineString(arr.with_coords(coords)) - } - GeometryArray::MultiPolygon(arr) => { - GeometryArray::MultiPolygon(arr.with_coords(coords)) - } - GeometryArray::Rect(arr) => GeometryArray::Rect(arr.with_coords(coords)), - } - } - - fn into_coord_type(self, coord_type: crate::array::CoordType) -> Self { - match self { - GeometryArray::Point(arr) => GeometryArray::Point(arr.into_coord_type(coord_type)), - GeometryArray::LineString(arr) => { - GeometryArray::LineString(arr.into_coord_type(coord_type)) - } - GeometryArray::Polygon(arr) => GeometryArray::Polygon(arr.into_coord_type(coord_type)), - GeometryArray::MultiPoint(arr) => { - GeometryArray::MultiPoint(arr.into_coord_type(coord_type)) - } - GeometryArray::MultiLineString(arr) => { - GeometryArray::MultiLineString(arr.into_coord_type(coord_type)) - } - GeometryArray::MultiPolygon(arr) => { - GeometryArray::MultiPolygon(arr.into_coord_type(coord_type)) - } - GeometryArray::Rect(arr) => GeometryArray::Rect(arr.into_coord_type(coord_type)), - } - } - - /// Slices the [`GeometryArray`] in place - /// # Implementation - /// This operation is `O(1)` over `len`, as it amounts to increase two ref counts - /// and moving the struct to the heap. - /// # Panic - /// This function panics iff `offset + length > self.len()`. - fn slice(&self, offset: usize, length: usize) -> Self { - match self { - GeometryArray::Point(arr) => GeometryArray::Point(arr.slice(offset, length)), - GeometryArray::LineString(arr) => GeometryArray::LineString(arr.slice(offset, length)), - GeometryArray::Polygon(arr) => GeometryArray::Polygon(arr.slice(offset, length)), - GeometryArray::MultiPoint(arr) => GeometryArray::MultiPoint(arr.slice(offset, length)), - GeometryArray::MultiLineString(arr) => { - GeometryArray::MultiLineString(arr.slice(offset, length)) - } - GeometryArray::MultiPolygon(arr) => { - GeometryArray::MultiPolygon(arr.slice(offset, length)) - } - GeometryArray::Rect(arr) => GeometryArray::Rect(arr.slice(offset, length)), - } - } - - fn owned_slice(&self, offset: usize, length: usize) -> Self { - match self { - GeometryArray::Point(arr) => GeometryArray::Point(arr.owned_slice(offset, length)), - GeometryArray::LineString(arr) => { - GeometryArray::LineString(arr.owned_slice(offset, length)) - } - GeometryArray::Polygon(arr) => GeometryArray::Polygon(arr.owned_slice(offset, length)), - GeometryArray::MultiPoint(arr) => { - GeometryArray::MultiPoint(arr.owned_slice(offset, length)) - } - GeometryArray::MultiLineString(arr) => { - GeometryArray::MultiLineString(arr.owned_slice(offset, length)) - } - GeometryArray::MultiPolygon(arr) => { - GeometryArray::MultiPolygon(arr.owned_slice(offset, length)) - } - GeometryArray::Rect(arr) => GeometryArray::Rect(arr.owned_slice(offset, length)), - } - } -} - -impl<'a, O: OffsetSizeTrait> GeometryArrayAccessor<'a> for GeometryArray { - type Item = Geometry<'a, O>; - type ItemGeo = geo::Geometry; - - unsafe fn value_unchecked(&'a self, index: usize) -> Self::Item { - match self { - GeometryArray::Point(arr) => Geometry::Point(arr.value_unchecked(index)), - GeometryArray::LineString(arr) => Geometry::LineString(arr.value_unchecked(index)), - GeometryArray::Polygon(arr) => Geometry::Polygon(arr.value_unchecked(index)), - GeometryArray::MultiPoint(arr) => Geometry::MultiPoint(arr.value_unchecked(index)), - GeometryArray::MultiLineString(arr) => { - Geometry::MultiLineString(arr.value_unchecked(index)) - } - GeometryArray::MultiPolygon(arr) => Geometry::MultiPolygon(arr.value_unchecked(index)), - GeometryArray::Rect(arr) => Geometry::Rect(arr.value_unchecked(index)), - } - } -} - -impl IntoArrow for GeometryArray { - type ArrowArray = Arc; - - fn into_arrow(self) -> Self::ArrowArray { - match self { - GeometryArray::Point(arr) => arr.into_arrow(), - GeometryArray::LineString(arr) => Arc::new(arr.into_arrow()), - GeometryArray::Polygon(arr) => Arc::new(arr.into_arrow()), - GeometryArray::MultiPoint(arr) => Arc::new(arr.into_arrow()), - GeometryArray::MultiLineString(arr) => Arc::new(arr.into_arrow()), - GeometryArray::MultiPolygon(arr) => Arc::new(arr.into_arrow()), - GeometryArray::Rect(arr) => Arc::new(arr.into_arrow()), - } - } -} - -impl TryFrom<(&Field, &dyn Array)> for GeometryArray { - type Error = GeoArrowError; - - fn try_from((field, array): (&Field, &dyn Array)) -> Result { - if let Some(extension_name) = field.metadata().get("ARROW:extension:name") { - let geom_arr = match extension_name.as_str() { - "geoarrow.point" => Ok(GeometryArray::Point(array.try_into()?)), - "geoarrow.linestring" => Ok(GeometryArray::LineString(array.try_into()?)), - "geoarrow.polygon" => Ok(GeometryArray::Polygon(array.try_into()?)), - "geoarrow.multipoint" => Ok(GeometryArray::MultiPoint(array.try_into()?)), - "geoarrow.multilinestring" => Ok(GeometryArray::MultiLineString(array.try_into()?)), - "geoarrow.multipolygon" => Ok(GeometryArray::MultiPolygon(array.try_into()?)), - // TODO: create a top-level API that parses any named geoarrow array? - // "geoarrow.wkb" => Ok(GeometryArray::WKB(array.try_into()?)), - _ => Err(GeoArrowError::General(format!( - "Unknown geoarrow type {}", - extension_name - ))), - }; - geom_arr - } else { - // TODO: better error here, and document that arrays without geoarrow extension - // metadata should use TryFrom for a specific geometry type directly, instead of using - // GeometryArray - Err(GeoArrowError::General( - "Can only construct an array with an extension type name.".to_string(), - )) - } - } -} - -impl TryFrom<(&Field, &dyn Array)> for GeometryArray { - type Error = GeoArrowError; - - fn try_from((field, array): (&Field, &dyn Array)) -> Result { - if let Some(extension_name) = field.metadata().get("ARROW:extension:name") { - let geom_arr = match extension_name.as_str() { - "geoarrow.point" => Ok(GeometryArray::Point(array.try_into()?)), - "geoarrow.linestring" => Ok(GeometryArray::LineString(array.try_into()?)), - "geoarrow.polygon" => Ok(GeometryArray::Polygon(array.try_into()?)), - "geoarrow.multipoint" => Ok(GeometryArray::MultiPoint(array.try_into()?)), - "geoarrow.multilinestring" => Ok(GeometryArray::MultiLineString(array.try_into()?)), - "geoarrow.multipolygon" => Ok(GeometryArray::MultiPolygon(array.try_into()?)), - // TODO: create a top-level API that parses any named geoarrow array? - // "geoarrow.wkb" => Ok(GeometryArray::WKB(array.try_into()?)), - _ => Err(GeoArrowError::General(format!( - "Unknown geoarrow type {}", - extension_name - ))), - }; - geom_arr - } else { - // TODO: better error here, and document that arrays without geoarrow extension - // metadata should use TryFrom for a specific geometry type directly, instead of using - // GeometryArray - Err(GeoArrowError::General( - "Can only construct an array with an extension type name.".to_string(), - )) - } - } -} - -// TODO: write a macro to dedupe these `From`s -impl From for GeometryArray { - fn from(value: PointArray) -> Self { - GeometryArray::Point(value) - } -} - -impl From> for GeometryArray { - fn from(value: LineStringArray) -> Self { - GeometryArray::LineString(value) - } -} - -impl From> for GeometryArray { - fn from(value: PolygonArray) -> Self { - GeometryArray::Polygon(value) - } -} - -impl From> for GeometryArray { - fn from(value: MultiPointArray) -> Self { - GeometryArray::MultiPoint(value) - } -} - -impl From> for GeometryArray { - fn from(value: MultiLineStringArray) -> Self { - GeometryArray::MultiLineString(value) - } -} - -impl From> for GeometryArray { - fn from(value: MultiPolygonArray) -> Self { - GeometryArray::MultiPolygon(value) - } -} - -impl TryFrom> for GeometryArray { - type Error = GeoArrowError; - fn try_from(value: WKBArray) -> Result { - let type_ids = value.get_unique_type_ids(); - - if type_ids.is_empty() { - return Err(GeoArrowError::General( - "Input WKB array is empty.".to_string(), - )); - } - - if type_ids.len() == 1 { - if type_ids.contains(&0) { - return Ok(GeometryArray::Point(value.try_into()?)); - } - - if type_ids.contains(&1) { - return Ok(GeometryArray::LineString(value.try_into()?)); - } - - if type_ids.contains(&3) { - return Ok(GeometryArray::Polygon(value.try_into()?)); - } - - if type_ids.contains(&4) { - return Ok(GeometryArray::MultiPoint(value.try_into()?)); - } - - if type_ids.contains(&5) { - return Ok(GeometryArray::MultiLineString(value.try_into()?)); - } - - if type_ids.contains(&6) { - return Ok(GeometryArray::MultiPolygon(value.try_into()?)); - } - } - - if type_ids.len() == 3 { - if type_ids.contains(&0) && type_ids.contains(&4) { - return Ok(GeometryArray::MultiPoint(value.try_into()?)); - } - - if type_ids.contains(&1) && type_ids.contains(&5) { - return Ok(GeometryArray::MultiLineString(value.try_into()?)); - } - - if type_ids.contains(&3) && type_ids.contains(&6) { - return Ok(GeometryArray::MultiPolygon(value.try_into()?)); - } - } - - Err(GeoArrowError::General( - "Mixed WKB parsing not yet implemented".to_string(), - )) - } -} - -impl From> for GeometryArray { - fn from(value: GeometryArray) -> Self { - match value { - GeometryArray::Point(arr) => GeometryArray::Point(arr), - GeometryArray::LineString(arr) => GeometryArray::LineString(arr.into()), - GeometryArray::Polygon(arr) => GeometryArray::Polygon(arr.into()), - GeometryArray::MultiPoint(arr) => GeometryArray::MultiPoint(arr.into()), - GeometryArray::MultiLineString(arr) => GeometryArray::MultiLineString(arr.into()), - GeometryArray::MultiPolygon(arr) => GeometryArray::MultiPolygon(arr.into()), - GeometryArray::Rect(arr) => GeometryArray::Rect(arr), - } - } -} - -impl TryFrom> for GeometryArray { - type Error = GeoArrowError; - - fn try_from(value: GeometryArray) -> Result { - Ok(match value { - GeometryArray::Point(arr) => GeometryArray::Point(arr), - GeometryArray::LineString(arr) => GeometryArray::LineString(arr.try_into()?), - GeometryArray::Polygon(arr) => GeometryArray::Polygon(arr.try_into()?), - GeometryArray::MultiPoint(arr) => GeometryArray::MultiPoint(arr.try_into()?), - GeometryArray::MultiLineString(arr) => GeometryArray::MultiLineString(arr.try_into()?), - GeometryArray::MultiPolygon(arr) => GeometryArray::MultiPolygon(arr.try_into()?), - GeometryArray::Rect(arr) => GeometryArray::Rect(arr), - }) - } -} diff --git a/src/array/geometry/iterator.rs b/src/array/geometry/iterator.rs deleted file mode 100644 index 8b137891..00000000 --- a/src/array/geometry/iterator.rs +++ /dev/null @@ -1 +0,0 @@ - diff --git a/src/array/geometry/mod.rs b/src/array/geometry/mod.rs deleted file mode 100644 index 8089ed8b..00000000 --- a/src/array/geometry/mod.rs +++ /dev/null @@ -1,7 +0,0 @@ -//! Contains the [`GeometryArray`], which is an enum over all geometry array types. - -pub use array::GeometryArray; - -mod array; -mod iterator; -// mod mutable; diff --git a/src/array/mod.rs b/src/array/mod.rs index ef486dce..addcd26e 100644 --- a/src/array/mod.rs +++ b/src/array/mod.rs @@ -5,7 +5,6 @@ pub use coord::{ CoordBuffer, CoordBufferBuilder, CoordType, InterleavedCoordBuffer, InterleavedCoordBufferBuilder, SeparatedCoordBuffer, SeparatedCoordBufferBuilder, }; -pub use geometry::GeometryArray; pub use geometrycollection::GeometryCollectionArray; pub use linestring::{LineStringArray, LineStringBuilder}; pub use mixed::{MixedGeometryArray, MixedGeometryBuilder}; @@ -18,7 +17,7 @@ pub use rect::RectArray; pub mod binary; pub mod coord; -pub mod geometry; +pub mod dyn_geometry_array; pub mod geometrycollection; pub mod linestring; pub mod mixed; diff --git a/src/io/geozero/table/data_source.rs b/src/io/geozero/table/data_source.rs index f6345054..d054d3dd 100644 --- a/src/io/geozero/table/data_source.rs +++ b/src/io/geozero/table/data_source.rs @@ -1,7 +1,6 @@ -use crate::array::GeometryArray; use crate::io::geozero::scalar::geometry::process_geometry; use crate::table::GeoTable; -use crate::trait_::GeometryArrayAccessor; +use crate::GeometryArrayTrait; use arrow_array::{ BinaryArray, Float16Array, Float32Array, Float64Array, Int16Array, Int32Array, Int64Array, Int8Array, LargeBinaryArray, LargeStringArray, RecordBatch, StringArray, UInt16Array, @@ -54,8 +53,10 @@ fn process_batch( let num_rows = batch.num_rows(); let geometry_field = schema.field(geometry_column_index); let geometry_column_box = &batch.columns()[geometry_column_index]; - let geometry_column: GeometryArray = - (geometry_field, &**geometry_column_box).try_into().unwrap(); + let geometry_column: Box = + (geometry_field, &**geometry_column_box, false) + .try_into() + .unwrap(); for within_batch_row_idx in 0..num_rows { processor.feature_begin((within_batch_row_idx + batch_start_idx) as u64)?; @@ -228,12 +229,13 @@ fn process_properties( Ok(()) } +#[allow(clippy::borrowed_box)] fn process_geometry_n( - geometry_column: &GeometryArray, + geometry_column: &Box, within_batch_row_idx: usize, processor: &mut P, ) -> Result<(), GeozeroError> { - let geom = geometry_column.value(within_batch_row_idx); + let geom = geometry_column.value::(within_batch_row_idx); // I think this index is 0 because it's not a multi-geometry? process_geometry(&geom, 0, processor)?; Ok(())