Skip to content

Commit 31bb27e

Browse files
authored
docs(pyo3-geoarrow): Improve docs (#1377)
1 parent 1600b69 commit 31bb27e

File tree

17 files changed

+192
-9
lines changed

17 files changed

+192
-9
lines changed

python/geoarrow-core/src/lib.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,6 @@
33
mod constructors;
44
mod interop;
55
mod operations;
6-
// pub mod ffi;
7-
// pub mod table;
86

97
use pyo3::exceptions::PyRuntimeWarning;
108
use pyo3::intern;

rust/pyo3-geoarrow/CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# Changelog
2+
3+
## [Unreleased]
4+
5+
- docs(pyo3-geoarrow): Improve docs #1377

rust/pyo3-geoarrow/README.md

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
# pyo3-geoarrow
2+
3+
[PyO3](https://pyo3.rs/) bindings for GeoArrow types, enabling seamless integration between Rust's GeoArrow implementation and Python.
4+
5+
This crate provides Python-compatible wrappers around GeoArrow data structures, allowing Python code to efficiently work with and share geospatial data in the GeoArrow format through the [Arrow C Data Interface][arrow-c-data-interface] (using the [Arrow PyCapsule Interface][arrow-pycapsule-interface]) without data copies.
6+
7+
[arrow-c-data-interface]: https://arrow.apache.org/docs/format/CDataInterface.html
8+
[arrow-pycapsule-interface]: https://arrow.apache.org/docs/format/CDataInterface/PyCapsuleInterface.html
9+
10+
## Features
11+
12+
- **Zero-copy data exchange**: Use Arrow's [C Data Interface][arrow-c-data-interface] for efficient memory sharing between Rust and Python.
13+
- **GeoArrow types**: Python bindings for GeoArrow geometry arrays, scalars, and metadata.
14+
- **Type safety**: Strongly-typed wrappers that preserve GeoArrow's type system in Python.
15+
- **FFI support**: Import and export GeoArrow data to/from Python using the [Arrow PyCapsule Interface][arrow-pycapsule-interface].
16+
17+
## Core Types
18+
19+
- [`PyGeoArray`]: Python wrapper for GeoArrow geometry arrays
20+
- [`PyGeoChunkedArray`]: Python wrapper for chunked GeoArrow geometry arrays
21+
- [`PyGeoArrayReader`]: Python wrapper for streaming array readers
22+
- [`PyGeoScalar`]: Python wrapper for GeoArrow scalar geometries
23+
- [`PyGeoType`]: Python wrapper for GeoArrow data types
24+
- [`PyCrs`]: Python wrapper for coordinate reference system representation
25+
26+
## Usage
27+
28+
This crate is primarily intended for use by Python binding developers who need to interoperate with GeoArrow data in Python. It is also used internally by the `geoarrow-rust-*` Python packages.
29+
30+
```rust
31+
use std::sync::Arc;
32+
33+
use pyo3::prelude::*;
34+
use pyo3_geoarrow::PyGeoArray;
35+
use geoarrow_array::GeoArrowArray;
36+
37+
#[pyfunction]
38+
fn process_geometry(py: Python, array: PyGeoArray) -> PyResult<PyGeoArray> {
39+
// Access the underlying GeoArrow array
40+
let inner: Arc<dyn GeoArrowArray> = array.into_inner();
41+
42+
// Perform operations...
43+
44+
Ok(PyGeoArray::new(inner))
45+
}
46+
```
47+
48+
## Integration with Arrow
49+
50+
This crate implements the [Arrow PyCapsule Interface](https://arrow.apache.org/docs/format/CDataInterface/PyCapsuleInterface.html), allowing GeoArrow objects to be exchanged with any Python library that supports Arrow, including:
51+
52+
- PyArrow
53+
- Polars (once they support extension types)
54+
- GeoPandas (via PyArrow)
55+
- DuckDB
56+
57+
## Dependencies
58+
59+
This crate builds on:
60+
61+
- [`pyo3`](https://docs.rs/pyo3): Python bindings for Rust
62+
- [`pyo3-arrow`](https://docs.rs/pyo3-arrow): Arrow integration for PyO3
63+
- [`geoarrow-array`](https://docs.rs/geoarrow-array): Core GeoArrow array types
64+
- [`geoarrow-schema`](https://docs.rs/geoarrow-schema): GeoArrow type system and metadata

rust/pyo3-geoarrow/src/array.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,15 @@ use crate::error::{PyGeoArrowError, PyGeoArrowResult};
2020
use crate::scalar::PyGeoScalar;
2121
use crate::utils::text_repr::text_repr;
2222

23+
/// Python wrapper for a GeoArrow geometry array.
24+
///
25+
/// This type wraps a Rust GeoArrow array and exposes it to Python through the Arrow C Data
26+
/// Interface. It supports zero-copy data exchange with Arrow-compatible Python libraries.
2327
#[pyclass(module = "geoarrow.rust.core", name = "GeoArray", subclass, frozen)]
2428
pub struct PyGeoArray(Arc<dyn GeoArrowArray>);
2529

2630
impl PyGeoArray {
31+
/// Create a new [`PyGeoArray`] from a GeoArrow array.
2732
pub fn new(array: Arc<dyn GeoArrowArray>) -> Self {
2833
Self(array)
2934
}
@@ -36,10 +41,12 @@ impl PyGeoArray {
3641
PyArray::from_arrow_pycapsule(schema_capsule, array_capsule)?.try_into()
3742
}
3843

44+
/// Access the underlying GeoArrow array.
3945
pub fn inner(&self) -> &Arc<dyn GeoArrowArray> {
4046
&self.0
4147
}
4248

49+
/// Consume this wrapper and return the underlying GeoArrow array.
4350
pub fn into_inner(self) -> Arc<dyn GeoArrowArray> {
4451
self.0
4552
}

rust/pyo3-geoarrow/src/array_reader.rs

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,15 @@ use crate::data_type::PyGeoType;
1616
use crate::utils::text_repr::text_repr;
1717
use crate::{PyGeoArray, PyGeoArrowError, PyGeoArrowResult, PyGeoChunkedArray};
1818

19-
/// A Python-facing GeoArrow array reader.
19+
/// Python wrapper for a GeoArrow array reader (stream).
2020
///
21-
/// This is a wrapper around a [PyArrayReader].
21+
/// This type represents a stream of GeoArrow arrays that can be read incrementally. It implements
22+
/// the Arrow C Stream Interface, allowing zero-copy data exchange with Arrow-compatible Python
23+
/// libraries.
24+
///
25+
/// The reader can be iterated over to yield individual [`PyGeoArray`] chunks, or materialized
26+
/// into a [`PyGeoChunkedArray`] using the [`into_chunked_array()`][Self::into_chunked_array]
27+
/// method. For stream processing, prefer [`into_reader()`][Self::into_reader].
2228
#[pyclass(
2329
module = "geoarrow.rust.core",
2430
name = "GeoArrayReader",
@@ -31,6 +37,7 @@ pub struct PyGeoArrayReader {
3137
}
3238

3339
impl PyGeoArrayReader {
40+
/// Create a new [`PyGeoArrayReader`] from a GeoArrow array reader.
3441
pub fn new(reader: Box<dyn GeoArrowArrayReader + Send>) -> Self {
3542
let data_type = reader.data_type();
3643
Self {
@@ -51,6 +58,7 @@ impl PyGeoArrayReader {
5158
// (self.iter, self.data_type)
5259
// }
5360

61+
/// Get the GeoArrow data type of arrays in this stream.
5462
pub fn data_type(&self) -> &GeoArrowType {
5563
&self.data_type
5664
}

rust/pyo3-geoarrow/src/chunked_array.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,9 @@ use crate::scalar::PyGeoScalar;
2222
use crate::utils::text_repr::text_repr;
2323
use crate::{PyCoordType, PyGeoArray};
2424

25+
/// Python wrapper for a chunked GeoArrow geometry array.
26+
///
27+
/// A chunked array is a collection of contiguous arrays of the same type.
2528
#[pyclass(
2629
module = "geoarrow.rust.core",
2730
name = "GeoChunkedArray",
@@ -82,6 +85,7 @@ impl PyGeoChunkedArray {
8285
Ok(Self::try_new(chunks, data_type)?)
8386
}
8487

88+
/// Consume this wrapper and return the underlying chunks and data type.
8589
pub fn into_inner(self) -> (Vec<Arc<dyn GeoArrowArray>>, GeoArrowType) {
8690
(self.chunks, self.data_type)
8791
}
@@ -155,7 +159,7 @@ impl PyGeoChunkedArray {
155159
}
156160

157161
#[classmethod]
158-
pub fn from_arrow(_cls: &Bound<PyType>, data: Self) -> Self {
162+
fn from_arrow(_cls: &Bound<PyType>, data: Self) -> Self {
159163
data
160164
}
161165

rust/pyo3-geoarrow/src/coord_buffer.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,15 @@ use pyo3_arrow::PyArray;
1111

1212
use crate::PyGeoArrowError;
1313

14+
/// Python wrapper for a GeoArrow coordinate buffer.
15+
///
16+
/// Coordinate buffers store the raw coordinate data for geometries. They can be in either
17+
/// separated format (separate arrays for x, y, z, m) or interleaved format (single array
18+
/// with coordinates interleaved).
1419
pub struct PyCoordBuffer(CoordBuffer);
1520

1621
impl PyCoordBuffer {
22+
/// Consume this wrapper and return the underlying coordinate buffer.
1723
pub fn into_inner(self) -> CoordBuffer {
1824
self.0
1925
}

rust/pyo3-geoarrow/src/coord_type.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,15 @@ use pyo3::exceptions::PyValueError;
33
use pyo3::intern;
44
use pyo3::prelude::*;
55

6+
/// Python wrapper for GeoArrow coordinate type.
7+
///
8+
/// Specifies whether coordinates are stored in an interleaved (XYZXYZ...) or
9+
/// separated (XXX..., YYY..., ZZZ...) layout in memory.
610
#[derive(Debug, Default, Clone, Copy)]
711
pub enum PyCoordType {
12+
/// Interleaved coordinate layout (XYZXYZ...).
813
Interleaved,
14+
/// Separated coordinate layout (XXX..., YYY..., ZZZ...).
915
#[default]
1016
Separated,
1117
}

rust/pyo3-geoarrow/src/crs.rs

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,11 @@ use serde_json::Value;
1111
use crate::PyGeoArrowError;
1212
use crate::error::PyGeoArrowResult;
1313

14-
/// A wrapper around [`Crs`] to integrate with `pyproj` Python APIs.
14+
/// Python wrapper for a coordinate reference system (CRS).
15+
///
16+
/// This type integrates with the `pyproj` Python library, allowing CRS definitions to be
17+
/// passed between Rust and Python. It can accept any input that `pyproj.CRS.from_user_input`
18+
/// accepts, including EPSG codes, WKT strings, PROJ strings, and `pyproj.CRS` objects.
1519
#[derive(Clone, Debug, Default)]
1620
// TODO: should this be under an Arc?
1721
pub struct PyCrs(Crs);
@@ -41,6 +45,7 @@ impl<'py> FromPyObject<'py> for PyCrs {
4145
}
4246

4347
impl PyCrs {
48+
/// Create a [`PyCrs`] from a PROJJSON value.
4449
pub fn from_projjson(value: Value) -> Self {
4550
Self(Crs::from_projjson(value))
4651
}
@@ -103,6 +108,7 @@ impl PyCrs {
103108
Ok(crs_obj.into())
104109
}
105110

111+
/// Convert the CRS to a PROJJSON value.
106112
pub fn to_projjson(&self, py: Python) -> PyResult<Option<Value>> {
107113
let pyproj_crs = self.to_pyproj(py)?;
108114
if pyproj_crs.is_none(py) {
@@ -118,6 +124,7 @@ impl PyCrs {
118124
}
119125
}
120126

127+
/// Convert the CRS to a WKT string.
121128
pub fn to_wkt(&self, py: Python) -> PyResult<Option<String>> {
122129
let pyproj_crs = self.to_pyproj(py)?;
123130
if pyproj_crs.is_none(py) {
@@ -155,11 +162,15 @@ impl<'py> IntoPyObject<'py> for PyCrs {
155162
}
156163
}
157164

158-
/// An implementation of [CrsTransform] using pyproj.
165+
/// An implementation of [`CrsTransform`] using pyproj.
166+
///
167+
/// This type enables CRS transformations by delegating to the pyproj Python library,
168+
/// allowing conversion between different CRS representations (PROJJSON, WKT, etc.).
159169
#[derive(Debug)]
160170
pub struct PyprojCRSTransform {}
161171

162172
impl PyprojCRSTransform {
173+
/// Create a new [`PyprojCRSTransform`].
163174
pub fn new() -> Self {
164175
Self {}
165176
}

rust/pyo3-geoarrow/src/data_type.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,13 @@
1+
//! GeoArrow data type definitions and constructors.
2+
//!
3+
//! This module provides Python bindings for GeoArrow geometry types, including:
4+
//! - Native geometry types (Point, LineString, Polygon, MultiPoint, etc.)
5+
//! - Well-Known Binary (WKB) and Well-Known Text (WKT) types
6+
//! - Type metadata (CRS, coordinate type, dimensions, edges)
7+
8+
// TODO: remove when we move type constructors to geoarrow-rust-core
9+
#![allow(missing_docs)]
10+
111
use std::sync::Arc;
212

313
use geoarrow_schema::{
@@ -14,10 +24,15 @@ use crate::error::{PyGeoArrowError, PyGeoArrowResult};
1424
use crate::utils::text_repr::text_repr;
1525
use crate::{PyCoordType, PyCrs, PyDimension, PyEdges};
1626

27+
/// Python wrapper for a GeoArrow data type.
28+
///
29+
/// This type represents the schema of a GeoArrow geometry array, including the geometry type,
30+
/// coordinate type, dimensions, coordinate reference system, and edge interpolation.
1731
#[pyclass(module = "geoarrow.rust.core", name = "GeoType", subclass, frozen)]
1832
pub struct PyGeoType(pub(crate) GeoArrowType);
1933

2034
impl PyGeoType {
35+
/// Create a new [`PyGeoType`] from a GeoArrow data type.
2136
pub fn new(data_type: GeoArrowType) -> Self {
2237
Self(data_type)
2338
}
@@ -27,6 +42,7 @@ impl PyGeoType {
2742
PyField::from_arrow_pycapsule(capsule)?.try_into()
2843
}
2944

45+
/// Consume this wrapper and return the underlying GeoArrow data type.
3046
pub fn into_inner(self) -> GeoArrowType {
3147
self.0
3248
}
@@ -154,6 +170,7 @@ impl_from_geoarrow_type!(BoxType, Rect);
154170

155171
macro_rules! impl_native_type_constructor {
156172
($fn_name:ident, $geoarrow_type:ty) => {
173+
#[allow(missing_docs)]
157174
#[pyfunction]
158175
#[pyo3(
159176
signature = (dimension, *, coord_type = PyCoordType::Separated, crs=None, edges=None),
@@ -205,6 +222,7 @@ pub fn geometry(coord_type: PyCoordType, crs: Option<PyCrs>, edges: Option<PyEdg
205222

206223
macro_rules! impl_wkb_wkt {
207224
($method_name:ident, $type_constructor:ty, $variant:expr) => {
225+
#[allow(missing_docs)]
208226
#[pyfunction]
209227
#[pyo3(signature = (*, crs=None, edges=None))]
210228
pub fn $method_name(crs: Option<PyCrs>, edges: Option<PyEdges>) -> PyGeoType {

0 commit comments

Comments
 (0)