Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove GeometryArray enum #291

Closed
wants to merge 17 commits into from
30 changes: 30 additions & 0 deletions src/algorithm/geo/bounding_rect.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@ use crate::array::*;
use arrow_array::OffsetSizeTrait;
use geo::algorithm::bounding_rect::BoundingRect as GeoBoundingRect;
use geo::Rect;
use crate::array::dyn_geometry_array::{as_line_string_array, as_point_array};
use crate::datatypes::GeoDataType;
use crate::GeometryArrayTrait;

/// Calculation of the bounding rectangle of a geometry.
pub trait BoundingRect {
Expand Down Expand Up @@ -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<Option<Rect>> = 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::<i32>(self);
let output_geoms: Vec<Option<Rect>> = array
.iter_geo()
.map(|maybe_g| maybe_g.and_then(|geom| geom.bounding_rect()))
.collect();

RectArray::from(output_geoms)
}
_ => unimplemented!()
}
}
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ideally we'll be able to use a similar macro as we already have here:

/// 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(),
}
}
)+
};
}

instead of copying the original function content for every branch

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I started scratch work of this in #326


impl BoundingRect for PointArray {
fn bounding_rect(&self) -> RectArray {
let output_geoms: Vec<Option<Rect>> = self
Expand Down
Loading