From 322d44cddcbe796a349687a757ff9aa9682ad85c Mon Sep 17 00:00:00 2001 From: Kyle Barron Date: Mon, 4 Dec 2023 00:38:36 -0500 Subject: [PATCH 1/2] wip top level function api --- python/core/Cargo.lock | 177 ++++++++++++++------------ python/core/src/algorithm/geo/area.rs | 92 +++++++++++++ python/core/src/ffi/from_python.rs | 81 +++++++++++- python/core/src/ffi/to_python.rs | 4 +- python/core/src/lib.rs | 3 + 5 files changed, 276 insertions(+), 81 deletions(-) diff --git a/python/core/Cargo.lock b/python/core/Cargo.lock index d31566e99..d7a112733 100644 --- a/python/core/Cargo.lock +++ b/python/core/Cargo.lock @@ -4,15 +4,16 @@ version = 3 [[package]] name = "ahash" -version = "0.8.3" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c99f64d1e06488f620f932677e24bc6e2897582980441ae90a671415bd7ec2f" +checksum = "91429305e9f0a25f6205c5b8e0d2db09e0708a7a6df0f42212bb56c32c8ac97a" dependencies = [ "cfg-if", "const-random", "getrandom", "once_cell", "version_check", + "zerocopy", ] [[package]] @@ -303,9 +304,9 @@ checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec" [[package]] name = "byteorder" -version = "1.4.3" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" @@ -362,9 +363,9 @@ dependencies = [ [[package]] name = "core-foundation-sys" -version = "0.8.4" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa" +checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" [[package]] name = "critical-section" @@ -401,11 +402,11 @@ dependencies = [ [[package]] name = "earcutr" -version = "0.4.2" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0812b44697951d35fde8fcb0da81c9de7e809e825a66bbf1ecb79d9829d4ca3d" +checksum = "79127ed59a85d7687c409e9978547cffb7dc79675355ed22da6b66fd5f6ead01" dependencies = [ - "itertools 0.10.5", + "itertools 0.11.0", "num-traits", ] @@ -511,9 +512,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.10" +version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427" +checksum = "fe9006bed769170c11f845cf00c7c1e9092aeb3f268e007c3e760ac68008070f" dependencies = [ "cfg-if", "libc", @@ -542,9 +543,9 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.14.1" +version = "0.14.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7dfda62a12f55daeae5015f81b0baea145391cb4520f86c248fc615d72640d12" +checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" dependencies = [ "ahash", "allocator-api2", @@ -594,9 +595,9 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.0.2" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8adf3ddd720272c6ea8bf59463c04e0f93d0bbf7c5439b691bca2987e0270897" +checksum = "d530e1a18b1cb4c484e6e34556a0d948706958449fca0cab753d649f2bce3d1f" dependencies = [ "equivalent", "hashbrown", @@ -610,15 +611,15 @@ checksum = "1e186cfbae8084e513daff4240b4797e342f988cecda4fb6c939150f96315fd8" [[package]] name = "inventory" -version = "0.3.12" +version = "0.3.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1be380c410bf0595e94992a648ea89db4dd3f3354ba54af206fd2a68cf5ac8e" +checksum = "0508c56cfe9bfd5dfeb0c22ab9a6abfda2f27bdca422132e494266351ed8d83c" [[package]] name = "itertools" -version = "0.10.5" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" +checksum = "b1c173a5686ce8bfa551b3563d0c2170bf24ca44da99c7ca4bfdab5418c3fe57" dependencies = [ "either", ] @@ -640,9 +641,9 @@ checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" [[package]] name = "js-sys" -version = "0.3.64" +version = "0.3.66" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5f195fe497f702db0f318b07fdd68edb16955aed830df8363d837542f8f935a" +checksum = "cee9c64da59eae3b50095c18d3e74f8b73c0b86d2792824ff01bbce68ba229ca" dependencies = [ "wasm-bindgen", ] @@ -719,21 +720,21 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.148" +version = "0.2.150" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9cdc71e17332e86d2e1d38c1f99edcb6288ee11b815fb1a4b049eaa2114d369b" +checksum = "89d92a4743f9a61002fae18374ed11e7973f530cb3a3255fb354818118b2203c" [[package]] name = "libm" -version = "0.2.7" +version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7012b1bbb0719e1097c47611d3898568c546d597c2e74d66f6087edd5233ff4" +checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058" [[package]] name = "lock_api" -version = "0.4.10" +version = "0.4.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1cc9717a20b1bb222f333e6a92fd32f7d8a18ddc5a3191a11af45dcbf4dcd16" +checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45" dependencies = [ "autocfg", "scopeguard", @@ -747,9 +748,9 @@ checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" [[package]] name = "memchr" -version = "2.6.3" +version = "2.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f232d6ef707e1956a43342693d2a31e72989554d58299d7a88738cc95b0d35c" +checksum = "f665ee40bc4a3c5590afb1e9677db74a508659dfd71e126420da8274909a0167" [[package]] name = "memoffset" @@ -829,9 +830,9 @@ dependencies = [ [[package]] name = "num-traits" -version = "0.2.16" +version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f30b0abd723be7e2ffca1272140fac1a2f084c77ec3e123c192b66af1ee9e6c2" +checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" dependencies = [ "autocfg", "libm", @@ -839,18 +840,18 @@ dependencies = [ [[package]] name = "num_enum" -version = "0.7.0" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70bf6736f74634d299d00086f02986875b3c2d924781a6a2cb6c201e73da0ceb" +checksum = "683751d591e6d81200c39fb0d1032608b77724f34114db54f571ff1317b337c0" dependencies = [ "num_enum_derive", ] [[package]] name = "num_enum_derive" -version = "0.7.0" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56ea360eafe1022f7cc56cd7b869ed57330fb2453d0c7831d99b74c65d2f5597" +checksum = "6c11e44798ad209ccdd91fc192f0526a369a01234f7373e1b141c96d7cee4f0e" dependencies = [ "proc-macro-crate", "proc-macro2", @@ -876,9 +877,9 @@ dependencies = [ [[package]] name = "parking_lot_core" -version = "0.9.8" +version = "0.9.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93f00c865fe7cabf650081affecd3871070f26767e7b2070a3ffae14c654b447" +checksum = "4c42a9226546d68acdd9c0a280d17ce19bfe27a46bf68784e4066115788d008e" dependencies = [ "cfg-if", "libc", @@ -889,19 +890,18 @@ dependencies = [ [[package]] name = "proc-macro-crate" -version = "1.3.1" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f4c021e1093a56626774e81216a4ce732a735e5bad4868a03f3ed65ca0c3919" +checksum = "7e8366a6159044a37876a2b9817124296703c586a5c92e2c53751fa06d8d43e8" dependencies = [ - "once_cell", "toml_edit", ] [[package]] name = "proc-macro2" -version = "1.0.67" +version = "1.0.70" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d433d9f1a3e8c1263d9456598b16fec66f4acc9a74dacffd35c7bb09b3a1328" +checksum = "39278fbbf5fb4f646ce651690877f89d1c5811a3d4acb27700c1cb3cdb78fd3b" dependencies = [ "unicode-ident", ] @@ -982,9 +982,9 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.3.5" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29" +checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" dependencies = [ "bitflags 1.3.2", ] @@ -1058,24 +1058,24 @@ checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" [[package]] name = "semver" -version = "1.0.19" +version = "1.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad977052201c6de01a8ef2aa3378c4bd23217a056337d1d6da40468d267a4fb0" +checksum = "836fa6a3e1e547f9a2c4040802ec865b5d85f4014efe00555d7090a3dcaa1090" [[package]] name = "serde" -version = "1.0.188" +version = "1.0.193" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf9e0fcba69a370eed61bcf2b728575f726b50b55cba78064753d708ddc7549e" +checksum = "25dd9975e68d0cb5aa1120c288333fc98731bd1dd12f561e468ea4728c042b89" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.188" +version = "1.0.193" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4eca7ac642d82aa35b60049a6eccb4be6be75e599bd2e9adb5f875a737654af2" +checksum = "43576ca501357b9b071ac53cdc7da8ef0cbd9493d8df094cd821777ea6e894d3" dependencies = [ "proc-macro2", "quote", @@ -1095,16 +1095,17 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.11.1" +version = "1.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a" +checksum = "4dccd0940a2dcdf68d092b8cbab7dc0ad8fa938bf95787e1b916b0e3d0e8e970" [[package]] name = "spade" -version = "2.2.1" +version = "2.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab085cfe5486093ca290034bd2d424e283f9725b4bcf8ba5a7f6c7612b59841c" +checksum = "87a3ef2efbc408c9051c1a27ce7edff430d74531d31a480b7ca4f618072c2670" dependencies = [ + "hashbrown", "num-traits", "robust", "smallvec", @@ -1133,9 +1134,9 @@ checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" [[package]] name = "syn" -version = "2.0.37" +version = "2.0.39" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7303ef2c05cd654186cb250d29049a24840ca25d2747c25c0381c8d9e2f582e8" +checksum = "23e78b90f2fcf45d3e842032ce32e3f2d1545ba6636271dcbf24fa306d87be7a" dependencies = [ "proc-macro2", "quote", @@ -1144,24 +1145,24 @@ dependencies = [ [[package]] name = "target-lexicon" -version = "0.12.11" +version = "0.12.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d0e916b1148c8e263850e1ebcbd046f333e0683c724876bb0da63ea4373dc8a" +checksum = "14c39fd04924ca3a864207c66fc2cd7d22d7c016007f9ce846cbb9326331930a" [[package]] name = "thiserror" -version = "1.0.49" +version = "1.0.50" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1177e8c6d7ede7afde3585fd2513e611227efd6481bd78d2e82ba1ce16557ed4" +checksum = "f9a7210f5c9a7156bb50aa36aed4c95afb51df0df00713949448cf9e97d382d2" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.49" +version = "1.0.50" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10712f02019e9288794769fba95cd6847df9874d49d871d062172f9dd41bc4cc" +checksum = "266b2e40bc00e5a6c09c3584011e08b06f123c00362c92b975ba9843aaaa14b8" dependencies = [ "proc-macro2", "quote", @@ -1179,15 +1180,15 @@ dependencies = [ [[package]] name = "toml_datetime" -version = "0.6.3" +version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7cda73e2f1397b1262d6dfdcef8aafae14d1de7748d66822d3bfeeb6d03e5e4b" +checksum = "3550f4e9685620ac18a50ed434eb3aec30db8ba93b0287467bca5826ea25baf1" [[package]] name = "toml_edit" -version = "0.19.15" +version = "0.20.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" +checksum = "70f427fce4d84c72b5b732388bf4a9f4531b53f74e2887e3ecb2481f68f66d81" dependencies = [ "indexmap", "toml_datetime", @@ -1220,9 +1221,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.87" +version = "0.2.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7706a72ab36d8cb1f80ffbf0e071533974a60d0a308d01a5d0375bf60499a342" +checksum = "0ed0d4f68a3015cc185aff4db9506a015f4b96f95303897bfa23f846db54064e" dependencies = [ "cfg-if", "wasm-bindgen-macro", @@ -1230,9 +1231,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.87" +version = "0.2.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ef2b6d3c510e9625e5fe6f509ab07d66a760f0885d858736483c32ed7809abd" +checksum = "1b56f625e64f3a1084ded111c4d5f477df9f8c92df113852fa5a374dbda78826" dependencies = [ "bumpalo", "log", @@ -1245,9 +1246,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.87" +version = "0.2.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dee495e55982a3bd48105a7b947fd2a9b4a8ae3010041b9e0faab3f9cd028f1d" +checksum = "0162dbf37223cd2afce98f3d0785506dcb8d266223983e4b5b525859e6e182b2" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -1255,9 +1256,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.87" +version = "0.2.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b" +checksum = "f0eb82fcb7930ae6219a7ecfd55b217f5f0893484b7a13022ebb2b2bf20b5283" dependencies = [ "proc-macro2", "quote", @@ -1268,9 +1269,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.87" +version = "0.2.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca6ad05a4870b2bf5fe995117d3728437bd27d7cd5f06f13c17443ef369775a1" +checksum = "7ab9b36309365056cd639da3134bf87fa8f3d86008abf99e612384a6eecd459f" [[package]] name = "windows-core" @@ -1340,9 +1341,29 @@ checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" [[package]] name = "winnow" -version = "0.5.15" +version = "0.5.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c2e3184b9c4e92ad5167ca73039d0c42476302ab603e2fec4487511f38ccefc" +checksum = "829846f3e3db426d4cee4510841b71a8e58aa2a76b1132579487ae430ccd9c7b" dependencies = [ "memchr", ] + +[[package]] +name = "zerocopy" +version = "0.7.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d6f15f7ade05d2a4935e34a457b936c23dc70a05cc1d97133dc99e7a3fe0f0e" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.7.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbbad221e3f78500350ecbd7dfa4e63ef945c05f4c61cb7f4d3f84cd0bba649b" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] diff --git a/python/core/src/algorithm/geo/area.rs b/python/core/src/algorithm/geo/area.rs index 96e38ed18..6ec6be15e 100644 --- a/python/core/src/algorithm/geo/area.rs +++ b/python/core/src/algorithm/geo/area.rs @@ -1,6 +1,98 @@ use crate::array::*; +use crate::ffi::from_python::{convert_to_geometry_array, import_arrow_c_array}; +use geoarrow::algorithm::geo::Area; +use geoarrow::datatypes::GeoDataType; +use pyo3::exceptions::PyTypeError; use pyo3::prelude::*; +#[pyfunction] +pub fn area(ob: &PyAny) -> PyResult { + let (array, field) = import_arrow_c_array(ob)?; + // TODO: need to improve crate's error handling + let geometry_array = convert_to_geometry_array(&array, &field).unwrap(); + + match geometry_array.data_type() { + GeoDataType::Point(_) => { + let geo_arr = array + .as_any() + .downcast_ref::() + .unwrap(); + Ok(geo_arr.unsigned_area().into()) + } + GeoDataType::LineString(_) => { + let geo_arr = array + .as_any() + .downcast_ref::>() + .unwrap(); + Ok(geo_arr.unsigned_area().into()) + } + GeoDataType::LargeLineString(_) => { + let geo_arr = array + .as_any() + .downcast_ref::>() + .unwrap(); + Ok(geo_arr.unsigned_area().into()) + } + GeoDataType::Polygon(_) => { + let geo_arr = array + .as_any() + .downcast_ref::>() + .unwrap(); + Ok(geo_arr.unsigned_area().into()) + } + GeoDataType::LargePolygon(_) => { + let geo_arr = array + .as_any() + .downcast_ref::>() + .unwrap(); + Ok(geo_arr.unsigned_area().into()) + } + GeoDataType::MultiPoint(_) => { + let geo_arr = array + .as_any() + .downcast_ref::>() + .unwrap(); + Ok(geo_arr.unsigned_area().into()) + } + GeoDataType::LargeMultiPoint(_) => { + let geo_arr = array + .as_any() + .downcast_ref::>() + .unwrap(); + Ok(geo_arr.unsigned_area().into()) + } + GeoDataType::MultiLineString(_) => { + let geo_arr = array + .as_any() + .downcast_ref::>() + .unwrap(); + Ok(geo_arr.unsigned_area().into()) + } + GeoDataType::LargeMultiLineString(_) => { + let geo_arr = array + .as_any() + .downcast_ref::>() + .unwrap(); + Ok(geo_arr.unsigned_area().into()) + } + GeoDataType::MultiPolygon(_) => { + let geo_arr = array + .as_any() + .downcast_ref::>() + .unwrap(); + Ok(geo_arr.unsigned_area().into()) + } + GeoDataType::LargeMultiPolygon(_) => { + let geo_arr = array + .as_any() + .downcast_ref::>() + .unwrap(); + Ok(geo_arr.unsigned_area().into()) + } + _ => Err(PyTypeError::new_err("Unexpected geometry type")), + } +} + macro_rules! impl_area { ($struct_name:ident) => { #[pymethods] diff --git a/python/core/src/ffi/from_python.rs b/python/core/src/ffi/from_python.rs index aadeef653..4e36107be 100644 --- a/python/core/src/ffi/from_python.rs +++ b/python/core/src/ffi/from_python.rs @@ -1,8 +1,12 @@ +use std::sync::Arc; + use crate::array::*; -use arrow::datatypes::Field; +use arrow::datatypes::{DataType, Field}; use arrow::error::ArrowError; use arrow::ffi::{FFI_ArrowArray, FFI_ArrowSchema}; use arrow_array::{make_array, ArrayRef}; +use geoarrow::error::GeoArrowError; +use geoarrow::GeometryArrayTrait; use pyo3::exceptions::{PyTypeError, PyValueError}; use pyo3::prelude::*; use pyo3::types::{PyCapsule, PyTuple}; @@ -78,3 +82,78 @@ pub(crate) fn import_arrow_c_array(ob: &PyAny) -> PyResult<(ArrayRef, Field)> { let field = Field::try_from(schema_ptr).map_err(to_py_err)?; Ok((make_array(array_data), field)) } + +pub fn convert_to_geometry_array( + array: &ArrayRef, + field: &Field, +) -> Result, GeoArrowError> { + if let Some(extension_name) = field.metadata().get("ARROW:extension:name") { + let geom_arr: Arc = match extension_name.as_str() { + "geoarrow.point" => { + Arc::new(geoarrow::array::PointArray::try_from(array.as_ref()).unwrap()) + } + "geoarrow.linestring" => match field.data_type() { + DataType::List(_) => Arc::new( + geoarrow::array::LineStringArray::::try_from(array.as_ref()).unwrap(), + ), + DataType::LargeList(_) => Arc::new( + geoarrow::array::LineStringArray::::try_from(array.as_ref()).unwrap(), + ), + _ => panic!("Unexpected data type"), + }, + "geoarrow.polygon" => match field.data_type() { + DataType::List(_) => Arc::new( + geoarrow::array::PolygonArray::::try_from(array.as_ref()).unwrap(), + ), + DataType::LargeList(_) => Arc::new( + geoarrow::array::PolygonArray::::try_from(array.as_ref()).unwrap(), + ), + _ => panic!("Unexpected data type"), + }, + "geoarrow.multipoint" => match field.data_type() { + DataType::List(_) => Arc::new( + geoarrow::array::MultiPointArray::::try_from(array.as_ref()).unwrap(), + ), + DataType::LargeList(_) => Arc::new( + geoarrow::array::MultiPointArray::::try_from(array.as_ref()).unwrap(), + ), + _ => panic!("Unexpected data type"), + }, + "geoarrow.multilinestring" => match field.data_type() { + DataType::List(_) => Arc::new( + geoarrow::array::MultiLineStringArray::::try_from(array.as_ref()).unwrap(), + ), + DataType::LargeList(_) => Arc::new( + geoarrow::array::MultiLineStringArray::::try_from(array.as_ref()).unwrap(), + ), + _ => panic!("Unexpected data type"), + }, + "geoarrow.multipolygon" => match field.data_type() { + DataType::List(_) => Arc::new( + geoarrow::array::MultiPolygonArray::::try_from(array.as_ref()).unwrap(), + ), + DataType::LargeList(_) => Arc::new( + geoarrow::array::MultiPolygonArray::::try_from(array.as_ref()).unwrap(), + ), + _ => panic!("Unexpected data type"), + }, + // TODO: create a top-level API that parses any named geoarrow array? + // "geoarrow.wkb" => Ok(GeometryArray::WKB(array.try_into()?)), + _ => { + return Err(GeoArrowError::General(format!( + "Unknown geoarrow type {}", + extension_name + ))) + } + }; + Ok(geom_arr) + } else { + // TODO: better error here, and document that arrays without geoarrow extension + // metadata should use TryFrom for a specific geometry type directly, instead of using + // GeometryArray + Err(GeoArrowError::General( + "Can only construct an array with an extension type name.".to_string(), + )) + } + // todo!() +} diff --git a/python/core/src/ffi/to_python.rs b/python/core/src/ffi/to_python.rs index 69ee68f36..5227e502c 100644 --- a/python/core/src/ffi/to_python.rs +++ b/python/core/src/ffi/to_python.rs @@ -13,7 +13,7 @@ macro_rules! impl_arrow_c_array_geometry_array { #[pymethods] impl $struct_name { /// An implementation of the Arrow PyCapsule Interface - fn __arrow_c_array__(&self, _requested_schema: PyObject) -> PyResult { + fn __arrow_c_array__(&self, _requested_schema: Option) -> PyResult { let field = self.0.extension_field(); let ffi_schema = FFI_ArrowSchema::try_from(&*field).unwrap(); let ffi_array = FFI_ArrowArray::new(&self.0.clone().into_array_ref().to_data()); @@ -44,7 +44,7 @@ macro_rules! impl_arrow_c_array_primitive { #[pymethods] impl $struct_name { /// An implementation of the Arrow PyCapsule Interface - fn __arrow_c_array__(&self, _requested_schema: PyObject) -> PyResult { + fn __arrow_c_array__(&self, _requested_schema: Option) -> PyResult { let ffi_schema = FFI_ArrowSchema::try_from(self.0.data_type()).unwrap(); let ffi_array = FFI_ArrowArray::new(&self.0.to_data()); diff --git a/python/core/src/lib.rs b/python/core/src/lib.rs index 192ce3ff6..1df8886d5 100644 --- a/python/core/src/lib.rs +++ b/python/core/src/lib.rs @@ -31,5 +31,8 @@ fn rust(_py: Python, m: &PyModule) -> PyResult<()> { m.add_class::()?; m.add_class::()?; + // Top-level functions + m.add_function(wrap_pyfunction!(crate::algorithm::geo::area::area, m)?)?; + Ok(()) } From 7fa661ec4cae363674d07fc6100d3a965acebc24 Mon Sep 17 00:00:00 2001 From: Kyle Barron Date: Mon, 4 Dec 2023 00:40:58 -0500 Subject: [PATCH 2/2] fix downcasting --- python/core/src/algorithm/geo/area.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/python/core/src/algorithm/geo/area.rs b/python/core/src/algorithm/geo/area.rs index 6ec6be15e..18e546083 100644 --- a/python/core/src/algorithm/geo/area.rs +++ b/python/core/src/algorithm/geo/area.rs @@ -9,9 +9,9 @@ use pyo3::prelude::*; pub fn area(ob: &PyAny) -> PyResult { let (array, field) = import_arrow_c_array(ob)?; // TODO: need to improve crate's error handling - let geometry_array = convert_to_geometry_array(&array, &field).unwrap(); + let array = convert_to_geometry_array(&array, &field).unwrap(); - match geometry_array.data_type() { + match array.data_type() { GeoDataType::Point(_) => { let geo_arr = array .as_any()