Skip to main content

geoarrow_geojson/encoder/
factory.rs

1use arrow_array::Array;
2use arrow_json::writer::NullableEncoder;
3use arrow_json::{Encoder, EncoderFactory, EncoderOptions};
4use arrow_schema::{ArrowError, FieldRef};
5use geoarrow_schema::GeoArrowType;
6
7use crate::encoder::geometry::GeometryEncoder;
8use crate::encoder::geometrycollection::GeometryCollectionEncoder;
9use crate::encoder::linestring::LineStringEncoder;
10use crate::encoder::multilinestring::MultiLineStringEncoder;
11use crate::encoder::multipoint::MultiPointEncoder;
12use crate::encoder::multipolygon::MultiPolygonEncoder;
13use crate::encoder::point::PointEncoder;
14use crate::encoder::polygon::PolygonEncoder;
15use crate::encoder::rect::RectEncoder;
16use crate::encoder::wkb::{GenericWkbEncoder, WkbViewEncoder};
17use crate::encoder::wkt::{GenericWktEncoder, WktViewEncoder};
18
19/// A [EncoderFactory] for writing GeoArrow arrays.
20#[derive(Debug)]
21pub struct GeoArrowEncoderFactory;
22
23impl EncoderFactory for GeoArrowEncoderFactory {
24    fn make_default_encoder<'a>(
25        &self,
26        field: &'a FieldRef,
27        array: &'a dyn Array,
28        _options: &'a EncoderOptions,
29    ) -> Result<Option<NullableEncoder<'a>>, ArrowError> {
30        if let Some(geoarrow_type) = GeoArrowType::from_extension_field(field)
31            .map_err(|e| ArrowError::from_external_error(Box::new(e)))?
32        {
33            let nulls = array.logical_nulls();
34            let encoder: Box<dyn Encoder> = match geoarrow_type {
35                GeoArrowType::Point(typ) => Box::new(PointEncoder::new((array, typ).try_into()?)),
36                GeoArrowType::LineString(typ) => {
37                    Box::new(LineStringEncoder::new((array, typ).try_into()?))
38                }
39                GeoArrowType::Polygon(typ) => {
40                    Box::new(PolygonEncoder::new((array, typ).try_into()?))
41                }
42                GeoArrowType::MultiPoint(typ) => {
43                    Box::new(MultiPointEncoder::new((array, typ).try_into()?))
44                }
45                GeoArrowType::MultiLineString(typ) => {
46                    Box::new(MultiLineStringEncoder::new((array, typ).try_into()?))
47                }
48                GeoArrowType::MultiPolygon(typ) => {
49                    Box::new(MultiPolygonEncoder::new((array, typ).try_into()?))
50                }
51                GeoArrowType::Geometry(typ) => {
52                    Box::new(GeometryEncoder::new((array, typ).try_into()?))
53                }
54                GeoArrowType::GeometryCollection(typ) => {
55                    Box::new(GeometryCollectionEncoder::new((array, typ).try_into()?))
56                }
57                GeoArrowType::Wkb(typ) => {
58                    Box::new(GenericWkbEncoder::<i32>::new((array, typ).try_into()?))
59                }
60                GeoArrowType::LargeWkb(typ) => {
61                    Box::new(GenericWkbEncoder::<i64>::new((array, typ).try_into()?))
62                }
63                GeoArrowType::WkbView(typ) => {
64                    Box::new(WkbViewEncoder::new((array, typ).try_into()?))
65                }
66                GeoArrowType::Wkt(typ) => {
67                    Box::new(GenericWktEncoder::<i32>::new((array, typ).try_into()?))
68                }
69                GeoArrowType::LargeWkt(typ) => {
70                    Box::new(GenericWktEncoder::<i64>::new((array, typ).try_into()?))
71                }
72                GeoArrowType::WktView(typ) => {
73                    Box::new(WktViewEncoder::new((array, typ).try_into()?))
74                }
75                GeoArrowType::Rect(typ) => Box::new(RectEncoder::new((array, typ).try_into()?)),
76            };
77            Ok(Some(NullableEncoder::new(encoder, nulls)))
78        } else {
79            Ok(None)
80        }
81    }
82}