Skip to content

Commit 722e92b

Browse files
authored
Refactor codebase to use geoarrow_schema crate (#1016)
### Changes to `geoarrow_schema` - Add accessors `crs_type` and `crs_value` to `Crs` - Make `CrsType` and `Edges` `Copy` - Implement `TryFrom<&Field> for Metadata` - Add `PointType::to_field` and similar for all geometry types - Fix `Geometry` type not containing GeometryCollection ### Change list - Update `NativeType` enum variants to hold the new types from #1015. This means that the `NativeType` now stores GeoArrow metadata as well, not just coordinate type and dimension. - Update geometry array structs to hold the new extension type from #1015. So `PointArray::data_type` is a `PointType`, not a `NativeType::Point`. - Update imports to import from `geoarrow_schema`. We **don't** currently re-export types from `geoarrow_schema` through `geoarrow` so that it's clear what pieces of code do or do not actually need the full `geoarrow` crate. - Skip some Python tests temporarily to get CI to pass. Post #1015
1 parent d7cfa0c commit 722e92b

File tree

229 files changed

+3330
-3560
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

229 files changed

+3330
-3560
lines changed

Cargo.lock

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

js/Cargo.lock

Lines changed: 14 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

js/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ futures = { version = "0.3.30", optional = true }
9191
geo = "0.30"
9292
geo-traits = "0.2"
9393
geoarrow = { path = "../rust/geoarrow" }
94+
geoarrow-schema = { path = "../rust/geoarrow-schema" }
9495
geodesy = { version = "0.12", optional = true, features = ["js"] }
9596
object_store = { version = "0.11", optional = true }
9697
# Use released version when it supports object-store 0.11

js/src/algorithm/geoarrow/coord_format.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,20 +16,20 @@ pub enum CoordType {
1616
Separated,
1717
}
1818

19-
impl From<CoordType> for geoarrow::array::CoordType {
19+
impl From<CoordType> for geoarrow_schema::CoordType {
2020
fn from(value: CoordType) -> Self {
2121
match value {
22-
CoordType::Interleaved => geoarrow::array::CoordType::Interleaved,
23-
CoordType::Separated => geoarrow::array::CoordType::Separated,
22+
CoordType::Interleaved => geoarrow_schema::CoordType::Interleaved,
23+
CoordType::Separated => geoarrow_schema::CoordType::Separated,
2424
}
2525
}
2626
}
2727

28-
impl From<geoarrow::array::CoordType> for CoordType {
29-
fn from(value: geoarrow::array::CoordType) -> Self {
28+
impl From<geoarrow_schema::CoordType> for CoordType {
29+
fn from(value: geoarrow_schema::CoordType) -> Self {
3030
match value {
31-
geoarrow::array::CoordType::Interleaved => CoordType::Interleaved,
32-
geoarrow::array::CoordType::Separated => CoordType::Separated,
31+
geoarrow_schema::CoordType::Interleaved => CoordType::Interleaved,
32+
geoarrow_schema::CoordType::Separated => CoordType::Separated,
3333
}
3434
}
3535
}

js/src/data/coord.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use arrow_buffer::ScalarBuffer;
2-
use geoarrow::datatypes::Dimension;
2+
use geoarrow_schema::Dimension;
33
use wasm_bindgen::prelude::*;
44

55
// TODO: remove InterleavedCoordBuffer and SeparatedCoordBuffer structs?

js/src/data/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ pub mod coord;
33
use arrow_array::BinaryArray;
44
use arrow_buffer::Buffer;
55
pub use coord::{CoordBuffer, InterleavedCoordBuffer, SeparatedCoordBuffer};
6-
use geoarrow::datatypes::Dimension;
6+
use geoarrow_schema::Dimension;
77

88
use crate::error::WasmResult;
99
use crate::utils::vec_to_offsets;

js/src/io/parquet/async.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ use geoarrow::io::parquet::{
99
GeoParquetDatasetMetadata, GeoParquetReaderMetadata, GeoParquetReaderOptions,
1010
GeoParquetRecordBatchStream, GeoParquetRecordBatchStreamBuilder,
1111
};
12+
use geoarrow_schema::CoordType;
1213
use object_store::{ObjectMeta, ObjectStore};
1314
use object_store_wasm::http::HttpStore;
1415
use parquet::arrow::arrow_reader::ArrowReaderMetadata;
@@ -238,7 +239,9 @@ impl ParquetDataset {
238239
pub async fn read(&self, options: JsValue) -> WasmResult<Table> {
239240
let options: Option<JsParquetReaderOptions> = serde_wasm_bindgen::from_value(options)?;
240241
let readers = self.to_readers(options.unwrap_or_default().into())?;
241-
let output_schema = self.meta.resolved_schema(Default::default())?;
242+
let output_schema = self
243+
.meta
244+
.resolved_schema(CoordType::default_interleaved())?;
242245

243246
let request_futures = readers.into_iter().map(|reader| reader.read_table());
244247
let tables = futures::future::join_all(request_futures)

js/src/io/parquet/options.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use geo::coord;
2-
use geoarrow::array::CoordType;
32
use geoarrow::io::parquet::GeoParquetReaderOptions;
3+
use geoarrow_schema::CoordType;
44
use serde::{Deserialize, Serialize};
55

66
#[derive(Serialize, Deserialize)]

python/Cargo.lock

Lines changed: 16 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

python/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ arrow-buffer = "54"
2020
arrow-schema = "54"
2121
geo-traits = "0.2"
2222
geoarrow = { path = "../rust/geoarrow" }
23+
geoarrow-schema = { path = "../rust/geoarrow-schema" }
2324
# Uncomment when publishing
2425
# geoarrow = { version = "0.4.0-beta.1" }
2526
geozero = "0.14"

python/geoarrow-core/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ pyo3-arrow = { workspace = true }
3131
pyo3-geoarrow = { path = "../pyo3-geoarrow" }
3232
geo = "0.30"
3333
geoarrow = { workspace = true }
34+
geoarrow-schema = { workspace = true }
3435
geozero = { version = "0.14", features = ["with-svg"] }
3536
numpy = { workspace = true }
3637
serde_json = "1"

python/geoarrow-core/python/geoarrow/rust/core/enums.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,3 +39,11 @@ class Dimension(StrEnum):
3939
XYZ = "xyz"
4040
"""Three dimensions, X, Y, and Z
4141
"""
42+
43+
XYM = "xym"
44+
"""Three dimensions, X, Y, and M
45+
"""
46+
47+
XYZM = "xyzm"
48+
"""Four dimensions, X, Y, Z, and M
49+
"""

python/geoarrow-core/src/constructors.rs

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,20 @@
11
use std::sync::Arc;
22

3-
use geoarrow::array::metadata::ArrayMetadata;
43
use geoarrow::array::{
54
LineStringArray, MultiLineStringArray, MultiPointArray, MultiPolygonArray, NativeArrayDyn,
65
PointArray, PolygonArray,
76
};
7+
use geoarrow_schema::Metadata;
88
use pyo3::prelude::*;
9-
use pyo3_geoarrow::{PyCoordBuffer, PyGeoArrowResult, PyNativeArray, PyOffsetBuffer, CRS};
9+
use pyo3_geoarrow::{PyCoordBuffer, PyCrs, PyGeoArrowResult, PyNativeArray, PyOffsetBuffer};
1010

11-
fn create_array_metadata(crs: Option<CRS>) -> Arc<ArrayMetadata> {
11+
fn create_array_metadata(crs: Option<PyCrs>) -> Arc<Metadata> {
1212
Arc::new(crs.map(|inner| inner.into_inner()).unwrap_or_default())
1313
}
1414

1515
#[pyfunction]
1616
#[pyo3(signature = (coords, *, crs = None))]
17-
pub fn points(coords: PyCoordBuffer, crs: Option<CRS>) -> PyGeoArrowResult<PyNativeArray> {
17+
pub fn points(coords: PyCoordBuffer, crs: Option<PyCrs>) -> PyGeoArrowResult<PyNativeArray> {
1818
let metadata = create_array_metadata(crs);
1919
let array = PointArray::new(coords.into_inner(), None, metadata);
2020
Ok(PyNativeArray::new(NativeArrayDyn::new(Arc::new(array))))
@@ -25,7 +25,7 @@ pub fn points(coords: PyCoordBuffer, crs: Option<CRS>) -> PyGeoArrowResult<PyNat
2525
pub fn linestrings(
2626
coords: PyCoordBuffer,
2727
geom_offsets: PyOffsetBuffer,
28-
crs: Option<CRS>,
28+
crs: Option<PyCrs>,
2929
) -> PyGeoArrowResult<PyNativeArray> {
3030
let metadata = create_array_metadata(crs);
3131
let array = LineStringArray::new(
@@ -43,7 +43,7 @@ pub fn polygons(
4343
coords: PyCoordBuffer,
4444
geom_offsets: PyOffsetBuffer,
4545
ring_offsets: PyOffsetBuffer,
46-
crs: Option<CRS>,
46+
crs: Option<PyCrs>,
4747
) -> PyGeoArrowResult<PyNativeArray> {
4848
let metadata = create_array_metadata(crs);
4949
let array = PolygonArray::new(
@@ -61,7 +61,7 @@ pub fn polygons(
6161
pub fn multipoints(
6262
coords: PyCoordBuffer,
6363
geom_offsets: PyOffsetBuffer,
64-
crs: Option<CRS>,
64+
crs: Option<PyCrs>,
6565
) -> PyGeoArrowResult<PyNativeArray> {
6666
let metadata = create_array_metadata(crs);
6767
let array = MultiPointArray::new(
@@ -79,7 +79,7 @@ pub fn multilinestrings(
7979
coords: PyCoordBuffer,
8080
geom_offsets: PyOffsetBuffer,
8181
ring_offsets: PyOffsetBuffer,
82-
crs: Option<CRS>,
82+
crs: Option<PyCrs>,
8383
) -> PyGeoArrowResult<PyNativeArray> {
8484
let metadata = create_array_metadata(crs);
8585
let array = MultiLineStringArray::new(
@@ -99,7 +99,7 @@ pub fn multipolygons(
9999
geom_offsets: PyOffsetBuffer,
100100
polygon_offsets: PyOffsetBuffer,
101101
ring_offsets: PyOffsetBuffer,
102-
crs: Option<CRS>,
102+
crs: Option<PyCrs>,
103103
) -> PyGeoArrowResult<PyNativeArray> {
104104
let metadata = create_array_metadata(crs);
105105
let array = MultiPolygonArray::new(

python/geoarrow-core/src/interop/shapely/from_shapely.rs

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,15 @@ use crate::constructors::{
66
use crate::ffi::to_python::native_array_to_pyobject;
77
use crate::interop::shapely::utils::import_shapely;
88
use arrow_array::builder::BinaryBuilder;
9-
use geoarrow::array::metadata::ArrayMetadata;
10-
use geoarrow::datatypes::{Dimension, NativeType};
9+
use geoarrow::datatypes::NativeType;
10+
use geoarrow_schema::{CoordType, Dimension, GeometryCollectionType, Metadata};
1111
use pyo3::exceptions::PyValueError;
1212
use pyo3::intern;
1313
use pyo3::prelude::*;
1414
use pyo3::pybacked::PyBackedBytes;
1515
use pyo3::types::{PyDict, PyString, PyTuple};
1616
use pyo3::PyAny;
17-
use pyo3_geoarrow::{PyGeoArrowResult, CRS};
17+
use pyo3_geoarrow::{PyCrs, PyGeoArrowResult};
1818

1919
/// Check that the value of the GeometryType enum returned from shapely.to_ragged_array matches the
2020
/// expected variant for this geometry array.
@@ -80,7 +80,7 @@ fn call_to_wkb<'a>(
8080
pub fn from_shapely(
8181
py: Python,
8282
input: &Bound<PyAny>,
83-
crs: Option<CRS>,
83+
crs: Option<PyCrs>,
8484
) -> PyGeoArrowResult<PyObject> {
8585
let numpy_mod = py.import(intern!(py, "numpy"))?;
8686
let shapely_mod = import_shapely(py)?;
@@ -160,7 +160,11 @@ pub fn from_shapely(
160160
let wkb_arr = make_wkb_arr(py, input, metadata)?;
161161
let geom_arr = geoarrow::io::wkb::from_wkb(
162162
&wkb_arr,
163-
NativeType::GeometryCollection(Default::default(), Dimension::XY),
163+
NativeType::GeometryCollection(GeometryCollectionType::new(
164+
CoordType::default_interleaved(),
165+
Dimension::XY,
166+
Default::default(),
167+
)),
164168
false,
165169
)?;
166170
native_array_to_pyobject(py, geom_arr)
@@ -170,7 +174,7 @@ pub fn from_shapely(
170174
fn make_wkb_arr(
171175
py: Python,
172176
input: &Bound<PyAny>,
173-
metadata: Arc<ArrayMetadata>,
177+
metadata: Arc<Metadata>,
174178
) -> PyGeoArrowResult<geoarrow::array::WKBArray<i32>> {
175179
let shapely_mod = import_shapely(py)?;
176180
let wkb_result = call_to_wkb(py, &shapely_mod, input)?;
@@ -198,7 +202,7 @@ macro_rules! impl_chunked_from_shapely {
198202
py: Python,
199203
input: &Bound<PyAny>,
200204
chunk_size: usize,
201-
crs: Option<CRS>,
205+
crs: Option<PyCrs>,
202206
) -> PyGeoArrowResult<Self> {
203207
let len = input.len()?;
204208
let num_chunks = (len as f64 / chunk_size as f64).ceil() as usize;

python/geoarrow-core/src/interop/shapely/to_shapely.rs

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -93,25 +93,23 @@ fn pyarray_to_shapely(py: Python, input: PyArray) -> PyGeoArrowResult<Bound<PyAn
9393

9494
use NativeType::*;
9595
match typ {
96-
Point(_, _) => point_arr(py, array.as_ref().as_point().clone()),
97-
LineString(_, _) => linestring_arr(py, array.as_ref().as_line_string().clone()),
98-
Polygon(_, _) => polygon_arr(py, array.as_ref().as_polygon().clone()),
99-
MultiPoint(_, _) => multipoint_arr(py, array.as_ref().as_multi_point().clone()),
100-
MultiLineString(_, _) => {
96+
Point(_) => point_arr(py, array.as_ref().as_point().clone()),
97+
LineString(_) => linestring_arr(py, array.as_ref().as_line_string().clone()),
98+
Polygon(_) => polygon_arr(py, array.as_ref().as_polygon().clone()),
99+
MultiPoint(_) => multipoint_arr(py, array.as_ref().as_multi_point().clone()),
100+
MultiLineString(_) => {
101101
multilinestring_arr(py, array.as_ref().as_multi_line_string().clone())
102102
}
103-
MultiPolygon(_, _) => {
104-
multipolygon_arr(py, array.as_ref().as_multi_polygon().clone())
105-
}
103+
MultiPolygon(_) => multipolygon_arr(py, array.as_ref().as_multi_polygon().clone()),
106104
Rect(_) => rect_arr(py, array.as_ref().as_rect().clone()),
107-
GeometryCollection(_, _) => via_wkb(py, array),
105+
GeometryCollection(_) => via_wkb(py, array),
108106
Geometry(_) => via_wkb(py, array),
109107
}
110108
}
111109
AnyType::Serialized(typ) => {
112110
let array = SerializedArrayDyn::from_arrow_array(&array, &field)?.into_inner();
113111
match typ {
114-
SerializedType::WKB => wkb_arr(py, array.as_ref().as_wkb().clone()),
112+
SerializedType::WKB(_) => wkb_arr(py, array.as_ref().as_wkb().clone()),
115113
t => Err(PyValueError::new_err(format!("unsupported type {:?}", t)).into()),
116114
}
117115
}

0 commit comments

Comments
 (0)