Skip to content

Commit

Permalink
Initial DataFusion extension crate (#939)
Browse files Browse the repository at this point in the history
### Change list

- Initial UDFs that wrap native Rust code
- Array types for Geometry, Box2D, Box3D, Point2D, and Point3D.
- Function support matrix in the README compared to PostGIS
  • Loading branch information
kylebarron authored Dec 13, 2024
1 parent a726afd commit b612869
Show file tree
Hide file tree
Showing 32 changed files with 3,157 additions and 46 deletions.
664 changes: 659 additions & 5 deletions Cargo.lock

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[workspace]
members = ["rust/geoarrow"]
members = ["rust/geoarrow", "rust/geodatafusion"]
exclude = ["js"]
resolver = "2"

Expand Down
78 changes: 78 additions & 0 deletions rust/geoarrow/src/algorithm/native/bounding_rect.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,11 @@ use geo_traits::{
MultiLineStringTrait, MultiPointTrait, MultiPolygonTrait, PointTrait, PolygonTrait, RectTrait,
};

use crate::array::*;
use crate::datatypes::{Dimension, NativeType};
use crate::error::Result;
use crate::trait_::ArrayAccessor;

#[derive(Debug, Clone, Copy)]
pub struct BoundingRect {
minx: f64,
Expand Down Expand Up @@ -301,4 +306,77 @@ pub fn bounding_rect_rect(geom: &impl RectTrait<T = f64>) -> ([f64; 2], [f64; 2]
rect.into()
}

/// Calculation of the bounding rectangle of a geometry.
pub trait BoundingRectArray {
type Output;

fn bounding_rect(&self) -> Self::Output;
}

/// Implementation that iterates over geo objects
macro_rules! array_impl {
($type:ty, $bounding_rect_fn:ident) => {
impl BoundingRectArray for $type {
type Output = RectArray;

fn bounding_rect(&self) -> Self::Output {
let mut builder = RectBuilder::with_capacity_and_options(
Dimension::XY,
self.len(),
self.metadata().clone(),
);
for geom in self.iter() {
if let Some(geom) = geom {
let ([minx, miny], [maxx, maxy]) = $bounding_rect_fn(&geom);
builder.push_box2d(Some([minx, miny, maxx, maxy]));
} else {
builder.push_null();
}
}

builder.finish()
}
}
};
}

array_impl!(PointArray, bounding_rect_point);
array_impl!(LineStringArray, bounding_rect_linestring);
array_impl!(PolygonArray, bounding_rect_polygon);
array_impl!(MultiPointArray, bounding_rect_multipoint);
array_impl!(MultiLineStringArray, bounding_rect_multilinestring);
array_impl!(MultiPolygonArray, bounding_rect_multipolygon);
array_impl!(MixedGeometryArray, bounding_rect_geometry);
array_impl!(GeometryCollectionArray, bounding_rect_geometry_collection);
array_impl!(GeometryArray, bounding_rect_geometry);

impl BoundingRectArray for RectArray {
type Output = RectArray;

fn bounding_rect(&self) -> Self::Output {
self.clone()
}
}

impl BoundingRectArray for &dyn NativeArray {
type Output = Result<RectArray>;

fn bounding_rect(&self) -> Self::Output {
use NativeType::*;

let result = match self.data_type() {
Point(_, _) => self.as_point().bounding_rect(),
LineString(_, _) => self.as_line_string().bounding_rect(),
Polygon(_, _) => self.as_polygon().bounding_rect(),
MultiPoint(_, _) => self.as_multi_point().bounding_rect(),
MultiLineString(_, _) => self.as_multi_line_string().bounding_rect(),
MultiPolygon(_, _) => self.as_multi_polygon().bounding_rect(),
GeometryCollection(_, _) => self.as_geometry_collection().bounding_rect(),
Geometry(_) => self.as_geometry().bounding_rect(),
Rect(_) => self.as_rect().bounding_rect(),
};
Ok(result)
}
}

// TODO: add tests from geo
1 change: 1 addition & 0 deletions rust/geoarrow/src/algorithm/native/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ pub(crate) mod type_id;
mod unary;

pub use binary::Binary;
pub use bounding_rect::BoundingRectArray;
pub use cast::Cast;
pub use concatenate::Concatenate;
pub use downcast::{Downcast, DowncastTable};
Expand Down
Loading

0 comments on commit b612869

Please sign in to comment.