Skip to content

Commit

Permalink
Merge branch 'main' into kyle/implement-algs-geometry-array
Browse files Browse the repository at this point in the history
  • Loading branch information
kylebarron committed Dec 10, 2024
2 parents 19f7741 + 9e68c71 commit ac3e9c4
Show file tree
Hide file tree
Showing 13 changed files with 540 additions and 484 deletions.
107 changes: 44 additions & 63 deletions rust/geoarrow/src/algorithm/native/cast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ impl Default for CastOptions {

/// Note: not currently used and outdated
#[allow(dead_code)]
fn can_cast_types(from_type: &NativeType, to_type: &NativeType) -> bool {
fn can_cast_types(from_type: NativeType, to_type: NativeType) -> bool {
if from_type == to_type {
return true;
}
Expand All @@ -51,13 +51,13 @@ pub trait Cast {
type Output;

/// Note: **does not currently implement dimension casts**
fn cast(&self, to_type: &NativeType) -> Self::Output;
fn cast(&self, to_type: NativeType) -> Self::Output;
}

impl Cast for PointArray {
type Output = Result<Arc<dyn NativeArray>>;

fn cast(&self, to_type: &NativeType) -> Self::Output {
fn cast(&self, to_type: NativeType) -> Self::Output {
use NativeType::*;

let array = self.to_coord_type(to_type.coord_type());
Expand All @@ -66,6 +66,7 @@ impl Cast for PointArray {
MultiPoint(_, _) => Ok(Arc::new(MultiPointArray::from(array))),
Mixed(_, _) => Ok(Arc::new(MixedGeometryArray::from(array))),
GeometryCollection(_, _) => Ok(Arc::new(GeometryCollectionArray::from(array))),
Geometry(_) => Ok(Arc::new(GeometryArray::from(array))),
dt => Err(GeoArrowError::General(format!(
"invalid cast to type {dt:?}"
))),
Expand All @@ -76,7 +77,7 @@ impl Cast for PointArray {
impl Cast for LineStringArray {
type Output = Result<Arc<dyn NativeArray>>;

fn cast(&self, to_type: &NativeType) -> Self::Output {
fn cast(&self, to_type: NativeType) -> Self::Output {
use NativeType::*;

let array = self.to_coord_type(to_type.coord_type());
Expand All @@ -86,6 +87,7 @@ impl Cast for LineStringArray {
MultiLineString(_, _) => Ok(Arc::new(MultiLineStringArray::from(array))),
Mixed(_, _) => Ok(Arc::new(MixedGeometryArray::from(array))),
GeometryCollection(_, _) => Ok(Arc::new(GeometryCollectionArray::from(array))),
Geometry(_) => Ok(Arc::new(GeometryArray::from(array))),
dt => Err(GeoArrowError::General(format!(
"invalid cast to type {dt:?}"
))),
Expand All @@ -96,7 +98,7 @@ impl Cast for LineStringArray {
impl Cast for PolygonArray {
type Output = Result<Arc<dyn NativeArray>>;

fn cast(&self, to_type: &NativeType) -> Self::Output {
fn cast(&self, to_type: NativeType) -> Self::Output {
use NativeType::*;

let array = self.to_coord_type(to_type.coord_type());
Expand All @@ -106,6 +108,7 @@ impl Cast for PolygonArray {
MultiPolygon(_, _) => Ok(Arc::new(MultiPolygonArray::from(array))),
Mixed(_, _) => Ok(Arc::new(MixedGeometryArray::from(array))),
GeometryCollection(_, _) => Ok(Arc::new(GeometryCollectionArray::from(array))),
Geometry(_) => Ok(Arc::new(GeometryArray::from(array))),
dt => Err(GeoArrowError::General(format!(
"invalid cast to type {dt:?}"
))),
Expand All @@ -116,7 +119,7 @@ impl Cast for PolygonArray {
impl Cast for MultiPointArray {
type Output = Result<Arc<dyn NativeArray>>;

fn cast(&self, to_type: &NativeType) -> Self::Output {
fn cast(&self, to_type: NativeType) -> Self::Output {
use NativeType::*;

let array = self.to_coord_type(to_type.coord_type());
Expand All @@ -126,6 +129,7 @@ impl Cast for MultiPointArray {
MultiPoint(_, _) => Ok(Arc::new(array)),
Mixed(_, _) => Ok(Arc::new(MixedGeometryArray::from(array))),
GeometryCollection(_, _) => Ok(Arc::new(GeometryCollectionArray::from(array))),
Geometry(_) => Ok(Arc::new(GeometryArray::from(array))),
dt => Err(GeoArrowError::General(format!(
"invalid cast to type {dt:?}"
))),
Expand All @@ -136,7 +140,7 @@ impl Cast for MultiPointArray {
impl Cast for MultiLineStringArray {
type Output = Result<Arc<dyn NativeArray>>;

fn cast(&self, to_type: &NativeType) -> Self::Output {
fn cast(&self, to_type: NativeType) -> Self::Output {
use NativeType::*;

let array = self.to_coord_type(to_type.coord_type());
Expand All @@ -145,6 +149,7 @@ impl Cast for MultiLineStringArray {
LineString(_, _) => Ok(Arc::new(LineStringArray::try_from(array)?)),
Mixed(_, _) => Ok(Arc::new(MixedGeometryArray::from(array))),
GeometryCollection(_, _) => Ok(Arc::new(GeometryCollectionArray::from(array))),
Geometry(_) => Ok(Arc::new(GeometryArray::from(array))),
dt => Err(GeoArrowError::General(format!(
"invalid cast to type {dt:?}"
))),
Expand All @@ -155,7 +160,7 @@ impl Cast for MultiLineStringArray {
impl Cast for MultiPolygonArray {
type Output = Result<Arc<dyn NativeArray>>;

fn cast(&self, to_type: &NativeType) -> Self::Output {
fn cast(&self, to_type: NativeType) -> Self::Output {
use NativeType::*;

let array = self.to_coord_type(to_type.coord_type());
Expand All @@ -164,6 +169,7 @@ impl Cast for MultiPolygonArray {
Polygon(_, _) => Ok(Arc::new(PolygonArray::try_from(array)?)),
Mixed(_, _) => Ok(Arc::new(MixedGeometryArray::from(array))),
GeometryCollection(_, _) => Ok(Arc::new(GeometryCollectionArray::from(array))),
Geometry(_) => Ok(Arc::new(GeometryArray::from(array))),
dt => Err(GeoArrowError::General(format!(
"invalid cast to type {dt:?}"
))),
Expand All @@ -174,7 +180,7 @@ impl Cast for MultiPolygonArray {
impl Cast for MixedGeometryArray {
type Output = Result<Arc<dyn NativeArray>>;

fn cast(&self, to_type: &NativeType) -> Self::Output {
fn cast(&self, to_type: NativeType) -> Self::Output {
use NativeType::*;

let array = self.to_coord_type(to_type.coord_type());
Expand All @@ -198,7 +204,7 @@ impl Cast for MixedGeometryArray {
impl Cast for GeometryCollectionArray {
type Output = Result<Arc<dyn NativeArray>>;

fn cast(&self, to_type: &NativeType) -> Self::Output {
fn cast(&self, to_type: NativeType) -> Self::Output {
use NativeType::*;

let array = self.to_coord_type(to_type.coord_type());
Expand All @@ -212,17 +218,29 @@ impl Cast for GeometryCollectionArray {
MultiPolygon(_, _) => Ok(Arc::new(MultiPolygonArray::try_from(array)?)),
Mixed(_, _) => Ok(Arc::new(MixedGeometryArray::try_from(array)?)),
GeometryCollection(_, _) => Ok(Arc::new(array)),
Geometry(_) => Ok(Arc::new(GeometryArray::from(array))),
dt => Err(GeoArrowError::General(format!(
"invalid cast to type {dt:?}"
))),
}
}
}

impl Cast for GeometryArray {
type Output = Result<Arc<dyn NativeArray>>;

fn cast(&self, to_type: NativeType) -> Self::Output {
// TODO: validate dimension
let array = self.to_coord_type(to_type.coord_type());
let mixed_array = MixedGeometryArray::try_from(array)?;
mixed_array.cast(to_type)
}
}

impl Cast for &dyn NativeArray {
type Output = Result<Arc<dyn NativeArray>>;

fn cast(&self, to_type: &NativeType) -> Self::Output {
fn cast(&self, to_type: NativeType) -> Self::Output {
// TODO: not working :/
// if self.data_type() == to_type {
// return Ok(Arc::new(self.to_owned()));
Expand All @@ -239,56 +257,18 @@ impl Cast for &dyn NativeArray {
MultiPolygon(_, _) => self.as_ref().as_multi_polygon().cast(to_type),
Mixed(_, _) => self.as_ref().as_mixed().cast(to_type),
GeometryCollection(_, _) => self.as_ref().as_geometry_collection().cast(to_type),
Geometry(_) => self.as_ref().as_geometry().cast(to_type),
_ => todo!(),
}
}
}

macro_rules! impl_chunked_cast_non_generic {
($chunked_array:ty) => {
impl Cast for $chunked_array {
type Output = Result<Arc<dyn ChunkedNativeArray>>;

fn cast(&self, to_type: &NativeType) -> Self::Output {
macro_rules! impl_cast {
($method:ident) => {
Arc::new(ChunkedGeometryArray::new(
self.geometry_chunks()
.iter()
.map(|chunk| {
Ok(chunk.as_ref().cast(to_type)?.as_ref().$method().clone())
})
.collect::<Result<Vec<_>>>()?,
))
};
}

use NativeType::*;

let result: Arc<dyn ChunkedNativeArray> = match to_type {
Point(_, _) => impl_cast!(as_point),
LineString(_, _) => impl_cast!(as_line_string),
Polygon(_, _) => impl_cast!(as_polygon),
MultiPoint(_, _) => impl_cast!(as_multi_point),
MultiLineString(_, _) => impl_cast!(as_multi_line_string),
MultiPolygon(_, _) => impl_cast!(as_multi_polygon),
Mixed(_, _) => impl_cast!(as_mixed),
GeometryCollection(_, _) => impl_cast!(as_geometry_collection),
Rect(_) => impl_cast!(as_rect),
Geometry(_) => todo!("cast to unknown"),
};
Ok(result)
}
}
};
}

macro_rules! impl_chunked_cast_generic {
macro_rules! impl_chunked_cast {
($chunked_array:ty) => {
impl Cast for $chunked_array {
type Output = Result<Arc<dyn ChunkedNativeArray>>;

fn cast(&self, to_type: &NativeType) -> Self::Output {
fn cast(&self, to_type: NativeType) -> Self::Output {
macro_rules! impl_cast {
($method:ident) => {
Arc::new(ChunkedGeometryArray::new(
Expand All @@ -314,21 +294,22 @@ macro_rules! impl_chunked_cast_generic {
Mixed(_, _) => impl_cast!(as_mixed),
GeometryCollection(_, _) => impl_cast!(as_geometry_collection),
Rect(_) => impl_cast!(as_rect),
Geometry(_) => todo!("cast to unknown"),
Geometry(_) => impl_cast!(as_geometry),
};
Ok(result)
}
}
};
}

impl_chunked_cast_non_generic!(ChunkedPointArray);
impl_chunked_cast_non_generic!(ChunkedRectArray);
impl_chunked_cast_non_generic!(&dyn ChunkedNativeArray);
impl_chunked_cast_generic!(ChunkedLineStringArray);
impl_chunked_cast_generic!(ChunkedPolygonArray);
impl_chunked_cast_generic!(ChunkedMultiPointArray);
impl_chunked_cast_generic!(ChunkedMultiLineStringArray);
impl_chunked_cast_generic!(ChunkedMultiPolygonArray);
impl_chunked_cast_generic!(ChunkedMixedGeometryArray);
impl_chunked_cast_generic!(ChunkedGeometryCollectionArray);
impl_chunked_cast!(ChunkedPointArray);
impl_chunked_cast!(ChunkedRectArray);
impl_chunked_cast!(&dyn ChunkedNativeArray);
impl_chunked_cast!(ChunkedLineStringArray);
impl_chunked_cast!(ChunkedPolygonArray);
impl_chunked_cast!(ChunkedMultiPointArray);
impl_chunked_cast!(ChunkedMultiLineStringArray);
impl_chunked_cast!(ChunkedMultiPolygonArray);
impl_chunked_cast!(ChunkedMixedGeometryArray);
impl_chunked_cast!(ChunkedGeometryCollectionArray);
impl_chunked_cast!(ChunkedUnknownGeometryArray);
Loading

0 comments on commit ac3e9c4

Please sign in to comment.