Skip to content

Commit

Permalink
commit wip
Browse files Browse the repository at this point in the history
  • Loading branch information
kylebarron committed Oct 7, 2024
1 parent de83eca commit b05bec0
Show file tree
Hide file tree
Showing 6 changed files with 107 additions and 151 deletions.
8 changes: 4 additions & 4 deletions benches/nybb.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ use std::fs::File;

use arrow_ipc::reader::FileReader;
use criterion::{criterion_group, criterion_main, Criterion};
use geoarrow::algorithm::geo::EuclideanDistance;
use geoarrow::algorithm::geo::EuclideanDistanceScalar;
use geoarrow::array::{MultiPolygonArray, PointArray};
use geoarrow::trait_::ArrayAccessor;
use geoarrow::trait_::{ArrayAccessor, NativeGeometryAccessor};

fn load_nybb() -> MultiPolygonArray<2> {
let file = File::open("fixtures/nybb.arrow").unwrap();
Expand Down Expand Up @@ -39,9 +39,9 @@ pub fn criterion_benchmark(c: &mut Criterion) {
c.bench_function("euclidean distance to scalar point", |b| {
b.iter(|| {
let point = geo::Point::new(0.0f64, 0.0f64);
let point_array = PointArray::from(vec![point].as_slice());
let point_array = PointArray::<2>::from(vec![point].as_slice());

let _distances = array.euclidean_distance(&point_array.value(0));
let _distances = array.euclidean_distance(&point_array.value_as_geometry(0));
})
});
}
Expand Down
79 changes: 4 additions & 75 deletions src/algorithm/broadcasting/geometry.rs
Original file line number Diff line number Diff line change
@@ -1,78 +1,7 @@
use crate::algorithm::broadcasting::linestring::BroadcastLineStringIter;
use crate::algorithm::broadcasting::multilinestring::BroadcastMultiLineStringIter;
use crate::algorithm::broadcasting::multipoint::BroadcastMultiPointIter;
use crate::algorithm::broadcasting::multipolygon::BroadcastMultiPolygonIter;
use crate::algorithm::broadcasting::point::BroadcastPointIter;
use crate::algorithm::broadcasting::polygon::BroadcastPolygonIter;
use crate::algorithm::broadcasting::{
BroadcastableLineString, BroadcastableMultiLineString, BroadcastableMultiPoint,
BroadcastableMultiPolygon, BroadcastablePoint, BroadcastablePolygon,
};
use crate::scalar::Geometry;
use arrow_array::OffsetSizeTrait;
use crate::trait_::NativeGeometryAccessor;

/// An enum over all broadcastable geometry types.
///
/// [`IntoIterator`] is implemented for this, where it will iterate over the `Array` variant
/// normally but will iterate over the `Scalar` variant forever.
#[derive(Debug)]
pub enum BroadcastableGeometry<'a, O: OffsetSizeTrait> {
Point(BroadcastablePoint<'a>),
LineString(BroadcastableLineString<'a, O>),
Polygon(BroadcastablePolygon<'a, O>),
MultiPoint(BroadcastableMultiPoint<'a, O>),
MultiLineString(BroadcastableMultiLineString<'a, O>),
MultiPolygon(BroadcastableMultiPolygon<'a, O>),
}

pub enum BroadcastGeometryIter<'a, O: OffsetSizeTrait> {
Point(BroadcastPointIter<'a>),
LineString(BroadcastLineStringIter<'a, O>),
Polygon(BroadcastPolygonIter<'a, O>),
MultiPoint(BroadcastMultiPointIter<'a, O>),
MultiLineString(BroadcastMultiLineStringIter<'a, O>),
MultiPolygon(BroadcastMultiPolygonIter<'a, O>),
}

impl<'a, O: OffsetSizeTrait> IntoIterator for &'a BroadcastableGeometry<'a, O> {
type Item = Option<Geometry<'a, O>>;
type IntoIter = BroadcastGeometryIter<'a, O>;

fn into_iter(self) -> Self::IntoIter {
match self {
BroadcastableGeometry::Point(p) => BroadcastGeometryIter::Point(p.into_iter()),
BroadcastableGeometry::LineString(p) => {
BroadcastGeometryIter::LineString(p.into_iter())
}
BroadcastableGeometry::Polygon(p) => BroadcastGeometryIter::Polygon(p.into_iter()),
BroadcastableGeometry::MultiPoint(p) => {
BroadcastGeometryIter::MultiPoint(p.into_iter())
}
BroadcastableGeometry::MultiLineString(p) => {
BroadcastGeometryIter::MultiLineString(p.into_iter())
}
BroadcastableGeometry::MultiPolygon(p) => {
BroadcastGeometryIter::MultiPolygon(p.into_iter())
}
}
}
}

impl<'a, O: OffsetSizeTrait> Iterator for BroadcastGeometryIter<'a, O> {
type Item = Option<Geometry<'a, O>>;

fn next(&mut self) -> Option<Self::Item> {
match self {
BroadcastGeometryIter::Point(p) => p.next().map(|g| g.map(Geometry::Point)),
BroadcastGeometryIter::LineString(p) => p.next().map(|g| g.map(Geometry::LineString)),
BroadcastGeometryIter::Polygon(p) => p.next().map(|g| g.map(Geometry::Polygon)),
BroadcastGeometryIter::MultiPoint(p) => p.next().map(|g| g.map(Geometry::MultiPoint)),
BroadcastGeometryIter::MultiLineString(p) => {
p.next().map(|g| g.map(Geometry::MultiLineString))
}
BroadcastGeometryIter::MultiPolygon(p) => {
p.next().map(|g| g.map(Geometry::MultiPolygon))
}
}
}
pub enum BroadcastableGeoGeometry<'a> {
Scalar(&'a geo::Geometry),
Array(&'a dyn NativeGeometryAccessor<'a, 2>),
}
78 changes: 78 additions & 0 deletions src/algorithm/broadcasting/geometry_bak.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
use crate::algorithm::broadcasting::linestring::BroadcastLineStringIter;
use crate::algorithm::broadcasting::multilinestring::BroadcastMultiLineStringIter;
use crate::algorithm::broadcasting::multipoint::BroadcastMultiPointIter;
use crate::algorithm::broadcasting::multipolygon::BroadcastMultiPolygonIter;
use crate::algorithm::broadcasting::point::BroadcastPointIter;
use crate::algorithm::broadcasting::polygon::BroadcastPolygonIter;
use crate::algorithm::broadcasting::{
BroadcastableLineString, BroadcastableMultiLineString, BroadcastableMultiPoint,
BroadcastableMultiPolygon, BroadcastablePoint, BroadcastablePolygon,
};
use crate::scalar::Geometry;
use arrow_array::OffsetSizeTrait;

/// An enum over all broadcastable geometry types.
///
/// [`IntoIterator`] is implemented for this, where it will iterate over the `Array` variant
/// normally but will iterate over the `Scalar` variant forever.
#[derive(Debug)]
pub enum BroadcastableGeometry<'a, O: OffsetSizeTrait> {
Point(BroadcastablePoint<'a>),
LineString(BroadcastableLineString<'a, O>),
Polygon(BroadcastablePolygon<'a, O>),
MultiPoint(BroadcastableMultiPoint<'a, O>),
MultiLineString(BroadcastableMultiLineString<'a, O>),
MultiPolygon(BroadcastableMultiPolygon<'a, O>),
}

pub enum BroadcastGeometryIter<'a, O: OffsetSizeTrait> {
Point(BroadcastPointIter<'a>),
LineString(BroadcastLineStringIter<'a, O>),
Polygon(BroadcastPolygonIter<'a, O>),
MultiPoint(BroadcastMultiPointIter<'a, O>),
MultiLineString(BroadcastMultiLineStringIter<'a, O>),
MultiPolygon(BroadcastMultiPolygonIter<'a, O>),
}

impl<'a, O: OffsetSizeTrait> IntoIterator for &'a BroadcastableGeometry<'a, O> {
type Item = Option<Geometry<'a, O>>;
type IntoIter = BroadcastGeometryIter<'a, O>;

fn into_iter(self) -> Self::IntoIter {
match self {
BroadcastableGeometry::Point(p) => BroadcastGeometryIter::Point(p.into_iter()),
BroadcastableGeometry::LineString(p) => {
BroadcastGeometryIter::LineString(p.into_iter())
}
BroadcastableGeometry::Polygon(p) => BroadcastGeometryIter::Polygon(p.into_iter()),
BroadcastableGeometry::MultiPoint(p) => {
BroadcastGeometryIter::MultiPoint(p.into_iter())
}
BroadcastableGeometry::MultiLineString(p) => {
BroadcastGeometryIter::MultiLineString(p.into_iter())
}
BroadcastableGeometry::MultiPolygon(p) => {
BroadcastGeometryIter::MultiPolygon(p.into_iter())
}
}
}
}

impl<'a, O: OffsetSizeTrait> Iterator for BroadcastGeometryIter<'a, O> {
type Item = Option<Geometry<'a, O>>;

fn next(&mut self) -> Option<Self::Item> {
match self {
BroadcastGeometryIter::Point(p) => p.next().map(|g| g.map(Geometry::Point)),
BroadcastGeometryIter::LineString(p) => p.next().map(|g| g.map(Geometry::LineString)),
BroadcastGeometryIter::Polygon(p) => p.next().map(|g| g.map(Geometry::Polygon)),
BroadcastGeometryIter::MultiPoint(p) => p.next().map(|g| g.map(Geometry::MultiPoint)),
BroadcastGeometryIter::MultiLineString(p) => {
p.next().map(|g| g.map(Geometry::MultiLineString))
}
BroadcastGeometryIter::MultiPolygon(p) => {
p.next().map(|g| g.map(Geometry::MultiPolygon))
}
}
}
}
2 changes: 1 addition & 1 deletion src/algorithm/broadcasting/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
mod primitive;
mod vec;

// pub use geometry::BroadcastableGeometry;
// pub use geometry::BroadcastableGeoGeometry;
// pub use linestring::BroadcastableLineString;
// pub use multilinestring::BroadcastableMultiLineString;
// pub use multipoint::BroadcastableMultiPoint;
Expand Down
89 changes: 19 additions & 70 deletions src/algorithm/geo/contains.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use crate::algorithm::native::{Binary, Unary};
use crate::algorithm::native::binary::try_binary_boolean_native_geometry;
use crate::algorithm::native::Unary;
use crate::array::*;
use crate::datatypes::{Dimension, NativeType};
use crate::error::GeoArrowError;
Expand All @@ -10,7 +11,7 @@ use crate::io::geo::{
geometry_collection_to_geo, geometry_to_geo, line_string_to_geo, multi_line_string_to_geo,
multi_point_to_geo, multi_polygon_to_geo, point_to_geo, polygon_to_geo,
};
use crate::trait_::{ArrayAccessor, NativeScalar};
use crate::trait_::{ArrayAccessor, NativeGeometryAccessor, NativeScalar};
use crate::NativeArray;
use arrow_array::builder::BooleanBuilder;
use arrow_array::BooleanArray;
Expand Down Expand Up @@ -50,84 +51,32 @@ use geo::Contains as _Contains;
/// // Point in Polygon
/// assert!(polygon.contains(&point!(x: 1., y: 1.)));
/// ```
pub trait Contains<Rhs = Self> {
fn contains(&self, rhs: &Rhs) -> BooleanArray;
}

// ┌────────────────────────────────┐
// │ Implementations for RHS arrays │
// └────────────────────────────────┘

// Note: this implementation is outside the macro because it is not generic over O
impl Contains for PointArray<2> {
fn contains(&self, rhs: &Self) -> BooleanArray {
self.try_binary_boolean(rhs, |left, right| {
Ok(left.to_geo().contains(&right.to_geo()))
})
.unwrap()
}
pub trait Contains<'a, Rhs> {
fn contains(&'a self, rhs: &'a Rhs) -> BooleanArray;
}

// Implementation that iterates over geo objects
macro_rules! iter_geo_impl {
($first:ty, $second:ty) => {
impl<'a> Contains<$second> for $first {
fn contains(&self, rhs: &$second) -> BooleanArray {
self.try_binary_boolean(rhs, |left, right| {
Ok(left.to_geo().contains(&right.to_geo()))
($array_type:ty) => {
impl<'a, R: NativeGeometryAccessor<'a, 2>> Contains<'a, R> for $array_type {
fn contains(&'a self, rhs: &'a R) -> BooleanArray {
try_binary_boolean_native_geometry(self, rhs, |l, r| {
Ok(l.to_geo().contains(&r.to_geo()))
})
.unwrap()
}
}
};
}

// Implementations on PointArray
iter_geo_impl!(PointArray<2>, LineStringArray<2>);
iter_geo_impl!(PointArray<2>, PolygonArray<2>);
iter_geo_impl!(PointArray<2>, MultiPointArray<2>);
iter_geo_impl!(PointArray<2>, MultiLineStringArray<2>);
iter_geo_impl!(PointArray<2>, MultiPolygonArray<2>);

// Implementations on LineStringArray
iter_geo_impl!(LineStringArray<2>, PointArray<2>);
iter_geo_impl!(LineStringArray<2>, LineStringArray<2>);
iter_geo_impl!(LineStringArray<2>, PolygonArray<2>);
iter_geo_impl!(LineStringArray<2>, MultiPointArray<2>);
iter_geo_impl!(LineStringArray<2>, MultiLineStringArray<2>);
iter_geo_impl!(LineStringArray<2>, MultiPolygonArray<2>);

// Implementations on PolygonArray
iter_geo_impl!(PolygonArray<2>, PointArray<2>);
iter_geo_impl!(PolygonArray<2>, LineStringArray<2>);
iter_geo_impl!(PolygonArray<2>, PolygonArray<2>);
iter_geo_impl!(PolygonArray<2>, MultiPointArray<2>);
iter_geo_impl!(PolygonArray<2>, MultiLineStringArray<2>);
iter_geo_impl!(PolygonArray<2>, MultiPolygonArray<2>);

// Implementations on MultiPointArray
iter_geo_impl!(MultiPointArray<2>, PointArray<2>);
iter_geo_impl!(MultiPointArray<2>, LineStringArray<2>);
iter_geo_impl!(MultiPointArray<2>, PolygonArray<2>);
iter_geo_impl!(MultiPointArray<2>, MultiPointArray<2>);
iter_geo_impl!(MultiPointArray<2>, MultiLineStringArray<2>);
iter_geo_impl!(MultiPointArray<2>, MultiPolygonArray<2>);

// Implementations on MultiLineStringArray
iter_geo_impl!(MultiLineStringArray<2>, PointArray<2>);
iter_geo_impl!(MultiLineStringArray<2>, LineStringArray<2>);
iter_geo_impl!(MultiLineStringArray<2>, PolygonArray<2>);
iter_geo_impl!(MultiLineStringArray<2>, MultiPointArray<2>);
iter_geo_impl!(MultiLineStringArray<2>, MultiLineStringArray<2>);
iter_geo_impl!(MultiLineStringArray<2>, MultiPolygonArray<2>);

// Implementations on MultiPolygonArray
iter_geo_impl!(MultiPolygonArray<2>, PointArray<2>);
iter_geo_impl!(MultiPolygonArray<2>, LineStringArray<2>);
iter_geo_impl!(MultiPolygonArray<2>, PolygonArray<2>);
iter_geo_impl!(MultiPolygonArray<2>, MultiPointArray<2>);
iter_geo_impl!(MultiPolygonArray<2>, MultiLineStringArray<2>);
iter_geo_impl!(MultiPolygonArray<2>, MultiPolygonArray<2>);
iter_geo_impl!(PointArray<2>);
iter_geo_impl!(LineStringArray<2>);
iter_geo_impl!(PolygonArray<2>);
iter_geo_impl!(MultiPointArray<2>);
iter_geo_impl!(MultiLineStringArray<2>);
iter_geo_impl!(MultiPolygonArray<2>);
iter_geo_impl!(MixedGeometryArray<2>);
iter_geo_impl!(GeometryCollectionArray<2>);
iter_geo_impl!(RectArray<2>);

// ┌─────────────────────────────────┐
// │ Implementations for RHS scalars │
Expand Down
2 changes: 1 addition & 1 deletion src/algorithm/geo/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ pub use euclidean_length::EuclideanLength;

/// Calculate the minimum Euclidean distance between two `Geometries`.
mod euclidean_distance;
pub use euclidean_distance::EuclideanDistance;
pub use euclidean_distance::{EuclideanDistance, EuclideanDistanceScalar};

mod frechet_distance;
pub use frechet_distance::{FrechetDistance, FrechetDistanceLineString};
Expand Down

0 comments on commit b05bec0

Please sign in to comment.