Question about how to fix InvalidGeoArrow error with Wkt Array
#1410
|
Thank you for your excellent work on geoarrow.
All my code compiles fine but I get an error saying the following which I am confused on how to fix. My Code / ContextBelow is a minimum viable example for constructing geoparquet. However, I am unclear why it is failing.
use std::sync::Arc;
use arrow_array::{self, ArrayRef, Int32Array, RecordBatch};
use geo_types::Geometry;
use geoarrow_array::{GeoArrowArray, builder::GeometryBuilder};
use geoarrow_schema::GeometryType;
use wkt::TryFromWkt;
use arrow_schema::{DataType::Int32, Field, SchemaBuilder};
use geoarrow_schema::GeoArrowType;
use geoparquet::writer::{GeoParquetRecordBatchEncoder, GeoParquetWriterOptionsBuilder};
use parquet::arrow::ArrowWriter;
pub fn new_parquet_creator(
file_name: &str,
) -> (GeoParquetRecordBatchEncoder, ArrowWriter<std::fs::File>) {
let options = GeoParquetWriterOptionsBuilder::default()
.set_primary_column("geometry".to_string())
.build();
let mut schema_builder = SchemaBuilder::new();
let geoarrow_type = GeoArrowType::Geometry(GeometryType::default());
let geometry_field = geoarrow_type.to_field("geometry", false);
schema_builder.push(geometry_field);
let geoconnex_pid = Field::new("id", Int32, false);
schema_builder.push(geoconnex_pid);
let schema = schema_builder.finish();
let gpq_encoder = GeoParquetRecordBatchEncoder::try_new(&schema, &options).unwrap();
let output_file = std::fs::File::create(file_name).unwrap();
let parquet_writer =
ArrowWriter::try_new(output_file, gpq_encoder.target_schema(), None).unwrap();
(gpq_encoder, parquet_writer)
}
fn main() {
let (mut gpq_encoder, mut parquet_writer) = new_parquet_creator("test.parquet");
let col = Arc::new(Int32Array::from_iter_values([2, 2, 4])) as ArrayRef;
let geometry1 = Geometry::try_from_wkt_str("POINT (1 2)").unwrap();
let geometry2 = Geometry::try_from_wkt_str("POINT (1 3)").unwrap();
let geometry3 = Geometry::try_from_wkt_str("POINT (1 3)").unwrap();
let generic_geometry_type = GeometryType::new(Default::default());
let mut builder = GeometryBuilder::new(generic_geometry_type);
builder.push_geometry(Some(&geometry1)).unwrap();
builder.push_geometry(Some(&geometry2)).unwrap();
builder.push_geometry(Some(&geometry3)).unwrap();
let geom_array = builder.finish();
let batch =
RecordBatch::try_from_iter([("geometry", geom_array.to_array_ref()), ("id", col)]).unwrap();
for batch in [batch] {
let encoded_batch = gpq_encoder.encode_record_batch(&batch).unwrap();
parquet_writer.write(&encoded_batch).unwrap();
}
let kv_metadata = gpq_encoder.into_keyvalue().unwrap();
parquet_writer.append_key_value_metadata(kv_metadata);
parquet_writer.finish().unwrap();
} |
Replies: 2 comments 3 replies
Can you say what line of code that's coming from? |
|
I'm not sure if this is the exact issue you're hitting, but you'll also hit similar issues with this: When you're doing this, you're saying to Instead, you need to always explicitly pass the schema with This is mostly a documentation issue but I'm not sure where else to document it. I have one such note on |
I'm not sure if this is the exact issue you're hitting, but you'll also hit similar issues with this:
When you're doing this, you're saying to
RecordBatchto infer the schema for you. The problem is that when you callto_array_ref, theArc<dyn Array>loses all information about the extension type.Instead, you need to always explicitly pass the schema with
RecordBatch::try_new, where you build the schema yourself. And any GeoArrow fields should be created with, e.g.GeoArrowType::to_schema.This is mostly a documentation issue but I'm not sure where else to document it. I …