BlakeOrth commented on code in PR #8801:
URL: https://github.com/apache/arrow-rs/pull/8801#discussion_r2525376461
##########
parquet-geospatial/src/types.rs:
##########
@@ -0,0 +1,210 @@
+use std::sync::Arc;
+
+use arrow::array::{Array, ArrayRef, BinaryArray, BinaryViewArray,
LargeBinaryArray, make_array};
+use arrow::buffer::NullBuffer;
+use arrow::error::Result;
+use arrow_schema::Field;
+use arrow_schema::{ArrowError, DataType, extension::ExtensionType};
+use serde::{Deserialize, Serialize};
+
+#[derive(Copy, Clone, Debug, Serialize, Deserialize)]
+pub enum Hint {
+ Geometry,
+ Geography,
+}
+
+#[derive(Clone, Debug, Default, Serialize, Deserialize)]
+pub struct Metadata {
+ #[serde(skip_serializing_if = "Option::is_none")]
+ pub crs: Option<String>, // TODO: explore when this is valid JSON to avoid
double escaping
+ #[serde(skip_serializing_if = "Option::is_none")]
+ pub algorithm: Option<String>,
+ #[serde(skip_serializing_if = "Option::is_none")]
+ type_hint: Option<Hint>,
+}
+
+impl Metadata {
+ pub fn new(crs: Option<String>, algorithm: Option<String>) -> Self {
+ Self {
+ crs,
+ algorithm,
+ type_hint: None,
+ }
+ }
+
+ pub fn with_type_hint(mut self, type_hint: Hint) -> Self {
+ self.type_hint = Some(type_hint);
+ self
+ }
+
+ pub fn set_type_hint(&mut self, type_hint: Hint) {
+ self.type_hint = Some(type_hint)
+ }
+
+ pub fn type_hint(&self) -> Option<Hint> {
+ if self.type_hint.is_some() {
+ return self.type_hint;
+ }
+
+ match &self.algorithm {
+ Some(s) if s.to_lowercase() == "planar" => Some(Hint::Geometry),
+ Some(_) => Some(Hint::Geography),
+ None => None,
+ }
+ }
+}
+
+#[derive(Debug, Default)]
+pub struct WkbType(Metadata);
+
+impl WkbType {
+ pub fn new_geometry(metadata: Option<Metadata>) -> Self {
+ Self(metadata.unwrap_or_default().with_type_hint(Hint::Geometry))
+ }
+
+ pub fn new_geography(metadata: Option<Metadata>) -> Self {
+ Self(metadata.unwrap_or_default().with_type_hint(Hint::Geography))
+ }
+}
+
+impl ExtensionType for WkbType {
+ const NAME: &'static str = "geoarrow.wkb";
+
+ type Metadata = Metadata;
+
+ fn metadata(&self) -> &Self::Metadata {
+ &self.0
+ }
+
+ fn serialize_metadata(&self) -> Option<String> {
+ serde_json::to_string(&self.0).ok()
+ }
+
+ fn deserialize_metadata(metadata: Option<&str>) -> Result<Self::Metadata> {
+ let Some(metadata) = metadata else {
+ return Ok(Self::Metadata::default());
+ };
+
+ serde_json::from_str(metadata).map_err(|e|
ArrowError::JsonError(e.to_string()))
+ }
+
+ fn supports_data_type(&self, data_type: &arrow_schema::DataType) ->
Result<()> {
+ match data_type {
+ DataType::Binary | DataType::LargeBinary | DataType::BinaryView =>
Ok(()),
+ dt => Err(ArrowError::InvalidArgumentError(format!(
+ "Geometry data type mismatch, expected one of Binary,
LargeBinary, BinaryView. Found {dt}"
+ ))),
+ }
+ }
+
+ fn try_new(data_type: &arrow_schema::DataType, metadata: Self::Metadata)
-> Result<Self> {
+ let wkb = Self(metadata);
+ wkb.supports_data_type(data_type)?;
+ Ok(wkb)
+ }
+}
+
+#[derive(Debug)]
+pub struct WkbArray {
+ inner: ArrayRef,
+ metadata: Metadata,
+}
+
+impl WkbArray {
Review Comment:
This `WkbArray` is a new addition in this most recent commit.
@alamb do you have some time to quickly look over this new type (as it's
still WIP) and provide any feedback regarding the general API? I've tried to
mimic the work done for the `VariantArray` as closely as possible.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]