macro_rules! downcast_geoarrow_array {
($array:ident, $fn:expr) => { ... };
}
Expand description
Downcast a GeoArrowArray to a concrete-typed array based on its GeoArrowType
.
For example: computing unsigned area:
use arrow_array::Float64Array;
use arrow_array::builder::Float64Builder;
use geo::Area;
use geo_traits::to_geo::ToGeoGeometry;
use geoarrow_schema::error::GeoArrowResult;
use geoarrow_array::{GeoArrowArrayAccessor, GeoArrowArray, downcast_geoarrow_array};
pub fn unsigned_area(array: &dyn GeoArrowArray) -> GeoArrowResult<Float64Array> {
downcast_geoarrow_array!(array, impl_unsigned_area)
}
fn impl_unsigned_area<'a>(array: &'a impl GeoArrowArrayAccessor<'a>) -> GeoArrowResult<Float64Array> {
let mut builder = Float64Builder::with_capacity(array.len());
for item in array.iter() {
if let Some(geom) = item {
builder.append_value(geom?.to_geometry().unsigned_area());
} else {
builder.append_null();
}
}
Ok(builder.finish())
}
You can also override the behavior of specific data types to specialize or provide a fast path. For example, we know that points and lines will always have an area of 0, and don’t need to iterate over the input values to compute that.
fn impl_unsigned_area_specialized<'a>(array: &'a impl GeoArrowArrayAccessor<'a>) -> GeoArrowResult<Float64Array> {
use GeoArrowType::*;
match array.data_type() {
Point(_) | LineString(_) | MultiPoint(_) | MultiLineString(_) => {
let values = vec![0.0f64; array.len()];
Ok(Float64Array::new(values.into(), array.logical_nulls()))
}
_ => impl_unsigned_area(array),
}
}
This is a simplified version of the upstream downcast_primitive_array.
If you would like to help in updating this downcast_geoarrow_array
to support the full range
of functionality of the upstream downcast_primitive_array
, please create an issue or submit a
PR.