├── rust ├── geoarrow │ ├── README.md │ ├── src │ │ ├── error.rs │ │ ├── array.rs │ │ ├── datatypes.rs │ │ └── lib.rs │ └── Cargo.toml ├── geoarrow-expr-geo │ ├── README.md │ ├── src │ │ ├── util │ │ │ └── mod.rs │ │ ├── lib.rs │ │ ├── centroid.rs │ │ ├── convex_hull.rs │ │ ├── interior_point.rs │ │ └── minimum_rotated_rect.rs │ ├── CHANGELOG.md │ └── Cargo.toml ├── geoarrow-flatgeobuf │ ├── README.md │ └── src │ │ ├── reader │ │ └── mod.rs │ │ └── lib.rs ├── geoarrow-old │ ├── fixtures │ ├── src │ │ ├── io │ │ │ ├── display │ │ │ │ ├── mod.rs │ │ │ │ └── table.rs │ │ │ ├── gdal │ │ │ │ └── mod.rs │ │ │ ├── postgis │ │ │ │ └── mod.rs │ │ │ ├── geozero │ │ │ │ ├── table │ │ │ │ │ ├── mod.rs │ │ │ │ │ └── builder │ │ │ │ │ │ └── mod.rs │ │ │ │ └── mod.rs │ │ │ ├── geojson │ │ │ │ ├── mod.rs │ │ │ │ ├── writer.rs │ │ │ │ └── reader.rs │ │ │ ├── geojson_lines │ │ │ │ ├── mod.rs │ │ │ │ ├── writer.rs │ │ │ │ └── reader.rs │ │ │ ├── shapefile │ │ │ │ └── mod.rs │ │ │ └── mod.rs │ │ ├── indexed │ │ │ └── mod.rs │ │ └── algorithm │ │ │ ├── geo │ │ │ └── utils.rs │ │ │ ├── mod.rs │ │ │ ├── geodesy │ │ │ └── mod.rs │ │ │ ├── geos │ │ │ └── mod.rs │ │ │ ├── native │ │ │ └── mod.rs │ │ │ └── broadcasting │ │ │ ├── point.rs │ │ │ ├── vec.rs │ │ │ └── mod.rs │ ├── examples │ │ ├── README.md │ │ └── gdal.rs │ └── benches │ │ ├── geos_buffer.rs │ │ ├── translate.rs │ │ ├── from_geo.rs │ │ └── area.rs ├── geoarrow-expr-geos │ ├── README.md │ ├── src │ │ ├── import │ │ │ ├── mod.rs │ │ │ ├── array │ │ │ │ ├── mod.rs │ │ │ │ └── wkb.rs │ │ │ └── scalar │ │ │ │ ├── mod.rs │ │ │ │ └── coord.rs │ │ ├── export │ │ │ ├── mod.rs │ │ │ └── scalar │ │ │ │ ├── mod.rs │ │ │ │ ├── point.rs │ │ │ │ ├── multipoint.rs │ │ │ │ ├── geometrycollection.rs │ │ │ │ ├── multipolygon.rs │ │ │ │ ├── multilinestring.rs │ │ │ │ ├── polygon.rs │ │ │ │ ├── linestring.rs │ │ │ │ └── geometry.rs │ │ └── lib.rs │ └── Cargo.toml ├── pyo3-geoarrow │ ├── src │ │ ├── ffi │ │ │ ├── from_python │ │ │ │ └── mod.rs │ │ │ └── mod.rs │ │ ├── utils │ │ │ └── mod.rs │ │ └── lib.rs │ ├── CHANGELOG.md │ └── Cargo.toml ├── geoparquet │ ├── src │ │ ├── test │ │ │ ├── geoarrow_data │ │ │ │ └── mod.rs │ │ │ └── mod.rs │ │ ├── writer │ │ │ └── mod.rs │ │ ├── lib.rs │ │ └── reader │ │ │ └── mod.rs │ ├── README.md │ └── Cargo.toml ├── geoarrow-test │ ├── README.md │ ├── src │ │ ├── lib.rs │ │ └── raw │ │ │ ├── mod.rs │ │ │ └── point.rs │ └── Cargo.toml ├── geoarrow-cast │ ├── README.md │ ├── CHANGELOG.md │ ├── src │ │ └── lib.rs │ └── Cargo.toml ├── geoarrow-array │ ├── src │ │ ├── geozero │ │ │ ├── mod.rs │ │ │ ├── export │ │ │ │ ├── data_source │ │ │ │ │ └── mod.rs │ │ │ │ ├── array │ │ │ │ │ ├── mod.rs │ │ │ │ │ ├── point.rs │ │ │ │ │ ├── geometry.rs │ │ │ │ │ ├── geometrycollection.rs │ │ │ │ │ ├── linestring.rs │ │ │ │ │ ├── rect.rs │ │ │ │ │ ├── multipoint.rs │ │ │ │ │ └── polygon.rs │ │ │ │ ├── mod.rs │ │ │ │ └── scalar │ │ │ │ │ ├── mod.rs │ │ │ │ │ ├── rect.rs │ │ │ │ │ ├── linestring.rs │ │ │ │ │ ├── multipoint.rs │ │ │ │ │ ├── multipolygon.rs │ │ │ │ │ ├── geometry_collection.rs │ │ │ │ │ ├── multilinestring.rs │ │ │ │ │ ├── coord.rs │ │ │ │ │ └── polygon.rs │ │ │ └── import │ │ │ │ └── mod.rs │ │ ├── test │ │ │ ├── properties.rs │ │ │ ├── mod.rs │ │ │ ├── geometry.rs │ │ │ ├── rect.rs │ │ │ ├── geometrycollection.rs │ │ │ ├── point.rs │ │ │ ├── linestring.rs │ │ │ └── multipoint.rs │ │ ├── scalar │ │ │ └── coord │ │ │ │ └── mod.rs │ │ ├── array │ │ │ └── coord │ │ │ │ └── mod.rs │ │ ├── builder │ │ │ ├── coord │ │ │ │ └── mod.rs │ │ │ └── mod.rs │ │ ├── lib.rs │ │ └── capacity │ │ │ └── mod.rs │ └── Cargo.toml ├── geoarrow-geojson │ ├── CHANGELOG.md │ ├── src │ │ ├── lib.rs │ │ └── encoder │ │ │ ├── mod.rs │ │ │ └── wkb.rs │ ├── Cargo.toml │ └── README.md ├── geoarrow-csv │ ├── example.csv │ ├── src │ │ └── lib.rs │ ├── CHANGELOG.md │ └── Cargo.toml └── geoarrow-schema │ ├── README.md │ ├── Cargo.toml │ ├── src │ ├── lib.rs │ └── coord_type.rs │ └── CHANGELOG.md ├── docs ├── .gitignore ├── .python-version ├── source │ ├── rust.md │ └── stylesheets │ │ └── extra.css ├── pyproject.toml └── README.md ├── js ├── LICENSE_MIT ├── src │ ├── cast │ │ ├── mod.rs │ │ └── wkb.rs │ ├── data │ │ ├── mod.rs │ │ ├── geoarrow.rs │ │ └── coord.rs │ ├── io │ │ ├── object_store_s3 │ │ │ └── mod.rs │ │ ├── parquet │ │ │ └── mod.rs │ │ └── mod.rs │ ├── lib.rs │ ├── vector.rs │ ├── data_type.rs │ ├── error.rs │ ├── dimension.rs │ └── utils.rs ├── LICENSE_APACHE ├── build │ └── modules │ │ ├── geoparquet-wasm │ │ ├── build.sh │ │ └── README.md │ │ └── flatgeobuf-wasm │ │ └── README.md ├── tsconfig.docs.json ├── .yarnrc.yml ├── .gitignore ├── tsconfig.json ├── tests │ ├── web.rs │ └── js │ │ ├── geoparquet.test.ts │ │ ├── flatgeobuf.test.ts │ │ └── example.test.ts ├── DEVELOP.md ├── RELEASE.md ├── typedoc.json └── package.json ├── python ├── tests │ ├── __init__.py │ ├── core │ │ └── __init__.py │ └── utils.py ├── tests_old │ ├── __init__.py │ ├── core │ │ ├── __init__.py │ │ ├── test_array.py │ │ └── test_geometry_type.py │ ├── io │ │ ├── __init__.py │ │ ├── test_shapefile.py │ │ └── test_pyogrio.py │ ├── algorithm │ │ ├── __init__.py │ │ ├── test_area.py │ │ ├── test_explode.py │ │ └── test_affine_ops.py │ ├── interop │ │ ├── __init__.py │ │ ├── test_geopandas.py │ │ └── test_wkt.py │ └── utils.py ├── docs │ ├── index.md │ ├── DEVELOP.md │ ├── CHANGELOG.md │ ├── api │ │ ├── core │ │ │ ├── enums.md │ │ │ ├── types.md │ │ │ ├── geometry │ │ │ │ ├── type.md │ │ │ │ └── scalar.md │ │ │ ├── array.md │ │ │ ├── chunked_array.md │ │ │ ├── index.md │ │ │ ├── constructors.md │ │ │ ├── functions.md │ │ │ └── geometry_type.md │ │ ├── compute │ │ │ ├── enums.md │ │ │ ├── types.md │ │ │ └── functions.md │ │ └── io │ │ │ ├── shapefile.md.bak │ │ │ ├── postgis.md.bak │ │ │ ├── csv.md.bak │ │ │ ├── flatgeobuf.md │ │ │ ├── index.md │ │ │ ├── geojson.md.bak │ │ │ ├── gdal.md │ │ │ ├── geoparquet.md │ │ │ └── arrow_ipc.md │ ├── stylesheets │ │ └── extra.css │ └── ecosystem │ │ ├── shapely.md.bak │ │ ├── gdal.md │ │ └── geopandas.md ├── proj │ ├── python │ │ └── geoarrow │ │ │ └── rust │ │ │ └── proj │ │ │ ├── py.typed │ │ │ └── __init__.py │ ├── README.md │ ├── src │ │ └── lib.rs │ ├── pyproject.toml │ └── Cargo.toml ├── geoarrow-io │ ├── python │ │ └── geoarrow │ │ │ └── rust │ │ │ └── io │ │ │ ├── py.typed │ │ │ ├── __init__.py │ │ │ ├── types.py │ │ │ ├── _postgis.pyi │ │ │ ├── _shapefile.pyi │ │ │ └── _io.pyi │ ├── src │ │ ├── flatgeobuf │ │ │ ├── mod.rs │ │ │ └── utils.rs │ │ ├── io │ │ │ ├── mod.rs │ │ │ ├── geojson.rs │ │ │ ├── geojson_lines.rs │ │ │ └── postgis.rs │ │ ├── parquet │ │ │ └── mod.rs │ │ └── runtime.rs │ ├── README.md │ └── pyproject.toml ├── geoarrow-core │ ├── python │ │ └── geoarrow │ │ │ └── rust │ │ │ └── core │ │ │ ├── py.typed │ │ │ ├── _operations │ │ │ └── __init__.pyi │ │ │ ├── __init__.py │ │ │ └── types.py │ ├── src │ │ ├── interop │ │ │ ├── numpy │ │ │ │ ├── mod.rs │ │ │ │ └── to_numpy.rs │ │ │ ├── pyogrio │ │ │ │ └── mod.rs │ │ │ ├── geopandas │ │ │ │ ├── mod.rs │ │ │ │ ├── to_geopandas.rs │ │ │ │ └── from_geopandas.rs │ │ │ ├── shapely │ │ │ │ ├── mod.rs │ │ │ │ └── utils.rs │ │ │ ├── mod.rs │ │ │ └── utils.rs │ │ ├── operations │ │ │ └── mod.rs │ │ ├── constructors │ │ │ └── mod.rs │ │ └── ffi │ │ │ ├── from_python │ │ │ └── mod.rs │ │ │ └── mod.rs │ ├── README.md │ ├── pyproject.toml │ ├── Cargo.toml │ └── DEVELOP.md ├── geoarrow-compute │ ├── python │ │ └── geoarrow │ │ │ └── rust │ │ │ └── compute │ │ │ ├── py.typed │ │ │ └── __init__.py │ ├── src │ │ ├── algorithm │ │ │ ├── native │ │ │ │ ├── mod.rs │ │ │ │ ├── total_bounds.rs │ │ │ │ └── explode.rs │ │ │ ├── mod.rs │ │ │ ├── geo │ │ │ │ ├── mod.rs │ │ │ │ ├── center.rs │ │ │ │ ├── densify.rs │ │ │ │ ├── centroid.rs │ │ │ │ ├── envelope.rs │ │ │ │ ├── chaikin_smoothing.rs │ │ │ │ ├── dimensions.rs │ │ │ │ ├── geodesic_area.rs │ │ │ │ ├── convex_hull.rs │ │ │ │ ├── skew.rs │ │ │ │ ├── scale.rs │ │ │ │ └── translate.rs │ │ │ └── polylabel.rs │ │ ├── ffi │ │ │ ├── from_python │ │ │ │ └── mod.rs │ │ │ └── mod.rs │ │ └── util.rs │ ├── README.md │ ├── pyproject.toml │ └── Cargo.toml ├── metapackage │ ├── DEVELOP.md │ ├── README.md │ └── pyproject.toml ├── pyproject.toml ├── .gitignore └── Cargo.toml ├── fixtures ├── nybb.arrow ├── flatgeobuf │ ├── poly00.fgb │ ├── poly01.fgb │ ├── countries.fgb │ ├── alldatatypes.fgb │ ├── ns-water_water-line_small.fgb │ ├── nz-building-outlines-small.fgb │ └── README.md └── geoparquet │ ├── nybb.parquet │ ├── nybb_wkb.parquet │ ├── nybb_geoarrow.parquet │ ├── nybb_wkb_covering.parquet │ ├── overture_buildings.parquet │ ├── overture_infrastructure.parquet │ └── generate_data.py ├── .gitmodules ├── .gitignore ├── .github └── workflows │ └── conventional-commits.yml ├── LICENSE_MIT └── CONTRIBUTING.md /rust/geoarrow/README.md: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /docs/.gitignore: -------------------------------------------------------------------------------- 1 | .cache 2 | -------------------------------------------------------------------------------- /js/LICENSE_MIT: -------------------------------------------------------------------------------- 1 | ../LICENSE_MIT -------------------------------------------------------------------------------- /python/tests/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /python/tests_old/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /docs/.python-version: -------------------------------------------------------------------------------- 1 | 3.11 2 | -------------------------------------------------------------------------------- /js/src/cast/mod.rs: -------------------------------------------------------------------------------- 1 | mod wkb; 2 | -------------------------------------------------------------------------------- /python/docs/index.md: -------------------------------------------------------------------------------- 1 | ../README.md -------------------------------------------------------------------------------- /python/tests/core/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /python/tests_old/core/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /python/tests_old/io/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /rust/geoarrow-expr-geo/README.md: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /js/LICENSE_APACHE: -------------------------------------------------------------------------------- 1 | ../LICENSE_APACHE -------------------------------------------------------------------------------- /python/docs/DEVELOP.md: -------------------------------------------------------------------------------- 1 | ../DEVELOP.md -------------------------------------------------------------------------------- /python/tests_old/algorithm/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /python/tests_old/interop/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /rust/geoarrow-flatgeobuf/README.md: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /docs/source/rust.md: -------------------------------------------------------------------------------- 1 | ../../rust/README.md -------------------------------------------------------------------------------- /js/build/modules/geoparquet-wasm/build.sh: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /python/docs/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ../CHANGELOG.md -------------------------------------------------------------------------------- /rust/geoarrow-old/fixtures: -------------------------------------------------------------------------------- 1 | ../../fixtures -------------------------------------------------------------------------------- /python/proj/python/geoarrow/rust/proj/py.typed: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /python/geoarrow-io/python/geoarrow/rust/io/py.typed: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /python/geoarrow-core/python/geoarrow/rust/core/py.typed: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /rust/geoarrow-expr-geos/README.md: -------------------------------------------------------------------------------- 1 | # geoarrow-expr-geos 2 | -------------------------------------------------------------------------------- /python/geoarrow-compute/python/geoarrow/rust/compute/py.typed: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /js/tsconfig.docs.json: -------------------------------------------------------------------------------- 1 | { 2 | "include": ["pkg/**/*.d.ts"] 3 | } 4 | -------------------------------------------------------------------------------- /python/geoarrow-core/src/interop/numpy/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod to_numpy; 2 | -------------------------------------------------------------------------------- /rust/pyo3-geoarrow/src/ffi/from_python/mod.rs: -------------------------------------------------------------------------------- 1 | // pub mod scalar; 2 | -------------------------------------------------------------------------------- /rust/pyo3-geoarrow/src/utils/mod.rs: -------------------------------------------------------------------------------- 1 | pub(crate) mod text_repr; 2 | -------------------------------------------------------------------------------- /python/geoarrow-core/src/interop/pyogrio/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod from_pyogrio; 2 | -------------------------------------------------------------------------------- /python/geoarrow-core/src/operations/mod.rs: -------------------------------------------------------------------------------- 1 | pub(crate) mod type_id; 2 | -------------------------------------------------------------------------------- /js/build/modules/geoparquet-wasm/README.md: -------------------------------------------------------------------------------- 1 | # `@geoarrow/geoparquet-wasm` 2 | -------------------------------------------------------------------------------- /python/docs/api/core/enums.md: -------------------------------------------------------------------------------- 1 | # Enums 2 | 3 | ::: geoarrow.rust.core.enums 4 | -------------------------------------------------------------------------------- /python/docs/api/core/types.md: -------------------------------------------------------------------------------- 1 | # Types 2 | 3 | ::: geoarrow.rust.core.types 4 | -------------------------------------------------------------------------------- /python/proj/python/geoarrow/rust/proj/__init__.py: -------------------------------------------------------------------------------- 1 | from ._rust_proj import * 2 | -------------------------------------------------------------------------------- /rust/geoarrow-expr-geos/src/import/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod array; 2 | pub mod scalar; 3 | -------------------------------------------------------------------------------- /rust/geoparquet/src/test/geoarrow_data/mod.rs: -------------------------------------------------------------------------------- 1 | mod example; 2 | mod example_crs; 3 | -------------------------------------------------------------------------------- /python/docs/api/compute/enums.md: -------------------------------------------------------------------------------- 1 | # Enums 2 | 3 | ::: geoarrow.rust.compute.enums 4 | -------------------------------------------------------------------------------- /python/docs/api/compute/types.md: -------------------------------------------------------------------------------- 1 | # Types 2 | 3 | ::: geoarrow.rust.compute.types 4 | -------------------------------------------------------------------------------- /python/docs/api/core/geometry/type.md: -------------------------------------------------------------------------------- 1 | # Type 2 | 3 | ::: geoarrow.rust.core.GeoType 4 | -------------------------------------------------------------------------------- /python/geoarrow-core/src/constructors/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod array; 2 | pub mod data_type; 3 | -------------------------------------------------------------------------------- /rust/geoarrow-test/README.md: -------------------------------------------------------------------------------- 1 | # geoarrow-test 2 | 3 | Test data for geoarrow-rs. 4 | -------------------------------------------------------------------------------- /fixtures/nybb.arrow: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geoarrow/geoarrow-rs/HEAD/fixtures/nybb.arrow -------------------------------------------------------------------------------- /python/geoarrow-compute/src/algorithm/native/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod explode; 2 | pub mod total_bounds; 3 | -------------------------------------------------------------------------------- /python/geoarrow-core/src/interop/geopandas/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod from_geopandas; 2 | pub mod to_geopandas; 3 | -------------------------------------------------------------------------------- /rust/geoarrow-expr-geos/src/export/mod.rs: -------------------------------------------------------------------------------- 1 | mod scalar; 2 | 3 | pub use scalar::to_geos_geometry; 4 | -------------------------------------------------------------------------------- /python/geoarrow-core/src/ffi/from_python/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod input; 2 | 3 | pub use input::AnyNativeInput; 4 | -------------------------------------------------------------------------------- /python/geoarrow-compute/src/ffi/from_python/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod input; 2 | 3 | pub use input::AnyNativeInput; 4 | -------------------------------------------------------------------------------- /fixtures/flatgeobuf/poly00.fgb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geoarrow/geoarrow-rs/HEAD/fixtures/flatgeobuf/poly00.fgb -------------------------------------------------------------------------------- /fixtures/flatgeobuf/poly01.fgb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geoarrow/geoarrow-rs/HEAD/fixtures/flatgeobuf/poly01.fgb -------------------------------------------------------------------------------- /fixtures/flatgeobuf/countries.fgb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geoarrow/geoarrow-rs/HEAD/fixtures/flatgeobuf/countries.fgb -------------------------------------------------------------------------------- /fixtures/geoparquet/nybb.parquet: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geoarrow/geoarrow-rs/HEAD/fixtures/geoparquet/nybb.parquet -------------------------------------------------------------------------------- /python/geoarrow-core/src/interop/shapely/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod from_shapely; 2 | // pub mod to_shapely; 3 | pub mod utils; 4 | -------------------------------------------------------------------------------- /fixtures/flatgeobuf/alldatatypes.fgb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geoarrow/geoarrow-rs/HEAD/fixtures/flatgeobuf/alldatatypes.fgb -------------------------------------------------------------------------------- /fixtures/geoparquet/nybb_wkb.parquet: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geoarrow/geoarrow-rs/HEAD/fixtures/geoparquet/nybb_wkb.parquet -------------------------------------------------------------------------------- /js/src/data/mod.rs: -------------------------------------------------------------------------------- 1 | mod coord; 2 | mod geoarrow; 3 | 4 | pub use coord::JsCoordBuffer; 5 | pub use geoarrow::JsGeoArrowData; 6 | -------------------------------------------------------------------------------- /python/docs/api/io/shapefile.md.bak: -------------------------------------------------------------------------------- 1 | # Shapefile 2 | 3 | Read Shapefile files. 4 | 5 | ::: geoarrow.rust.io.read_shapefile 6 | -------------------------------------------------------------------------------- /rust/geoarrow-cast/README.md: -------------------------------------------------------------------------------- 1 | # geoarrow-cast 2 | 3 | Functions for converting from one GeoArrow geometry type to another. 4 | -------------------------------------------------------------------------------- /rust/geoarrow-old/src/io/display/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod array; 2 | pub mod chunked_array; 3 | pub mod scalar; 4 | pub mod table; 5 | -------------------------------------------------------------------------------- /js/.yarnrc.yml: -------------------------------------------------------------------------------- 1 | # Note: we force node-modules so that tests can access node_modules/tape/bin/tape 2 | nodeLinker: node-modules 3 | -------------------------------------------------------------------------------- /fixtures/geoparquet/nybb_geoarrow.parquet: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geoarrow/geoarrow-rs/HEAD/fixtures/geoparquet/nybb_geoarrow.parquet -------------------------------------------------------------------------------- /python/docs/api/core/array.md: -------------------------------------------------------------------------------- 1 | # Array 2 | 3 | ::: geoarrow.rust.core.GeoArray 4 | options: 5 | show_if_no_docstring: true 6 | -------------------------------------------------------------------------------- /python/geoarrow-compute/src/algorithm/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod geo; 2 | pub mod native; 3 | 4 | #[cfg(feature = "libc")] 5 | pub mod polylabel; 6 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "fixtures/geoarrow-data"] 2 | path = fixtures/geoarrow-data 3 | url = https://github.com/geoarrow/geoarrow-data 4 | -------------------------------------------------------------------------------- /js/src/io/object_store_s3/mod.rs: -------------------------------------------------------------------------------- 1 | //! This is vendored from https://github.com/JanKaul/object_store_s3_wasm 2 | //! under the MIT license 3 | -------------------------------------------------------------------------------- /rust/geoarrow-old/src/io/gdal/mod.rs: -------------------------------------------------------------------------------- 1 | //! Read-only integration with [GDAL][gdal]. 2 | 3 | mod reader; 4 | 5 | pub use reader::read_gdal; 6 | -------------------------------------------------------------------------------- /rust/pyo3-geoarrow/src/ffi/mod.rs: -------------------------------------------------------------------------------- 1 | //! Arrow FFI via the C Data Interface and the Arrow PyCapsule Interface. 2 | 3 | pub mod from_python; 4 | -------------------------------------------------------------------------------- /fixtures/geoparquet/nybb_wkb_covering.parquet: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geoarrow/geoarrow-rs/HEAD/fixtures/geoparquet/nybb_wkb_covering.parquet -------------------------------------------------------------------------------- /fixtures/geoparquet/overture_buildings.parquet: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geoarrow/geoarrow-rs/HEAD/fixtures/geoparquet/overture_buildings.parquet -------------------------------------------------------------------------------- /python/geoarrow-compute/src/ffi/mod.rs: -------------------------------------------------------------------------------- 1 | //! Arrow FFI via the C Data Interface and the Arrow PyCapsule Interface. 2 | 3 | pub mod from_python; 4 | -------------------------------------------------------------------------------- /python/geoarrow-core/python/geoarrow/rust/core/_operations/__init__.pyi: -------------------------------------------------------------------------------- 1 | from ._type_id import get_type_id 2 | 3 | __all__ = ["get_type_id"] 4 | -------------------------------------------------------------------------------- /python/docs/api/core/geometry/scalar.md: -------------------------------------------------------------------------------- 1 | # Geometry 2 | 3 | ::: geoarrow.rust.core.GeoScalar 4 | options: 5 | show_if_no_docstring: true 6 | -------------------------------------------------------------------------------- /fixtures/flatgeobuf/ns-water_water-line_small.fgb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geoarrow/geoarrow-rs/HEAD/fixtures/flatgeobuf/ns-water_water-line_small.fgb -------------------------------------------------------------------------------- /fixtures/flatgeobuf/nz-building-outlines-small.fgb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geoarrow/geoarrow-rs/HEAD/fixtures/flatgeobuf/nz-building-outlines-small.fgb -------------------------------------------------------------------------------- /fixtures/geoparquet/overture_infrastructure.parquet: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geoarrow/geoarrow-rs/HEAD/fixtures/geoparquet/overture_infrastructure.parquet -------------------------------------------------------------------------------- /python/proj/README.md: -------------------------------------------------------------------------------- 1 | # `geoarrow.rust.proj` 2 | 3 | Python bindings to [PROJ](https://proj.org/en/9.3/) for coordinate reprojection on GeoArrow arrays. 4 | -------------------------------------------------------------------------------- /rust/geoarrow-old/src/io/postgis/mod.rs: -------------------------------------------------------------------------------- 1 | //! Read from PostGIS databases. 2 | 3 | mod reader; 4 | mod type_info; 5 | 6 | pub use reader::read_postgis; 7 | -------------------------------------------------------------------------------- /js/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | /target 3 | **/*.rs.bk 4 | bin/ 5 | pkg/ 6 | wasm-pack.log 7 | .pnp.cjs 8 | .pnp.loader.mjs 9 | docs_build/ 10 | .yarn 11 | -------------------------------------------------------------------------------- /python/docs/api/core/chunked_array.md: -------------------------------------------------------------------------------- 1 | # Chunked Array 2 | 3 | ::: geoarrow.rust.core.GeoChunkedArray 4 | options: 5 | show_if_no_docstring: true 6 | -------------------------------------------------------------------------------- /python/geoarrow-core/src/ffi/mod.rs: -------------------------------------------------------------------------------- 1 | //! Arrow FFI via the C Data Interface and the Arrow PyCapsule Interface. 2 | 3 | pub mod from_python; 4 | pub mod to_python; 5 | -------------------------------------------------------------------------------- /python/docs/api/io/postgis.md.bak: -------------------------------------------------------------------------------- 1 | # PostGIS 2 | 3 | Read from a PostGIS database. 4 | 5 | ::: geoarrow.rust.io.read_postgis 6 | ::: geoarrow.rust.io.read_postgis_async 7 | -------------------------------------------------------------------------------- /python/geoarrow-io/python/geoarrow/rust/io/__init__.py: -------------------------------------------------------------------------------- 1 | from . import enums 2 | from ._io import * 3 | from ._io import ___version 4 | 5 | __version__: str = ___version() 6 | -------------------------------------------------------------------------------- /js/build/modules/flatgeobuf-wasm/README.md: -------------------------------------------------------------------------------- 1 | # `@flatgeobuf-wasm` 2 | 3 | 4 | ## Publishing 5 | 6 | ```bash 7 | ./build.sh 8 | wasm-pack publish --access=public 9 | ``` 10 | -------------------------------------------------------------------------------- /rust/geoarrow-array/src/geozero/mod.rs: -------------------------------------------------------------------------------- 1 | //! Implements the geometry and dataset conversion APIs defined by the [`geozero`] 2 | //! crate. 3 | 4 | pub mod export; 5 | pub mod import; 6 | -------------------------------------------------------------------------------- /rust/geoarrow-old/src/io/geozero/table/mod.rs: -------------------------------------------------------------------------------- 1 | pub(crate) mod builder; 2 | mod data_source; 3 | mod json_encoder; 4 | 5 | pub use builder::{GeoTableBuilder, GeoTableBuilderOptions}; 6 | -------------------------------------------------------------------------------- /rust/geoarrow/src/error.rs: -------------------------------------------------------------------------------- 1 | //! Defines `GeoArrowError` for representing failures in various GeoArrow operations. 2 | 3 | pub use geoarrow_schema::error::{GeoArrowError, GeoArrowResult}; 4 | -------------------------------------------------------------------------------- /python/docs/api/io/csv.md.bak: -------------------------------------------------------------------------------- 1 | # CSV 2 | 3 | Read and write CSV files with a geometry column encoded as Well-Known Text. 4 | 5 | ::: geoarrow.rust.io.read_csv 6 | ::: geoarrow.rust.io.write_csv 7 | -------------------------------------------------------------------------------- /python/geoarrow-compute/python/geoarrow/rust/compute/__init__.py: -------------------------------------------------------------------------------- 1 | from . import enums 2 | from ._compute import * 3 | from ._compute import ___version 4 | 5 | __version__: str = ___version() 6 | -------------------------------------------------------------------------------- /rust/geoarrow-old/src/io/geozero/table/builder/mod.rs: -------------------------------------------------------------------------------- 1 | pub(crate) mod anyvalue; 2 | pub(crate) mod properties; 3 | mod table; 4 | 5 | pub use table::{GeoTableBuilder, GeoTableBuilderOptions}; 6 | -------------------------------------------------------------------------------- /python/geoarrow-core/python/geoarrow/rust/core/__init__.py: -------------------------------------------------------------------------------- 1 | from . import enums 2 | from ._crs import get_crs 3 | from ._rust import * 4 | from ._rust import ___version 5 | 6 | __version__: str = ___version() 7 | -------------------------------------------------------------------------------- /rust/geoarrow-old/src/io/geojson/mod.rs: -------------------------------------------------------------------------------- 1 | //! Read from and write to [GeoJSON](https://geojson.org/) files. 2 | 3 | pub use reader::read_geojson; 4 | pub use writer::write_geojson; 5 | 6 | mod reader; 7 | mod writer; 8 | -------------------------------------------------------------------------------- /rust/geoarrow-array/src/geozero/export/data_source/mod.rs: -------------------------------------------------------------------------------- 1 | mod record_batch; 2 | mod record_batch_reader; 3 | 4 | pub use record_batch::GeozeroRecordBatchWriter; 5 | pub use record_batch_reader::GeozeroRecordBatchReader; 6 | -------------------------------------------------------------------------------- /rust/geoarrow-old/src/indexed/mod.rs: -------------------------------------------------------------------------------- 1 | //! Indexed geometry arrays are associated with a spatial index for efficient 2 | //! boolean operations. 3 | 4 | #![allow(missing_docs)] // FIXME 5 | 6 | pub mod array; 7 | pub mod chunked; 8 | -------------------------------------------------------------------------------- /rust/geoarrow-geojson/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | ## 0.6.0 - 2025-10-15 4 | 5 | - feat(geoarrow-geojson): GeoJSON writer using arrow-json's new custom encoders by @kylebarron in https://github.com/geoarrow/geoarrow-rs/pull/1040 6 | -------------------------------------------------------------------------------- /js/src/lib.rs: -------------------------------------------------------------------------------- 1 | pub mod cast; 2 | #[cfg(feature = "data")] 3 | pub mod data; 4 | pub mod data_type; 5 | pub mod dimension; 6 | pub mod error; 7 | pub mod io; 8 | pub mod utils; 9 | #[cfg(feature = "vector")] 10 | pub mod vector; 11 | -------------------------------------------------------------------------------- /python/docs/api/io/flatgeobuf.md: -------------------------------------------------------------------------------- 1 | # FlatGeobuf 2 | 3 | Read and write [FlatGeobuf](https://flatgeobuf.org/) files. 4 | 5 | ::: geoarrow.rust.io.read_flatgeobuf 6 | ::: geoarrow.rust.io.read_flatgeobuf_async 7 | ::: geoarrow.rust.io.write_flatgeobuf 8 | -------------------------------------------------------------------------------- /python/geoarrow-compute/README.md: -------------------------------------------------------------------------------- 1 | # `geoarrow.rust.compute` 2 | 3 | Compute operations on GeoArrow data. 4 | 5 | ## Documentation 6 | 7 | Refer to the documentation at [geoarrow.org/geoarrow-rs/python](https://geoarrow.org/geoarrow-rs/python). 8 | -------------------------------------------------------------------------------- /python/geoarrow-io/src/flatgeobuf/mod.rs: -------------------------------------------------------------------------------- 1 | #[cfg(feature = "async")] 2 | mod r#async; 3 | mod sync; 4 | mod utils; 5 | 6 | #[cfg(feature = "async")] 7 | pub use r#async::read_flatgeobuf_async; 8 | pub use sync::{read_flatgeobuf, write_flatgeobuf}; 9 | -------------------------------------------------------------------------------- /js/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "commonjs", 4 | "moduleResolution": "node" 5 | }, 6 | "include": ["tests/**/*"], 7 | "exclude": ["node_modules"], 8 | "ts-node": { 9 | "swc": true 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /rust/geoarrow-csv/example.csv: -------------------------------------------------------------------------------- 1 | address,type,datetime,report location,incident number 2 | 904 7th Ave,Car Fire,05/22/19,POINT (-122.329051 47.6069),F190051945 3 | 9610 53rd Av S,Aid Response,"05/22/2019 12:55:00 PM,",POINT (-122.266529 47.515984),F190051946 4 | -------------------------------------------------------------------------------- /python/docs/api/io/index.md: -------------------------------------------------------------------------------- 1 | # `geoarrow.rust.io` 2 | 3 | All functionality described within this directory are part of the `geoarrow.rust.io` submodule. To use, install the `geoarrow-rust-io` PyPI package: 4 | 5 | ``` 6 | pip install geoarrow-rust-io 7 | ``` 8 | -------------------------------------------------------------------------------- /python/geoarrow-io/README.md: -------------------------------------------------------------------------------- 1 | # `geoarrow.rust.io` 2 | 3 | Read and write geospatial file formats to and from GeoArrow. 4 | 5 | ## Documentation 6 | 7 | Refer to the documentation at [geoarrow.org/geoarrow-rs/python](https://geoarrow.org/geoarrow-rs/python). 8 | -------------------------------------------------------------------------------- /rust/geoarrow-array/src/geozero/export/array/mod.rs: -------------------------------------------------------------------------------- 1 | mod geometry; 2 | mod geometrycollection; 3 | mod linestring; 4 | mod multilinestring; 5 | mod multipoint; 6 | mod multipolygon; 7 | mod point; 8 | mod polygon; 9 | mod rect; 10 | mod wkb; 11 | mod wkt; 12 | -------------------------------------------------------------------------------- /rust/geoarrow-array/src/geozero/export/mod.rs: -------------------------------------------------------------------------------- 1 | //! Implementation to export GeoArrow arrays through the geozero API. 2 | 3 | mod array; 4 | mod data_source; 5 | pub(crate) mod scalar; 6 | 7 | pub use data_source::{GeozeroRecordBatchReader, GeozeroRecordBatchWriter}; 8 | -------------------------------------------------------------------------------- /rust/geoarrow-old/src/io/geojson_lines/mod.rs: -------------------------------------------------------------------------------- 1 | //! Read from and write to [newline-delimited GeoJSON](https://stevage.github.io/ndgeojson/) files. 2 | 3 | mod reader; 4 | mod writer; 5 | 6 | pub use reader::read_geojson_lines; 7 | pub use writer::write_geojson_lines; 8 | -------------------------------------------------------------------------------- /python/docs/api/core/index.md: -------------------------------------------------------------------------------- 1 | # `geoarrow.rust.core` 2 | 3 | All functionality described within this directory are part of the `geoarrow.rust.core` submodule. To use, install the `geoarrow-rust-core` PyPI package: 4 | 5 | ``` 6 | pip install geoarrow-rust-core 7 | ``` 8 | -------------------------------------------------------------------------------- /python/docs/api/io/geojson.md.bak: -------------------------------------------------------------------------------- 1 | # GeoJSON 2 | 3 | Read and write GeoJSON and newline-delimited GeoJSON files. 4 | 5 | ::: geoarrow.rust.io.read_geojson 6 | ::: geoarrow.rust.io.read_geojson_lines 7 | ::: geoarrow.rust.io.write_geojson 8 | ::: geoarrow.rust.io.write_geojson_lines 9 | -------------------------------------------------------------------------------- /rust/geoarrow-expr-geos/src/export/scalar/mod.rs: -------------------------------------------------------------------------------- 1 | mod coord; 2 | mod geometry; 3 | mod geometrycollection; 4 | mod linestring; 5 | mod multilinestring; 6 | mod multipoint; 7 | mod multipolygon; 8 | mod point; 9 | mod polygon; 10 | 11 | pub use geometry::to_geos_geometry; 12 | -------------------------------------------------------------------------------- /rust/geoarrow-array/src/test/properties.rs: -------------------------------------------------------------------------------- 1 | use arrow_array::{StringArray, UInt8Array}; 2 | 3 | pub(crate) fn u8_array() -> UInt8Array { 4 | UInt8Array::from(vec![1, 2, 3]) 5 | } 6 | 7 | pub(crate) fn string_array() -> StringArray { 8 | vec!["foo", "bar", "baz"].into() 9 | } 10 | -------------------------------------------------------------------------------- /python/geoarrow-io/src/io/mod.rs: -------------------------------------------------------------------------------- 1 | //! Read and write to geospatial file formats. 2 | 3 | pub mod csv; 4 | pub mod flatgeobuf; 5 | pub mod geojson; 6 | pub mod geojson_lines; 7 | pub mod input; 8 | pub mod parquet; 9 | #[cfg(feature = "async")] 10 | pub mod postgis; 11 | pub mod shapefile; 12 | -------------------------------------------------------------------------------- /rust/geoarrow-old/src/algorithm/geo/utils.rs: -------------------------------------------------------------------------------- 1 | use arrow_array::Float64Array; 2 | use arrow_buffer::NullBuffer; 3 | 4 | pub(crate) fn zeroes(len: usize, nulls: Option<&NullBuffer>) -> Float64Array { 5 | let values = vec![0.0f64; len]; 6 | Float64Array::new(values.into(), nulls.cloned()) 7 | } 8 | -------------------------------------------------------------------------------- /python/metapackage/DEVELOP.md: -------------------------------------------------------------------------------- 1 | ## Publishing 2 | 3 | Install dependencies: 4 | 5 | ``` 6 | pip install -U build twine 7 | ``` 8 | 9 | then build the package: 10 | 11 | ``` 12 | python -m build 13 | ``` 14 | 15 | then upload to pypi: 16 | 17 | ``` 18 | python -m twine upload dist/* 19 | ``` 20 | -------------------------------------------------------------------------------- /python/geoarrow-io/src/parquet/mod.rs: -------------------------------------------------------------------------------- 1 | #[cfg(feature = "async")] 2 | mod r#async; 3 | mod sync; 4 | 5 | pub mod options; 6 | 7 | #[cfg(feature = "async")] 8 | pub use r#async::{GeoParquetDataset, GeoParquetFile, read_parquet_async}; 9 | pub use sync::{PyGeoParquetWriter, read_parquet, write_parquet}; 10 | -------------------------------------------------------------------------------- /rust/geoarrow-array/src/test/mod.rs: -------------------------------------------------------------------------------- 1 | #![allow(dead_code)] 2 | 3 | pub mod geometry; 4 | pub mod geometrycollection; 5 | pub mod linestring; 6 | pub mod multilinestring; 7 | pub mod multipoint; 8 | pub mod multipolygon; 9 | pub mod point; 10 | pub mod polygon; 11 | pub mod properties; 12 | pub mod rect; 13 | -------------------------------------------------------------------------------- /rust/geoarrow-expr-geo/src/util/mod.rs: -------------------------------------------------------------------------------- 1 | use std::sync::Arc; 2 | 3 | use geoarrow_array::GeoArrowArray; 4 | 5 | pub(crate) mod downcast; 6 | pub mod to_geo; 7 | 8 | pub(crate) fn copy_geoarrow_array_ref(array: &dyn GeoArrowArray) -> Arc { 9 | array.slice(0, array.len()) 10 | } 11 | -------------------------------------------------------------------------------- /rust/geoparquet/src/writer/mod.rs: -------------------------------------------------------------------------------- 1 | #![doc = include_str!("README.md")] 2 | 3 | mod encode; 4 | mod metadata; 5 | mod options; 6 | 7 | pub use encode::GeoParquetRecordBatchEncoder; 8 | pub use options::{ 9 | GeoParquetWriterEncoding, GeoParquetWriterOptions, GeoParquetWriterOptionsBuilder, 10 | }; 11 | -------------------------------------------------------------------------------- /js/tests/web.rs: -------------------------------------------------------------------------------- 1 | //! Test suite for the Web and headless browsers. 2 | 3 | #![cfg(target_arch = "wasm32")] 4 | 5 | extern crate wasm_bindgen_test; 6 | use wasm_bindgen_test::*; 7 | 8 | wasm_bindgen_test_configure!(run_in_browser); 9 | 10 | #[wasm_bindgen_test] 11 | fn pass() { 12 | assert_eq!(1 + 1, 2); 13 | } 14 | -------------------------------------------------------------------------------- /python/geoarrow-core/src/interop/mod.rs: -------------------------------------------------------------------------------- 1 | // pub mod geopandas; 2 | // pub mod numpy; 3 | // pub mod pyogrio; 4 | mod shapely; 5 | // pub mod util; 6 | mod utils; 7 | mod wkb; 8 | mod wkt; 9 | 10 | pub(crate) use shapely::from_shapely; 11 | pub(crate) use wkb::{from_wkb, to_wkb}; 12 | pub(crate) use wkt::{from_wkt, to_wkt}; 13 | -------------------------------------------------------------------------------- /js/DEVELOP.md: -------------------------------------------------------------------------------- 1 | 2 | ### 🛠️ Build with `wasm-pack build` 3 | 4 | ``` 5 | wasm-pack build 6 | ``` 7 | 8 | ### 🔬 Test in Headless Browsers with `wasm-pack test` 9 | 10 | ``` 11 | wasm-pack test --headless --firefox 12 | ``` 13 | 14 | ### 🎁 Publish to NPM with `wasm-pack publish` 15 | 16 | ``` 17 | wasm-pack publish 18 | ``` 19 | -------------------------------------------------------------------------------- /js/src/io/parquet/mod.rs: -------------------------------------------------------------------------------- 1 | #[cfg(feature = "io_parquet_async")] 2 | pub mod r#async; 3 | #[cfg(feature = "io_parquet_async")] 4 | pub mod async_file_reader; 5 | pub mod options; 6 | pub mod sync; 7 | 8 | #[cfg(feature = "io_parquet_async")] 9 | pub use r#async::{ParquetDataset, ParquetFile}; 10 | pub use sync::read_geoparquet; 11 | -------------------------------------------------------------------------------- /python/geoarrow-io/python/geoarrow/rust/io/types.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | from typing import Literal 4 | 5 | 6 | GeoParquetEncodingT = Literal["wkb", "geoarrow"] 7 | """Acceptable strings to be passed into the `encoding` parameter for 8 | [`GeoParquetWriter`][geoarrow.rust.io.GeoParquetWriter]. 9 | """ 10 | -------------------------------------------------------------------------------- /rust/geoarrow-expr-geos/src/lib.rs: -------------------------------------------------------------------------------- 1 | #![cfg_attr(docsrs, feature(doc_cfg))] 2 | #![cfg_attr(not(test), deny(unused_crate_dependencies))] 3 | #![doc( 4 | html_logo_url = "https://github.com/geoarrow.png", 5 | html_favicon_url = "https://github.com/geoarrow.png?size=32" 6 | )] 7 | 8 | pub mod export; 9 | pub mod import; 10 | -------------------------------------------------------------------------------- /rust/geoarrow-old/src/io/shapefile/mod.rs: -------------------------------------------------------------------------------- 1 | //! Read from [Shapefile](https://www.esri.com/content/dam/esrisites/sitecore-archive/Files/Pdfs/library/whitepapers/pdfs/shapefile.pdf) datasets. 2 | //! 3 | //! This wraps the [shapefile] crate. 4 | 5 | mod reader; 6 | mod scalar; 7 | 8 | pub use reader::{ShapefileReaderOptions, read_shapefile}; 9 | -------------------------------------------------------------------------------- /rust/geoarrow-test/src/lib.rs: -------------------------------------------------------------------------------- 1 | //! Test data for GeoArrow 2 | 3 | #![cfg_attr(docsrs, feature(doc_cfg))] 4 | #![cfg_attr(not(test), warn(unused_crate_dependencies))] 5 | #![doc( 6 | html_logo_url = "https://github.com/geoarrow.png", 7 | html_favicon_url = "https://github.com/geoarrow.png?size=32" 8 | )] 9 | 10 | pub mod raw; 11 | -------------------------------------------------------------------------------- /rust/pyo3-geoarrow/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | ## [Unreleased] 4 | 5 | - Add `PyGeoArrowArrayReader::into_geoarrow_py`. 6 | 7 | ## 0.6.1 - 2025-10-16 8 | 9 | - docs(pyo3-geoarrow): Improve docs #1377 10 | - refactor(pyo3-geoarrow): Move Python data type constructors out of pyo3-geoarrow (deprecating existing constructors) #1379 11 | -------------------------------------------------------------------------------- /python/docs/api/core/constructors.md: -------------------------------------------------------------------------------- 1 | # Constructors 2 | 3 | ::: geoarrow.rust.core 4 | options: 5 | filters: 6 | - "!^_" 7 | members: 8 | - CoordsInput 9 | - points 10 | - linestrings 11 | - polygons 12 | - multipoints 13 | - multilinestrings 14 | - multipolygons 15 | -------------------------------------------------------------------------------- /js/src/io/mod.rs: -------------------------------------------------------------------------------- 1 | // #[cfg(feature = "io_flatgeobuf")] 2 | // pub mod flatgeobuf; 3 | // #[cfg(feature = "io_geojson")] 4 | // pub mod geojson; 5 | // #[cfg(feature = "io_object_store")] 6 | // pub mod object_store; 7 | // #[cfg(feature = "io_object_store")] 8 | // pub mod object_store_s3; 9 | // #[cfg(feature = "io_parquet")] 10 | // pub mod parquet; 11 | -------------------------------------------------------------------------------- /docs/pyproject.toml: -------------------------------------------------------------------------------- 1 | [project] 2 | name = "docs" 3 | version = "0.1.0" 4 | description = "Add your description here" 5 | readme = "README.md" 6 | requires-python = ">=3.11" 7 | dependencies = [] 8 | 9 | [tool.uv] 10 | dev-dependencies = [ 11 | "mkdocs>=1.6.1", 12 | "mkdocs-material[imaging]>=9.5.40", 13 | "pymdown-extensions>=10.11.2", 14 | ] 15 | -------------------------------------------------------------------------------- /python/docs/api/io/gdal.md: -------------------------------------------------------------------------------- 1 | # GDAL 2 | 3 | GDAL natively supports reading data from any vector driver as GeoArrow data, and natively supports writing data to any vector driver from GeoArrow data. 4 | 5 | For reading and writing, use [`pyogrio`'s Arrow integration](https://pyogrio.readthedocs.io/en/latest/api.html#arrow-integration) directly, which supports WKB-encoded GeoArrow data. 6 | -------------------------------------------------------------------------------- /rust/geoarrow-cast/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | **This is the changelog for the core Rust library**. There's a [separate changelog](./python/CHANGELOG.md) for the Python bindings, and there will be another for the JS bindings. 4 | 5 | ## 0.5.0 - 2025-08-07 6 | 7 | No changes. 8 | 9 | --- 10 | 11 | Previous releases were documented in the top-level `CHANGELOG.md` file. 12 | -------------------------------------------------------------------------------- /python/docs/api/io/geoparquet.md: -------------------------------------------------------------------------------- 1 | # GeoParquet 2 | 3 | Read and write [GeoParquet](https://geoparquet.org/) files. 4 | 5 | ::: geoarrow.rust.io.GeoParquetDataset 6 | ::: geoarrow.rust.io.GeoParquetFile 7 | ::: geoarrow.rust.io.GeoParquetWriter 8 | ::: geoarrow.rust.io.enums.GeoParquetEncoding 9 | ::: geoarrow.rust.io.types.GeoParquetEncodingT 10 | ::: geoarrow.rust.io.PathInput 11 | -------------------------------------------------------------------------------- /python/geoarrow-core/README.md: -------------------------------------------------------------------------------- 1 | # `geoarrow.rust.core` 2 | 3 | Core data structures to store and manage geometry data in GeoArrow format. 4 | 5 | ## Documentation 6 | 7 | Refer to the [documentation website](https://geoarrow.org/geoarrow-rs/python). 8 | 9 | ## Documentation 10 | 11 | Refer to the documentation at [geoarrow.org/geoarrow-rs/python](https://geoarrow.org/geoarrow-rs/python). 12 | -------------------------------------------------------------------------------- /rust/geoarrow-cast/src/lib.rs: -------------------------------------------------------------------------------- 1 | #![doc = include_str!("../README.md")] 2 | #![warn(missing_docs)] 3 | #![cfg_attr(docsrs, feature(doc_cfg))] 4 | #![cfg_attr(not(test), warn(unused_crate_dependencies))] 5 | #![doc( 6 | html_logo_url = "https://github.com/geoarrow.png", 7 | html_favicon_url = "https://github.com/geoarrow.png?size=32" 8 | )] 9 | 10 | pub mod cast; 11 | pub mod downcast; 12 | -------------------------------------------------------------------------------- /rust/geoarrow-csv/src/lib.rs: -------------------------------------------------------------------------------- 1 | #![doc = include_str!("../README.md")] 2 | #![warn(missing_docs)] 3 | #![cfg_attr(docsrs, feature(doc_cfg))] 4 | #![cfg_attr(not(test), deny(unused_crate_dependencies))] 5 | #![doc( 6 | html_logo_url = "https://github.com/geoarrow.png", 7 | html_favicon_url = "https://github.com/geoarrow.png?size=32" 8 | )] 9 | 10 | pub mod reader; 11 | pub mod writer; 12 | -------------------------------------------------------------------------------- /fixtures/geoparquet/generate_data.py: -------------------------------------------------------------------------------- 1 | import geodatasets 2 | import geopandas as gpd 3 | 4 | nybb = gpd.read_file(geodatasets.get_path("nybb")) 5 | nybb.to_parquet("nybb_wkb.parquet", geometry_encoding="WKB") 6 | nybb.to_parquet( 7 | "nybb_wkb_covering.parquet", geometry_encoding="WKB", write_covering_bbox=True 8 | ) 9 | nybb.to_parquet("nybb_geoarrow.parquet", geometry_encoding="geoarrow") 10 | -------------------------------------------------------------------------------- /python/docs/api/core/functions.md: -------------------------------------------------------------------------------- 1 | # Functions 2 | 3 | Interoperability with other Python geospatial libraries (Shapely, GeoPandas) and in-memory geospatial formats (WKB, WKT). 4 | 5 | ::: geoarrow.rust.core.from_wkb 6 | ::: geoarrow.rust.core.from_wkt 7 | ::: geoarrow.rust.core.to_wkb 8 | ::: geoarrow.rust.core.to_wkt 9 | ::: geoarrow.rust.core.get_crs 10 | ::: geoarrow.rust.core.get_type_id 11 | -------------------------------------------------------------------------------- /python/proj/src/lib.rs: -------------------------------------------------------------------------------- 1 | use pyo3::prelude::*; 2 | 3 | const VERSION: &str = env!("CARGO_PKG_VERSION"); 4 | 5 | #[pyfunction] 6 | fn ___version() -> &'static str { 7 | VERSION 8 | } 9 | 10 | /// A Python module implemented in Rust. 11 | #[pymodule] 12 | fn _rust_proj(_py: Python, m: &PyModule) -> PyResult<()> { 13 | m.add_wrapped(wrap_pyfunction!(___version))?; 14 | 15 | Ok(()) 16 | } 17 | -------------------------------------------------------------------------------- /rust/geoarrow-geojson/src/lib.rs: -------------------------------------------------------------------------------- 1 | #![doc = include_str!("../README.md")] 2 | // #![warn(missing_docs)] 3 | #![cfg_attr(docsrs, feature(doc_cfg))] 4 | #![cfg_attr(not(test), deny(unused_crate_dependencies))] 5 | #![doc( 6 | html_logo_url = "https://github.com/geoarrow.png", 7 | html_favicon_url = "https://github.com/geoarrow.png?size=32" 8 | )] 9 | 10 | pub mod encoder; 11 | pub mod writer; 12 | -------------------------------------------------------------------------------- /rust/geoarrow-old/src/io/display/table.rs: -------------------------------------------------------------------------------- 1 | use std::fmt; 2 | 3 | use crate::table::Table; 4 | 5 | impl fmt::Display for Table { 6 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 7 | writeln!(f, "Table")?; 8 | for field in self.schema().fields() { 9 | writeln!(f, "{}: {}", field.name(), field.data_type())?; 10 | } 11 | Ok(()) 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /rust/geoarrow-schema/README.md: -------------------------------------------------------------------------------- 1 | # geoarrow-schema 2 | 3 | GeoArrow geometry type and metadata definitions. 4 | 5 | All geometry type definitions, such as [`PointType`], [`GeometryType`], or 6 | [`WkbType`] implement the upstream 7 | [`ExtensionType`][arrow_schema::extension::ExtensionType] trait. 8 | 9 | Instances of type definitions are included within the variants on the 10 | [`GeoArrowType`] enum. 11 | -------------------------------------------------------------------------------- /rust/geoarrow-csv/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | ## 0.6.0 - 2025-10-15 4 | 5 | * feat(geoarrow-csv): Initial CSV reader, wrapping upstream arrow-csv by @kylebarron in https://github.com/geoarrow/geoarrow-rs/pull/1050 6 | * feat(geoarrow-csv): add CSV writer by @kylebarron in https://github.com/geoarrow/geoarrow-rs/pull/1314 7 | * docs: Geoarrow-csv docs by @nuts-rice in https://github.com/geoarrow/geoarrow-rs/pull/1340 8 | -------------------------------------------------------------------------------- /rust/geoarrow-old/src/algorithm/mod.rs: -------------------------------------------------------------------------------- 1 | //! Vectorized algorithms implemented on and returning GeoArrow arrays. 2 | 3 | #![allow(missing_docs)] // FIXME 4 | 5 | pub mod broadcasting; 6 | pub mod geo; 7 | pub mod geo_index; 8 | #[cfg(feature = "geos")] 9 | pub mod geos; 10 | pub mod native; 11 | #[cfg(feature = "polylabel")] 12 | pub mod polylabel; 13 | #[cfg(feature = "proj")] 14 | pub mod proj; 15 | pub mod rstar; 16 | -------------------------------------------------------------------------------- /rust/geoarrow-old/src/io/geozero/mod.rs: -------------------------------------------------------------------------------- 1 | //! Implements the geometry and dataset conversion APIs defined by the [`geozero`] 2 | //! crate. 3 | 4 | pub(crate) mod array; 5 | mod scalar; 6 | pub(crate) mod table; 7 | 8 | pub use array::{ 9 | ToGeometryArray, ToLineStringArray, ToMultiLineStringArray, ToMultiPointArray, 10 | ToMultiPolygonArray, ToPointArray, ToPolygonArray, 11 | }; 12 | pub use scalar::ToGeometry; 13 | -------------------------------------------------------------------------------- /js/RELEASE.md: -------------------------------------------------------------------------------- 1 | ## Release docs 2 | 3 | ```bash 4 | export PATH="/opt/homebrew/opt/llvm/bin/:$PATH" 5 | export CC=/opt/homebrew/opt/llvm/bin/clang 6 | export AR=/opt/homebrew/opt/llvm/bin/llvm-ar 7 | ``` 8 | 9 | ``` 10 | yarn build 11 | cd pkg 12 | npm publish 13 | ``` 14 | 15 | ``` 16 | yarn build:geoparquet 17 | cd pkg 18 | npm publish 19 | ``` 20 | 21 | ``` 22 | yarn build:flatgeobuf 23 | cd pkg 24 | npm publish 25 | ``` 26 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | emsdk 2 | vcpkg 3 | vcpkg_installed 4 | .pyodide* 5 | 6 | *.whl 7 | *.DS_Store 8 | .idea 9 | 10 | # Generated by Cargo 11 | # will have compiled files and executables 12 | debug/ 13 | target/ 14 | 15 | # These are backup files generated by rustfmt 16 | **/*.rs.bk 17 | 18 | # MSVC Windows builds of rustc generate these, which store debugging information 19 | *.pdb 20 | 21 | *.fgb 22 | *.arrow* 23 | *.parquet 24 | .vscode 25 | -------------------------------------------------------------------------------- /rust/geoarrow-expr-geo/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | ## 0.6.0 - 2025-10-15 4 | 5 | - chore(geoarrow-geo): Bump geo to 0.31 by @kylebarron in https://github.com/geoarrow/geoarrow-rs/pull/1316 6 | - feat(geoarrow-geo): Add support for ST_length by @notreallystatic in https://github.com/geoarrow/geoarrow-rs/pull/1308 7 | - feat: Rename `geoarrow-geo` to `geoarrow-expr-geo` by @kylebarron in https://github.com/geoarrow/geoarrow-rs/pull/1353 8 | -------------------------------------------------------------------------------- /python/geoarrow-core/src/interop/utils.rs: -------------------------------------------------------------------------------- 1 | use std::sync::Arc; 2 | 3 | use geoarrow_schema::Metadata; 4 | use pyo3_geoarrow::{PyCrs, PyEdges}; 5 | 6 | /// Create a new Metadata from optional PyCrs and PyEdges 7 | pub(crate) fn new_metadata(crs: Option, edges: Option) -> Arc { 8 | let crs = crs.map(|inner| inner.into()).unwrap_or_default(); 9 | Arc::new(Metadata::new(crs, edges.map(|e| e.into()))) 10 | } 11 | -------------------------------------------------------------------------------- /rust/geoarrow-old/examples/README.md: -------------------------------------------------------------------------------- 1 | # Rust Examples 2 | 3 | ## Usage with GDAL Arrow API 4 | 5 | As of GDAL version 3.6, GDAL has included support for [reading data into Arrow 6 | directly](https://gdal.org/development/rfc/rfc86_column_oriented_api.html). The file 7 | [`gdal.rs`](gdal.rs) shows how to use this API to efficiently load data into GeoArrow memory. 8 | 9 | Run with 10 | 11 | ```bash 12 | cargo run --example gdal --features gdal 13 | ``` 14 | -------------------------------------------------------------------------------- /python/tests_old/io/test_shapefile.py: -------------------------------------------------------------------------------- 1 | import geodatasets 2 | from geoarrow.rust.core import get_crs 3 | from geoarrow.rust.io import read_shapefile 4 | from pyproj import CRS 5 | 6 | 7 | def test_read_shapefile(): 8 | shp_path = geodatasets.get_path("ny.bb") 9 | 10 | table = read_shapefile(shp_path) 11 | crs = get_crs(table) 12 | assert crs is not None 13 | 14 | assert crs == CRS.from_epsg(2263) 15 | 16 | assert len(table) == 5 17 | -------------------------------------------------------------------------------- /js/src/vector.rs: -------------------------------------------------------------------------------- 1 | use std::sync::Arc; 2 | 3 | use geoarrow_array::GeoArrowArray; 4 | use geoarrow_schema::GeoArrowType; 5 | use wasm_bindgen::prelude::*; 6 | 7 | /// An immutable vector (chunked array) of geometries stored in WebAssembly memory using GeoArrow's 8 | /// in-memory representation. 9 | #[wasm_bindgen(js_name = GeoArrowVector)] 10 | pub struct JsGeoArrowVector { 11 | _chunks: Vec>, 12 | _data_type: GeoArrowType, 13 | } 14 | -------------------------------------------------------------------------------- /rust/geoparquet/src/lib.rs: -------------------------------------------------------------------------------- 1 | #![doc = include_str!("../README.md")] 2 | #![cfg_attr(docsrs, feature(doc_cfg))] 3 | #![cfg_attr(not(test), warn(unused_crate_dependencies))] 4 | #![warn(missing_docs)] 5 | #![doc( 6 | html_logo_url = "https://github.com/geoarrow.png", 7 | html_favicon_url = "https://github.com/geoarrow.png?size=32" 8 | )] 9 | 10 | pub mod metadata; 11 | pub mod reader; 12 | #[cfg(test)] 13 | mod test; 14 | mod total_bounds; 15 | pub mod writer; 16 | -------------------------------------------------------------------------------- /rust/geoarrow-flatgeobuf/src/reader/mod.rs: -------------------------------------------------------------------------------- 1 | #![doc = include_str!("README.md")] 2 | 3 | #[cfg(feature = "async")] 4 | mod r#async; 5 | mod common; 6 | #[cfg(feature = "object_store")] 7 | pub mod object_store; 8 | pub mod schema; 9 | mod sync; 10 | mod table_builder; 11 | 12 | #[cfg(feature = "async")] 13 | pub use r#async::FlatGeobufRecordBatchStream; 14 | pub use common::{FlatGeobufHeaderExt, FlatGeobufReaderOptions}; 15 | pub use sync::FlatGeobufRecordBatchIterator; 16 | -------------------------------------------------------------------------------- /rust/geoarrow/src/array.rs: -------------------------------------------------------------------------------- 1 | //! Statically typed implementations of GeoArrow Arrays 2 | //! 3 | //! **See [geoarrow_array] for examples and usage instructions** 4 | 5 | pub use geoarrow_array::array::*; 6 | pub use geoarrow_array::builder::*; 7 | pub use geoarrow_array::cast::*; 8 | pub use geoarrow_array::scalar::*; 9 | pub use geoarrow_array::{ 10 | GeoArrowArray, GeoArrowArrayAccessor, GeoArrowArrayIterator, GeoArrowArrayReader, IntoArrow, 11 | WrapArray, 12 | }; 13 | -------------------------------------------------------------------------------- /rust/geoarrow-test/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "geoarrow-test" 3 | version = { workspace = true } 4 | authors = { workspace = true } 5 | edition = { workspace = true } 6 | license = { workspace = true } 7 | repository = { workspace = true } 8 | description = "Test data for GeoArrow data " 9 | categories = ["science::geo"] 10 | rust-version = { workspace = true } 11 | 12 | [dependencies] 13 | wkt = { workspace = true } 14 | 15 | [package.metadata.docs.rs] 16 | all-features = true 17 | -------------------------------------------------------------------------------- /.github/workflows/conventional-commits.yml: -------------------------------------------------------------------------------- 1 | name: PR Conventional Commit Validation 2 | 3 | on: 4 | pull_request_target: 5 | types: [opened, synchronize, reopened, edited] 6 | 7 | jobs: 8 | validate-pr-title: 9 | runs-on: ubuntu-latest 10 | steps: 11 | - name: PR Conventional Commit Validation 12 | uses: ytanikin/pr-conventional-commits@1.4.0 13 | with: 14 | task_types: '["feat","fix","docs","test","ci","refactor","perf","chore","revert"]' 15 | -------------------------------------------------------------------------------- /python/tests_old/utils.py: -------------------------------------------------------------------------------- 1 | from pathlib import Path 2 | 3 | 4 | def get_repo_root() -> Path: 5 | current_dir = Path(".").absolute() 6 | 7 | while current_dir.stem != "geoarrow-rs": 8 | if current_dir == Path("/"): 9 | raise ValueError("Could not find repo root; is it named geoarrow-rs?") 10 | current_dir = current_dir.parent 11 | 12 | return current_dir 13 | 14 | 15 | REPO_ROOT = get_repo_root() 16 | FIXTURES_DIR = REPO_ROOT / "fixtures" 17 | 18 | -------------------------------------------------------------------------------- /rust/geoarrow-array/src/test/geometry.rs: -------------------------------------------------------------------------------- 1 | use geoarrow_schema::{CoordType, GeometryType}; 2 | use geoarrow_test::raw; 3 | 4 | use crate::array::GeometryArray; 5 | use crate::builder::GeometryBuilder; 6 | 7 | pub fn array(coord_type: CoordType, _prefer_multi: bool) -> GeometryArray { 8 | let typ = GeometryType::new(Default::default()).with_coord_type(coord_type); 9 | GeometryBuilder::from_nullable_geometries(&raw::geometry::geoms(), typ) 10 | .unwrap() 11 | .finish() 12 | } 13 | -------------------------------------------------------------------------------- /rust/geoparquet/src/test/mod.rs: -------------------------------------------------------------------------------- 1 | mod geoarrow_data; 2 | 3 | use std::path::PathBuf; 4 | 5 | pub(crate) fn fixture_dir() -> PathBuf { 6 | let p = PathBuf::from("../../fixtures"); 7 | assert!(p.exists()); 8 | p 9 | } 10 | 11 | pub(crate) fn geoarrow_data_example_files() -> PathBuf { 12 | fixture_dir().join("geoarrow-data/example/files") 13 | } 14 | 15 | pub(crate) fn geoarrow_data_example_crs_files() -> PathBuf { 16 | fixture_dir().join("geoarrow-data/example-crs/files") 17 | } 18 | -------------------------------------------------------------------------------- /rust/geoarrow-old/src/algorithm/geodesy/mod.rs: -------------------------------------------------------------------------------- 1 | //! Bindings to the [`geodesy`] crate for coordinate reprojection. 2 | //! 3 | //! Note that this library does **not** aim to be a full PROJ "rewrite in Rust". Consult the 4 | //! [library's documentation][geodesy] for how to construct the projection string to pass into 5 | //! `reproject`. 6 | 7 | // TODO: reimplement not based on old GeometryArray enum 8 | // mod reproject; 9 | 10 | // pub use geodesy::Direction; 11 | // pub use reproject::reproject; 12 | -------------------------------------------------------------------------------- /docs/source/stylesheets/extra.css: -------------------------------------------------------------------------------- 1 | [data-md-color-scheme="rust-light"] { 2 | --md-primary-fg-color: #dea584; 3 | --md-primary-bg-color: #1f292d; 4 | --md-primary-fg-color--light: #f9c6a9; 5 | --md-primary-fg-color--dark: #c28a6a; 6 | } 7 | 8 | /* Override just a couple colors from slate */ 9 | [data-md-color-scheme="slate"] { 10 | --md-primary-fg-color: #dea584; 11 | --md-primary-bg-color: #1f292d; 12 | --md-primary-fg-color--light: #f9c6a9; 13 | --md-primary-fg-color--dark: #c28a6a; 14 | } 15 | -------------------------------------------------------------------------------- /js/typedoc.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "geoarrow", 3 | "cleanOutputDir": true, 4 | "darkHighlightTheme": "material-theme-ocean", 5 | "entryPoints": [ 6 | "pkg/node/index.d.ts", 7 | "pkg/bundler/index.d.ts", 8 | "pkg/esm/index.d.ts", 9 | ], 10 | "lightHighlightTheme": "material-theme-lighter", 11 | "tsconfig": "tsconfig.docs.json", 12 | "out": "docs_build", 13 | "excludePrivate": true, 14 | "excludeProtected": true, 15 | "excludeExternals": true, 16 | "includeVersion": true 17 | } 18 | -------------------------------------------------------------------------------- /python/docs/stylesheets/extra.css: -------------------------------------------------------------------------------- 1 | [data-md-color-scheme="rust-light"] { 2 | --md-primary-fg-color: #dea584; 3 | --md-primary-bg-color: #1f292d; 4 | --md-primary-fg-color--light: #f9c6a9; 5 | --md-primary-fg-color--dark: #c28a6a; 6 | } 7 | 8 | /* Override just a couple colors from slate */ 9 | [data-md-color-scheme="slate"] { 10 | --md-primary-fg-color: #dea584; 11 | --md-primary-bg-color: #1f292d; 12 | --md-primary-fg-color--light: #f9c6a9; 13 | --md-primary-fg-color--dark: #c28a6a; 14 | } 15 | -------------------------------------------------------------------------------- /rust/geoparquet/src/reader/mod.rs: -------------------------------------------------------------------------------- 1 | #![doc = include_str!("README.md")] 2 | 3 | #[cfg(feature = "async")] 4 | mod r#async; 5 | mod geo_ext; 6 | mod metadata; 7 | mod parse; 8 | mod spatial_filter; 9 | mod sync; 10 | 11 | #[cfg(feature = "async")] 12 | pub use r#async::GeoParquetRecordBatchStream; 13 | pub use geo_ext::GeoParquetReaderBuilder; 14 | pub use metadata::{GeoParquetDatasetMetadata, GeoParquetReaderMetadata}; 15 | pub use parse::infer_geoarrow_schema; 16 | pub use sync::GeoParquetRecordBatchReader; 17 | -------------------------------------------------------------------------------- /rust/geoarrow-array/src/scalar/coord/mod.rs: -------------------------------------------------------------------------------- 1 | //! Contains implementations for how to encode arrays of coordinates for all other geometry array 2 | //! types. 3 | //! 4 | //! Coordinates can be either _interleaved_, where they're represented as a `FixedSizeList`, or 5 | //! _separated_, where they're represented with a `StructArray`. 6 | 7 | mod combined; 8 | mod interleaved; 9 | mod separated; 10 | 11 | pub use combined::Coord; 12 | pub use interleaved::InterleavedCoord; 13 | pub use separated::SeparatedCoord; 14 | -------------------------------------------------------------------------------- /rust/geoarrow-expr-geos/src/export/scalar/point.rs: -------------------------------------------------------------------------------- 1 | use geo_traits::PointTrait; 2 | 3 | use crate::export::scalar::coord::coord_to_geos; 4 | 5 | pub(crate) fn to_geos_point( 6 | point: &impl PointTrait, 7 | ) -> std::result::Result { 8 | if let Some(coord) = point.coord() { 9 | let coord_seq = coord_to_geos(&coord)?; 10 | Ok(geos::Geometry::create_point(coord_seq)?) 11 | } else { 12 | Ok(geos::Geometry::create_empty_point()?) 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /rust/geoarrow-flatgeobuf/src/lib.rs: -------------------------------------------------------------------------------- 1 | //! Read from and write to [FlatGeobuf](https://flatgeobuf.org/) files. 2 | //! 3 | //! For more information, refer to module documentation for [`reader`]. 4 | 5 | #![warn(missing_docs)] 6 | #![cfg_attr(docsrs, feature(doc_cfg))] 7 | #![cfg_attr(not(test), deny(unused_crate_dependencies))] 8 | #![doc( 9 | html_logo_url = "https://github.com/geoarrow.png", 10 | html_favicon_url = "https://github.com/geoarrow.png?size=32" 11 | )] 12 | 13 | pub mod reader; 14 | pub mod writer; 15 | -------------------------------------------------------------------------------- /js/src/data/geoarrow.rs: -------------------------------------------------------------------------------- 1 | use std::sync::Arc; 2 | 3 | use geoarrow_array::GeoArrowArray; 4 | use wasm_bindgen::prelude::*; 5 | 6 | #[wasm_bindgen(js_name = GeoArrowData)] 7 | pub struct JsGeoArrowData(Arc); 8 | 9 | impl JsGeoArrowData { 10 | #[expect(dead_code)] 11 | pub(crate) fn inner(&self) -> &Arc { 12 | &self.0 13 | } 14 | 15 | #[expect(dead_code)] 16 | pub(crate) fn into_inner(self) -> Arc { 17 | self.0 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /rust/geoarrow-array/src/array/coord/mod.rs: -------------------------------------------------------------------------------- 1 | //! Contains implementations for how to encode arrays of coordinates for all other geometry array 2 | //! types. 3 | //! 4 | //! Coordinates can be either _interleaved_, where they're represented as a `FixedSizeList`, or 5 | //! _separated_, where they're represented with a `StructArray`. 6 | 7 | mod combined; 8 | mod interleaved; 9 | mod separated; 10 | 11 | pub use combined::CoordBuffer; 12 | pub use interleaved::InterleavedCoordBuffer; 13 | pub use separated::SeparatedCoordBuffer; 14 | -------------------------------------------------------------------------------- /rust/geoarrow-old/src/algorithm/geos/mod.rs: -------------------------------------------------------------------------------- 1 | //! Bindings to the [`geos`] crate for geometry operations. 2 | 3 | mod area; 4 | mod bool_ops; 5 | mod buffer; 6 | mod is_empty; 7 | mod is_ring; 8 | mod is_simple; 9 | mod is_valid; 10 | mod length; 11 | mod util; 12 | 13 | pub use area::Area; 14 | pub use bool_ops::{BooleanOps, BooleanOpsScalar}; 15 | pub use buffer::Buffer; 16 | pub use is_empty::IsEmpty; 17 | pub use is_ring::IsRing; 18 | pub use is_simple::IsSimple; 19 | pub use is_valid::IsValid; 20 | pub use length::Length; 21 | -------------------------------------------------------------------------------- /rust/geoarrow/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "geoarrow" 3 | version = { workspace = true } 4 | authors = { workspace = true } 5 | edition = { workspace = true } 6 | license = { workspace = true } 7 | repository = { workspace = true } 8 | description = "GeoArrow amalgamation crate." 9 | categories = { workspace = true } 10 | rust-version = { workspace = true } 11 | 12 | [dependencies] 13 | geoarrow-array = { workspace = true } 14 | geoarrow-schema = { workspace = true } 15 | 16 | [package.metadata.docs.rs] 17 | all-features = true 18 | -------------------------------------------------------------------------------- /python/geoarrow-compute/src/algorithm/native/total_bounds.rs: -------------------------------------------------------------------------------- 1 | use crate::ffi::from_python::AnyNativeInput; 2 | use geoarrow::algorithm::native::TotalBounds; 3 | use pyo3::prelude::*; 4 | use pyo3_geoarrow::PyGeoArrowResult; 5 | 6 | #[pyfunction] 7 | pub fn total_bounds(input: AnyNativeInput) -> PyGeoArrowResult<(f64, f64, f64, f64)> { 8 | match input { 9 | AnyNativeInput::Array(arr) => Ok(arr.as_ref().total_bounds().into()), 10 | AnyNativeInput::Chunked(arr) => Ok(arr.as_ref().total_bounds().into()), 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /rust/geoarrow-expr-geos/src/export/scalar/multipoint.rs: -------------------------------------------------------------------------------- 1 | use geo_traits::MultiPointTrait; 2 | 3 | use crate::export::scalar::point::to_geos_point; 4 | 5 | pub(crate) fn to_geos_multi_point( 6 | multi_point: &impl MultiPointTrait, 7 | ) -> std::result::Result { 8 | geos::Geometry::create_multipoint( 9 | multi_point 10 | .points() 11 | .map(|point| to_geos_point(&point)) 12 | .collect::, geos::Error>>()?, 13 | ) 14 | } 15 | -------------------------------------------------------------------------------- /rust/geoarrow-test/src/raw/mod.rs: -------------------------------------------------------------------------------- 1 | //! Raw test data, copied from geoarrow-data 2 | //! 3 | //! - 4 | //! - 5 | 6 | pub mod geometry; 7 | pub mod geometrycollection; 8 | pub mod linestring; 9 | pub mod multilinestring; 10 | pub mod multipoint; 11 | pub mod multipolygon; 12 | pub mod point; 13 | pub mod polygon; 14 | -------------------------------------------------------------------------------- /rust/geoarrow-array/src/builder/coord/mod.rs: -------------------------------------------------------------------------------- 1 | //! Contains implementations for how to encode arrays of coordinates for all other geometry array 2 | //! types. 3 | //! 4 | //! Coordinates can be either _interleaved_, where they're represented as a `FixedSizeList`, or 5 | //! _separated_, where they're represented with a `StructArray`. 6 | 7 | mod combined; 8 | mod interleaved; 9 | mod separated; 10 | 11 | pub use combined::CoordBufferBuilder; 12 | pub use interleaved::InterleavedCoordBufferBuilder; 13 | pub use separated::SeparatedCoordBufferBuilder; 14 | -------------------------------------------------------------------------------- /rust/geoarrow-array/src/geozero/import/mod.rs: -------------------------------------------------------------------------------- 1 | //! Import geozero types into GeoArrow arrays 2 | 3 | mod geometry; 4 | mod linestring; 5 | mod multilinestring; 6 | mod multipoint; 7 | mod multipolygon; 8 | mod point; 9 | mod polygon; 10 | mod util; 11 | 12 | pub use geometry::ToGeometryArray; 13 | pub use linestring::ToLineStringArray; 14 | pub use multilinestring::ToMultiLineStringArray; 15 | pub use multipoint::ToMultiPointArray; 16 | pub use multipolygon::ToMultiPolygonArray; 17 | pub use point::ToPointArray; 18 | pub use polygon::ToPolygonArray; 19 | -------------------------------------------------------------------------------- /rust/geoarrow-expr-geos/src/export/scalar/geometrycollection.rs: -------------------------------------------------------------------------------- 1 | use geo_traits::GeometryCollectionTrait; 2 | 3 | use crate::export::scalar::to_geos_geometry; 4 | 5 | pub(crate) fn to_geos_geometry_collection( 6 | gc: &impl GeometryCollectionTrait, 7 | ) -> std::result::Result { 8 | geos::Geometry::create_geometry_collection( 9 | gc.geometries() 10 | .map(|geometry| to_geos_geometry(&geometry)) 11 | .collect::, geos::Error>>()?, 12 | ) 13 | } 14 | -------------------------------------------------------------------------------- /rust/geoarrow-old/src/io/geojson_lines/writer.rs: -------------------------------------------------------------------------------- 1 | use geozero::GeozeroDatasource; 2 | use geozero::geojson::GeoJsonLineWriter; 3 | use std::io::Write; 4 | 5 | use crate::error::Result; 6 | use crate::io::stream::RecordBatchReader; 7 | 8 | /// Write a table to newline-delimited GeoJSON 9 | pub fn write_geojson_lines>( 10 | stream: S, 11 | writer: W, 12 | ) -> Result<()> { 13 | let mut geojson_writer = GeoJsonLineWriter::new(writer); 14 | stream.into().process(&mut geojson_writer)?; 15 | Ok(()) 16 | } 17 | -------------------------------------------------------------------------------- /rust/geoarrow-expr-geos/src/export/scalar/multipolygon.rs: -------------------------------------------------------------------------------- 1 | use geo_traits::MultiPolygonTrait; 2 | 3 | use crate::export::scalar::polygon::to_geos_polygon; 4 | 5 | pub(crate) fn to_geos_multi_polygon( 6 | multi_polygon: &impl MultiPolygonTrait, 7 | ) -> std::result::Result { 8 | geos::Geometry::create_multipolygon( 9 | multi_polygon 10 | .polygons() 11 | .map(|polygon| to_geos_polygon(&polygon)) 12 | .collect::, geos::Error>>()?, 13 | ) 14 | } 15 | -------------------------------------------------------------------------------- /python/geoarrow-compute/src/algorithm/native/explode.rs: -------------------------------------------------------------------------------- 1 | use geoarrow::algorithm::native::ExplodeTable; 2 | use pyo3::prelude::*; 3 | use pyo3_arrow::PyTable; 4 | use pyo3_arrow::export::Arro3Table; 5 | use pyo3_geoarrow::PyGeoArrowResult; 6 | 7 | use crate::util::{pytable_to_table, table_to_pytable}; 8 | 9 | #[pyfunction] 10 | pub fn explode(py: Python, input: PyTable) -> PyGeoArrowResult { 11 | let table = pytable_to_table(input)?; 12 | let exploded_table = py.allow_threads(|| table.explode(None))?; 13 | Ok(table_to_pytable(exploded_table).into()) 14 | } 15 | -------------------------------------------------------------------------------- /python/geoarrow-io/src/flatgeobuf/utils.rs: -------------------------------------------------------------------------------- 1 | use std::sync::Arc; 2 | 3 | use arrow::datatypes::{Schema, SchemaRef}; 4 | 5 | pub(super) fn apply_projection(schema: SchemaRef, columns: &Option>) -> SchemaRef { 6 | if let Some(cols) = columns { 7 | let fields: Vec<_> = schema 8 | .fields() 9 | .iter() 10 | .filter(|f| cols.contains(f.name())) 11 | .cloned() 12 | .collect(); 13 | Arc::new(Schema::new_with_metadata(fields, schema.metadata().clone())) 14 | } else { 15 | schema 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /python/proj/pyproject.toml: -------------------------------------------------------------------------------- 1 | [build-system] 2 | requires = ["maturin>=1.2.1,<2.0"] 3 | build-backend = "maturin" 4 | 5 | [project] 6 | name = "geoarrow-rust-proj" 7 | requires-python = ">=3.9" 8 | dependencies = [] 9 | classifiers = [ 10 | "Programming Language :: Rust", 11 | "Programming Language :: Python :: Implementation :: CPython", 12 | "Programming Language :: Python :: Implementation :: PyPy", 13 | ] 14 | dynamic = ["version"] 15 | 16 | [tool.maturin] 17 | features = ["pyo3/extension-module"] 18 | module-name = "geoarrow.rust.proj._rust_proj" 19 | python-source = "python" 20 | -------------------------------------------------------------------------------- /python/tests_old/interop/test_geopandas.py: -------------------------------------------------------------------------------- 1 | import geoarrow.rust.core as gars 2 | import geodatasets 3 | import geopandas as gpd 4 | from geopandas.testing import assert_geodataframe_equal 5 | 6 | nybb_path = geodatasets.get_path("nybb") 7 | 8 | 9 | # Test it works without error 10 | # Superseded by full assertion when CRS is fixed 11 | def test_geopandas_round_trip(): 12 | gdf = gpd.read_file(nybb_path) 13 | assert isinstance(gdf, gpd.GeoDataFrame) 14 | table = gars.from_geopandas(gdf) 15 | retour = gars.to_geopandas(table) 16 | assert_geodataframe_equal(gdf, retour) 17 | -------------------------------------------------------------------------------- /rust/geoarrow-expr-geos/src/export/scalar/multilinestring.rs: -------------------------------------------------------------------------------- 1 | use geo_traits::MultiLineStringTrait; 2 | 3 | use crate::export::scalar::linestring::to_geos_line_string; 4 | 5 | pub(crate) fn to_geos_multi_line_string( 6 | multi_line_string: &impl MultiLineStringTrait, 7 | ) -> std::result::Result { 8 | geos::Geometry::create_multiline_string( 9 | multi_line_string 10 | .line_strings() 11 | .map(|line| to_geos_line_string(&line)) 12 | .collect::, geos::Error>>()?, 13 | ) 14 | } 15 | -------------------------------------------------------------------------------- /python/docs/ecosystem/shapely.md.bak: -------------------------------------------------------------------------------- 1 | # Shapely 2 | 3 | For interoperability with [Shapely](https://shapely.readthedocs.io/en/stable/index.html), use the top-level [`to_shapely`][geoarrow.rust.core.to_shapely] and [`from_shapely`][geoarrow.rust.core.from_shapely] functions. 4 | 5 | Shapely interoperability requires `shapely` to be installed, and requires Shapely version 2.0 or higher. 6 | 7 | ## Examples 8 | 9 | ```py 10 | from geoarrow.rust.core import from_shapely, to_shapely 11 | import shapely 12 | 13 | shapely_geoms = to_shapely(geoarrow_array) 14 | geoarrow_array = from_shapely(shapely_geoms) 15 | ``` 16 | -------------------------------------------------------------------------------- /python/geoarrow-core/src/interop/geopandas/to_geopandas.rs: -------------------------------------------------------------------------------- 1 | use crate::interop::util::import_geopandas; 2 | use pyo3::intern; 3 | use pyo3::prelude::*; 4 | use pyo3::types::PyTuple; 5 | use pyo3_geoarrow::PyGeoArrowResult; 6 | 7 | #[pyfunction] 8 | pub fn to_geopandas(py: Python, input: PyObject) -> PyGeoArrowResult { 9 | let geopandas_mod = import_geopandas(py)?; 10 | let geodataframe_class = geopandas_mod.getattr(intern!(py, "GeoDataFrame"))?; 11 | let gdf = geodataframe_class 12 | .call_method1(intern!(py, "from_arrow"), PyTuple::new(py, vec![input])?)?; 13 | Ok(gdf.into()) 14 | } 15 | -------------------------------------------------------------------------------- /python/geoarrow-io/pyproject.toml: -------------------------------------------------------------------------------- 1 | [build-system] 2 | requires = ["maturin>=1.4.0,<2.0"] 3 | build-backend = "maturin" 4 | 5 | [project] 6 | name = "geoarrow-rust-io" 7 | requires-python = ">=3.9" 8 | dependencies = ["arro3-core>=0.4", "pyproj"] 9 | classifiers = [ 10 | "Programming Language :: Rust", 11 | "Programming Language :: Python :: Implementation :: CPython", 12 | "Programming Language :: Python :: Implementation :: PyPy", 13 | ] 14 | dynamic = ["version"] 15 | 16 | [tool.maturin] 17 | features = ["pyo3/extension-module"] 18 | module-name = "geoarrow.rust.io._io" 19 | python-source = "python" 20 | -------------------------------------------------------------------------------- /rust/geoarrow-old/examples/gdal.rs: -------------------------------------------------------------------------------- 1 | use gdal::Dataset; 2 | use geoarrow::error::GeoArrowError; 3 | use geoarrow::io::gdal::read_gdal; 4 | use geoarrow::table::Table; 5 | use std::path::Path; 6 | 7 | fn run() -> Result<(), GeoArrowError> { 8 | // Open a dataset and access a layer 9 | let dataset = Dataset::open(Path::new("fixtures/roads.geojson"))?; 10 | let mut layer = dataset.layer(0)?; 11 | 12 | let reader = read_gdal(&mut layer, None)?; 13 | let table: Table = reader.try_into()?; 14 | dbg!(&table.schema()); 15 | 16 | Ok(()) 17 | } 18 | 19 | fn main() { 20 | run().unwrap() 21 | } 22 | -------------------------------------------------------------------------------- /python/geoarrow-core/pyproject.toml: -------------------------------------------------------------------------------- 1 | [build-system] 2 | requires = ["maturin>=1.4.0,<2.0"] 3 | build-backend = "maturin" 4 | 5 | [project] 6 | name = "geoarrow-rust-core" 7 | requires-python = ">=3.9" 8 | dependencies = ["arro3-core>=0.4", "pyproj"] 9 | classifiers = [ 10 | "Programming Language :: Rust", 11 | "Programming Language :: Python :: Implementation :: CPython", 12 | "Programming Language :: Python :: Implementation :: PyPy", 13 | ] 14 | dynamic = ["version"] 15 | 16 | [tool.maturin] 17 | features = ["pyo3/extension-module"] 18 | module-name = "geoarrow.rust.core._rust" 19 | python-source = "python" 20 | -------------------------------------------------------------------------------- /python/docs/ecosystem/gdal.md: -------------------------------------------------------------------------------- 1 | # GDAL 2 | 3 | GDAL natively supports reading data from any vector driver as GeoArrow data, and natively supports writing data to any vector driver from GeoArrow data. 4 | 5 | For reading and writing, use [`pyogrio`'s Arrow integration](https://pyogrio.readthedocs.io/en/latest/api.html#arrow-integration) directly, which supports WKB-encoded GeoArrow data. 6 | 7 | This output table can be used with any GeoArrow-compatible library, including `geoarrow-rust` but also [`geoarrow-pyarrow`](https://geoarrow.org/geoarrow-python/main/pyarrow.html#) and [`lonboard`](https://developmentseed.org/lonboard/latest/). 8 | -------------------------------------------------------------------------------- /python/tests_old/core/test_array.py: -------------------------------------------------------------------------------- 1 | import geodatasets 2 | import geopandas as gpd 3 | import shapely 4 | import shapely.testing 5 | from geoarrow.rust.core import from_geopandas, geometry_col 6 | 7 | nybb_path = geodatasets.get_path("nybb") 8 | 9 | 10 | def test_indexing(): 11 | gdf = gpd.read_file(nybb_path) 12 | table = from_geopandas(gdf) 13 | geometry = geometry_col(table) 14 | 15 | shapely_scalar = shapely.geometry.shape(geometry[0]) 16 | assert gdf.geometry[0] == shapely_scalar 17 | 18 | shapely_scalar = shapely.geometry.shape(geometry[-1]) 19 | assert gdf.geometry.iloc[-1] == shapely_scalar 20 | -------------------------------------------------------------------------------- /python/geoarrow-compute/src/algorithm/geo/mod.rs: -------------------------------------------------------------------------------- 1 | pub(crate) mod affine_ops; 2 | pub(crate) mod area; 3 | pub(crate) mod center; 4 | pub(crate) mod centroid; 5 | pub(crate) mod chaikin_smoothing; 6 | pub(crate) mod convex_hull; 7 | pub(crate) mod densify; 8 | pub(crate) mod dimensions; 9 | pub(crate) mod envelope; 10 | pub(crate) mod frechet_distance; 11 | pub(crate) mod geodesic_area; 12 | pub(crate) mod length; 13 | pub(crate) mod line_interpolate_point; 14 | pub(crate) mod line_locate_point; 15 | pub(crate) mod rotate; 16 | pub(crate) mod scale; 17 | pub(crate) mod simplify; 18 | pub(crate) mod skew; 19 | pub(crate) mod translate; 20 | -------------------------------------------------------------------------------- /python/docs/api/core/geometry_type.md: -------------------------------------------------------------------------------- 1 | # Geometry Type 2 | 3 | ::: geoarrow.rust.core.GeoType 4 | ::: geoarrow.rust.core.point 5 | ::: geoarrow.rust.core.linestring 6 | ::: geoarrow.rust.core.polygon 7 | ::: geoarrow.rust.core.multipoint 8 | ::: geoarrow.rust.core.multilinestring 9 | ::: geoarrow.rust.core.multipolygon 10 | ::: geoarrow.rust.core.geometry 11 | ::: geoarrow.rust.core.geometrycollection 12 | ::: geoarrow.rust.core.box 13 | ::: geoarrow.rust.core.wkb 14 | ::: geoarrow.rust.core.large_wkb 15 | ::: geoarrow.rust.core.wkb_view 16 | ::: geoarrow.rust.core.wkt 17 | ::: geoarrow.rust.core.large_wkt 18 | ::: geoarrow.rust.core.wkt_view 19 | -------------------------------------------------------------------------------- /python/geoarrow-core/src/interop/shapely/utils.rs: -------------------------------------------------------------------------------- 1 | use pyo3::exceptions::PyValueError; 2 | use pyo3::intern; 3 | use pyo3::prelude::*; 4 | use pyo3_geoarrow::PyGeoArrowResult; 5 | 6 | pub(crate) fn import_shapely(py: Python) -> PyGeoArrowResult> { 7 | let shapely_mod = py.import(intern!(py, "shapely"))?; 8 | let shapely_version_string = shapely_mod 9 | .getattr(intern!(py, "__version__"))? 10 | .extract::()?; 11 | if !shapely_version_string.starts_with('2') { 12 | Err(PyValueError::new_err("Shapely version 2 required").into()) 13 | } else { 14 | Ok(shapely_mod) 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /rust/geoarrow-expr-geos/src/import/array/mod.rs: -------------------------------------------------------------------------------- 1 | mod geometry; 2 | mod geometrycollection; 3 | mod linestring; 4 | mod multilinestring; 5 | mod multipoint; 6 | mod multipolygon; 7 | mod point; 8 | mod polygon; 9 | mod wkb; 10 | 11 | use arrow_schema::extension::ExtensionType; 12 | use geoarrow_schema::error::GeoArrowResult; 13 | 14 | pub trait FromGEOS: Sized { 15 | type GeoArrowType: ExtensionType; 16 | 17 | /// Convert a sequence of GEOS geometries to a GeoArrow array. 18 | fn from_geos( 19 | geoms: impl IntoIterator>, 20 | typ: Self::GeoArrowType, 21 | ) -> GeoArrowResult; 22 | } 23 | -------------------------------------------------------------------------------- /python/geoarrow-compute/pyproject.toml: -------------------------------------------------------------------------------- 1 | [build-system] 2 | requires = ["maturin>=1.4.0,<2.0"] 3 | build-backend = "maturin" 4 | 5 | [project] 6 | name = "geoarrow-rust-compute" 7 | requires-python = ">=3.9" 8 | dependencies = ["arro3-core>=0.4", "geoarrow-rust-core", "pyproj"] 9 | classifiers = [ 10 | "Programming Language :: Rust", 11 | "Programming Language :: Python :: Implementation :: CPython", 12 | "Programming Language :: Python :: Implementation :: PyPy", 13 | ] 14 | dynamic = ["version"] 15 | 16 | [tool.maturin] 17 | features = ["pyo3/extension-module"] 18 | module-name = "geoarrow.rust.compute._compute" 19 | python-source = "python" 20 | -------------------------------------------------------------------------------- /python/metapackage/README.md: -------------------------------------------------------------------------------- 1 | # `geoarrow-rust` 2 | 3 | This is a metapackage for the `geoarrow.rust` namespace. 4 | 5 | Both the `geoarrow` and `geoarrow-rust` Python libraries are distributed with [namespace packaging](https://packaging.python.org/en/latest/guides/packaging-namespace-packages/), meaning that each python package `geoarrow-[submodule-name]` and `geoarrow-rust-[submodule-name]` (imported as `geoarrow.[submodule-name]` or `geoarrow.rust.[submodule-name]`) can be published to PyPI independently. 6 | 7 | In order to obtain relevant modules, you should install them from PyPI directly, e.g.: 8 | 9 | ``` 10 | pip install geoarrow-rust-core 11 | ``` 12 | -------------------------------------------------------------------------------- /python/geoarrow-io/src/runtime.rs: -------------------------------------------------------------------------------- 1 | use std::sync::Arc; 2 | 3 | use pyo3::exceptions::PyValueError; 4 | use pyo3::prelude::*; 5 | use pyo3::sync::PyOnceLock; 6 | use tokio::runtime::Runtime; 7 | 8 | static RUNTIME: PyOnceLock> = PyOnceLock::new(); 9 | 10 | /// Get the tokio runtime for sync requests 11 | pub(crate) fn get_runtime(py: Python<'_>) -> PyResult> { 12 | let runtime = RUNTIME.get_or_try_init(py, || { 13 | Ok::<_, PyErr>(Arc::new(Runtime::new().map_err(|err| { 14 | PyValueError::new_err(format!("Could not create tokio runtime. {err}")) 15 | })?)) 16 | })?; 17 | Ok(runtime.clone()) 18 | } 19 | -------------------------------------------------------------------------------- /rust/geoarrow-csv/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "geoarrow-csv" 3 | version = { workspace = true } 4 | authors = { workspace = true } 5 | edition = { workspace = true } 6 | license = { workspace = true } 7 | repository = { workspace = true } 8 | description = "CSV reader and writer for GeoArrow" 9 | categories = { workspace = true } 10 | rust-version = { workspace = true } 11 | 12 | 13 | [dependencies] 14 | arrow-array = { workspace = true } 15 | arrow-csv = { workspace = true } 16 | arrow-schema = { workspace = true } 17 | geoarrow-array = { workspace = true } 18 | geoarrow-schema = { workspace = true } 19 | 20 | [dev-dependencies] 21 | geo-traits = { workspace = true } 22 | -------------------------------------------------------------------------------- /rust/geoarrow/src/datatypes.rs: -------------------------------------------------------------------------------- 1 | //! Defines the logical data types of GeoArrow arrays. 2 | //! 3 | //! The most important things you might be looking for are: 4 | //! 5 | //! * [`GeoArrowType`] to describe an array's geometry type. 6 | //! * [`Dimension`] to describe the dimension of an array. 7 | //! * [`CoordType`] to describe whether an array has interleaved or separated coordinatesx. 8 | 9 | pub use geoarrow_schema::{ 10 | BoxType, CoordType, Crs, CrsType, Dimension, Edges, GeoArrowType, GeometryCollectionType, 11 | GeometryType, LineStringType, Metadata, MultiLineStringType, MultiPointType, MultiPolygonType, 12 | PointType, PolygonType, WkbType, WktType, 13 | }; 14 | -------------------------------------------------------------------------------- /js/src/data_type.rs: -------------------------------------------------------------------------------- 1 | use geoarrow_schema::GeoArrowType; 2 | use wasm_bindgen::prelude::*; 3 | 4 | #[wasm_bindgen(js_name = GeoArrowType)] 5 | pub struct JsGeoArrowType(GeoArrowType); 6 | 7 | impl JsGeoArrowType { 8 | pub fn new(geoarrow_type: GeoArrowType) -> Self { 9 | Self(geoarrow_type) 10 | } 11 | 12 | pub fn inner(&self) -> &GeoArrowType { 13 | &self.0 14 | } 15 | } 16 | 17 | impl From for GeoArrowType { 18 | fn from(value: JsGeoArrowType) -> Self { 19 | value.0 20 | } 21 | } 22 | 23 | impl From for JsGeoArrowType { 24 | fn from(value: GeoArrowType) -> Self { 25 | Self(value) 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /rust/geoarrow-expr-geos/src/import/scalar/mod.rs: -------------------------------------------------------------------------------- 1 | mod coord; 2 | mod geometry; 3 | mod geometrycollection; 4 | mod linearring; 5 | mod linestring; 6 | mod multilinestring; 7 | mod multipoint; 8 | mod multipolygon; 9 | mod point; 10 | mod polygon; 11 | 12 | pub use geometry::GEOSGeometry; 13 | pub use geometrycollection::GEOSGeometryCollection; 14 | pub use linearring::GEOSConstLinearRing; 15 | pub use linestring::{GEOSConstLineString, GEOSLineString}; 16 | pub use multilinestring::GEOSMultiLineString; 17 | pub use multipoint::GEOSMultiPoint; 18 | pub use multipolygon::GEOSMultiPolygon; 19 | pub use point::{GEOSConstPoint, GEOSPoint}; 20 | pub use polygon::{GEOSConstPolygon, GEOSPolygon}; 21 | -------------------------------------------------------------------------------- /rust/geoarrow-schema/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "geoarrow-schema" 3 | version = { workspace = true } 4 | authors = { workspace = true } 5 | edition = { workspace = true } 6 | license = { workspace = true } 7 | repository = { workspace = true } 8 | description = "GeoArrow geometry type and metadata definitions." 9 | categories = { workspace = true } 10 | rust-version = { workspace = true } 11 | 12 | [dependencies] 13 | arrow-schema = { workspace = true } 14 | geo-traits = { workspace = true } 15 | serde = { workspace = true, features = ["derive"] } 16 | serde_json = { workspace = true } 17 | thiserror = { workspace = true } 18 | 19 | [package.metadata.docs.rs] 20 | all-features = true 21 | -------------------------------------------------------------------------------- /fixtures/flatgeobuf/README.md: -------------------------------------------------------------------------------- 1 | - https://github.com/flatgeobuf/flatgeobuf/blob/2876fac0456775199a061313d7d6fcc0b6f338c7/test/data/countries.fgb 2 | - https://raw.githubusercontent.com/flatgeobuf/flatgeobuf/master/test/data/countries.fgb 3 | 4 | 5 | ### `nz-building-outlines-small.fgb` 6 | 7 | ``` 8 | ogr2ogr nz-building-outlines-small.fgb /vsicurl/https://storage.googleapis.com/open-geodata/linz-examples/nz-building-outlines.parquet -limit 2000 9 | ``` 10 | 11 | ### `ns-water_water-line.fgb` 12 | 13 | ``` 14 | wget https://github.com/geoarrow/geoarrow-data/releases/download/v0.2.0/ns-water_water-line.fgb 15 | ogr2ogr ns-water_water-line_small.fgb ns-water_water-line.fgb -limit 10 16 | ``` 17 | -------------------------------------------------------------------------------- /python/tests_old/algorithm/test_area.py: -------------------------------------------------------------------------------- 1 | import geoarrow.rust.compute as grc 2 | import geoarrow.rust.core as gars 3 | import geodatasets 4 | import geopandas as gpd 5 | import numpy as np 6 | import pyarrow as pa 7 | 8 | nybb_path = geodatasets.get_path("nybb") 9 | 10 | 11 | def test_area(): 12 | gdf = gpd.read_file(nybb_path) 13 | shapely_area = gdf.geometry.area 14 | assert isinstance(gdf, gpd.GeoDataFrame) 15 | 16 | table = gars.from_geopandas(gdf) 17 | ga_area = grc.area(gars.geometry_col(table)) 18 | pa_arr = pa.chunked_array(ga_area) 19 | assert pa_arr.num_chunks == 1 20 | 21 | pa_area = pa_arr.chunk(0) 22 | assert np.allclose(shapely_area, pa_area) 23 | -------------------------------------------------------------------------------- /rust/geoarrow-array/src/test/rect.rs: -------------------------------------------------------------------------------- 1 | use geo_types::{Rect, coord}; 2 | use geoarrow_schema::{BoxType, Dimension}; 3 | 4 | use crate::array::RectArray; 5 | use crate::builder::RectBuilder; 6 | 7 | pub(crate) fn r0() -> Rect { 8 | Rect::new(coord! { x: 10., y: 20. }, coord! { x: 30., y: 10. }) 9 | } 10 | 11 | pub(crate) fn r1() -> Rect { 12 | Rect::new(coord! { x: 100., y: 200. }, coord! { x: 300., y: 100. }) 13 | } 14 | 15 | pub(crate) fn r_array() -> RectArray { 16 | let geoms = [Some(r0()), None, Some(r1()), None]; 17 | let typ = BoxType::new(Dimension::XY, Default::default()); 18 | RectBuilder::from_nullable_rects(geoms.iter().map(|x| x.as_ref()), typ).finish() 19 | } 20 | -------------------------------------------------------------------------------- /rust/geoarrow-old/src/io/mod.rs: -------------------------------------------------------------------------------- 1 | //! Reader and writer implementations of many common geospatial file formats, including 2 | //! interoperability with the [`geozero`] crate. 3 | 4 | pub mod crs; 5 | #[cfg(feature = "csv")] 6 | pub mod csv; 7 | pub(crate) mod display; 8 | #[cfg(feature = "flatgeobuf")] 9 | pub mod flatgeobuf; 10 | #[cfg(feature = "gdal")] 11 | pub mod gdal; 12 | pub(crate) mod geo; 13 | pub mod geojson; 14 | pub mod geojson_lines; 15 | #[cfg(feature = "geos")] 16 | pub(crate) mod geos; 17 | pub mod geozero; 18 | pub mod ipc; 19 | #[cfg(feature = "postgis")] 20 | pub mod postgis; 21 | pub mod shapefile; 22 | mod stream; 23 | pub mod wkb; 24 | pub mod wkt; 25 | 26 | pub use stream::RecordBatchReader; 27 | -------------------------------------------------------------------------------- /python/tests/utils.py: -------------------------------------------------------------------------------- 1 | import json 2 | from pathlib import Path 3 | 4 | 5 | def get_repo_root() -> Path: 6 | current_dir = Path(".").absolute() 7 | 8 | while current_dir.stem != "geoarrow-rs": 9 | if current_dir == Path("/"): 10 | raise ValueError("Could not find repo root; is it named geoarrow-rs?") 11 | current_dir = current_dir.parent 12 | 13 | return current_dir 14 | 15 | 16 | REPO_ROOT = get_repo_root() 17 | FIXTURES_DIR = REPO_ROOT / "fixtures" 18 | 19 | 20 | def geo_interface_equals(d1, d2): 21 | """Compare two __geo_interface__ dictionaries for equality. 22 | 23 | This handles list/tuple equality 24 | """ 25 | return json.loads(json.dumps(d1)) == json.loads(json.dumps(d2)) 26 | -------------------------------------------------------------------------------- /rust/geoarrow-expr-geos/src/export/scalar/polygon.rs: -------------------------------------------------------------------------------- 1 | use geo_traits::PolygonTrait; 2 | 3 | use crate::export::scalar::linestring::to_geos_linear_ring; 4 | 5 | pub(crate) fn to_geos_polygon( 6 | polygon: &impl PolygonTrait, 7 | ) -> std::result::Result { 8 | if let Some(exterior) = polygon.exterior() { 9 | let exterior = to_geos_linear_ring(&exterior)?; 10 | let interiors = polygon 11 | .interiors() 12 | .map(|interior| to_geos_linear_ring(&interior)) 13 | .collect::, geos::Error>>()?; 14 | geos::Geometry::create_polygon(exterior, interiors) 15 | } else { 16 | geos::Geometry::create_empty_polygon() 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /python/geoarrow-io/python/geoarrow/rust/io/_postgis.pyi: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | from typing import Optional 4 | 5 | from arro3.core import Table 6 | 7 | def read_postgis(connection_url: str, sql: str) -> Optional[Table]: 8 | """ 9 | Read a PostGIS query into an Arrow Table. 10 | 11 | Args: 12 | connection_url: _description_ 13 | sql: _description_ 14 | 15 | Returns: 16 | Table from query. 17 | """ 18 | 19 | async def read_postgis_async(connection_url: str, sql: str) -> Optional[Table]: 20 | """ 21 | Read a PostGIS query into an Arrow Table. 22 | 23 | Args: 24 | connection_url: _description_ 25 | sql: _description_ 26 | 27 | Returns: 28 | Table from query. 29 | """ 30 | -------------------------------------------------------------------------------- /python/tests_old/core/test_geometry_type.py: -------------------------------------------------------------------------------- 1 | import geodatasets 2 | import geopandas as gpd 3 | from geoarrow.rust.core import from_geopandas, geometry_col 4 | from geoarrow.rust.core.enums import CoordType, Dimension 5 | 6 | nybb_path = geodatasets.get_path("nybb") 7 | 8 | 9 | def test_geometry_type(): 10 | gdf = gpd.read_file(nybb_path) 11 | table = from_geopandas(gdf) 12 | geometry = geometry_col(table) 13 | geometry_type = geometry.type 14 | 15 | assert geometry_type.coord_type == CoordType.Interleaved 16 | assert geometry_type.dimension == Dimension.XY 17 | 18 | # TODO: come back to this 19 | # assert geometry_type == NativeType( 20 | # "multipolygon", 21 | # Dimension.XY, 22 | # CoordType.Interleaved, 23 | # ) 24 | -------------------------------------------------------------------------------- /python/docs/ecosystem/geopandas.md: -------------------------------------------------------------------------------- 1 | # GeoPandas 2 | 3 | As of GeoPandas v1.0, GeoPandas natively supports GeoArrow. 4 | 5 | Use [`GeoDataFrame.to_arrow`][geopandas.GeoDataFrame.to_arrow] to convert a GeoPandas `GeoDataFrame` to a GeoArrow table object. This table object is compatible with any GeoArrow-compatible library, including `geoarrow-rust` but also [`geoarrow-pyarrow`](https://geoarrow.org/geoarrow-python/main/pyarrow.html#) and [`lonboard`](https://developmentseed.org/lonboard/latest/). 6 | 7 | Use [`GeoDataFrame.from_arrow`][geopandas.GeoDataFrame.from_arrow] to convert a GeoArrow table back to a GeoPandas `GeoDataFrame`. This supports all GeoArrow geometry types _except_ for the new Geometry, GeometryCollection, and Box array types introduced in GeoArrow specification version 0.2. 8 | -------------------------------------------------------------------------------- /rust/geoarrow-array/src/geozero/export/scalar/mod.rs: -------------------------------------------------------------------------------- 1 | mod coord; 2 | mod geometry; 3 | mod geometry_collection; 4 | mod linestring; 5 | mod multilinestring; 6 | mod multipoint; 7 | mod multipolygon; 8 | mod point; 9 | mod polygon; 10 | mod rect; 11 | 12 | pub(crate) use coord::process_coord; 13 | pub(crate) use geometry::process_geometry; 14 | pub(crate) use geometry_collection::process_geometry_collection; 15 | pub(crate) use linestring::process_line_string; 16 | pub(crate) use multilinestring::process_multi_line_string; 17 | pub(crate) use multipoint::process_multi_point; 18 | pub(crate) use multipolygon::process_multi_polygon; 19 | pub(crate) use point::{process_point, process_point_as_coord}; 20 | pub(crate) use polygon::process_polygon; 21 | pub(crate) use rect::process_rect; 22 | -------------------------------------------------------------------------------- /python/geoarrow-compute/src/algorithm/geo/center.rs: -------------------------------------------------------------------------------- 1 | use std::sync::Arc; 2 | 3 | use crate::ffi::from_python::AnyNativeInput; 4 | use crate::util::{return_chunked_geometry_array, return_geometry_array}; 5 | use geoarrow::algorithm::geo::Center; 6 | use pyo3::prelude::*; 7 | use pyo3_geoarrow::PyGeoArrowResult; 8 | 9 | #[pyfunction] 10 | pub fn center(py: Python, input: AnyNativeInput) -> PyGeoArrowResult { 11 | match input { 12 | AnyNativeInput::Array(arr) => { 13 | let out = arr.as_ref().center()?; 14 | return_geometry_array(py, Arc::new(out)) 15 | } 16 | AnyNativeInput::Chunked(arr) => { 17 | let out = arr.as_ref().center()?; 18 | return_chunked_geometry_array(py, Arc::new(out)) 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /python/geoarrow-compute/src/algorithm/geo/densify.rs: -------------------------------------------------------------------------------- 1 | use crate::ffi::from_python::AnyNativeInput; 2 | use crate::util::{return_chunked_geometry_array, return_geometry_array}; 3 | use geoarrow::algorithm::geo::Densify; 4 | use pyo3::prelude::*; 5 | use pyo3_geoarrow::PyGeoArrowResult; 6 | 7 | #[pyfunction] 8 | pub fn densify(py: Python, input: AnyNativeInput, max_distance: f64) -> PyGeoArrowResult { 9 | match input { 10 | AnyNativeInput::Array(arr) => { 11 | let out = arr.as_ref().densify(max_distance)?; 12 | return_geometry_array(py, out) 13 | } 14 | AnyNativeInput::Chunked(arr) => { 15 | let out = arr.as_ref().densify(max_distance)?; 16 | return_chunked_geometry_array(py, out) 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /rust/geoarrow-array/src/geozero/export/array/point.rs: -------------------------------------------------------------------------------- 1 | use geozero::{GeomProcessor, GeozeroGeometry}; 2 | 3 | use crate::array::PointArray; 4 | use crate::geozero::export::scalar::process_point; 5 | use crate::{GeoArrowArray, GeoArrowArrayAccessor}; 6 | 7 | impl GeozeroGeometry for PointArray { 8 | fn process_geom(&self, processor: &mut P) -> geozero::error::Result<()> 9 | where 10 | Self: Sized, 11 | { 12 | let num_geometries = self.len(); 13 | processor.geometrycollection_begin(num_geometries, 0)?; 14 | 15 | for idx in 0..num_geometries { 16 | process_point(&self.value(idx).unwrap(), idx, processor)?; 17 | } 18 | 19 | processor.geometrycollection_end(num_geometries)?; 20 | Ok(()) 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /python/docs/api/io/arrow_ipc.md: -------------------------------------------------------------------------------- 1 | # Arrow IPC 2 | 3 | It's possible to read and write GeoArrow data to the [Arrow IPC format](https://arrow.apache.org/docs/python/ipc.html). 4 | 5 | The Arrow IPC format is able to fully represent GeoArrow data. Loading such files back into memory will identically reproduce the prior data. 6 | 7 | Arrow IPC generically supports GeoArrow data without any extra behavior, so the functionality to read and write Arrow IPC files lives in [`arro3`](https://github.com/kylebarron/arro3). 8 | 9 | Refer to: 10 | 11 | - [`arro3.io.read_ipc`][] 12 | - [`arro3.io.read_ipc_stream`][] 13 | - [`arro3.io.write_ipc`][] 14 | - [`arro3.io.write_ipc_stream`][] 15 | 16 | When saved without any internal compression, the Arrow IPC format can also be memory-mapped, enabling faster reading. 17 | -------------------------------------------------------------------------------- /python/geoarrow-compute/src/algorithm/geo/centroid.rs: -------------------------------------------------------------------------------- 1 | use std::sync::Arc; 2 | 3 | use crate::ffi::from_python::AnyNativeInput; 4 | use crate::util::{return_chunked_geometry_array, return_geometry_array}; 5 | use geoarrow::algorithm::geo::Centroid; 6 | use pyo3::prelude::*; 7 | use pyo3_geoarrow::PyGeoArrowResult; 8 | 9 | #[pyfunction] 10 | pub fn centroid(py: Python, input: AnyNativeInput) -> PyGeoArrowResult { 11 | match input { 12 | AnyNativeInput::Array(arr) => { 13 | let out = arr.as_ref().centroid()?; 14 | return_geometry_array(py, Arc::new(out)) 15 | } 16 | AnyNativeInput::Chunked(arr) => { 17 | let out = arr.as_ref().centroid()?; 18 | return_chunked_geometry_array(py, Arc::new(out)) 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /rust/geoarrow-geojson/src/encoder/mod.rs: -------------------------------------------------------------------------------- 1 | mod factory; 2 | mod geometry; 3 | mod geometrycollection; 4 | mod linestring; 5 | mod multilinestring; 6 | mod multipoint; 7 | mod multipolygon; 8 | mod point; 9 | mod polygon; 10 | mod rect; 11 | mod wkb; 12 | mod wkt; 13 | 14 | pub use factory::GeoArrowEncoderFactory; 15 | pub use geometry::GeometryEncoder; 16 | pub use geometrycollection::GeometryCollectionEncoder; 17 | pub use linestring::LineStringEncoder; 18 | pub use multilinestring::MultiLineStringEncoder; 19 | pub use multipoint::MultiPointEncoder; 20 | pub use multipolygon::MultiPolygonEncoder; 21 | pub use point::PointEncoder; 22 | pub use polygon::PolygonEncoder; 23 | pub use rect::RectEncoder; 24 | pub use wkb::{GenericWkbEncoder, WkbViewEncoder}; 25 | pub use wkt::{GenericWktEncoder, WktViewEncoder}; 26 | -------------------------------------------------------------------------------- /python/geoarrow-compute/src/algorithm/geo/envelope.rs: -------------------------------------------------------------------------------- 1 | use std::sync::Arc; 2 | 3 | use crate::ffi::from_python::AnyNativeInput; 4 | use crate::util::{return_chunked_geometry_array, return_geometry_array}; 5 | use geoarrow::algorithm::geo::BoundingRect; 6 | use pyo3::prelude::*; 7 | use pyo3_geoarrow::PyGeoArrowResult; 8 | 9 | #[pyfunction] 10 | pub fn envelope(py: Python, input: AnyNativeInput) -> PyGeoArrowResult { 11 | match input { 12 | AnyNativeInput::Array(arr) => { 13 | let out = arr.as_ref().bounding_rect()?; 14 | return_geometry_array(py, Arc::new(out)) 15 | } 16 | AnyNativeInput::Chunked(arr) => { 17 | let out = arr.as_ref().bounding_rect()?; 18 | return_chunked_geometry_array(py, Arc::new(out)) 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /python/pyproject.toml: -------------------------------------------------------------------------------- 1 | [project] 2 | name = "python" 3 | version = "0.1.0" 4 | requires-python = ">=3.9" 5 | dependencies = [] 6 | 7 | [tool.uv] 8 | dev-dependencies = [ 9 | "affine>=2.4.0", 10 | "arro3-core>=0.5.0", 11 | "black>=24.10.0", 12 | "geodatasets>=2024.8.0", 13 | "geopandas>=1.0.1", 14 | "griffe-inherited-docstrings>=1.0.1", 15 | "ipykernel>=6.29.5", 16 | "maturin>=1.9.6", 17 | "mkdocs>=1.6.1", 18 | "mkdocs-material[imaging]>=9.5.40", 19 | "pip>=24.2", 20 | "pyarrow>=17.0.0", 21 | "pyogrio>=0.10.0", 22 | "pytest>=8.3.3", 23 | "shapely>=2.0.6", 24 | "mkdocstrings[python]>=0.29.1", 25 | "mike>=2.1.3", 26 | "numpy", 27 | "obstore>=0.6.0", 28 | "geoarrow-types>=0.3.0", 29 | "pytest-asyncio>=1.0.0", 30 | "arro3-io>=0.6.4", 31 | ] 32 | -------------------------------------------------------------------------------- /rust/geoarrow-expr-geos/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "geoarrow-expr-geos" 3 | version = { workspace = true } 4 | authors = { workspace = true } 5 | edition = { workspace = true } 6 | license = { workspace = true } 7 | repository = { workspace = true } 8 | description = "Rust implementation of GeoArrow" 9 | categories = { workspace = true } 10 | rust-version = { workspace = true } 11 | 12 | 13 | [dependencies] 14 | arrow-array = { workspace = true } 15 | arrow-schema = { workspace = true } 16 | geo-traits = { workspace = true } 17 | geoarrow-array = { workspace = true, features = ["test-data"] } 18 | geoarrow-schema = { workspace = true } 19 | geos = { workspace = true } 20 | 21 | [dev-dependencies] 22 | geos = { workspace = true, features = ["static"] } 23 | 24 | [package.metadata.docs.rs] 25 | all-features = true 26 | -------------------------------------------------------------------------------- /rust/geoarrow-array/src/geozero/export/array/geometry.rs: -------------------------------------------------------------------------------- 1 | use geozero::{GeomProcessor, GeozeroGeometry}; 2 | 3 | use crate::array::GeometryArray; 4 | use crate::geozero::export::scalar::process_geometry; 5 | use crate::{GeoArrowArray, GeoArrowArrayAccessor}; 6 | 7 | impl GeozeroGeometry for GeometryArray { 8 | fn process_geom(&self, processor: &mut P) -> geozero::error::Result<()> 9 | where 10 | Self: Sized, 11 | { 12 | let num_geometries = self.len(); 13 | processor.geometrycollection_begin(num_geometries, 0)?; 14 | 15 | for geom_idx in 0..num_geometries { 16 | process_geometry(&self.value(geom_idx).unwrap(), geom_idx, processor)?; 17 | } 18 | 19 | processor.geometrycollection_end(num_geometries - 1)?; 20 | Ok(()) 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /rust/geoarrow-cast/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "geoarrow-cast" 3 | version = { workspace = true } 4 | authors = { workspace = true } 5 | edition = { workspace = true } 6 | license = { workspace = true } 7 | repository = { workspace = true } 8 | description = "Functions for converting from one GeoArrow geometry type to another." 9 | categories = { workspace = true } 10 | rust-version = { workspace = true } 11 | 12 | 13 | [dependencies] 14 | arrow-schema = { workspace = true } 15 | geo-traits = { workspace = true } 16 | geoarrow-array = { workspace = true } 17 | geoarrow-schema = { workspace = true } 18 | wkt = { workspace = true } 19 | 20 | [dev-dependencies] 21 | geoarrow-array = { workspace = true, features = ["test-data"] } 22 | geoarrow-test = { workspace = true } 23 | 24 | [package.metadata.docs.rs] 25 | all-features = true 26 | -------------------------------------------------------------------------------- /rust/geoarrow-expr-geo/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "geoarrow-expr-geo" 3 | version = { workspace = true } 4 | authors = { workspace = true } 5 | edition = { workspace = true } 6 | license = { workspace = true } 7 | repository = { workspace = true } 8 | description = "Rust implementation of GeoArrow" 9 | categories = { workspace = true } 10 | rust-version = { workspace = true } 11 | 12 | 13 | [dependencies] 14 | arrow-buffer = { workspace = true } 15 | arrow-array = { workspace = true } 16 | geo = { workspace = true } 17 | geo-traits = { workspace = true } 18 | geoarrow-array = { workspace = true } 19 | geoarrow-schema = { workspace = true } 20 | 21 | [dev-dependencies] 22 | geo = { workspace = true } 23 | geoarrow-array = { workspace = true, features = ["test-data"] } 24 | 25 | [package.metadata.docs.rs] 26 | all-features = true 27 | -------------------------------------------------------------------------------- /rust/geoarrow-expr-geos/src/export/scalar/linestring.rs: -------------------------------------------------------------------------------- 1 | use geo_traits::LineStringTrait; 2 | 3 | use crate::export::scalar::coord::{coords_to_geos, dims_to_geos}; 4 | 5 | pub(crate) fn to_geos_line_string( 6 | line_string: &impl LineStringTrait, 7 | ) -> std::result::Result { 8 | let dims = dims_to_geos(line_string.dim()); 9 | let coord_seq = coords_to_geos(line_string.coords(), dims)?; 10 | geos::Geometry::create_line_string(coord_seq) 11 | } 12 | 13 | pub(crate) fn to_geos_linear_ring( 14 | line_string: &impl LineStringTrait, 15 | ) -> std::result::Result { 16 | let dims = dims_to_geos(line_string.dim()); 17 | let coord_seq = coords_to_geos(line_string.coords(), dims)?; 18 | geos::Geometry::create_linear_ring(coord_seq) 19 | } 20 | -------------------------------------------------------------------------------- /rust/geoarrow-array/src/lib.rs: -------------------------------------------------------------------------------- 1 | #![doc = include_str!("../README.md")] 2 | #![warn(missing_docs)] 3 | #![cfg_attr(docsrs, feature(doc_cfg))] 4 | #![cfg_attr(not(test), deny(unused_crate_dependencies))] 5 | #![doc( 6 | html_logo_url = "https://github.com/geoarrow.png", 7 | html_favicon_url = "https://github.com/geoarrow.png?size=32" 8 | )] 9 | 10 | pub mod array; 11 | pub mod builder; 12 | pub mod capacity; 13 | pub mod cast; 14 | mod eq; 15 | #[cfg(feature = "geozero")] 16 | pub mod geozero; 17 | pub mod scalar; 18 | mod trait_; 19 | pub(crate) mod util; 20 | mod wrap_array; 21 | 22 | pub use trait_::{ 23 | GeoArrowArray, GeoArrowArrayAccessor, GeoArrowArrayIterator, GeoArrowArrayReader, IntoArrow, 24 | }; 25 | pub use wrap_array::WrapArray; 26 | 27 | #[cfg(any(test, feature = "test-data"))] 28 | #[allow(missing_docs)] 29 | pub mod test; 30 | -------------------------------------------------------------------------------- /js/src/error.rs: -------------------------------------------------------------------------------- 1 | // use arrow2::error::Error as ArrowError; 2 | use arrow_wasm::error::ArrowWasmError; 3 | use thiserror::Error; 4 | use wasm_bindgen::JsError; 5 | 6 | #[derive(Error, Debug)] 7 | pub enum GeoArrowWasmError { 8 | // #[error(transparent)] 9 | // ArrowError(Box), 10 | #[error(transparent)] 11 | ArrowWasmError(Box), 12 | 13 | #[cfg(feature = "io_object_store")] 14 | #[error(transparent)] 15 | ObjectStoreError(#[from] object_store::Error), 16 | 17 | #[cfg(feature = "io_parquet")] 18 | #[error(transparent)] 19 | ParquetError(#[from] parquet::errors::ParquetError), 20 | 21 | #[error("Internal error: `{0}`")] 22 | InternalError(String), 23 | } 24 | 25 | pub type Result = std::result::Result; 26 | pub type WasmResult = std::result::Result; 27 | -------------------------------------------------------------------------------- /python/geoarrow-compute/src/algorithm/geo/chaikin_smoothing.rs: -------------------------------------------------------------------------------- 1 | use crate::ffi::from_python::AnyNativeInput; 2 | use crate::util::{return_chunked_geometry_array, return_geometry_array}; 3 | use geoarrow::algorithm::geo::ChaikinSmoothing; 4 | use pyo3::prelude::*; 5 | use pyo3_geoarrow::PyGeoArrowResult; 6 | 7 | #[pyfunction] 8 | pub fn chaikin_smoothing( 9 | py: Python, 10 | input: AnyNativeInput, 11 | n_iterations: u32, 12 | ) -> PyGeoArrowResult { 13 | match input { 14 | AnyNativeInput::Array(arr) => { 15 | let out = arr.as_ref().chaikin_smoothing(n_iterations)?; 16 | return_geometry_array(py, out) 17 | } 18 | AnyNativeInput::Chunked(arr) => { 19 | let out = arr.as_ref().chaikin_smoothing(n_iterations)?; 20 | return_chunked_geometry_array(py, out) 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /python/geoarrow-io/src/io/geojson.rs: -------------------------------------------------------------------------------- 1 | use crate::error::PyGeoArrowResult; 2 | use crate::io::input::sync::{FileReader, FileWriter}; 3 | use crate::util::to_arro3_table; 4 | 5 | use geoarrow::io::geojson::read_geojson as _read_geojson; 6 | use geoarrow::io::geojson::write_geojson as _write_geojson; 7 | use pyo3::prelude::*; 8 | use pyo3_arrow::PyRecordBatchReader; 9 | use pyo3_arrow::export::Arro3Table; 10 | 11 | #[pyfunction] 12 | #[pyo3(signature = (file, *, batch_size=65536))] 13 | pub fn read_geojson(mut file: FileReader, batch_size: usize) -> PyGeoArrowResult { 14 | let table = _read_geojson(&mut file, Some(batch_size))?; 15 | Ok(to_arro3_table(table)) 16 | } 17 | 18 | #[pyfunction] 19 | pub fn write_geojson(table: PyRecordBatchReader, file: FileWriter) -> PyGeoArrowResult<()> { 20 | _write_geojson(table.into_reader()?, file)?; 21 | Ok(()) 22 | } 23 | -------------------------------------------------------------------------------- /rust/geoarrow-array/src/geozero/export/array/geometrycollection.rs: -------------------------------------------------------------------------------- 1 | use geozero::{GeomProcessor, GeozeroGeometry}; 2 | 3 | use crate::array::GeometryCollectionArray; 4 | use crate::geozero::export::scalar::process_geometry_collection; 5 | use crate::{GeoArrowArray, GeoArrowArrayAccessor}; 6 | 7 | impl GeozeroGeometry for GeometryCollectionArray { 8 | fn process_geom(&self, processor: &mut P) -> geozero::error::Result<()> 9 | where 10 | Self: Sized, 11 | { 12 | let num_geometries = self.len(); 13 | processor.geometrycollection_begin(num_geometries, 0)?; 14 | 15 | for geom_idx in 0..num_geometries { 16 | process_geometry_collection(&self.value(geom_idx).unwrap(), geom_idx, processor)?; 17 | } 18 | 19 | processor.geometrycollection_end(num_geometries - 1)?; 20 | Ok(()) 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /python/geoarrow-io/python/geoarrow/rust/io/_shapefile.pyi: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | from pathlib import Path 4 | from typing import Union 5 | 6 | from arro3.core import Table 7 | from geoarrow.rust.core.enums import CoordType 8 | from geoarrow.rust.core.types import CoordTypeT 9 | 10 | def read_shapefile( 11 | shp_path: Union[str, Path], 12 | *, 13 | batch_size: int = 65536, 14 | coord_type: CoordType | CoordTypeT | None = None, 15 | ) -> Table: 16 | """ 17 | Read a Shapefile into an Arrow Table. 18 | 19 | The returned Arrow table will have geometry information in native GeoArrow encoding. 20 | 21 | Args: 22 | shp_path: the path to the `.shp` file 23 | 24 | Other args: 25 | batch_size: the number of rows to include in each internal batch of the table. 26 | coord_type: The coordinate type. Defaults to None. 27 | 28 | """ 29 | -------------------------------------------------------------------------------- /python/metapackage/pyproject.toml: -------------------------------------------------------------------------------- 1 | [build-system] 2 | requires = ["hatchling"] 3 | build-backend = "hatchling.build" 4 | 5 | [project] 6 | name = "geoarrow-rust" 7 | version = "0.1.0" 8 | description = 'Metapackage for geoarrow.rust namespace.' 9 | readme = "README.md" 10 | requires-python = ">=3.7" 11 | license = "Apache-2.0" 12 | keywords = [] 13 | authors = [{ name = "Kyle Barron", email = "kylebarron2@gmail.com" }] 14 | classifiers = [ 15 | "Programming Language :: Python", 16 | "Programming Language :: Python :: 3.9", 17 | "Programming Language :: Python :: 3.10", 18 | "Programming Language :: Python :: 3.11", 19 | "Programming Language :: Python :: 3.12", 20 | ] 21 | dependencies = ["geoarrow-rust-core"] 22 | 23 | [project.urls] 24 | Documentation = "https://geoarrow.org" 25 | Issues = "https://github.com/geoarrow/geoarrow-rs/issues" 26 | Source = "https://github.com/geoarrow/geoarrow-rs" 27 | -------------------------------------------------------------------------------- /docs/README.md: -------------------------------------------------------------------------------- 1 | # Top-level documentation website 2 | 3 | Mkdocs-based website to serve as high-level website and refer people to language-specific documentation. 4 | 5 | To build website: 6 | 7 | ``` 8 | uv run mkdocs serve 9 | ``` 10 | 11 | To deploy: We have a couple manual steps because `mkdocs gh-deploy` _replaces_ 12 | any existing content on the `gh-pages` branch and we want an _upsert_ that 13 | doesn't touch the `js/` or `python/` directories, which are deployed separately. 14 | 15 | ```bash 16 | uv run mkdocs build 17 | git checkout gh-pages 18 | cd .. 19 | git pull 20 | rm -rf 404.html assets index.html sitemap.xml sitemap.xml.gz search stylesheets rust 21 | mv -f docs/site/* ./ 22 | git add 404.html assets index.html sitemap.xml sitemap.xml.gz search stylesheets rust 23 | git commit -m "New revision of top-level docs site" 24 | git push 25 | # Return to previous branch 26 | git checkout - 27 | ``` 28 | -------------------------------------------------------------------------------- /js/src/cast/wkb.rs: -------------------------------------------------------------------------------- 1 | // use wasm_bindgen::prelude::*; 2 | 3 | // use crate::data::JsGeoArrowData; 4 | // use crate::data_type::JsGeoArrowType; 5 | // use crate::error::WasmResult; 6 | 7 | // #[wasm_bindgen] 8 | // pub fn from_wkb( 9 | // input: &JsGeoArrowData, 10 | // to_type: Option, 11 | // ) -> WasmResult { 12 | // let input = input.inner(); 13 | // let input_metadata = input.data_type().metadata().clone(); 14 | // let to_type = to_type 15 | // .map(|x| x.into_inner()) 16 | // .unwrap_or(GeometryType::new(input_metadata).into()); 17 | 18 | // let x = geoarrow_array::cast::from_wkb(arr.inner(), to_type.inner())?; 19 | // let casted_array = geoarrow_array 20 | // .cast_to_type(target_type) 21 | // .map_err(|e| wasm_bindgen::JsError::new(&e.to_string()))?; 22 | 23 | // Ok(JsGeoArrowData(Arc::from(casted_array))) 24 | // } 25 | -------------------------------------------------------------------------------- /python/geoarrow-compute/src/algorithm/geo/dimensions.rs: -------------------------------------------------------------------------------- 1 | use std::sync::Arc; 2 | 3 | use crate::ffi::from_python::AnyNativeInput; 4 | use crate::util::{return_array, return_chunked_array}; 5 | use geoarrow::algorithm::geo::HasDimensions; 6 | use pyo3::prelude::*; 7 | use pyo3_arrow::{PyArray, PyChunkedArray}; 8 | use pyo3_geoarrow::PyGeoArrowResult; 9 | 10 | #[pyfunction] 11 | pub fn is_empty(py: Python, input: AnyNativeInput) -> PyGeoArrowResult { 12 | match input { 13 | AnyNativeInput::Array(arr) => { 14 | let out = HasDimensions::is_empty(&arr.as_ref())?; 15 | return_array(py, PyArray::from_array_ref(Arc::new(out))) 16 | } 17 | AnyNativeInput::Chunked(arr) => { 18 | let out = HasDimensions::is_empty(&arr.as_ref())?; 19 | return_chunked_array(py, PyChunkedArray::from_array_refs(out.chunk_refs())?) 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /python/geoarrow-compute/src/algorithm/geo/geodesic_area.rs: -------------------------------------------------------------------------------- 1 | use std::sync::Arc; 2 | 3 | use crate::ffi::from_python::AnyNativeInput; 4 | use crate::util::{return_array, return_chunked_array}; 5 | use geoarrow::algorithm::geo::GeodesicArea; 6 | use pyo3::prelude::*; 7 | use pyo3_arrow::{PyArray, PyChunkedArray}; 8 | use pyo3_geoarrow::PyGeoArrowResult; 9 | 10 | #[pyfunction] 11 | pub fn geodesic_perimeter(py: Python, input: AnyNativeInput) -> PyGeoArrowResult { 12 | match input { 13 | AnyNativeInput::Array(arr) => { 14 | let out = arr.as_ref().geodesic_perimeter()?; 15 | return_array(py, PyArray::from_array_ref(Arc::new(out))) 16 | } 17 | AnyNativeInput::Chunked(arr) => { 18 | let out = arr.as_ref().geodesic_perimeter()?; 19 | return_chunked_array(py, PyChunkedArray::from_array_refs(out.chunk_refs())?) 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /rust/geoarrow-array/src/geozero/export/scalar/rect.rs: -------------------------------------------------------------------------------- 1 | use geo_traits::RectTrait; 2 | use geozero::{GeomProcessor, GeozeroGeometry}; 3 | 4 | use crate::builder::geo_trait_wrappers::RectWrapper; 5 | use crate::geozero::export::scalar::process_polygon; 6 | use crate::scalar::Rect; 7 | 8 | pub(crate) fn process_rect( 9 | geom: &impl RectTrait, 10 | geom_idx: usize, 11 | processor: &mut P, 12 | ) -> geozero::error::Result<()> { 13 | let polygon = RectWrapper::try_new(geom) 14 | .map_err(|err| geozero::error::GeozeroError::Geometry(err.to_string()))?; 15 | process_polygon(&polygon, true, geom_idx, processor) 16 | } 17 | 18 | impl GeozeroGeometry for Rect<'_> { 19 | fn process_geom(&self, processor: &mut P) -> geozero::error::Result<()> 20 | where 21 | Self: Sized, 22 | { 23 | process_rect(self, 0, processor) 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /python/docs/api/compute/functions.md: -------------------------------------------------------------------------------- 1 | # Functions 2 | 3 | ## Array/Chunked Array functions 4 | 5 | ::: geoarrow.rust.compute 6 | options: 7 | filters: 8 | - "!^_" 9 | members: 10 | - affine_transform 11 | - area 12 | - center 13 | - centroid 14 | - chaikin_smoothing 15 | - convex_hull 16 | - densify 17 | - envelope 18 | - frechet_distance 19 | - geodesic_perimeter 20 | - is_empty 21 | - length 22 | - line_interpolate_point 23 | - line_locate_point 24 | - polylabel 25 | - rotate 26 | - scale 27 | - signed_area 28 | - simplify 29 | - skew 30 | - total_bounds 31 | - translate 32 | 33 | ## Table functions 34 | 35 | ::: geoarrow.rust.compute 36 | options: 37 | filters: 38 | - "!^_" 39 | members: 40 | - explode 41 | -------------------------------------------------------------------------------- /rust/geoarrow-geojson/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "geoarrow-geojson" 3 | version = { workspace = true } 4 | authors = { workspace = true } 5 | edition = { workspace = true } 6 | license = { workspace = true } 7 | repository = { workspace = true } 8 | description = "Write GeoArrow arrays to GeoJSON." 9 | categories = { workspace = true } 10 | rust-version = { workspace = true } 11 | 12 | [dependencies] 13 | arrow-array = { workspace = true } 14 | arrow-json = { workspace = true } 15 | arrow-schema = { workspace = true } 16 | geo-traits = { workspace = true } 17 | geoarrow-array = { workspace = true } 18 | geoarrow-schema = { workspace = true } 19 | 20 | [dev-dependencies] 21 | geo = { workspace = true } 22 | geo-types = { workspace = true } 23 | geoarrow-array = { workspace = true, features = ["test-data"] } 24 | geojson = { workspace = true } 25 | serde_json = "1.0" 26 | 27 | [package.metadata.docs.rs] 28 | all-features = true 29 | -------------------------------------------------------------------------------- /js/src/dimension.rs: -------------------------------------------------------------------------------- 1 | use geoarrow_schema::Dimension; 2 | use wasm_bindgen::prelude::*; 3 | 4 | #[wasm_bindgen(js_name = Dimension)] 5 | pub enum JsDimension { 6 | XY, 7 | XYZ, 8 | XYM, 9 | XYZM, 10 | } 11 | 12 | impl From for Dimension { 13 | fn from(value: JsDimension) -> Self { 14 | match value { 15 | JsDimension::XY => Dimension::XY, 16 | JsDimension::XYZ => Dimension::XYZ, 17 | JsDimension::XYM => Dimension::XYM, 18 | JsDimension::XYZM => Dimension::XYZM, 19 | } 20 | } 21 | } 22 | 23 | impl From for JsDimension { 24 | fn from(value: Dimension) -> Self { 25 | match value { 26 | Dimension::XY => JsDimension::XY, 27 | Dimension::XYZ => JsDimension::XYZ, 28 | Dimension::XYM => JsDimension::XYM, 29 | Dimension::XYZM => JsDimension::XYZM, 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /rust/geoarrow-schema/src/lib.rs: -------------------------------------------------------------------------------- 1 | #![doc = include_str!("../README.md")] 2 | #![cfg_attr(docsrs, feature(doc_cfg))] 3 | #![cfg_attr(not(test), warn(unused_crate_dependencies))] 4 | #![warn(missing_docs)] 5 | #![doc( 6 | html_logo_url = "https://github.com/geoarrow.png", 7 | html_favicon_url = "https://github.com/geoarrow.png?size=32" 8 | )] 9 | 10 | mod coord_type; 11 | pub mod crs; 12 | mod datatype; 13 | mod dimension; 14 | mod edges; 15 | pub mod error; 16 | mod metadata; 17 | mod r#type; 18 | pub mod type_id; 19 | 20 | pub use coord_type::CoordType; 21 | pub use crs::{Crs, CrsType}; 22 | pub use datatype::GeoArrowType; 23 | pub use dimension::Dimension; 24 | pub use edges::Edges; 25 | pub use metadata::Metadata; 26 | pub use r#type::{ 27 | BoxType, GeometryCollectionType, GeometryType, LineStringType, MultiLineStringType, 28 | MultiPointType, MultiPolygonType, PointType, PolygonType, RectType, WkbType, WktType, 29 | }; 30 | -------------------------------------------------------------------------------- /python/geoarrow-io/src/io/geojson_lines.rs: -------------------------------------------------------------------------------- 1 | use crate::error::PyGeoArrowResult; 2 | use crate::io::input::sync::{FileReader, FileWriter}; 3 | use crate::util::to_arro3_table; 4 | 5 | use geoarrow::io::geojson_lines::read_geojson_lines as _read_geojson_lines; 6 | use geoarrow::io::geojson_lines::write_geojson_lines as _write_geojson_lines; 7 | use pyo3::prelude::*; 8 | use pyo3_arrow::export::Arro3Table; 9 | use pyo3_arrow::input::AnyRecordBatch; 10 | 11 | #[pyfunction] 12 | #[pyo3(signature = (file, *, batch_size=65536))] 13 | pub fn read_geojson_lines(mut file: FileReader, batch_size: usize) -> PyGeoArrowResult { 14 | let table = _read_geojson_lines(&mut file, Some(batch_size))?; 15 | Ok(to_arro3_table(table)) 16 | } 17 | 18 | #[pyfunction] 19 | pub fn write_geojson_lines(table: AnyRecordBatch, file: FileWriter) -> PyGeoArrowResult<()> { 20 | _write_geojson_lines(table.into_reader()?, file)?; 21 | Ok(()) 22 | } 23 | -------------------------------------------------------------------------------- /python/tests_old/io/test_pyogrio.py: -------------------------------------------------------------------------------- 1 | import geodatasets 2 | import geopandas as gpd 3 | import pytest 4 | import shapely.testing 5 | from geoarrow.rust.core import geometry_col, read_pyogrio, to_shapely 6 | 7 | nybb_path = geodatasets.get_path("nybb") 8 | 9 | 10 | def test_read_pyogrio(): 11 | _table = read_pyogrio(nybb_path) 12 | # gdf = gpd.read_file(nybb_path) 13 | # shapely.testing.assert_geometries_equal( 14 | # to_shapely(geometry_col(table)), gdf.geometry 15 | # ) 16 | 17 | 18 | @pytest.mark.xfail( 19 | reason=( 20 | "to_shapely currently failing on WKB input with:\n" 21 | "Exception: General error: Unexpected extension name geoarrow.wkb" 22 | ) 23 | ) 24 | def test_read_pyogrio_round_trip(): 25 | table = read_pyogrio(nybb_path) 26 | gdf = gpd.read_file(nybb_path) 27 | shapely.testing.assert_geometries_equal( 28 | to_shapely(geometry_col(table)), gdf.geometry 29 | ) 30 | -------------------------------------------------------------------------------- /rust/geoarrow-array/src/test/geometrycollection.rs: -------------------------------------------------------------------------------- 1 | use geoarrow_schema::{CoordType, Dimension, GeometryCollectionType}; 2 | use geoarrow_test::raw; 3 | 4 | use crate::array::GeometryCollectionArray; 5 | use crate::builder::GeometryCollectionBuilder; 6 | 7 | pub fn array( 8 | coord_type: CoordType, 9 | dim: Dimension, 10 | _prefer_multi: bool, 11 | ) -> GeometryCollectionArray { 12 | let typ = GeometryCollectionType::new(dim, Default::default()).with_coord_type(coord_type); 13 | let geoms = match dim { 14 | Dimension::XY => raw::geometrycollection::xy::geoms(), 15 | Dimension::XYZ => raw::geometrycollection::xyz::geoms(), 16 | Dimension::XYM => raw::geometrycollection::xym::geoms(), 17 | Dimension::XYZM => raw::geometrycollection::xyzm::geoms(), 18 | }; 19 | 20 | GeometryCollectionBuilder::from_nullable_geometry_collections(&geoms, typ) 21 | .unwrap() 22 | .finish() 23 | } 24 | -------------------------------------------------------------------------------- /python/geoarrow-compute/src/algorithm/geo/convex_hull.rs: -------------------------------------------------------------------------------- 1 | use std::sync::Arc; 2 | 3 | use crate::ffi::from_python::AnyNativeInput; 4 | use crate::util::{return_chunked_geometry_array, return_geometry_array}; 5 | use geoarrow::algorithm::geo::ConvexHull; 6 | use geoarrow::array::PolygonArray; 7 | use geoarrow::chunked_array::ChunkedGeometryArray; 8 | use pyo3::prelude::*; 9 | use pyo3_geoarrow::PyGeoArrowResult; 10 | 11 | #[pyfunction] 12 | pub fn convex_hull(py: Python, input: AnyNativeInput) -> PyGeoArrowResult { 13 | match input { 14 | AnyNativeInput::Array(arr) => { 15 | let out: PolygonArray = arr.as_ref().convex_hull()?; 16 | return_geometry_array(py, Arc::new(out)) 17 | } 18 | AnyNativeInput::Chunked(arr) => { 19 | let out: ChunkedGeometryArray = arr.as_ref().convex_hull()?; 20 | return_chunked_geometry_array(py, Arc::new(out)) 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /python/proj/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "geoarrow-rust-proj" 3 | version = "0.1.0" 4 | authors = ["Kyle Barron "] 5 | edition = "2024" 6 | description = "GeoArrow bindings to PROJ." 7 | readme = "README.md" 8 | repository = "https://github.com/geoarrow/geoarrow-rs" 9 | license = "MIT OR Apache-2.0" 10 | keywords = ["python", "arrow", "geospatial"] 11 | categories = ["wasm", "science::geo"] 12 | rust-version = "1.85" 13 | 14 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 15 | [lib] 16 | name = "_rust_proj" 17 | crate-type = ["cdylib"] 18 | 19 | [dependencies] 20 | arrow-array = "50" 21 | arrow-buffer = "50" 22 | arrow = { version = "50", features = ["ffi"] } 23 | pyo3 = { version = "0.24", features = [ 24 | "abi3-py38", 25 | "multiple-pymethods", 26 | "hashbrown", 27 | "serde", 28 | "anyhow", 29 | ] } 30 | geo = "0.31" 31 | geoarrow-rust-core = { path = "../core" } 32 | -------------------------------------------------------------------------------- /rust/geoarrow-expr-geos/src/import/scalar/coord.rs: -------------------------------------------------------------------------------- 1 | use geo_traits::CoordTrait; 2 | 3 | pub struct GEOSConstCoord { 4 | pub(crate) coords: geos::CoordSeq, 5 | pub(crate) geom_index: usize, 6 | pub(crate) dim: geo_traits::Dimensions, 7 | } 8 | 9 | impl CoordTrait for GEOSConstCoord { 10 | type T = f64; 11 | 12 | fn dim(&self) -> geo_traits::Dimensions { 13 | self.dim 14 | } 15 | 16 | fn nth_or_panic(&self, n: usize) -> Self::T { 17 | match n { 18 | 0 => self.coords.get_x(self.geom_index).unwrap(), 19 | 1 => self.coords.get_y(self.geom_index).unwrap(), 20 | 2 => self.coords.get_z(self.geom_index).unwrap(), 21 | _ => panic!(), 22 | } 23 | } 24 | 25 | fn x(&self) -> Self::T { 26 | self.coords.get_x(self.geom_index).unwrap() 27 | } 28 | 29 | fn y(&self) -> Self::T { 30 | self.coords.get_y(self.geom_index).unwrap() 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /python/tests_old/algorithm/test_explode.py: -------------------------------------------------------------------------------- 1 | # import geoarrow.rust.core as gars 2 | 3 | # import geopandas as gpd 4 | # import pandas as pd 5 | # from geoarrow.rust.core import GeoTable 6 | 7 | # gdf = gpd.read_file(gpd.datasets.get_path('nybb')) 8 | 9 | # table = GeoTable.from_geopandas(gdf) 10 | # exploded_table = table.explode() 11 | # round_trip_gdf = exploded_table.to_geopandas() 12 | # geopandas_impl = gdf.explode(index_parts=False) 13 | 14 | # all(round_trip_gdf.geometry.reset_index(drop=True) == geopandas_impl.geometry.reset_index(drop=True)) 15 | # # True! Yay! 16 | 17 | # ### 18 | # # Perf testing 19 | # large = pd.concat([gdf] * 1000) 20 | 21 | # table = GeoTable.from_geopandas(large) 22 | # %timeit exploded_table = table.explode() 23 | # # 590 µs ± 33.2 µs per loop (mean ± std. dev. of 7 runs, 1,000 loops each) 24 | 25 | # %timeit gdf_exp = large.explode(index_parts=False) 26 | # # 262 ms ± 10.9 ms per loop (mean ± std. dev. of 7 runs, 1 loop each) 27 | -------------------------------------------------------------------------------- /rust/geoarrow-array/src/geozero/export/scalar/linestring.rs: -------------------------------------------------------------------------------- 1 | use geo_traits::LineStringTrait; 2 | use geozero::{GeomProcessor, GeozeroGeometry}; 3 | 4 | use super::process_coord; 5 | use crate::scalar::LineString; 6 | 7 | pub(crate) fn process_line_string( 8 | geom: &impl LineStringTrait, 9 | geom_idx: usize, 10 | processor: &mut P, 11 | ) -> geozero::error::Result<()> { 12 | processor.linestring_begin(true, geom.num_coords(), geom_idx)?; 13 | 14 | for (coord_idx, coord) in geom.coords().enumerate() { 15 | process_coord(&coord, coord_idx, processor)?; 16 | } 17 | 18 | processor.linestring_end(true, geom_idx)?; 19 | Ok(()) 20 | } 21 | 22 | impl GeozeroGeometry for LineString<'_> { 23 | fn process_geom(&self, processor: &mut P) -> geozero::error::Result<()> 24 | where 25 | Self: Sized, 26 | { 27 | process_line_string(self, 0, processor) 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /python/geoarrow-compute/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "geoarrow-rust-compute" 3 | version = { workspace = true } 4 | authors = { workspace = true } 5 | edition = { workspace = true } 6 | description = "Efficient, vectorized geospatial operations in Python." 7 | readme = "README.md" 8 | repository = { workspace = true } 9 | homepage = { workspace = true } 10 | license = { workspace = true } 11 | keywords = { workspace = true } 12 | categories = { workspace = true } 13 | rust-version = { workspace = true } 14 | 15 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 16 | [lib] 17 | name = "_compute" 18 | crate-type = ["cdylib"] 19 | 20 | [dependencies] 21 | arrow = { workspace = true } 22 | arrow-array = { workspace = true } 23 | arrow-buffer = { workspace = true } 24 | pyo3 = { workspace = true } 25 | pyo3-arrow = { workspace = true } 26 | pyo3-geoarrow = { workspace = true } 27 | geo = "0.31" 28 | numpy = { workspace = true } 29 | -------------------------------------------------------------------------------- /rust/geoarrow-array/src/geozero/export/scalar/multipoint.rs: -------------------------------------------------------------------------------- 1 | use geo_traits::MultiPointTrait; 2 | use geozero::{GeomProcessor, GeozeroGeometry}; 3 | 4 | use super::process_point_as_coord; 5 | use crate::scalar::MultiPoint; 6 | 7 | pub(crate) fn process_multi_point( 8 | geom: &impl MultiPointTrait, 9 | geom_idx: usize, 10 | processor: &mut P, 11 | ) -> geozero::error::Result<()> { 12 | processor.multipoint_begin(geom.num_points(), geom_idx)?; 13 | 14 | for (point_idx, point) in geom.points().enumerate() { 15 | process_point_as_coord(&point, point_idx, processor)?; 16 | } 17 | 18 | processor.multipoint_end(geom_idx)?; 19 | Ok(()) 20 | } 21 | 22 | impl GeozeroGeometry for MultiPoint<'_> { 23 | fn process_geom(&self, processor: &mut P) -> geozero::error::Result<()> 24 | where 25 | Self: Sized, 26 | { 27 | process_multi_point(self, 0, processor) 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /rust/geoarrow-array/src/builder/mod.rs: -------------------------------------------------------------------------------- 1 | //! Push-based APIs for constructing arrays. 2 | 3 | mod coord; 4 | pub(crate) mod geo_trait_wrappers; 5 | mod geometry; 6 | mod geometrycollection; 7 | mod linestring; 8 | mod mixed; 9 | mod multilinestring; 10 | mod multipoint; 11 | mod multipolygon; 12 | mod offsets; 13 | mod point; 14 | mod polygon; 15 | mod rect; 16 | mod wkb; 17 | 18 | pub use coord::{CoordBufferBuilder, InterleavedCoordBufferBuilder, SeparatedCoordBufferBuilder}; 19 | pub use geometry::GeometryBuilder; 20 | pub use geometrycollection::GeometryCollectionBuilder; 21 | pub use linestring::LineStringBuilder; 22 | pub(crate) use mixed::MixedGeometryBuilder; 23 | pub use multilinestring::MultiLineStringBuilder; 24 | pub use multipoint::MultiPointBuilder; 25 | pub use multipolygon::MultiPolygonBuilder; 26 | pub(crate) use offsets::OffsetsBuilder; 27 | pub use point::PointBuilder; 28 | pub use polygon::PolygonBuilder; 29 | pub use rect::RectBuilder; 30 | pub use wkb::WkbBuilder; 31 | -------------------------------------------------------------------------------- /python/tests_old/interop/test_wkt.py: -------------------------------------------------------------------------------- 1 | import pyarrow as pa 2 | import pytest 3 | import shapely 4 | from geoarrow.rust.core import from_wkt, to_shapely 5 | from shapely.testing import assert_geometries_equal 6 | 7 | 8 | @pytest.mark.skip 9 | def test_from_wkt(): 10 | s = [ 11 | "POINT (3 2)", 12 | "POINT (0 2)", 13 | "POINT (1 4)", 14 | "POINT (3 2)", 15 | "POINT (0 2)", 16 | "POINT (1 4)", 17 | ] 18 | shapely_arr = shapely.from_wkt(s) 19 | geo_arr = from_wkt(pa.array(s)) 20 | assert_geometries_equal(shapely_arr, to_shapely(geo_arr)) 21 | 22 | 23 | @pytest.mark.skip 24 | def test_from_wkt_chunked(): 25 | s1 = ["POINT (3 2)", "POINT (0 2)", "POINT (1 4)"] 26 | s2 = ["POINT (3 2)", "POINT (0 2)", "POINT (1 4)"] 27 | ca = pa.chunked_array([pa.array(s1), pa.array(s2)]) 28 | shapely_arr = shapely.from_wkt(s1 + s2) 29 | geo_arr = from_wkt(ca) 30 | assert_geometries_equal(shapely_arr, to_shapely(geo_arr)) 31 | -------------------------------------------------------------------------------- /rust/geoarrow-array/src/geozero/export/scalar/multipolygon.rs: -------------------------------------------------------------------------------- 1 | use geo_traits::MultiPolygonTrait; 2 | use geozero::{GeomProcessor, GeozeroGeometry}; 3 | 4 | use super::process_polygon; 5 | use crate::scalar::MultiPolygon; 6 | 7 | pub(crate) fn process_multi_polygon( 8 | geom: &impl MultiPolygonTrait, 9 | geom_idx: usize, 10 | processor: &mut P, 11 | ) -> geozero::error::Result<()> { 12 | processor.multipolygon_begin(geom.num_polygons(), geom_idx)?; 13 | 14 | for (polygon_idx, polygon) in geom.polygons().enumerate() { 15 | process_polygon(&polygon, false, polygon_idx, processor)?; 16 | } 17 | 18 | processor.multipolygon_end(geom_idx)?; 19 | Ok(()) 20 | } 21 | 22 | impl GeozeroGeometry for MultiPolygon<'_> { 23 | fn process_geom(&self, processor: &mut P) -> geozero::error::Result<()> 24 | where 25 | Self: Sized, 26 | { 27 | process_multi_polygon(self, 0, processor) 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /rust/geoarrow-old/src/algorithm/native/mod.rs: -------------------------------------------------------------------------------- 1 | //! Operations that are implemented natively in this crate. 2 | //! 3 | //! Where possible, operations on scalars are implemented in terms of [geometry 4 | //! traits](../../geo_traits). 5 | 6 | mod binary; 7 | pub mod bounding_rect; 8 | mod cast; 9 | mod concatenate; 10 | pub(crate) mod downcast; 11 | pub(crate) mod eq; 12 | mod explode; 13 | mod map_chunks; 14 | mod map_coords; 15 | mod rechunk; 16 | mod take; 17 | mod total_bounds; 18 | pub(crate) mod type_id; 19 | mod unary; 20 | 21 | pub use binary::Binary; 22 | pub use bounding_rect::BoundingRectArray; 23 | pub use cast::Cast; 24 | pub use concatenate::Concatenate; 25 | pub use downcast::{Downcast, DowncastTable}; 26 | pub use explode::{Explode, ExplodeTable}; 27 | pub use map_chunks::MapChunks; 28 | pub use map_coords::MapCoords; 29 | pub use rechunk::Rechunk; 30 | pub use take::Take; 31 | pub use total_bounds::TotalBounds; 32 | pub use type_id::TypeIds; 33 | pub use unary::{Unary, UnaryPoint}; 34 | -------------------------------------------------------------------------------- /rust/geoarrow-old/benches/geos_buffer.rs: -------------------------------------------------------------------------------- 1 | use criterion::{Criterion, criterion_group, criterion_main}; 2 | use geoarrow::algorithm::geos::Buffer; 3 | use geoarrow::array::{CoordBuffer, InterleavedCoordBuffer, PointArray, PolygonArray}; 4 | use geoarrow_schema::Dimension; 5 | 6 | fn generate_data() -> PointArray { 7 | let coords = vec![0.0; 100_000]; 8 | let coord_buffer = 9 | CoordBuffer::Interleaved(InterleavedCoordBuffer::new(coords.into(), Dimension::XY)); 10 | PointArray::new(coord_buffer, None, Default::default()) 11 | } 12 | 13 | pub fn criterion_benchmark(c: &mut Criterion) { 14 | let point_array = generate_data(); 15 | 16 | c.bench_function("buffer", |b| { 17 | b.iter(|| { 18 | let _buffered: PolygonArray = point_array.buffer(1.0, 8).unwrap(); 19 | }) 20 | }); 21 | } 22 | 23 | criterion_group! { 24 | name = benches; 25 | config = Criterion::default().sample_size(10); 26 | targets = criterion_benchmark 27 | } 28 | criterion_main!(benches); 29 | -------------------------------------------------------------------------------- /rust/geoarrow-array/src/geozero/export/scalar/geometry_collection.rs: -------------------------------------------------------------------------------- 1 | use geo_traits::GeometryCollectionTrait; 2 | use geozero::{GeomProcessor, GeozeroGeometry}; 3 | 4 | use super::process_geometry; 5 | use crate::scalar::GeometryCollection; 6 | 7 | pub(crate) fn process_geometry_collection( 8 | geom: &impl GeometryCollectionTrait, 9 | geom_idx: usize, 10 | processor: &mut P, 11 | ) -> geozero::error::Result<()> { 12 | processor.geometrycollection_begin(geom.num_geometries(), geom_idx)?; 13 | 14 | for (i, geometry) in geom.geometries().enumerate() { 15 | process_geometry(&geometry, i, processor)?; 16 | } 17 | 18 | processor.geometrycollection_end(geom_idx)?; 19 | Ok(()) 20 | } 21 | 22 | impl GeozeroGeometry for GeometryCollection<'_> { 23 | fn process_geom(&self, processor: &mut P) -> geozero::error::Result<()> 24 | where 25 | Self: Sized, 26 | { 27 | process_geometry_collection(&self, 0, processor) 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /python/geoarrow-core/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "geoarrow-rust-core" 3 | version = { workspace = true } 4 | authors = { workspace = true } 5 | edition = { workspace = true } 6 | description = "Efficient, vectorized geospatial operations in Python." 7 | readme = "README.md" 8 | repository = { workspace = true } 9 | homepage = { workspace = true } 10 | license = { workspace = true } 11 | keywords = { workspace = true } 12 | categories = { workspace = true } 13 | rust-version = { workspace = true } 14 | 15 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 16 | [lib] 17 | name = "_rust" 18 | crate-type = ["cdylib"] 19 | 20 | [features] 21 | 22 | [dependencies] 23 | arrow-array = { workspace = true } 24 | arrow-schema = { workspace = true } 25 | pyo3 = { workspace = true } 26 | pyo3-arrow = { workspace = true } 27 | pyo3-geoarrow = { workspace = true, features = ["geozero"] } 28 | geoarrow-array = { workspace = true } 29 | geoarrow-schema = { workspace = true } 30 | geo-traits = { workspace = true } 31 | -------------------------------------------------------------------------------- /rust/geoarrow-old/src/io/geojson/writer.rs: -------------------------------------------------------------------------------- 1 | use crate::error::Result; 2 | use crate::io::stream::RecordBatchReader; 3 | use geozero::GeozeroDatasource; 4 | use geozero::geojson::GeoJsonWriter; 5 | use std::io::Write; 6 | 7 | /// Write a Table to GeoJSON 8 | /// 9 | /// Note: Does not reproject to WGS84 for you 10 | pub fn write_geojson>(stream: S, writer: W) -> Result<()> { 11 | let mut geojson = GeoJsonWriter::new(writer); 12 | stream.into().process(&mut geojson)?; 13 | Ok(()) 14 | } 15 | 16 | #[cfg(test)] 17 | mod test { 18 | use super::*; 19 | use crate::test::point; 20 | use std::io::BufWriter; 21 | 22 | #[test] 23 | fn test_write() { 24 | let table = point::table(); 25 | 26 | let mut output_buffer = Vec::new(); 27 | let writer = BufWriter::new(&mut output_buffer); 28 | write_geojson(&table, writer).unwrap(); 29 | let output_string = String::from_utf8(output_buffer).unwrap(); 30 | println!("{}", output_string); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /python/geoarrow-core/DEVELOP.md: -------------------------------------------------------------------------------- 1 | ## Pyodide 2 | 3 | 4 | Install rust nightly and add wasm toolchain 5 | 6 | ``` 7 | rustup toolchain install nightly 8 | rustup target add --toolchain nightly wasm32-unknown-emscripten 9 | ``` 10 | 11 | Install dependencies. You need to set the `pyodide-build` version to the same version as the `pyodide` release you distribute for. 12 | 13 | ``` 14 | pip install -U maturin 15 | pip install pyodide-build 16 | ``` 17 | 18 | Install emsdk. 19 | 20 | ``` 21 | git clone https://github.com/emscripten-core/emsdk.git 22 | cd emsdk 23 | PYODIDE_EMSCRIPTEN_VERSION=$(pyodide config get emscripten_version) 24 | ./emsdk install ${PYODIDE_EMSCRIPTEN_VERSION} 25 | ./emsdk activate ${PYODIDE_EMSCRIPTEN_VERSION} 26 | source emsdk_env.sh 27 | cd .. 28 | ``` 29 | 30 | - You must use `--no-default-features` to remove any async support. `tokio` does not compile for emscripten. 31 | 32 | ```bash 33 | maturin build / 34 | --no-default-features / 35 | --release / 36 | -o dist / 37 | --target wasm32-unknown-emscripten 38 | ``` 39 | -------------------------------------------------------------------------------- /rust/geoparquet/README.md: -------------------------------------------------------------------------------- 1 | # geoparquet 2 | 3 | Support for reading and writing [GeoParquet][geoparquet repo] files. 4 | 5 | The reader and writer APIs are built on top of the [`parquet`] crate, and are designed to be used in conjunction with the upstream [arrow-enabled APIs][parquet::arrow]. 6 | 7 | See the [crate-level `parquet` documentation][parquet] and the [GeoParquet specification][geoparquet repo] for more high-level details about the GeoParquet format. 8 | 9 | [geoparquet repo]: https://github.com/opengeospatial/geoparquet 10 | 11 | ## Feature flags 12 | 13 | This crate provides the following features which may be enabled in your `Cargo.toml`: 14 | 15 | - `async`: support `async` APIs for reading and writing GeoParquet 16 | 17 | You can enable compression codecs for reading and writing GeoParquet files directly via the upstream `parquet` crate's feature flags. 18 | 19 | ## Rust version compatibility 20 | 21 | This crate is tested with the latest stable version of Rust. We do not currently test against other, older versions of the Rust compiler. 22 | -------------------------------------------------------------------------------- /js/tests/js/geoparquet.test.ts: -------------------------------------------------------------------------------- 1 | // import * as geoarrow from "../../pkg/node"; 2 | // import { tableFromIPC } from "apache-arrow"; 3 | // import { readFileSync } from "fs"; 4 | // import { expect, it } from "vitest"; 5 | 6 | // geoarrow.set_panic_hook(); 7 | 8 | // it("read GeoParquet", () => { 9 | // const path = "../fixtures/geoparquet/nybb.parquet"; 10 | // const buffer = new Uint8Array(readFileSync(path)); 11 | // const wasmTable = geoarrow.readGeoParquet(buffer); 12 | // const arrowIPCBuffer = wasmTable.intoIPCStream(); 13 | // const arrowJsTable = tableFromIPC(arrowIPCBuffer); 14 | // const geometryIdx = arrowJsTable.schema.fields.findIndex( 15 | // (field) => field.name === "geometry" 16 | // ); 17 | // const geometryField = arrowJsTable.schema.fields[geometryIdx]; 18 | // const geometryFieldMetadata = geometryField.metadata; 19 | // expect(geometryFieldMetadata.get("ARROW:extension:name")).toStrictEqual( 20 | // "geoarrow.multipolygon" 21 | // ); 22 | // }); 23 | 24 | import { it } from "vitest"; 25 | 26 | it("hello world", () => {}); 27 | -------------------------------------------------------------------------------- /rust/geoarrow-schema/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | **This is the changelog for the core Rust library**. There's a [separate changelog](./python/CHANGELOG.md) for the Python bindings, and there will be another for the JS bindings. 4 | 5 | ## Unreleased 6 | 7 | ## 0.6.0 - 2025-10-15 8 | 9 | - feat(geoarrow-schema): add `RectType` as alias for `BoxType` by @kylebarron in https://github.com/geoarrow/geoarrow-rs/pull/1310 10 | - feat: `GeometryTypeId` trait to infer GeoArrow type id for a type #1372 11 | 12 | ## 0.5.0 - 2025-08-07 13 | 14 | - **Breaking**: Use GeoArrowError in TryFrom from geo_traits::Dimension by @kylebarron in https://github.com/geoarrow/geoarrow-rs/pull/1266 15 | - Check inferred dimension against list size for interleaved point input by @kylebarron in https://github.com/geoarrow/geoarrow-rs/pull/1267 16 | - **Breaking**: Better distinction of creating GeoArrowType depending on extension metadata by @kylebarron in https://github.com/geoarrow/geoarrow-rs/pull/1275 17 | 18 | --- 19 | 20 | Previous releases were documented in the top-level `CHANGELOG.md` file. 21 | -------------------------------------------------------------------------------- /js/tests/js/flatgeobuf.test.ts: -------------------------------------------------------------------------------- 1 | // import * as geoarrow from "../../pkg/node"; 2 | // import { tableFromIPC } from "apache-arrow"; 3 | // import { readFileSync } from "fs"; 4 | import { it } from "vitest"; 5 | 6 | it("hello world", () => {}); 7 | 8 | // geoarrow.set_panic_hook(); 9 | 10 | // it("read FlatGeobuf", () => { 11 | // const path = "../fixtures/flatgeobuf/nz-building-outlines-small.fgb"; 12 | // const buffer = new Uint8Array(readFileSync(path)); 13 | // const wasmTable = geoarrow.readFlatGeobuf(buffer); 14 | // const arrowIPCBuffer = wasmTable.intoIPCStream(); 15 | // const arrowJsTable = tableFromIPC(arrowIPCBuffer); 16 | // const geometryIdx = arrowJsTable.schema.fields.findIndex( 17 | // (field) => field.name === "geometry" 18 | // ); 19 | // const geometryField = arrowJsTable.schema.fields[geometryIdx]; 20 | // const geometryFieldMetadata = geometryField.metadata; 21 | // console.log(geometryFieldMetadata); 22 | // expect(geometryFieldMetadata.get("ARROW:extension:name")).toStrictEqual( 23 | // "geoarrow.multipolygon" 24 | // ); 25 | // }); 26 | -------------------------------------------------------------------------------- /rust/geoarrow-array/src/capacity/mod.rs: -------------------------------------------------------------------------------- 1 | //! Counters for managing buffer lengths for each geometry array type. 2 | //! 3 | //! The most memory-efficient way to construct an array from a set of geometries is to make a 4 | //! first pass over these geometries to count exactly how big each underlying buffer of the Arrow 5 | //! array must be, allocate _once_ for exactly what you need, and then fill those buffers in a 6 | //! second pass. Capacity counters help with this process. 7 | 8 | mod geometry; 9 | mod geometrycollection; 10 | mod linestring; 11 | mod mixed; 12 | mod multilinestring; 13 | mod multipoint; 14 | mod multipolygon; 15 | mod point; 16 | mod polygon; 17 | mod wkb; 18 | 19 | pub use geometry::GeometryCapacity; 20 | pub use geometrycollection::GeometryCollectionCapacity; 21 | pub use linestring::LineStringCapacity; 22 | pub(crate) use mixed::MixedCapacity; 23 | pub use multilinestring::MultiLineStringCapacity; 24 | pub use multipoint::MultiPointCapacity; 25 | pub use multipolygon::MultiPolygonCapacity; 26 | pub use polygon::PolygonCapacity; 27 | pub use wkb::WkbCapacity; 28 | -------------------------------------------------------------------------------- /python/geoarrow-compute/src/algorithm/polylabel.rs: -------------------------------------------------------------------------------- 1 | use std::sync::Arc; 2 | 3 | use crate::ffi::from_python::AnyNativeInput; 4 | use geoarrow::algorithm::polylabel::Polylabel; 5 | use geoarrow::array::NativeArrayDyn; 6 | use pyo3::prelude::*; 7 | use pyo3_geoarrow::PyGeoArrowResult; 8 | use pyo3_geoarrow::{PyChunkedNativeArray, PyNativeArray}; 9 | 10 | #[pyfunction] 11 | pub fn polylabel(py: Python, input: AnyNativeInput, tolerance: f64) -> PyGeoArrowResult { 12 | match input { 13 | AnyNativeInput::Array(arr) => { 14 | let out = arr.as_ref().polylabel(tolerance)?; 15 | Ok(PyNativeArray::new(NativeArrayDyn::new(Arc::new(out))) 16 | .into_pyobject(py)? 17 | .into_any() 18 | .unbind()) 19 | } 20 | AnyNativeInput::Chunked(chunked) => { 21 | let out = chunked.as_ref().polylabel(tolerance)?; 22 | Ok(PyChunkedNativeArray::new(Arc::new(out)) 23 | .into_pyobject(py)? 24 | .into_any() 25 | .unbind()) 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /rust/pyo3-geoarrow/src/lib.rs: -------------------------------------------------------------------------------- 1 | #![doc = include_str!("../README.md")] 2 | #![warn(missing_docs)] 3 | #![cfg_attr(docsrs, feature(doc_cfg))] 4 | #![cfg_attr(not(test), warn(unused_crate_dependencies))] 5 | #![doc( 6 | html_logo_url = "https://github.com/geoarrow.png", 7 | html_favicon_url = "https://github.com/geoarrow.png?size=32" 8 | )] 9 | 10 | mod array; 11 | mod array_reader; 12 | mod chunked_array; 13 | mod coord_buffer; 14 | mod coord_type; 15 | mod crs; 16 | pub mod data_type; 17 | mod dimension; 18 | mod edges; 19 | mod error; 20 | mod ffi; 21 | pub mod input; 22 | mod offset_buffer; 23 | mod scalar; 24 | mod utils; 25 | 26 | pub use array::PyGeoArray; 27 | pub use array_reader::PyGeoArrayReader; 28 | pub use chunked_array::PyGeoChunkedArray; 29 | pub use coord_buffer::PyCoordBuffer; 30 | pub use coord_type::PyCoordType; 31 | pub use crs::{PyCrs, PyprojCRSTransform}; 32 | pub use data_type::PyGeoType; 33 | pub use dimension::PyDimension; 34 | pub use edges::PyEdges; 35 | pub use error::{PyGeoArrowError, PyGeoArrowResult}; 36 | pub use offset_buffer::PyOffsetBuffer; 37 | pub use scalar::PyGeoScalar; 38 | -------------------------------------------------------------------------------- /python/.gitignore: -------------------------------------------------------------------------------- 1 | .ipynb_checkpoints 2 | 3 | tmp*.py 4 | tmp*.ts 5 | tmp*.js 6 | *.zip 7 | site 8 | /target 9 | 10 | # Byte-compiled / optimized / DLL files 11 | __pycache__/ 12 | .pytest_cache/ 13 | *.py[cod] 14 | 15 | # C extensions 16 | *.so 17 | 18 | # Distribution / packaging 19 | .Python 20 | .venv/ 21 | env/ 22 | bin/ 23 | build/ 24 | develop-eggs/ 25 | dist/ 26 | eggs/ 27 | lib/ 28 | lib64/ 29 | parts/ 30 | sdist/ 31 | var/ 32 | include/ 33 | man/ 34 | venv/ 35 | *.egg-info/ 36 | .installed.cfg 37 | *.egg 38 | 39 | # Installer logs 40 | pip-log.txt 41 | pip-delete-this-directory.txt 42 | pip-selfcheck.json 43 | 44 | # Unit test / coverage reports 45 | htmlcov/ 46 | .tox/ 47 | .coverage 48 | .cache 49 | nosetests.xml 50 | coverage.xml 51 | 52 | # Translations 53 | *.mo 54 | 55 | # Mr Developer 56 | .mr.developer.cfg 57 | .project 58 | .pydevproject 59 | 60 | # Rope 61 | .ropeproject 62 | 63 | # Django stuff: 64 | *.log 65 | *.pot 66 | 67 | .DS_Store 68 | 69 | # Sphinx documentation 70 | docs/_build/ 71 | 72 | # PyCharm 73 | .idea/ 74 | 75 | # VSCode 76 | .vscode/ 77 | 78 | # Pyenv 79 | .python-version 80 | -------------------------------------------------------------------------------- /js/src/data/coord.rs: -------------------------------------------------------------------------------- 1 | use geoarrow_array::array::{CoordBuffer, InterleavedCoordBuffer, SeparatedCoordBuffer}; 2 | use geoarrow_schema::Dimension; 3 | use wasm_bindgen::prelude::*; 4 | 5 | use crate::dimension::JsDimension; 6 | 7 | /// An immutable buffer of coordinates in WebAssembly memory, that can be either interleaved or 8 | /// separated. 9 | #[wasm_bindgen] 10 | #[allow(dead_code)] 11 | pub struct JsCoordBuffer(CoordBuffer); 12 | 13 | #[wasm_bindgen] 14 | impl JsCoordBuffer { 15 | /// Create a new CoordBuffer from a `Float64Array` of interleaved XY coordinates 16 | #[wasm_bindgen(js_name = fromInterleaved)] 17 | pub fn from_interleaved(coords: Vec, dim: JsDimension) -> Self { 18 | Self(InterleavedCoordBuffer::new(coords.into(), dim.into()).into()) 19 | } 20 | 21 | /// Create a new CoordBuffer from two `Float64Array`s of X and Y 22 | #[wasm_bindgen(js_name = fromSeparated)] 23 | pub fn from_separated(x: Vec, y: Vec) -> Self { 24 | let cb = SeparatedCoordBuffer::from_vec(vec![x.into(), y.into()], Dimension::XY).unwrap(); 25 | Self(cb.into()) 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /python/tests_old/algorithm/test_affine_ops.py: -------------------------------------------------------------------------------- 1 | import geoarrow.rust.compute as grc 2 | import geoarrow.rust.core as gars 3 | import geodatasets 4 | import geopandas as gpd 5 | import shapely.geometry 6 | from affine import Affine 7 | 8 | nybb_path = geodatasets.get_path("nybb") 9 | 10 | 11 | def test_affine_function(): 12 | gdf = gpd.read_file(nybb_path) 13 | # shapely_area = gdf.geometry.area 14 | assert isinstance(gdf, gpd.GeoDataFrame) 15 | 16 | table = gars.from_geopandas(gdf) 17 | geom = gars.geometry_col(table) 18 | 19 | xoff = 10 20 | yoff = 20 21 | 22 | affine = Affine.translation(xoff, yoff) 23 | translated = grc.affine_transform(geom, affine) 24 | orig_geom = geom.chunk(0)[0] 25 | translated_geom = translated.chunk(0)[0] 26 | 27 | first_coord = shapely.geometry.shape(orig_geom).geoms[0].exterior.coords[0] 28 | first_coord_translated = ( 29 | shapely.geometry.shape(translated_geom).geoms[0].exterior.coords[0] 30 | ) 31 | 32 | assert first_coord_translated[0] - xoff == first_coord[0] 33 | assert first_coord_translated[1] - yoff == first_coord[1] 34 | -------------------------------------------------------------------------------- /rust/geoarrow-old/benches/translate.rs: -------------------------------------------------------------------------------- 1 | use geo::polygon; 2 | 3 | use criterion::{Criterion, criterion_group, criterion_main}; 4 | use geoarrow::algorithm::geo::Translate; 5 | use geoarrow::array::PolygonArray; 6 | use geoarrow_schema::Dimension; 7 | 8 | fn create_data() -> PolygonArray { 9 | // An L shape 10 | // https://github.com/georust/geo/blob/7cb7d0ffa6bf1544c5ca9922bd06100c36f815d7/README.md?plain=1#L40 11 | let poly = polygon![ 12 | (x: 0.0, y: 0.0), 13 | (x: 4.0, y: 0.0), 14 | (x: 4.0, y: 1.0), 15 | (x: 1.0, y: 1.0), 16 | (x: 1.0, y: 4.0), 17 | (x: 0.0, y: 4.0), 18 | (x: 0.0, y: 0.0), 19 | ]; 20 | let v = vec![poly; 1000]; 21 | (v.as_slice(), Dimension::XY).into() 22 | } 23 | 24 | pub fn criterion_benchmark(c: &mut Criterion) { 25 | let data = create_data(); 26 | 27 | c.bench_function("translate PolygonArray", |b| { 28 | b.iter(|| { 29 | let _ = data.translate(&10.0.into(), &20.0.into()); 30 | }) 31 | }); 32 | } 33 | 34 | criterion_group!(benches, criterion_benchmark); 35 | criterion_main!(benches); 36 | -------------------------------------------------------------------------------- /rust/geoarrow-expr-geo/src/lib.rs: -------------------------------------------------------------------------------- 1 | #![cfg_attr(docsrs, feature(doc_cfg))] 2 | #![cfg_attr(not(test), warn(unused_crate_dependencies))] 3 | #![doc( 4 | html_logo_url = "https://github.com/geoarrow.png", 5 | html_favicon_url = "https://github.com/geoarrow.png?size=32" 6 | )] 7 | 8 | mod area; 9 | mod centroid; 10 | mod contains; 11 | mod convex_hull; 12 | mod distance; 13 | mod interior_point; 14 | mod intersects; 15 | mod length; 16 | mod minimum_rotated_rect; 17 | mod relate; 18 | mod simplify; 19 | mod simplify_vw; 20 | mod simplify_vw_preserve; 21 | pub mod util; 22 | pub mod validation; 23 | 24 | pub use area::{signed_area, unsigned_area}; 25 | pub use centroid::centroid; 26 | pub use contains::contains; 27 | pub use convex_hull::convex_hull; 28 | pub use distance::euclidean_distance; 29 | pub use interior_point::interior_point; 30 | pub use intersects::intersects; 31 | pub use length::euclidean_length; 32 | pub use minimum_rotated_rect::minimum_rotated_rect; 33 | pub use relate::relate_boolean; 34 | pub use simplify::simplify; 35 | pub use simplify_vw::simplify_vw; 36 | pub use simplify_vw_preserve::simplify_vw_preserve; 37 | -------------------------------------------------------------------------------- /LICENSE_MIT: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 Kyle Barron 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /rust/geoarrow-schema/src/coord_type.rs: -------------------------------------------------------------------------------- 1 | /// The permitted GeoArrow coordinate representations. 2 | /// 3 | /// GeoArrow permits coordinate types to either be "Interleaved", where the X and Y coordinates are 4 | /// in a single buffer as `XYXYXY` or "Separated", where the X and Y coordinates are in multiple 5 | /// buffers as `XXXX` and `YYYY`. 6 | #[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash)] 7 | pub enum CoordType { 8 | /// Interleaved coordinates. 9 | /// 10 | /// This stores coordinates in an Arrow 11 | /// [fixed-size-list-typed][arrow_schema::DataType::FixedSizeList] array. 12 | /// 13 | /// The size of the internal fixed-size list depends on the [dimension][crate::Dimension] of 14 | /// the array. 15 | /// 16 | /// ```notest 17 | /// FixedSizeList[n_dim] 18 | /// ``` 19 | Interleaved, 20 | 21 | /// Separated coordinates. 22 | /// 23 | /// This stores coordinates in an Arrow [struct-typed][arrow_schema::DataType::Struct] array: 24 | /// 25 | /// ```notest 26 | /// Struct]] 27 | /// ``` 28 | #[default] 29 | Separated, 30 | } 31 | -------------------------------------------------------------------------------- /rust/geoarrow/src/lib.rs: -------------------------------------------------------------------------------- 1 | //! A complete, safe, native Rust implementation of [GeoArrow](https://geoarrow.org/), which adds 2 | //! geospatial support to the [Apache Arrow](https://arrow.apache.org) tabular in-memory data 3 | //! format. 4 | //! 5 | //! As of version 0.4, the `geoarrow` crate was refactored to a monorepo of smaller crates, each 6 | //! with a more well-defined scope. Users may want to depend on the subcrates manually: 7 | //! 8 | //! - [`geoarrow_array`]: GeoArrow array definitions. 9 | //! - [`geoarrow_cast`](https://docs.rs/geoarrow-cast/latest/geoarrow_cast/): Functions for converting from one GeoArrow geometry type to another. 10 | //! - [`geoarrow_schema`]: GeoArrow geometry type and metadata definitions. 11 | //! 12 | //! This crate is an "amalgam" crate, which just re-exports types from the underlying sub-crates. 13 | 14 | #![cfg_attr(docsrs, feature(doc_cfg))] 15 | #![cfg_attr(not(test), warn(unused_crate_dependencies))] 16 | #![warn(missing_docs)] 17 | #![doc( 18 | html_logo_url = "https://github.com/geoarrow.png", 19 | html_favicon_url = "https://github.com/geoarrow.png?size=32" 20 | )] 21 | pub mod array; 22 | pub mod datatypes; 23 | pub mod error; 24 | -------------------------------------------------------------------------------- /python/geoarrow-core/python/geoarrow/rust/core/types.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | from typing import Literal, Union 4 | from .enums import CoordType, Dimension, Edges 5 | 6 | # The top-level import doesn't work for docs interlinking 7 | from pyproj.crs.crs import CRS 8 | 9 | CRSInput = Union[CRS, str, dict, int] 10 | """Acceptable input for the CRS parameter. 11 | 12 | This can be a `pyproj.CRS` object or anything that can be passed to 13 | `pyproj.CRS.from_user_input()`. 14 | """ 15 | 16 | IntFloat = Union[int, float] 17 | 18 | 19 | CoordTypeT = Literal["interleaved", "separated"] 20 | """Acceptable coord_type strings. 21 | """ 22 | 23 | DimensionT = Literal["XY", "XYZ", "XYM", "XYZM", "xy", "xyz", "xym", "xyzm"] 24 | """Acceptable dimension strings. 25 | """ 26 | 27 | EdgesT = Literal["andoyer", "karney", "spherical", "thomas", "vincenty"] 28 | """Acceptable edges strings. 29 | """ 30 | 31 | 32 | CoordTypeInput = Union[CoordType, CoordTypeT] 33 | """Acceptable coord_type input. 34 | """ 35 | 36 | DimensionInput = Union[Dimension, DimensionT] 37 | """Acceptable dimension input. 38 | """ 39 | 40 | EdgesInput = Union[Edges, EdgesT] 41 | """Acceptable edges input. 42 | """ 43 | -------------------------------------------------------------------------------- /rust/geoarrow-expr-geos/src/import/array/wkb.rs: -------------------------------------------------------------------------------- 1 | use arrow_array::OffsetSizeTrait; 2 | use geoarrow_array::array::GenericWkbArray; 3 | use geoarrow_array::builder::WkbBuilder; 4 | use geoarrow_schema::WkbType; 5 | use geoarrow_schema::error::GeoArrowResult; 6 | 7 | use crate::import::array::FromGEOS; 8 | use crate::import::scalar::GEOSGeometry; 9 | 10 | impl FromGEOS for WkbBuilder { 11 | type GeoArrowType = WkbType; 12 | 13 | fn from_geos( 14 | geoms: impl IntoIterator>, 15 | typ: Self::GeoArrowType, 16 | ) -> GeoArrowResult { 17 | let geoms = geoms 18 | .into_iter() 19 | .map(|geom| geom.map(GEOSGeometry::new)) 20 | .collect::>(); 21 | Self::from_nullable_geometries(&geoms, typ) 22 | } 23 | } 24 | 25 | impl FromGEOS for GenericWkbArray { 26 | type GeoArrowType = WkbType; 27 | 28 | fn from_geos( 29 | geoms: impl IntoIterator>, 30 | typ: Self::GeoArrowType, 31 | ) -> GeoArrowResult { 32 | Ok(WkbBuilder::from_geos(geoms, typ)?.finish()) 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /rust/geoarrow-old/src/io/geojson_lines/reader.rs: -------------------------------------------------------------------------------- 1 | use std::io::BufRead; 2 | 3 | use geoarrow_schema::{CoordType, Dimension}; 4 | use geozero::GeozeroDatasource; 5 | use geozero::geojson::GeoJsonLineReader; 6 | 7 | use crate::error::Result; 8 | use crate::io::geozero::array::GeometryStreamBuilder; 9 | use crate::io::geozero::table::{GeoTableBuilder, GeoTableBuilderOptions}; 10 | use crate::table::Table; 11 | 12 | /// Read a GeoJSON Lines file 13 | /// 14 | /// This expects a GeoJSON Feature on each line of a text file, with a newline character separating 15 | /// each Feature. 16 | pub fn read_geojson_lines(reader: R, batch_size: Option) -> Result { 17 | let mut geojson_line_reader = GeoJsonLineReader::new(reader); 18 | 19 | // TODO: set crs to epsg:4326? 20 | let options = GeoTableBuilderOptions::new( 21 | CoordType::Interleaved, 22 | true, 23 | batch_size, 24 | None, 25 | None, 26 | Default::default(), 27 | ); 28 | let mut geo_table = 29 | GeoTableBuilder::::new_with_options(Dimension::XY, options); 30 | geojson_line_reader.process(&mut geo_table)?; 31 | geo_table.finish() 32 | } 33 | -------------------------------------------------------------------------------- /rust/geoarrow-geojson/src/encoder/wkb.rs: -------------------------------------------------------------------------------- 1 | use arrow_array::OffsetSizeTrait; 2 | use arrow_json::Encoder; 3 | use geoarrow_array::GeoArrowArrayAccessor; 4 | use geoarrow_array::array::{GenericWkbArray, WkbViewArray}; 5 | 6 | use crate::encoder::geometry::encode_geometry; 7 | 8 | // An [Encoder] for [GenericWkbArray]. 9 | pub struct GenericWkbEncoder(GenericWkbArray); 10 | 11 | impl GenericWkbEncoder { 12 | pub fn new(array: GenericWkbArray) -> Self { 13 | Self(array) 14 | } 15 | } 16 | 17 | impl Encoder for GenericWkbEncoder { 18 | fn encode(&mut self, idx: usize, out: &mut Vec) { 19 | let geom = self.0.value(idx).unwrap(); 20 | encode_geometry(&geom, out); 21 | } 22 | } 23 | 24 | // An [Encoder] for [WkbViewArray]. 25 | pub struct WkbViewEncoder(WkbViewArray); 26 | 27 | impl WkbViewEncoder { 28 | pub fn new(array: WkbViewArray) -> Self { 29 | Self(array) 30 | } 31 | } 32 | 33 | impl Encoder for WkbViewEncoder { 34 | fn encode(&mut self, idx: usize, out: &mut Vec) { 35 | let geom = self.0.value(idx).unwrap(); 36 | encode_geometry(&geom, out); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /js/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "scripts": { 3 | "build": "FEATURES='--all-features' NAME='@geoarrow/geoarrow-wasm' bash ./scripts/build.sh", 4 | "build:test": "ENV='DEV' FEATURES='--all-features' bash ./scripts/build.sh", 5 | "build:geoparquet": "FEATURES='--no-default-features --features debug --features io_parquet --features io_parquet_async --features io_parquet_compressions' NAME='@geoarrow/geoparquet-wasm' bash ./scripts/build.sh", 6 | "build:flatgeobuf": "FEATURES='--no-default-features --features debug --features io_flatgeobuf' NAME='@geoarrow/flatgeobuf-wasm' bash ./scripts/build.sh", 7 | "docs:build": "typedoc", 8 | "docs:serve": "cd docs_build && http-server", 9 | "docs:publish": "gh-pages --dist docs_build --dest js/", 10 | "test": "vitest run" 11 | }, 12 | "devDependencies": { 13 | "@swc/core": "^1.3.83", 14 | "@swc/helpers": "^0.5.2", 15 | "@types/node": "^20.4.0", 16 | "apache-arrow": "^15.0.1", 17 | "arrow-js-ffi": "^0.4.1", 18 | "gh-pages": "^5.0.0", 19 | "http-server": "^14.1.1", 20 | "typedoc": "0.24.8", 21 | "typescript": "^4.6.2", 22 | "vitest": "^0.34.0" 23 | }, 24 | "volta": { 25 | "node": "20.4.0", 26 | "yarn": "3.3.1" 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /rust/geoarrow-array/src/geozero/export/scalar/multilinestring.rs: -------------------------------------------------------------------------------- 1 | use geo_traits::{LineStringTrait, MultiLineStringTrait}; 2 | use geozero::{GeomProcessor, GeozeroGeometry}; 3 | 4 | use super::process_coord; 5 | use crate::scalar::MultiLineString; 6 | 7 | pub(crate) fn process_multi_line_string( 8 | geom: &impl MultiLineStringTrait, 9 | geom_idx: usize, 10 | processor: &mut P, 11 | ) -> geozero::error::Result<()> { 12 | processor.multilinestring_begin(geom.num_line_strings(), geom_idx)?; 13 | 14 | for (line_idx, line) in geom.line_strings().enumerate() { 15 | processor.linestring_begin(false, line.num_coords(), line_idx)?; 16 | 17 | for (coord_idx, coord) in line.coords().enumerate() { 18 | process_coord(&coord, coord_idx, processor)?; 19 | } 20 | 21 | processor.linestring_end(false, line_idx)?; 22 | } 23 | 24 | processor.multilinestring_end(geom_idx)?; 25 | Ok(()) 26 | } 27 | 28 | impl GeozeroGeometry for MultiLineString<'_> { 29 | fn process_geom(&self, processor: &mut P) -> geozero::error::Result<()> 30 | where 31 | Self: Sized, 32 | { 33 | process_multi_line_string(self, 0, processor) 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /python/geoarrow-core/src/interop/geopandas/from_geopandas.rs: -------------------------------------------------------------------------------- 1 | use crate::interop::util::import_geopandas; 2 | use pyo3::PyAny; 3 | use pyo3::exceptions::PyValueError; 4 | use pyo3::intern; 5 | use pyo3::prelude::*; 6 | use pyo3::types::{PyDict, PyTuple}; 7 | use pyo3_arrow::PyTable; 8 | use pyo3_arrow::export::Arro3Table; 9 | use pyo3_geoarrow::PyGeoArrowResult; 10 | 11 | #[pyfunction] 12 | pub fn from_geopandas(py: Python, input: &Bound) -> PyGeoArrowResult { 13 | let geopandas_mod = import_geopandas(py)?; 14 | let geodataframe_class = geopandas_mod.getattr(intern!(py, "GeoDataFrame"))?; 15 | if !input.is_instance(&geodataframe_class)? { 16 | return Err(PyValueError::new_err("Expected GeoDataFrame input.").into()); 17 | } 18 | 19 | // Note: I got an error in test_write_native_multi_points in `from_geopandas` with the WKB 20 | // encoding 21 | let kwargs = PyDict::new(py); 22 | kwargs.set_item("geometry_encoding", "geoarrow")?; 23 | let table = input 24 | .call_method( 25 | intern!(py, "to_arrow"), 26 | PyTuple::new(py, std::iter::empty::())?, 27 | Some(&kwargs), 28 | )? 29 | .extract::()?; 30 | 31 | Ok(table.into()) 32 | } 33 | -------------------------------------------------------------------------------- /js/src/utils.rs: -------------------------------------------------------------------------------- 1 | use arrow_buffer::OffsetBuffer; 2 | #[cfg(feature = "console_error_panic_hook")] 3 | use wasm_bindgen::prelude::*; 4 | 5 | #[cfg(feature = "console_error_panic_hook")] 6 | #[wasm_bindgen] 7 | pub fn set_panic_hook() { 8 | // When the `console_error_panic_hook` feature is enabled, we can call the 9 | // `set_panic_hook` function at least once during initialization, and then 10 | // we will get better error messages if our code ever panics. 11 | // 12 | // For more details see 13 | // https://github.com/rustwasm/console_error_panic_hook#readme 14 | console_error_panic_hook::set_once(); 15 | } 16 | 17 | /// Convert vec to OffsetsBuffer 18 | pub fn vec_to_offsets(v: Vec) -> OffsetBuffer { 19 | unsafe { OffsetBuffer::new_unchecked(v.into()) } 20 | } 21 | 22 | // A macro to provide `println!(..)`-style syntax for `console.log` logging. 23 | #[cfg(target_arch = "wasm32")] 24 | #[macro_export] 25 | macro_rules! log { 26 | ( $( $t:tt )* ) => { 27 | web_sys::console::log_1(&format!( $( $t )* ).into()); 28 | } 29 | } 30 | 31 | #[cfg(not(target_arch = "wasm32"))] 32 | #[macro_export] 33 | macro_rules! log { 34 | ( $( $t:tt )* ) => { 35 | println!("LOG - {}", format!( $( $t )* )); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /js/tests/js/example.test.ts: -------------------------------------------------------------------------------- 1 | import * as geoarrow from "../../pkg/node"; 2 | import { parseField, parseVector } from "arrow-js-ffi"; 3 | import { it } from "vitest"; 4 | 5 | geoarrow.set_panic_hook(); 6 | 7 | const WASM_MEMORY = geoarrow.wasmMemory(); 8 | 9 | it("hello world", () => { 10 | // let xs = new Float64Array([1, 2, 3, 4]); 11 | // let ys = new Float64Array([5, 6, 7, 8]); 12 | // let separatedCoords = new geoarrow.SeparatedCoordBuffer(xs, ys); 13 | // let coords = geoarrow.CoordBuffer.fromSeparatedCoords(separatedCoords); 14 | // let pointArray = new geoarrow.PointData(coords); 15 | 16 | // let xOffset = new Float64Array([1, 2, 3, 4]); 17 | // let yOffset = new Float64Array([1, 2, 3, 4]); 18 | 19 | // let translatedPoints = pointArray.translate( 20 | // geoarrow.BroadcastableFloat.fromArray(xOffset), 21 | // geoarrow.BroadcastableFloat.fromArray(yOffset) 22 | // ); 23 | 24 | // let ffiArray = translatedPoints.toFFI(); 25 | // const field = parseField(WASM_MEMORY.buffer, ffiArray.field_addr()); 26 | // const vector = parseVector( 27 | // WASM_MEMORY.buffer, 28 | // ffiArray.array_addr(), 29 | // field.type 30 | // ); 31 | 32 | // console.log(field.metadata); 33 | // console.log(vector.getChildAt(0)?.toArray()); 34 | }); 35 | -------------------------------------------------------------------------------- /rust/geoarrow-expr-geo/src/centroid.rs: -------------------------------------------------------------------------------- 1 | use geo::Centroid; 2 | use geoarrow_array::array::PointArray; 3 | use geoarrow_array::builder::PointBuilder; 4 | use geoarrow_array::{GeoArrowArray, GeoArrowArrayAccessor, downcast_geoarrow_array}; 5 | use geoarrow_schema::error::GeoArrowResult; 6 | use geoarrow_schema::{CoordType, Dimension, PointType}; 7 | 8 | use crate::util::to_geo::geometry_to_geo; 9 | 10 | pub fn centroid(array: &dyn GeoArrowArray, coord_type: CoordType) -> GeoArrowResult { 11 | downcast_geoarrow_array!(array, _centroid_impl, coord_type) 12 | } 13 | 14 | fn _centroid_impl<'a>( 15 | array: &'a impl GeoArrowArrayAccessor<'a>, 16 | coord_type: CoordType, 17 | ) -> GeoArrowResult { 18 | let typ = PointType::new(Dimension::XY, array.data_type().metadata().clone()) 19 | .with_coord_type(coord_type); 20 | let mut builder = PointBuilder::with_capacity(typ, array.len()); 21 | 22 | for item in array.iter() { 23 | if let Some(geom) = item { 24 | let geo_geom = geometry_to_geo(&geom?)?; 25 | let centroid = geo_geom.centroid(); 26 | builder.push_point(centroid.as_ref()); 27 | } else { 28 | builder.push_null(); 29 | } 30 | } 31 | 32 | Ok(builder.finish()) 33 | } 34 | -------------------------------------------------------------------------------- /rust/geoarrow-old/benches/from_geo.rs: -------------------------------------------------------------------------------- 1 | use geo::polygon; 2 | 3 | use criterion::{Criterion, criterion_group, criterion_main}; 4 | use geoarrow::array::{PolygonArray, PolygonBuilder}; 5 | use geoarrow_schema::{CoordType, Dimension}; 6 | 7 | fn create_data() -> Vec { 8 | // An L shape 9 | // https://github.com/georust/geo/blob/7cb7d0ffa6bf1544c5ca9922bd06100c36f815d7/README.md?plain=1#L40 10 | let poly = polygon![ 11 | (x: 0.0, y: 0.0), 12 | (x: 4.0, y: 0.0), 13 | (x: 4.0, y: 1.0), 14 | (x: 1.0, y: 1.0), 15 | (x: 1.0, y: 4.0), 16 | (x: 0.0, y: 4.0), 17 | (x: 0.0, y: 0.0), 18 | ]; 19 | let v = vec![poly; 1000]; 20 | v 21 | } 22 | 23 | pub fn criterion_benchmark(c: &mut Criterion) { 24 | let data = create_data(); 25 | 26 | c.bench_function("convert Vec to PolygonArray", |b| { 27 | b.iter(|| { 28 | let mut_arr = PolygonBuilder::from_polygons( 29 | &data, 30 | Dimension::XY, 31 | CoordType::default_interleaved(), 32 | Default::default(), 33 | ); 34 | let _arr: PolygonArray = mut_arr.into(); 35 | }) 36 | }); 37 | } 38 | 39 | criterion_group!(benches, criterion_benchmark); 40 | criterion_main!(benches); 41 | -------------------------------------------------------------------------------- /rust/geoarrow-geojson/README.md: -------------------------------------------------------------------------------- 1 | # geoarrow-geojson 2 | 3 | This crate provides two types of writers. 4 | 5 | - [`GeoJsonWriter`][crate::writer::GeoJsonWriter] streams Arrow record batches as a GeoJSON FeatureCollection, writing the collection header once and appending each batch of features. Use it when you need a single GeoJSON document containing all features. 6 | 7 | Example output (formatted for readability): 8 | 9 | ```json 10 | { 11 | "type": "FeatureCollection", 12 | "features": [ 13 | { 14 | "type": "Feature", 15 | "geometry": { "type": "Point", "coordinates": [30, 10] }, 16 | "properties": { "count": 10 } 17 | }, 18 | { 19 | "type": "Feature", 20 | "geometry": { "type": "Point", "coordinates": [40, 20] }, 21 | "properties": { "count": 20 } 22 | } 23 | ] 24 | } 25 | ``` 26 | 27 | - [`GeoJsonLinesWriter`][crate::writer::GeoJsonWriter] writes each feature as a standalone GeoJSON object separated by newlines, making it suitable for line-delimited sinks and streaming pipelines. 28 | 29 | Example output: 30 | 31 | ```json 32 | {"type":"Feature","geometry":{"type":"Point","coordinates":[30,10]},"properties":{"count":10}} 33 | {"type":"Feature","geometry":{"type":"Point","coordinates":[40,20]},"properties":{"count":20}} 34 | ``` 35 | -------------------------------------------------------------------------------- /rust/geoarrow-array/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "geoarrow-array" 3 | version = { workspace = true } 4 | authors = { workspace = true } 5 | edition = { workspace = true } 6 | license = { workspace = true } 7 | repository = { workspace = true } 8 | description = "GeoArrow array definitions." 9 | categories = { workspace = true } 10 | rust-version = { workspace = true } 11 | 12 | [features] 13 | geozero = ["dep:geozero", "dep:arrow-json"] 14 | # Include test data in public API 15 | # TODO: Remove geo-types here 16 | test-data = ["dep:geoarrow-test", "dep:geo-types"] 17 | 18 | [dependencies] 19 | arrow-array = { workspace = true } 20 | arrow-buffer = { workspace = true } 21 | arrow-json = { workspace = true, optional = true } 22 | arrow-schema = { workspace = true } 23 | geo-traits = { workspace = true } 24 | geo-types = { workspace = true, optional = true } 25 | geoarrow-schema = { workspace = true } 26 | geoarrow-test = { workspace = true, optional = true } 27 | geozero = { workspace = true, optional = true } 28 | num-traits = { workspace = true } 29 | wkb = { workspace = true } 30 | wkt = { workspace = true } 31 | 32 | [dev-dependencies] 33 | geo = { workspace = true } 34 | geo-types = { workspace = true } 35 | geoarrow-test = { workspace = true } 36 | wkt = { workspace = true } 37 | 38 | [package.metadata.docs.rs] 39 | all-features = true 40 | -------------------------------------------------------------------------------- /rust/geoarrow-old/benches/area.rs: -------------------------------------------------------------------------------- 1 | use criterion::{Criterion, criterion_group, criterion_main}; 2 | use geoarrow::algorithm::geo::Area; 3 | use geoarrow::array::{AsChunkedNativeArray, MultiPolygonArray}; 4 | use geoarrow::io::flatgeobuf::FlatGeobufReaderBuilder; 5 | use geoarrow::table::Table; 6 | use std::fs::File; 7 | 8 | fn load_file() -> MultiPolygonArray { 9 | let file = File::open("fixtures/flatgeobuf/countries.fgb").unwrap(); 10 | let reader_builder = FlatGeobufReaderBuilder::open(file).unwrap(); 11 | let record_batch_reader = reader_builder.read(Default::default()).unwrap(); 12 | let table = 13 | Table::try_from(Box::new(record_batch_reader) as Box) 14 | .unwrap(); 15 | 16 | table 17 | .geometry_column(None) 18 | .unwrap() 19 | .as_ref() 20 | .as_multi_polygon() 21 | .chunks() 22 | .first() 23 | .unwrap() 24 | .clone() 25 | } 26 | 27 | fn criterion_benchmark(c: &mut Criterion) { 28 | let data = load_file(); 29 | 30 | c.bench_function("area", |bencher| { 31 | bencher.iter(|| { 32 | criterion::black_box(criterion::black_box(&data).signed_area()); 33 | }); 34 | }); 35 | } 36 | 37 | criterion_group!(benches, criterion_benchmark); 38 | criterion_main!(benches); 39 | -------------------------------------------------------------------------------- /rust/pyo3-geoarrow/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "pyo3-geoarrow" 3 | version = { workspace = true } 4 | authors = { workspace = true } 5 | edition = { workspace = true } 6 | description = "GeoArrow integration for pyo3." 7 | readme = "README.md" 8 | repository = { workspace = true } 9 | license = { workspace = true } 10 | keywords = ["python", "arrow"] 11 | categories = [] 12 | rust-version = { workspace = true } 13 | 14 | [features] 15 | default = ["geozero", "geojson"] 16 | geozero = ["dep:geozero", "geoarrow-array/geozero"] 17 | 18 | [dependencies] 19 | arrow-array = { workspace = true } 20 | arrow-buffer = { workspace = true } 21 | arrow-cast = { workspace = true } 22 | arrow-schema = { workspace = true } 23 | geo-traits = { workspace = true } 24 | geo-types = { workspace = true } 25 | geoarrow-array = { workspace = true } 26 | geoarrow-cast = { workspace = true } 27 | geoarrow-schema = { workspace = true } 28 | geoarrow-expr-geo = { workspace = true } 29 | geojson = { workspace = true, optional = true } 30 | geozero = { workspace = true, optional = true } 31 | pyo3 = { workspace = true, features = ["chrono", "indexmap"] } 32 | pyo3-arrow = { workspace = true } 33 | serde_json = { workspace = true } 34 | url = { workspace = true } 35 | 36 | [lib] 37 | crate-type = ["rlib"] 38 | 39 | [package.metadata.docs.rs] 40 | all-features = true 41 | -------------------------------------------------------------------------------- /rust/geoarrow-expr-geo/src/convex_hull.rs: -------------------------------------------------------------------------------- 1 | use geo::ConvexHull; 2 | use geoarrow_array::array::PolygonArray; 3 | use geoarrow_array::builder::PolygonBuilder; 4 | use geoarrow_array::{GeoArrowArray, GeoArrowArrayAccessor, downcast_geoarrow_array}; 5 | use geoarrow_schema::error::GeoArrowResult; 6 | use geoarrow_schema::{CoordType, Dimension, PolygonType}; 7 | 8 | use crate::util::to_geo::geometry_to_geo; 9 | 10 | pub fn convex_hull( 11 | array: &dyn GeoArrowArray, 12 | coord_type: CoordType, 13 | ) -> GeoArrowResult { 14 | downcast_geoarrow_array!(array, convex_hull_impl, coord_type) 15 | } 16 | 17 | fn convex_hull_impl<'a>( 18 | array: &'a impl GeoArrowArrayAccessor<'a>, 19 | coord_type: CoordType, 20 | ) -> GeoArrowResult { 21 | let typ = PolygonType::new(Dimension::XY, array.data_type().metadata().clone()) 22 | .with_coord_type(coord_type); 23 | let mut builder = PolygonBuilder::new(typ); 24 | 25 | for item in array.iter() { 26 | if let Some(geom) = item { 27 | let geo_geom = geometry_to_geo(&geom?)?; 28 | let poly = geo_geom.convex_hull(); 29 | builder.push_polygon(Some(&poly))?; 30 | } else { 31 | builder.push_polygon(None::.as_ref())?; 32 | } 33 | } 34 | 35 | Ok(builder.finish()) 36 | } 37 | -------------------------------------------------------------------------------- /rust/geoarrow-expr-geo/src/interior_point.rs: -------------------------------------------------------------------------------- 1 | use geo::InteriorPoint; 2 | use geoarrow_array::array::PointArray; 3 | use geoarrow_array::builder::PointBuilder; 4 | use geoarrow_array::{GeoArrowArray, GeoArrowArrayAccessor, downcast_geoarrow_array}; 5 | use geoarrow_schema::error::GeoArrowResult; 6 | use geoarrow_schema::{CoordType, Dimension, PointType}; 7 | 8 | use crate::util::to_geo::geometry_to_geo; 9 | 10 | pub fn interior_point( 11 | array: &dyn GeoArrowArray, 12 | coord_type: CoordType, 13 | ) -> GeoArrowResult { 14 | downcast_geoarrow_array!(array, _interior_point_impl, coord_type) 15 | } 16 | 17 | fn _interior_point_impl<'a>( 18 | array: &'a impl GeoArrowArrayAccessor<'a>, 19 | coord_type: CoordType, 20 | ) -> GeoArrowResult { 21 | let typ = PointType::new(Dimension::XY, array.data_type().metadata().clone()) 22 | .with_coord_type(coord_type); 23 | let mut builder = PointBuilder::with_capacity(typ, array.len()); 24 | 25 | for item in array.iter() { 26 | if let Some(geom) = item { 27 | let geo_geom = geometry_to_geo(&geom?)?; 28 | let interior_point = geo_geom.interior_point(); 29 | builder.push_point(interior_point.as_ref()); 30 | } else { 31 | builder.push_null(); 32 | } 33 | } 34 | 35 | Ok(builder.finish()) 36 | } 37 | -------------------------------------------------------------------------------- /python/geoarrow-compute/src/algorithm/geo/skew.rs: -------------------------------------------------------------------------------- 1 | use crate::ffi::from_python::AnyNativeInput; 2 | use crate::util::{return_chunked_geometry_array, return_geometry_array}; 3 | use geoarrow::algorithm::geo::Skew; 4 | use geoarrow::chunked_array::ChunkedNativeArrayDyn; 5 | use geoarrow::error::GeoArrowError; 6 | use pyo3::prelude::*; 7 | use pyo3_geoarrow::PyGeoArrowResult; 8 | 9 | #[pyfunction] 10 | #[pyo3(signature = (geom, xs=0.0, ys=0.0))] 11 | pub fn skew(py: Python, geom: AnyNativeInput, xs: f64, ys: f64) -> PyGeoArrowResult { 12 | match geom { 13 | AnyNativeInput::Array(arr) => { 14 | let out = arr.as_ref().skew_xy(&xs.into(), &ys.into())?; 15 | return_geometry_array(py, out) 16 | } 17 | AnyNativeInput::Chunked(chunked) => { 18 | let out = chunked 19 | .as_ref() 20 | .geometry_chunks() 21 | .iter() 22 | .map(|chunk| chunk.as_ref().skew_xy(&xs.into(), &ys.into())) 23 | .collect::, GeoArrowError>>()?; 24 | let out_refs = out.iter().map(|x| x.as_ref()).collect::>(); 25 | return_chunked_geometry_array( 26 | py, 27 | ChunkedNativeArrayDyn::from_geoarrow_chunks(out_refs.as_slice())?.into_inner(), 28 | ) 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /python/Cargo.toml: -------------------------------------------------------------------------------- 1 | [workspace] 2 | members = ["geoarrow-compute", "geoarrow-core", "geoarrow-io"] 3 | resolver = "2" 4 | 5 | [workspace.package] 6 | authors = ["Kyle Barron "] 7 | version = "0.6.1" 8 | edition = "2024" 9 | homepage = "https://geoarrow.org/geoarrow-rs/" 10 | repository = "https://github.com/geoarrow/geoarrow-rs" 11 | license = "MIT OR Apache-2.0" 12 | keywords = ["python", "arrow", "geospatial"] 13 | categories = ["wasm", "science::geo"] 14 | rust-version = "1.85" 15 | 16 | [workspace.dependencies] 17 | arrow = "57" 18 | arrow-array = "57" 19 | arrow-buffer = "57" 20 | arrow-schema = "57" 21 | flatgeobuf = { version = "5.0", default-features = false } 22 | geo-traits = "0.3" 23 | geoarrow-array = { path = "../rust/geoarrow-array" } 24 | geoarrow-cast = { path = "../rust/geoarrow-cast" } 25 | geoarrow-flatgeobuf = { path = "../rust/geoarrow-flatgeobuf" } 26 | geoarrow-schema = { path = "../rust/geoarrow-schema" } 27 | geoparquet = { path = "../rust/geoparquet" } 28 | geozero = "0.14" 29 | http-range-client = { version = "0.9.0", default-features = false } 30 | indexmap = "2.5.0" 31 | numpy = "0.27" 32 | object_store = "0.12" 33 | parquet = "57" 34 | pyo3 = { version = "0.27", features = ["hashbrown", "serde", "anyhow"] } 35 | pyo3-arrow = "0.15" 36 | pyo3-geoarrow = { path = "../rust/pyo3-geoarrow" } 37 | serde_json = "1" 38 | thiserror = "1" 39 | -------------------------------------------------------------------------------- /rust/geoarrow-array/src/geozero/export/array/linestring.rs: -------------------------------------------------------------------------------- 1 | use geozero::{GeomProcessor, GeozeroGeometry}; 2 | 3 | use crate::array::LineStringArray; 4 | use crate::geozero::export::scalar::process_line_string; 5 | use crate::{GeoArrowArray, GeoArrowArrayAccessor}; 6 | 7 | impl GeozeroGeometry for LineStringArray { 8 | fn process_geom(&self, processor: &mut P) -> geozero::error::Result<()> 9 | where 10 | Self: Sized, 11 | { 12 | let num_geometries = self.len(); 13 | processor.geometrycollection_begin(num_geometries, 0)?; 14 | 15 | for geom_idx in 0..num_geometries { 16 | process_line_string(&self.value(geom_idx).unwrap(), geom_idx, processor)?; 17 | } 18 | 19 | processor.geometrycollection_end(num_geometries - 1)?; 20 | Ok(()) 21 | } 22 | } 23 | 24 | #[cfg(test)] 25 | mod test { 26 | use geoarrow_schema::CoordType; 27 | use geozero::ToWkt; 28 | 29 | use crate::test::linestring::ls_array; 30 | 31 | #[test] 32 | fn geozero_process_geom() -> geozero::error::Result<()> { 33 | let arr = ls_array(CoordType::Interleaved); 34 | let wkt = ToWkt::to_wkt(&arr)?; 35 | let expected = "GEOMETRYCOLLECTION(LINESTRING(0 1,1 2),LINESTRING EMPTY,LINESTRING(3 4,5 6),LINESTRING EMPTY)"; 36 | assert_eq!(wkt, expected); 37 | Ok(()) 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /rust/geoarrow-array/src/test/point.rs: -------------------------------------------------------------------------------- 1 | use geo_types::{Point, point}; 2 | use geoarrow_schema::{CoordType, Dimension, PointType}; 3 | use geoarrow_test::raw; 4 | 5 | use crate::array::PointArray; 6 | use crate::builder::PointBuilder; 7 | 8 | pub(crate) fn p0() -> Point { 9 | point!( 10 | x: 0., y: 1. 11 | ) 12 | } 13 | 14 | pub(crate) fn p1() -> Point { 15 | point!( 16 | x: 1., y: 2. 17 | ) 18 | } 19 | 20 | pub(crate) fn p2() -> Point { 21 | point!( 22 | x: 2., y: 3. 23 | ) 24 | } 25 | 26 | pub(crate) fn point_array(coord_type: CoordType) -> PointArray { 27 | let geoms = [Some(p0()), Some(p1()), None, Some(p2())]; 28 | let typ = PointType::new(Dimension::XY, Default::default()).with_coord_type(coord_type); 29 | PointBuilder::from_nullable_points(geoms.iter().map(|x| x.as_ref()), typ).finish() 30 | } 31 | 32 | pub fn array(coord_type: CoordType, dim: Dimension) -> PointArray { 33 | let typ = PointType::new(dim, Default::default()).with_coord_type(coord_type); 34 | let geoms = match dim { 35 | Dimension::XY => raw::point::xy::geoms(), 36 | Dimension::XYZ => raw::point::xyz::geoms(), 37 | Dimension::XYM => raw::point::xym::geoms(), 38 | Dimension::XYZM => raw::point::xyzm::geoms(), 39 | }; 40 | PointBuilder::from_nullable_points(geoms.iter().map(|x| x.as_ref()), typ).finish() 41 | } 42 | -------------------------------------------------------------------------------- /rust/geoarrow-expr-geos/src/export/scalar/geometry.rs: -------------------------------------------------------------------------------- 1 | use geo_traits::GeometryTrait; 2 | 3 | use crate::export::scalar::geometrycollection::to_geos_geometry_collection; 4 | use crate::export::scalar::linestring::to_geos_line_string; 5 | use crate::export::scalar::multilinestring::to_geos_multi_line_string; 6 | use crate::export::scalar::multipoint::to_geos_multi_point; 7 | use crate::export::scalar::multipolygon::to_geos_multi_polygon; 8 | use crate::export::scalar::point::to_geos_point; 9 | use crate::export::scalar::polygon::to_geos_polygon; 10 | 11 | pub fn to_geos_geometry( 12 | geometry: &impl GeometryTrait, 13 | ) -> std::result::Result { 14 | use geo_traits::GeometryType::*; 15 | 16 | match geometry.as_type() { 17 | Point(g) => to_geos_point(g), 18 | LineString(g) => to_geos_line_string(g), 19 | Polygon(g) => to_geos_polygon(g), 20 | MultiPoint(g) => to_geos_multi_point(g), 21 | MultiLineString(g) => to_geos_multi_line_string(g), 22 | MultiPolygon(g) => to_geos_multi_polygon(g), 23 | GeometryCollection(g) => to_geos_geometry_collection(g), 24 | Rect(_) => panic!("Unsupported rect in conversion to GEOS"), 25 | Triangle(_) => panic!("Unsupported triangle in conversion to GEOS"), 26 | Line(_) => panic!("Unsupported Line in conversion to GEOS"), 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /rust/geoarrow-old/src/algorithm/broadcasting/point.rs: -------------------------------------------------------------------------------- 1 | use crate::array::PointArray; 2 | use crate::scalar::Point; 3 | 4 | /// An enum over a [`Point`] scalar and [`PointArray`] array. 5 | /// 6 | /// [`IntoIterator`] is implemented for this, where it will iterate over the `Array` variant 7 | /// normally but will iterate over the `Scalar` variant forever. 8 | #[derive(Debug)] 9 | pub enum BroadcastablePoint<'a> { 10 | Scalar(Point<'a>), 11 | Array(PointArray), 12 | } 13 | 14 | pub enum BroadcastPointIter<'a> { 15 | Scalar(Point<'a>), 16 | Array(PointArrayIter<'a>), 17 | } 18 | 19 | impl<'a> IntoIterator for &'a BroadcastablePoint<'a> { 20 | type Item = Option>; 21 | type IntoIter = BroadcastPointIter<'a>; 22 | 23 | fn into_iter(self) -> Self::IntoIter { 24 | match self { 25 | BroadcastablePoint::Array(arr) => BroadcastPointIter::Array(PointArrayIter::new(arr)), 26 | BroadcastablePoint::Scalar(val) => BroadcastPointIter::Scalar(val.to_owned()), 27 | } 28 | } 29 | } 30 | 31 | impl<'a> Iterator for BroadcastPointIter<'a> { 32 | type Item = Option>; 33 | 34 | fn next(&mut self) -> Option { 35 | match self { 36 | BroadcastPointIter::Array(arr) => arr.next(), 37 | BroadcastPointIter::Scalar(val) => Some(Some(val.to_owned())), 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /rust/geoarrow-expr-geo/src/minimum_rotated_rect.rs: -------------------------------------------------------------------------------- 1 | use geo::MinimumRotatedRect; 2 | use geoarrow_array::array::PolygonArray; 3 | use geoarrow_array::builder::PolygonBuilder; 4 | use geoarrow_array::{GeoArrowArray, GeoArrowArrayAccessor, downcast_geoarrow_array}; 5 | use geoarrow_schema::error::GeoArrowResult; 6 | use geoarrow_schema::{CoordType, Dimension, PolygonType}; 7 | 8 | use crate::util::to_geo::geometry_to_geo; 9 | 10 | pub fn minimum_rotated_rect( 11 | array: &dyn GeoArrowArray, 12 | coord_type: CoordType, 13 | ) -> GeoArrowResult { 14 | downcast_geoarrow_array!(array, minimum_rotated_rect_impl, coord_type) 15 | } 16 | 17 | fn minimum_rotated_rect_impl<'a>( 18 | array: &'a impl GeoArrowArrayAccessor<'a>, 19 | coord_type: CoordType, 20 | ) -> GeoArrowResult { 21 | let typ = PolygonType::new(Dimension::XY, array.data_type().metadata().clone()) 22 | .with_coord_type(coord_type); 23 | let mut builder = PolygonBuilder::new(typ); 24 | 25 | for item in array.iter() { 26 | if let Some(geom) = item { 27 | let geo_geom = geometry_to_geo(&geom?)?; 28 | let poly = geo_geom.minimum_rotated_rect(); 29 | builder.push_polygon(poly.as_ref())?; 30 | } else { 31 | builder.push_polygon(None::.as_ref())?; 32 | } 33 | } 34 | 35 | Ok(builder.finish()) 36 | } 37 | -------------------------------------------------------------------------------- /rust/geoarrow-array/src/test/linestring.rs: -------------------------------------------------------------------------------- 1 | use geo_types::{LineString, line_string}; 2 | use geoarrow_schema::{CoordType, Dimension, LineStringType}; 3 | use geoarrow_test::raw; 4 | 5 | use crate::array::LineStringArray; 6 | use crate::builder::LineStringBuilder; 7 | 8 | pub(crate) fn ls0() -> LineString { 9 | line_string![ 10 | (x: 0., y: 1.), 11 | (x: 1., y: 2.) 12 | ] 13 | } 14 | 15 | pub(crate) fn ls1() -> LineString { 16 | line_string![ 17 | (x: 3., y: 4.), 18 | (x: 5., y: 6.) 19 | ] 20 | } 21 | 22 | pub(crate) fn ls_array(coord_type: CoordType) -> LineStringArray { 23 | let geoms = vec![Some(ls0()), None, Some(ls1()), None]; 24 | let typ = LineStringType::new(Dimension::XY, Default::default()).with_coord_type(coord_type); 25 | LineStringBuilder::from_nullable_line_strings(&geoms, typ).finish() 26 | } 27 | 28 | pub fn array(coord_type: CoordType, dim: Dimension) -> LineStringArray { 29 | let typ = LineStringType::new(dim, Default::default()).with_coord_type(coord_type); 30 | let geoms = match dim { 31 | Dimension::XY => raw::linestring::xy::geoms(), 32 | Dimension::XYZ => raw::linestring::xyz::geoms(), 33 | Dimension::XYM => raw::linestring::xym::geoms(), 34 | Dimension::XYZM => raw::linestring::xyzm::geoms(), 35 | }; 36 | LineStringBuilder::from_nullable_line_strings(&geoms, typ).finish() 37 | } 38 | -------------------------------------------------------------------------------- /rust/geoarrow-test/src/raw/point.rs: -------------------------------------------------------------------------------- 1 | use wkt::wkt; 2 | 3 | pub mod xy { 4 | use super::*; 5 | 6 | pub fn geoms() -> Vec>> { 7 | vec![ 8 | Some(wkt! { POINT (30. 10.) }), 9 | Some(wkt! { POINT (40. 20.) }), 10 | None, 11 | Some(wkt! { POINT EMPTY }), 12 | ] 13 | } 14 | } 15 | 16 | pub mod xyz { 17 | use super::*; 18 | 19 | pub fn geoms() -> Vec>> { 20 | vec![ 21 | Some(wkt! { POINT Z (30. 10. 40.) }), 22 | Some(wkt! { POINT Z (40. 20. 60.) }), 23 | None, 24 | Some(wkt! { POINT Z EMPTY }), 25 | ] 26 | } 27 | } 28 | 29 | pub mod xym { 30 | use super::*; 31 | 32 | pub fn geoms() -> Vec>> { 33 | vec![ 34 | Some(wkt! { POINT M (30. 10. 300.) }), 35 | Some(wkt! { POINT M (40. 20. 800.) }), 36 | None, 37 | Some(wkt! { POINT M EMPTY }), 38 | ] 39 | } 40 | } 41 | 42 | pub mod xyzm { 43 | use super::*; 44 | 45 | pub fn geoms() -> Vec>> { 46 | vec![ 47 | Some(wkt! { POINT ZM (30. 10. 40. 300.) }), 48 | Some(wkt! { POINT ZM (40. 20. 60. 800.) }), 49 | None, 50 | Some(wkt! { POINT ZM EMPTY }), 51 | ] 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /python/geoarrow-io/python/geoarrow/rust/io/_io.pyi: -------------------------------------------------------------------------------- 1 | from ._flatgeobuf import read_flatgeobuf as read_flatgeobuf 2 | from ._flatgeobuf import read_flatgeobuf_async as read_flatgeobuf_async 3 | from ._flatgeobuf import write_flatgeobuf as write_flatgeobuf 4 | from ._parquet import GeoParquetDataset as GeoParquetDataset 5 | from ._parquet import GeoParquetFile as GeoParquetFile 6 | from ._parquet import GeoParquetWriter as GeoParquetWriter 7 | from ._parquet import PathInput as PathInput 8 | 9 | # from ._csv import read_csv as read_csv 10 | # from ._csv import write_csv as write_csv 11 | # from ._geojson import read_geojson as read_geojson 12 | # from ._geojson import read_geojson_lines as read_geojson_lines 13 | # from ._geojson import write_geojson as write_geojson 14 | # from ._geojson import write_geojson_lines as write_geojson_lines 15 | # from ._parquet import read_parquet as read_parquet 16 | # from ._parquet import read_parquet_async as read_parquet_async 17 | # from ._parquet import write_parquet as write_parquet 18 | # from ._postgis import read_postgis as read_postgis 19 | # from ._postgis import read_postgis_async as read_postgis_async 20 | # from ._shapefile import read_shapefile as read_shapefile 21 | 22 | __all__ = [ 23 | "GeoParquetDataset", 24 | "GeoParquetFile", 25 | "GeoParquetWriter", 26 | "PathInput", 27 | "read_flatgeobuf_async", 28 | "read_flatgeobuf", 29 | "write_flatgeobuf", 30 | ] 31 | -------------------------------------------------------------------------------- /python/geoarrow-compute/src/algorithm/geo/scale.rs: -------------------------------------------------------------------------------- 1 | use crate::ffi::from_python::AnyNativeInput; 2 | use crate::util::{return_chunked_geometry_array, return_geometry_array}; 3 | use geoarrow::algorithm::geo::Scale; 4 | use geoarrow::chunked_array::ChunkedNativeArrayDyn; 5 | use geoarrow::error::GeoArrowError; 6 | use pyo3::prelude::*; 7 | use pyo3_geoarrow::PyGeoArrowResult; 8 | 9 | #[pyfunction] 10 | #[pyo3(signature = (geom, xfact=1.0, yfact=1.0))] 11 | pub fn scale( 12 | py: Python, 13 | geom: AnyNativeInput, 14 | xfact: f64, 15 | yfact: f64, 16 | ) -> PyGeoArrowResult { 17 | match geom { 18 | AnyNativeInput::Array(arr) => { 19 | let out = arr.as_ref().scale_xy(&xfact.into(), &yfact.into())?; 20 | return_geometry_array(py, out) 21 | } 22 | AnyNativeInput::Chunked(chunked) => { 23 | let out = chunked 24 | .as_ref() 25 | .geometry_chunks() 26 | .iter() 27 | .map(|chunk| chunk.as_ref().scale_xy(&xfact.into(), &yfact.into())) 28 | .collect::, GeoArrowError>>()?; 29 | let out_refs = out.iter().map(|x| x.as_ref()).collect::>(); 30 | return_chunked_geometry_array( 31 | py, 32 | ChunkedNativeArrayDyn::from_geoarrow_chunks(out_refs.as_slice())?.into_inner(), 33 | ) 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /python/geoarrow-compute/src/algorithm/geo/translate.rs: -------------------------------------------------------------------------------- 1 | use crate::ffi::from_python::AnyNativeInput; 2 | use crate::util::{return_chunked_geometry_array, return_geometry_array}; 3 | use geoarrow::algorithm::geo::Translate; 4 | use geoarrow::chunked_array::ChunkedNativeArrayDyn; 5 | use geoarrow::error::GeoArrowError; 6 | use pyo3::prelude::*; 7 | use pyo3_geoarrow::PyGeoArrowResult; 8 | 9 | #[pyfunction] 10 | #[pyo3(signature = (geom, xoff=0.0, yoff=0.0))] 11 | pub(crate) fn translate( 12 | py: Python, 13 | geom: AnyNativeInput, 14 | xoff: f64, 15 | yoff: f64, 16 | ) -> PyGeoArrowResult { 17 | match geom { 18 | AnyNativeInput::Array(arr) => { 19 | let out = arr.as_ref().translate(&xoff.into(), &yoff.into())?; 20 | return_geometry_array(py, out) 21 | } 22 | AnyNativeInput::Chunked(chunked) => { 23 | let out = chunked 24 | .as_ref() 25 | .geometry_chunks() 26 | .iter() 27 | .map(|chunk| chunk.as_ref().translate(&xoff.into(), &yoff.into())) 28 | .collect::, GeoArrowError>>()?; 29 | let out_refs = out.iter().map(|x| x.as_ref()).collect::>(); 30 | return_chunked_geometry_array( 31 | py, 32 | ChunkedNativeArrayDyn::from_geoarrow_chunks(out_refs.as_slice())?.into_inner(), 33 | ) 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /rust/geoarrow-old/src/io/geojson/reader.rs: -------------------------------------------------------------------------------- 1 | use geoarrow_schema::{CoordType, Dimension}; 2 | use geozero::GeozeroDatasource; 3 | use geozero::geojson::GeoJsonReader; 4 | use std::io::Read; 5 | 6 | use crate::error::Result; 7 | use crate::io::geozero::array::GeometryStreamBuilder; 8 | use crate::io::geozero::table::{GeoTableBuilder, GeoTableBuilderOptions}; 9 | use crate::table::Table; 10 | 11 | /// Read a GeoJSON file to a Table. 12 | pub fn read_geojson(reader: R, batch_size: Option) -> Result
{ 13 | let mut geojson = GeoJsonReader(reader); 14 | // TODO: set CRS to epsg:4326? 15 | let options = GeoTableBuilderOptions::new( 16 | CoordType::Interleaved, 17 | true, 18 | batch_size, 19 | None, 20 | None, 21 | Default::default(), 22 | ); 23 | let mut geo_table = 24 | GeoTableBuilder::::new_with_options(Dimension::XY, options); 25 | geojson.process(&mut geo_table)?; 26 | geo_table.finish() 27 | } 28 | 29 | #[cfg(test)] 30 | mod test { 31 | use std::fs::File; 32 | use std::io::BufReader; 33 | 34 | use super::*; 35 | 36 | #[ignore = "non-vendored file"] 37 | #[test] 38 | fn test_read_geojson() { 39 | let path = "/Users/kyle/Downloads/UScounties.geojson"; 40 | let mut filein = BufReader::new(File::open(path).unwrap()); 41 | let _table = read_geojson(&mut filein, None).unwrap(); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /rust/geoparquet/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "geoparquet" 3 | version = { workspace = true } 4 | authors = { workspace = true } 5 | edition = { workspace = true } 6 | license = { workspace = true } 7 | repository = { workspace = true } 8 | description = "GeoParquet reader and writer." 9 | categories = { workspace = true } 10 | rust-version = { workspace = true } 11 | 12 | [features] 13 | async = ["parquet/async", "dep:futures"] 14 | 15 | [dependencies] 16 | arrow-arith = { workspace = true } 17 | arrow-array = { workspace = true } 18 | arrow-buffer = { workspace = true } 19 | arrow-ord = { workspace = true } 20 | arrow-schema = { workspace = true } 21 | futures = { workspace = true, optional = true } 22 | geo-traits = { workspace = true } 23 | geo-types = { workspace = true } 24 | geoarrow-array = { workspace = true } 25 | geoarrow-schema = { workspace = true } 26 | indexmap = { workspace = true } 27 | parquet = { workspace = true, features = ["arrow"] } 28 | serde = { workspace = true, features = ["derive"] } 29 | serde_with = { workspace = true } 30 | serde_json = { workspace = true } 31 | wkt = { workspace = true } 32 | 33 | [dev-dependencies] 34 | parquet = { workspace = true, features = [ 35 | "brotli", 36 | "flate2-zlib-rs", 37 | "flate2", 38 | "lz4", 39 | "snap", 40 | "zstd", 41 | ] } 42 | tokio = { workspace = true, features = ["macros", "fs", "rt-multi-thread"] } 43 | tokio-test = "0.4" 44 | 45 | [package.metadata.docs.rs] 46 | all-features = true 47 | -------------------------------------------------------------------------------- /rust/geoarrow-old/src/algorithm/broadcasting/vec.rs: -------------------------------------------------------------------------------- 1 | /// An enum over any arbitrary object, where a [`Vec`] is used to hold the Array variant. 2 | /// 3 | /// [`IntoIterator`] is implemented for this, where it will iterate over the `Array` variant 4 | /// normally but will iterate over the `Scalar` variant forever. 5 | #[derive(Debug, Clone)] 6 | pub enum BroadcastableVec 7 | where 8 | T: Clone, 9 | { 10 | Scalar(T), 11 | Array(Vec), 12 | } 13 | 14 | pub enum BroadcastIter<'a, T> { 15 | Scalar(T), 16 | // TODO: switch this to a ZipValidity that yields option values 17 | // Array(ZipValidity<&'a T, std::slice::Iter<'a, T>, BitIterator<'a>>), 18 | Array(std::slice::Iter<'a, T>), 19 | } 20 | 21 | impl<'a, T> IntoIterator for &'a BroadcastableVec 22 | where 23 | T: Clone, 24 | { 25 | type Item = T; 26 | type IntoIter = BroadcastIter<'a, T>; 27 | 28 | fn into_iter(self) -> Self::IntoIter { 29 | match self { 30 | BroadcastableVec::Array(arr) => BroadcastIter::Array(arr.iter()), 31 | BroadcastableVec::Scalar(val) => BroadcastIter::Scalar(val.clone()), 32 | } 33 | } 34 | } 35 | 36 | impl Iterator for BroadcastIter<'_, T> 37 | where 38 | T: Clone, 39 | { 40 | type Item = T; 41 | 42 | fn next(&mut self) -> Option { 43 | match self { 44 | BroadcastIter::Array(arr) => arr.next().cloned(), 45 | BroadcastIter::Scalar(val) => Some(val.to_owned()), 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /python/geoarrow-io/src/io/postgis.rs: -------------------------------------------------------------------------------- 1 | use crate::error::PyGeoArrowError; 2 | use crate::util::to_arro3_table; 3 | 4 | use geoarrow::error::GeoArrowError; 5 | use geoarrow::io::postgis::read_postgis as _read_postgis; 6 | use pyo3::prelude::*; 7 | use pyo3_arrow::export::Arro3Table; 8 | use pyo3_async_runtimes::tokio::future_into_py; 9 | use sqlx::postgres::PgPoolOptions; 10 | 11 | #[pyfunction] 12 | pub fn read_postgis(connection_url: String, sql: String) -> PyResult> { 13 | // https://tokio.rs/tokio/topics/bridging#what-tokiomain-expands-to 14 | let runtime = tokio::runtime::Builder::new_multi_thread() 15 | .enable_all() 16 | .build() 17 | .unwrap(); 18 | 19 | // TODO: py.allow_threads 20 | runtime.block_on(read_postgis_inner(connection_url, sql)) 21 | } 22 | 23 | #[pyfunction] 24 | pub fn read_postgis_async( 25 | py: Python, 26 | connection_url: String, 27 | sql: String, 28 | ) -> PyResult> { 29 | future_into_py(py, read_postgis_inner(connection_url, sql)) 30 | } 31 | 32 | async fn read_postgis_inner(connection_url: String, sql: String) -> PyResult> { 33 | let pool = PgPoolOptions::new() 34 | .connect(&connection_url) 35 | .await 36 | .map_err(|err| PyGeoArrowError::GeoArrowError(GeoArrowError::SqlxError(err)))?; 37 | 38 | let table = _read_postgis(&pool, &sql) 39 | .await 40 | .map_err(PyGeoArrowError::GeoArrowError)?; 41 | 42 | Ok(table.map(to_arro3_table)) 43 | } 44 | -------------------------------------------------------------------------------- /rust/geoarrow-array/src/geozero/export/array/rect.rs: -------------------------------------------------------------------------------- 1 | use geozero::{GeomProcessor, GeozeroGeometry}; 2 | 3 | use crate::array::RectArray; 4 | use crate::geozero::export::scalar::process_rect; 5 | use crate::{GeoArrowArray, GeoArrowArrayAccessor}; 6 | 7 | impl GeozeroGeometry for RectArray { 8 | fn process_geom(&self, processor: &mut P) -> geozero::error::Result<()> 9 | where 10 | Self: Sized, 11 | { 12 | let num_geometries = self.len(); 13 | processor.geometrycollection_begin(num_geometries, 0)?; 14 | 15 | for geom_idx in 0..num_geometries { 16 | process_rect(&self.value(geom_idx).unwrap(), geom_idx, processor)?; 17 | } 18 | 19 | processor.geometrycollection_end(num_geometries - 1)?; 20 | Ok(()) 21 | } 22 | } 23 | 24 | #[cfg(test)] 25 | mod test { 26 | use geoarrow_schema::{BoxType, Dimension}; 27 | use geozero::ToWkt; 28 | 29 | use crate::builder::RectBuilder; 30 | use crate::test::rect::{r0, r1}; 31 | 32 | #[test] 33 | fn geozero_process_geom() -> geozero::error::Result<()> { 34 | let typ = BoxType::new(Dimension::XY, Default::default()); 35 | let geo_arr = RectBuilder::from_rects([r0(), r1()].iter(), typ).finish(); 36 | let wkt = ToWkt::to_wkt(&geo_arr)?; 37 | let expected = "GEOMETRYCOLLECTION(POLYGON((10 10,10 20,30 20,30 10,10 10)),POLYGON((100 100,100 200,300 200,300 100,100 100)))"; 38 | assert_eq!(wkt, expected); 39 | Ok(()) 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /rust/geoarrow-old/src/algorithm/broadcasting/mod.rs: -------------------------------------------------------------------------------- 1 | //! Structs intended to help with 2 | //! ["broadcasting"](https://numpy.org/doc/stable/user/basics.broadcasting.html) for applying 3 | //! either a scalar or an array as an argument into an operation. 4 | //! 5 | //! **NOTE! This approach to broadcasting was an early prototype but is likely to be removed in 6 | //! the future.** 7 | //! 8 | //! Many algorithms, such as [`Translate`][crate::algorithm::geo::Translate], accept either a 9 | //! scalar or an array as input. If you pass in a scalar, every geometry in the geometry array will 10 | //! be moved by the same amount, whereas if you pass in an array of values, every geometry will 11 | //! have a different argument applied. 12 | //! 13 | //! The objects in this module are enums with two variants: `Scalar` and `Array`. Create an object 14 | //! with the variant desired for your operation. 15 | 16 | // mod geometry; 17 | // mod linestring; 18 | // mod multilinestring; 19 | // mod multipoint; 20 | // mod multipolygon; 21 | // mod point; 22 | // mod polygon; 23 | mod primitive; 24 | mod vec; 25 | 26 | // pub use geometry::BroadcastableGeometry; 27 | // pub use linestring::BroadcastableLineString; 28 | // pub use multilinestring::BroadcastableMultiLineString; 29 | // pub use multipoint::BroadcastableMultiPoint; 30 | // pub use multipolygon::BroadcastableMultiPolygon; 31 | // pub use point::BroadcastablePoint; 32 | // pub use polygon::BroadcastablePolygon; 33 | pub use primitive::BroadcastablePrimitive; 34 | pub use vec::BroadcastableVec; 35 | -------------------------------------------------------------------------------- /rust/geoarrow-array/src/geozero/export/array/multipoint.rs: -------------------------------------------------------------------------------- 1 | use geozero::{GeomProcessor, GeozeroGeometry}; 2 | 3 | use crate::array::MultiPointArray; 4 | use crate::geozero::export::scalar::process_multi_point; 5 | use crate::{GeoArrowArray, GeoArrowArrayAccessor}; 6 | 7 | impl GeozeroGeometry for MultiPointArray { 8 | fn process_geom(&self, processor: &mut P) -> geozero::error::Result<()> 9 | where 10 | Self: Sized, 11 | { 12 | let num_geometries = self.len(); 13 | processor.geometrycollection_begin(num_geometries, 0)?; 14 | 15 | for geom_idx in 0..num_geometries { 16 | process_multi_point(&self.value(geom_idx).unwrap(), geom_idx, processor)?; 17 | } 18 | 19 | processor.geometrycollection_end(num_geometries - 1)?; 20 | Ok(()) 21 | } 22 | } 23 | 24 | #[cfg(test)] 25 | mod test { 26 | use geoarrow_schema::{Dimension, MultiPointType}; 27 | use geozero::ToWkt; 28 | use geozero::error::Result; 29 | 30 | use crate::builder::MultiPointBuilder; 31 | use crate::test::multipoint::{mp0, mp1}; 32 | 33 | #[test] 34 | fn geozero_process_geom() -> Result<()> { 35 | let typ = MultiPointType::new(Dimension::XY, Default::default()); 36 | let geo_arr = MultiPointBuilder::from_multi_points(&[&mp0(), &mp1()], typ).finish(); 37 | let wkt = ToWkt::to_wkt(&geo_arr)?; 38 | let expected = "GEOMETRYCOLLECTION(MULTIPOINT(0 1,1 2),MULTIPOINT(3 4,5 6))"; 39 | assert_eq!(wkt, expected); 40 | Ok(()) 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /rust/geoarrow-array/src/test/multipoint.rs: -------------------------------------------------------------------------------- 1 | use geo_types::{MultiPoint, point}; 2 | use geoarrow_schema::{CoordType, Dimension, MultiPointType}; 3 | use geoarrow_test::raw; 4 | 5 | use crate::array::MultiPointArray; 6 | use crate::builder::MultiPointBuilder; 7 | 8 | pub(crate) fn mp0() -> MultiPoint { 9 | MultiPoint::new(vec![ 10 | point!( 11 | x: 0., y: 1. 12 | ), 13 | point!( 14 | x: 1., y: 2. 15 | ), 16 | ]) 17 | } 18 | 19 | pub(crate) fn mp1() -> MultiPoint { 20 | MultiPoint::new(vec![ 21 | point!( 22 | x: 3., y: 4. 23 | ), 24 | point!( 25 | x: 5., y: 6. 26 | ), 27 | ]) 28 | } 29 | 30 | pub(crate) fn mp_array(coord_type: CoordType) -> MultiPointArray { 31 | let geoms = vec![Some(mp0()), None, Some(mp1()), None]; 32 | let typ = MultiPointType::new(Dimension::XY, Default::default()).with_coord_type(coord_type); 33 | MultiPointBuilder::from_nullable_multi_points(&geoms, typ).finish() 34 | } 35 | 36 | pub fn array(coord_type: CoordType, dim: Dimension) -> MultiPointArray { 37 | let typ = MultiPointType::new(dim, Default::default()).with_coord_type(coord_type); 38 | let geoms = match dim { 39 | Dimension::XY => raw::multipoint::xy::geoms(), 40 | Dimension::XYZ => raw::multipoint::xyz::geoms(), 41 | Dimension::XYM => raw::multipoint::xym::geoms(), 42 | Dimension::XYZM => raw::multipoint::xyzm::geoms(), 43 | }; 44 | MultiPointBuilder::from_nullable_multi_points(&geoms, typ).finish() 45 | } 46 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | Get [rust](https://rustup.rs/). 4 | Then: 5 | 6 | ```shell 7 | git clone git@github.com:geoarrow/geoarrow-rs.git 8 | cd geoarrow-rs 9 | cargo test --all-features 10 | ``` 11 | 12 | Use Github [pull requests](https://github.com/geoarrow/geoarrow-rs/pulls) to provide code and documentation. 13 | Use [issues](https://github.com/geoarrow/geoarrow-rs/issues) to report bugs or request features. 14 | 15 | ## Conventional commits 16 | 17 | We require all PRs to follow [conventional commits](https://www.conventionalcommits.org/en/v1.0.0/). 18 | We squash merge, so only the PR title needs to follow the standard. 19 | You'll get the idea by looking at a list of recent commits. 20 | You can find our allowed task types [here](.github/workflows/conventional-commits.yml). 21 | 22 | ## Build issues 23 | 24 | If you get the following error: 25 | 26 | ```text 27 | CMake Error at cmake/Ccache.cmake:10 (cmake_minimum_required): 28 | Compatibility with CMake < 3.5 has been removed from CMake. 29 | 30 | Update the VERSION argument value. Or, use the ... syntax 31 | to tell CMake that the project requires at least but has been updated 32 | to work with policies introduced by or earlier. 33 | 34 | Or, add -DCMAKE_POLICY_VERSION_MINIMUM=3.5 to try configuring anyway. 35 | Call Stack (most recent call first): 36 | CMakeLists.txt:130 (include) 37 | ``` 38 | 39 | Fix by following those instructions: 40 | 41 | ```shell 42 | export CMAKE_POLICY_VERSION_MINIMUM=3.5 43 | cargo test --all-features 44 | ``` 45 | -------------------------------------------------------------------------------- /python/geoarrow-compute/src/util.rs: -------------------------------------------------------------------------------- 1 | use std::sync::Arc; 2 | 3 | use geoarrow::NativeArray; 4 | use geoarrow::array::NativeArrayDyn; 5 | use geoarrow::chunked_array::ChunkedNativeArray; 6 | use geoarrow::error::GeoArrowError; 7 | use pyo3::prelude::*; 8 | use pyo3_arrow::{PyArray, PyChunkedArray, PyTable}; 9 | use pyo3_geoarrow::{PyChunkedNativeArray, PyGeoArrowResult, PyNativeArray}; 10 | 11 | pub(crate) fn table_to_pytable(table: geoarrow::table::Table) -> PyTable { 12 | let (batches, schema) = table.into_inner(); 13 | PyTable::try_new(batches, schema).unwrap() 14 | } 15 | 16 | pub(crate) fn pytable_to_table(table: PyTable) -> Result { 17 | let (batches, schema) = table.into_inner(); 18 | geoarrow::table::Table::try_new(batches, schema) 19 | } 20 | 21 | pub(crate) fn return_geometry_array( 22 | py: Python, 23 | arr: Arc, 24 | ) -> PyGeoArrowResult { 25 | Ok(PyNativeArray::new(NativeArrayDyn::new(arr)) 26 | .to_geoarrow(py)? 27 | .unbind()) 28 | } 29 | 30 | pub(crate) fn return_chunked_geometry_array( 31 | py: Python, 32 | arr: Arc, 33 | ) -> PyGeoArrowResult { 34 | Ok(PyChunkedNativeArray::new(arr).to_geoarrow(py)?.unbind()) 35 | } 36 | 37 | pub(crate) fn return_array(py: Python, arr: PyArray) -> PyGeoArrowResult { 38 | Ok(arr.to_arro3(py)?.unbind()) 39 | } 40 | 41 | pub(crate) fn return_chunked_array(py: Python, arr: PyChunkedArray) -> PyGeoArrowResult { 42 | Ok(arr.to_arro3(py)?.unbind()) 43 | } 44 | -------------------------------------------------------------------------------- /python/geoarrow-core/src/interop/numpy/to_numpy.rs: -------------------------------------------------------------------------------- 1 | use geoarrow::ArrayBase; 2 | use geoarrow::trait_::ArrayAccessor; 3 | use pyo3::exceptions::PyValueError; 4 | use pyo3::intern; 5 | use pyo3::prelude::*; 6 | use pyo3::types::{PyBytes, PyDict}; 7 | 8 | pub fn wkb_array_to_numpy(py: Python, arr: &geoarrow_array::array::WkbArray) -> PyResult { 9 | if arr.null_count() > 0 { 10 | return Err(PyValueError::new_err( 11 | "Cannot create numpy array from pyarrow array with nulls.", 12 | )); 13 | } 14 | 15 | let numpy_mod = py.import(intern!(py, "numpy"))?; 16 | 17 | let args = (arr.len(),); 18 | let kwargs = PyDict::new(py); 19 | kwargs.set_item("dtype", numpy_mod.getattr(intern!(py, "object_"))?)?; 20 | let np_arr = numpy_mod.call_method(intern!(py, "empty"), args, Some(&kwargs))?; 21 | 22 | for (i, wkb) in arr.iter_values().enumerate() { 23 | np_arr.set_item(i, PyBytes::new(py, wkb.as_ref()))?; 24 | } 25 | 26 | Ok(np_arr.into_pyobject(py)?.into_any().unbind()) 27 | } 28 | 29 | pub fn chunked_wkb_array_to_numpy( 30 | py: Python, 31 | arr: geoarrow_array::chunked_array::ChunkedWkbArray, 32 | ) -> PyResult { 33 | let numpy_mod = py.import(intern!(py, "numpy"))?; 34 | let shapely_chunks = arr 35 | .chunks() 36 | .iter() 37 | .map(|chunk| wkb_array_to_numpy(py, chunk)) 38 | .collect::>>()?; 39 | let np_arr = numpy_mod.call_method1(intern!(py, "concatenate"), (shapely_chunks,))?; 40 | Ok(np_arr.into_pyobject(py)?.into_any().unbind()) 41 | } 42 | -------------------------------------------------------------------------------- /rust/geoarrow-array/src/geozero/export/scalar/coord.rs: -------------------------------------------------------------------------------- 1 | use geo_traits::CoordTrait; 2 | use geozero::GeomProcessor; 3 | 4 | pub(crate) fn process_coord( 5 | coord: &impl CoordTrait, 6 | coord_idx: usize, 7 | processor: &mut P, 8 | ) -> geozero::error::Result<()> { 9 | use geo_traits::Dimensions; 10 | 11 | match coord.dim() { 12 | Dimensions::Xy | Dimensions::Unknown(2) => processor.xy(coord.x(), coord.y(), coord_idx)?, 13 | Dimensions::Xyz | Dimensions::Unknown(3) => processor.coordinate( 14 | coord.x(), 15 | coord.y(), 16 | Some(unsafe { coord.nth_unchecked(2) }), 17 | None, 18 | None, 19 | None, 20 | coord_idx, 21 | )?, 22 | Dimensions::Xym => processor.coordinate( 23 | coord.x(), 24 | coord.y(), 25 | None, 26 | Some(unsafe { coord.nth_unchecked(2) }), 27 | None, 28 | None, 29 | coord_idx, 30 | )?, 31 | Dimensions::Xyzm | Dimensions::Unknown(4) => processor.coordinate( 32 | coord.x(), 33 | coord.y(), 34 | Some(unsafe { coord.nth_unchecked(2) }), 35 | Some(unsafe { coord.nth_unchecked(3) }), 36 | None, 37 | None, 38 | coord_idx, 39 | )?, 40 | d => { 41 | return Err(geozero::error::GeozeroError::Geometry(format!( 42 | "Unexpected dimension {d:?}", 43 | ))); 44 | } 45 | }; 46 | Ok(()) 47 | } 48 | -------------------------------------------------------------------------------- /rust/geoarrow-array/src/geozero/export/array/polygon.rs: -------------------------------------------------------------------------------- 1 | use geozero::{GeomProcessor, GeozeroGeometry}; 2 | 3 | use crate::array::PolygonArray; 4 | use crate::geozero::export::scalar::process_polygon; 5 | use crate::{GeoArrowArray, GeoArrowArrayAccessor}; 6 | 7 | impl GeozeroGeometry for PolygonArray { 8 | fn process_geom(&self, processor: &mut P) -> geozero::error::Result<()> 9 | where 10 | Self: Sized, 11 | { 12 | let num_geometries = self.len(); 13 | processor.geometrycollection_begin(num_geometries, 0)?; 14 | 15 | for geom_idx in 0..num_geometries { 16 | process_polygon(&self.value(geom_idx).unwrap(), true, geom_idx, processor)?; 17 | } 18 | 19 | processor.geometrycollection_end(num_geometries - 1)?; 20 | Ok(()) 21 | } 22 | } 23 | 24 | #[cfg(test)] 25 | mod test { 26 | use geoarrow_schema::{Dimension, PolygonType}; 27 | use geozero::ToWkt; 28 | 29 | use crate::builder::PolygonBuilder; 30 | use crate::test::polygon::{p0, p1}; 31 | 32 | #[test] 33 | fn geozero_process_geom() -> geozero::error::Result<()> { 34 | let typ = PolygonType::new(Dimension::XY, Default::default()); 35 | let geo_arr = PolygonBuilder::from_polygons(&[&p0(), &p1()], typ).finish(); 36 | let wkt = ToWkt::to_wkt(&geo_arr)?; 37 | let expected = "GEOMETRYCOLLECTION(POLYGON((-111 45,-111 41,-104 41,-104 45,-111 45)),POLYGON((-111 45,-111 41,-104 41,-104 45,-111 45),(-110 44,-110 42,-105 42,-105 44,-110 44)))"; 38 | assert_eq!(wkt, expected); 39 | Ok(()) 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /rust/geoarrow-array/src/geozero/export/scalar/polygon.rs: -------------------------------------------------------------------------------- 1 | use geo_traits::{LineStringTrait, PolygonTrait}; 2 | use geozero::{GeomProcessor, GeozeroGeometry}; 3 | 4 | use super::process_coord; 5 | use crate::scalar::Polygon; 6 | 7 | fn process_ring( 8 | ring: impl LineStringTrait, 9 | ring_idx: usize, 10 | processor: &mut P, 11 | ) -> geozero::error::Result<()> { 12 | processor.linestring_begin(false, ring.num_coords(), ring_idx)?; 13 | 14 | for (coord_idx, coord) in ring.coords().enumerate() { 15 | process_coord(&coord, coord_idx, processor)?; 16 | } 17 | 18 | processor.linestring_end(false, ring_idx)?; 19 | Ok(()) 20 | } 21 | 22 | pub(crate) fn process_polygon( 23 | geom: &impl PolygonTrait, 24 | tagged: bool, 25 | geom_idx: usize, 26 | processor: &mut P, 27 | ) -> geozero::error::Result<()> { 28 | processor.polygon_begin(tagged, geom.num_interiors() + 1, geom_idx)?; 29 | 30 | if let Some(exterior) = geom.exterior() { 31 | process_ring(exterior, 0, processor)?; 32 | } 33 | 34 | for (interior_ring_idx, interior_ring) in geom.interiors().enumerate() { 35 | process_ring(interior_ring, interior_ring_idx + 1, processor)?; 36 | } 37 | 38 | processor.polygon_end(tagged, geom_idx)?; 39 | 40 | Ok(()) 41 | } 42 | 43 | impl GeozeroGeometry for Polygon<'_> { 44 | fn process_geom(&self, processor: &mut P) -> geozero::error::Result<()> 45 | where 46 | Self: Sized, 47 | { 48 | process_polygon(self, true, 0, processor) 49 | } 50 | } 51 | --------------------------------------------------------------------------------