Skip to content

Commit

Permalink
Flesh out io docs
Browse files Browse the repository at this point in the history
  • Loading branch information
kylebarron committed Dec 20, 2024
1 parent 9d8fadc commit 358b115
Show file tree
Hide file tree
Showing 15 changed files with 104 additions and 30 deletions.
1 change: 1 addition & 0 deletions rust/geoarrow/src/io/flatgeobuf/reader/async.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ use crate::io::geozero::array::MixedGeometryStreamBuilder;
use crate::io::geozero::table::{GeoTableBuilder, GeoTableBuilderOptions};
use crate::table::Table;

/// Read a FlatGeobuf file to a Table asynchronously from object storage.
pub async fn read_flatgeobuf_async(
reader: Arc<dyn ObjectStore>,
location: Path,
Expand Down
3 changes: 2 additions & 1 deletion rust/geoarrow/src/io/geos/array/binary.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ use crate::array::WKBArray;
use crate::error::Result;

impl<O: OffsetSizeTrait> WKBArray<O> {
pub fn from_geos(value: Vec<Option<geos::Geometry>>) -> Result<Self> {
#[allow(dead_code)]
pub(crate) fn from_geos(value: Vec<Option<geos::Geometry>>) -> Result<Self> {
let mut builder = GenericBinaryBuilder::new();
for maybe_geom in value {
if let Some(geom) = maybe_geom {
Expand Down
6 changes: 4 additions & 2 deletions rust/geoarrow/src/io/geos/array/linestring.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ use crate::error::Result;
use crate::io::geos::scalar::GEOSLineString;

impl LineStringBuilder {
pub fn from_geos(value: Vec<Option<geos::Geometry>>, dim: Dimension) -> Result<Self> {
#[allow(dead_code)]
pub(crate) fn from_geos(value: Vec<Option<geos::Geometry>>, dim: Dimension) -> Result<Self> {
// TODO: don't use new_unchecked
let geos_objects: Vec<Option<GEOSLineString>> = value
.into_iter()
Expand All @@ -15,7 +16,8 @@ impl LineStringBuilder {
}

impl LineStringArray {
pub fn from_geos(value: Vec<Option<geos::Geometry>>, dim: Dimension) -> Result<Self> {
#[allow(dead_code)]
pub(crate) fn from_geos(value: Vec<Option<geos::Geometry>>, dim: Dimension) -> Result<Self> {
let mutable_arr = LineStringBuilder::from_geos(value, dim)?;
Ok(mutable_arr.into())
}
Expand Down
6 changes: 4 additions & 2 deletions rust/geoarrow/src/io/geos/array/multilinestring.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ use crate::error::Result;
use crate::io::geos::scalar::GEOSMultiLineString;

impl MultiLineStringBuilder {
pub fn from_geos(value: Vec<Option<geos::Geometry>>, dim: Dimension) -> Result<Self> {
#[allow(dead_code)]
pub(crate) fn from_geos(value: Vec<Option<geos::Geometry>>, dim: Dimension) -> Result<Self> {
// TODO: don't use new_unchecked
let geos_objects: Vec<Option<GEOSMultiLineString>> = value
.into_iter()
Expand All @@ -15,7 +16,8 @@ impl MultiLineStringBuilder {
}

impl MultiLineStringArray {
pub fn from_geos(value: Vec<Option<geos::Geometry>>, dim: Dimension) -> Result<Self> {
#[allow(dead_code)]
pub(crate) fn from_geos(value: Vec<Option<geos::Geometry>>, dim: Dimension) -> Result<Self> {
let mutable_arr = MultiLineStringBuilder::from_geos(value, dim)?;
Ok(mutable_arr.into())
}
Expand Down
6 changes: 4 additions & 2 deletions rust/geoarrow/src/io/geos/array/multipoint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ use crate::error::Result;
use crate::io::geos::scalar::GEOSMultiPoint;

impl MultiPointBuilder {
pub fn from_geos(value: Vec<Option<geos::Geometry>>, dim: Dimension) -> Result<Self> {
#[allow(dead_code)]
pub(crate) fn from_geos(value: Vec<Option<geos::Geometry>>, dim: Dimension) -> Result<Self> {
// TODO: don't use new_unchecked
let geos_objects: Vec<Option<GEOSMultiPoint>> = value
.into_iter()
Expand All @@ -15,7 +16,8 @@ impl MultiPointBuilder {
}

impl MultiPointArray {
pub fn from_geos(value: Vec<Option<geos::Geometry>>, dim: Dimension) -> Result<Self> {
#[allow(dead_code)]
pub(crate) fn from_geos(value: Vec<Option<geos::Geometry>>, dim: Dimension) -> Result<Self> {
let mutable_arr = MultiPointBuilder::from_geos(value, dim)?;
Ok(mutable_arr.into())
}
Expand Down
6 changes: 4 additions & 2 deletions rust/geoarrow/src/io/geos/array/multipolygon.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ use crate::error::Result;
use crate::io::geos::scalar::GEOSMultiPolygon;

impl MultiPolygonBuilder {
pub fn from_geos(value: Vec<Option<geos::Geometry>>, dim: Dimension) -> Result<Self> {
#[allow(dead_code)]
pub(crate) fn from_geos(value: Vec<Option<geos::Geometry>>, dim: Dimension) -> Result<Self> {
// TODO: don't use new_unchecked
let geos_objects: Vec<Option<GEOSMultiPolygon>> = value
.into_iter()
Expand All @@ -15,7 +16,8 @@ impl MultiPolygonBuilder {
}

impl MultiPolygonArray {
pub fn from_geos(value: Vec<Option<geos::Geometry>>, dim: Dimension) -> Result<Self> {
#[allow(dead_code)]
pub(crate) fn from_geos(value: Vec<Option<geos::Geometry>>, dim: Dimension) -> Result<Self> {
let mutable_arr = MultiPolygonBuilder::from_geos(value, dim)?;
Ok(mutable_arr.into())
}
Expand Down
6 changes: 4 additions & 2 deletions rust/geoarrow/src/io/geos/array/point.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ use crate::error::Result;
use crate::io::geos::scalar::GEOSPoint;

impl PointBuilder {
pub fn from_geos(value: Vec<Option<geos::Geometry>>, dim: Dimension) -> Result<Self> {
#[allow(dead_code)]
pub(crate) fn from_geos(value: Vec<Option<geos::Geometry>>, dim: Dimension) -> Result<Self> {
// TODO: don't use new_unchecked
let geos_linestring_objects: Vec<Option<GEOSPoint>> = value
.into_iter()
Expand All @@ -15,7 +16,8 @@ impl PointBuilder {
}

impl PointArray {
pub fn from_geos(value: Vec<Option<geos::Geometry>>, dim: Dimension) -> Result<Self> {
#[allow(dead_code)]
pub(crate) fn from_geos(value: Vec<Option<geos::Geometry>>, dim: Dimension) -> Result<Self> {
let mutable_arr = PointBuilder::from_geos(value, dim)?;
Ok(mutable_arr.into())
}
Expand Down
6 changes: 4 additions & 2 deletions rust/geoarrow/src/io/geos/array/polygon.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ use crate::error::Result;
use crate::io::geos::scalar::GEOSPolygon;

impl PolygonBuilder {
pub fn from_geos(value: Vec<Option<geos::Geometry>>, dim: Dimension) -> Result<Self> {
#[allow(dead_code)]
pub(crate) fn from_geos(value: Vec<Option<geos::Geometry>>, dim: Dimension) -> Result<Self> {
// TODO: don't use new_unchecked
let geos_objects: Vec<Option<GEOSPolygon>> = value
.into_iter()
Expand All @@ -16,7 +17,8 @@ impl PolygonBuilder {
}

impl PolygonArray {
pub fn from_geos(value: Vec<Option<geos::Geometry>>, dim: Dimension) -> Result<Self> {
#[allow(dead_code)]
pub(crate) fn from_geos(value: Vec<Option<geos::Geometry>>, dim: Dimension) -> Result<Self> {
let mutable_arr = PolygonBuilder::from_geos(value, dim)?;
Ok(mutable_arr.into())
}
Expand Down
4 changes: 3 additions & 1 deletion rust/geoarrow/src/io/geos/scalar/linestring.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,9 @@ impl<'a> TryFrom<&'a LineString<'_>> for geos::Geometry {
}

impl LineString<'_> {
pub fn to_geos_linear_ring(&self) -> std::result::Result<geos::Geometry, geos::Error> {
/// Convert to a GEOS LinearRing
#[allow(dead_code)]
pub(crate) fn to_geos_linear_ring(&self) -> std::result::Result<geos::Geometry, geos::Error> {
let (start, end) = self.geom_offsets.start_end(self.geom_index);

let sliced_coords = self.coords.clone().slice(start, end - start);
Expand Down
2 changes: 2 additions & 0 deletions rust/geoarrow/src/io/geozero/scalar/geometry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,9 @@ impl GeozeroGeometry for Geometry<'_> {
}
}

/// Convert a geozero scalar data source to an [OwnedGeometry].
pub trait ToGeometry<O: OffsetSizeTrait> {
/// Convert a geozero scalar data source to an [OwnedGeometry].
fn to_geometry(&self, dim: Dimension) -> geozero::error::Result<OwnedGeometry>;
}

Expand Down
1 change: 1 addition & 0 deletions rust/geoarrow/src/io/postgis/reader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,7 @@ impl<G: GeometryArrayBuilder + GeomProcessor> GeoTableBuilder<G> {
}
}

/// Execute a SQL string against a PostGIS database, returning the result as an Arrow table.
pub async fn read_postgis<'c, E: Executor<'c, Database = Postgres>>(
executor: E,
sql: &str,
Expand Down
1 change: 1 addition & 0 deletions rust/geoarrow/src/io/shapefile/reader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ pub struct ShapefileReaderOptions {

// TODO:
// stretch goal: return a record batch reader.
/// Read a Shapefile into a [Table].
pub fn read_shapefile<T: Read + Seek>(
shp_reader: T,
dbf_reader: T,
Expand Down
43 changes: 27 additions & 16 deletions rust/geoarrow/src/io/wkb/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,10 @@ use arrow_array::OffsetSizeTrait;
/// determine the exact buffer sizes, then making a single set of allocations and filling those new
/// arrays with the WKB coordinate values.
pub trait FromWKB: Sized {
/// The input array type. Either [`WKBArray`] or [`ChunkedWKBArray`]
type Input<O: OffsetSizeTrait>;

/// Parse the WKB input.
fn from_wkb<O: OffsetSizeTrait>(
arr: &Self::Input<O>,
coord_type: CoordType,
Expand Down Expand Up @@ -100,6 +102,20 @@ impl FromWKB for GeometryCollectionArray {
}
}

impl FromWKB for GeometryArray {
type Input<O: OffsetSizeTrait> = WKBArray<O>;

fn from_wkb<O: OffsetSizeTrait>(
arr: &WKBArray<O>,
coord_type: CoordType,
_dim: Dimension,
) -> Result<Self> {
let wkb_objects: Vec<Option<WKB<'_, O>>> = arr.iter().collect();
let builder = GeometryBuilder::from_wkb(&wkb_objects, coord_type, arr.metadata(), true)?;
Ok(builder.finish())
}
}

impl FromWKB for Arc<dyn NativeArray> {
type Input<O: OffsetSizeTrait> = WKBArray<O>;

Expand All @@ -108,15 +124,7 @@ impl FromWKB for Arc<dyn NativeArray> {
coord_type: CoordType,
dim: Dimension,
) -> Result<Self> {
let wkb_objects: Vec<Option<WKB<'_, O>>> = arr.iter().collect();
let builder = GeometryCollectionBuilder::from_wkb(
&wkb_objects,
dim,
coord_type,
arr.metadata(),
true,
)?;
builder.finish().downcast()
Ok(Arc::new(GeometryArray::from_wkb(arr, coord_type, dim)?))
}
}

Expand Down Expand Up @@ -175,15 +183,17 @@ impl FromWKB for Arc<dyn ChunkedNativeArray> {
///
/// This supports either ISO or EWKB-flavored data.
///
/// Does not downcast automatically
/// The returned array is guaranteed to have exactly the type of `target_type`.
///
/// `NativeType::Rect` is currently not allowed.
pub fn from_wkb<O: OffsetSizeTrait>(
arr: &WKBArray<O>,
target_geo_data_type: NativeType,
target_type: NativeType,
prefer_multi: bool,
) -> Result<Arc<dyn NativeArray>> {
use NativeType::*;
let wkb_objects: Vec<Option<crate::scalar::WKB<'_, O>>> = arr.iter().collect();
match target_geo_data_type {
match target_type {
Point(coord_type, dim) => {
let builder = PointBuilder::from_wkb(&wkb_objects, dim, coord_type, arr.metadata())?;
Ok(Arc::new(builder.finish()))
Expand Down Expand Up @@ -224,7 +234,7 @@ pub fn from_wkb<O: OffsetSizeTrait>(
}
Rect(_) => Err(GeoArrowError::General(format!(
"Unexpected data type {:?}",
target_geo_data_type,
target_type,
))),
Geometry(coord_type) => {
let builder =
Expand All @@ -240,8 +250,10 @@ pub fn from_wkb<O: OffsetSizeTrait>(
/// determine the exact buffer sizes, then making a single set of allocations and filling those new
/// arrays with the WKB coordinate values.
pub trait ToWKB: Sized {
/// The output type, either [WKBArray] or [ChunkedWKBArray]
type Output<O: OffsetSizeTrait>;

/// Encode as WKB
fn to_wkb<O: OffsetSizeTrait>(&self) -> Self::Output<O>;
}

Expand All @@ -259,8 +271,7 @@ impl ToWKB for &dyn NativeArray {
MultiLineString(_, _) => self.as_multi_line_string().into(),
MultiPolygon(_, _) => self.as_multi_polygon().into(),
GeometryCollection(_, _) => self.as_geometry_collection().into(),

Rect(_) => todo!(),
Rect(_) => self.as_rect().into(),
Geometry(_) => self.as_geometry().into(),
}
}
Expand Down Expand Up @@ -308,7 +319,7 @@ pub fn to_wkb<O: OffsetSizeTrait>(arr: &dyn NativeArray) -> WKBArray<O> {
MultiLineString(_, _) => arr.as_multi_line_string().into(),
MultiPolygon(_, _) => arr.as_multi_polygon().into(),
GeometryCollection(_, _) => arr.as_geometry_collection().into(),
Rect(_) => todo!(),
Rect(_) => arr.as_rect().into(),
Geometry(_) => arr.as_geometry().into(),
}
}
Expand Down
1 change: 1 addition & 0 deletions rust/geoarrow/src/io/wkb/writer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@ mod multipoint;
mod multipolygon;
mod point;
mod polygon;
mod rect;
42 changes: 42 additions & 0 deletions rust/geoarrow/src/io/wkb/writer/rect.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
use crate::array::offset_builder::OffsetsBuilder;
use crate::array::{RectArray, WKBArray};
use crate::trait_::ArrayAccessor;
use crate::ArrayBase;
use arrow_array::{GenericBinaryArray, OffsetSizeTrait};
use arrow_buffer::Buffer;
use std::io::Cursor;
use wkb::writer::{rect_wkb_size, write_rect};
use wkb::Endianness;

impl<O: OffsetSizeTrait> From<&RectArray> for WKBArray<O> {
fn from(value: &RectArray) -> Self {
let mut offsets: OffsetsBuilder<O> = OffsetsBuilder::with_capacity(value.len());

// First pass: calculate binary array offsets
for maybe_geom in value.iter() {
if let Some(geom) = maybe_geom {
offsets.try_push_usize(rect_wkb_size(&geom)).unwrap();
} else {
offsets.extend_constant(1);
}
}

let values = {
let values = Vec::with_capacity(offsets.last().to_usize().unwrap());
let mut writer = Cursor::new(values);

for geom in value.iter().flatten() {
write_rect(&mut writer, &geom, Endianness::LittleEndian).unwrap();
}

writer.into_inner()
};

let binary_arr = GenericBinaryArray::new(
offsets.into(),
Buffer::from_vec(values),
value.nulls().cloned(),
);
WKBArray::new(binary_arr, value.metadata())
}
}

0 comments on commit 358b115

Please sign in to comment.