1- use polars:: prelude:: DataType ;
1+ use std:: collections:: HashMap ;
2+
3+ use geoarrow_schema:: GeoArrowType ;
4+ use geopolars_arrow:: to_arrow:: polars_field_to_arrow;
25use polars:: prelude:: extension:: { ExtensionTypeFactory , ExtensionTypeImpl } ;
6+ use polars:: prelude:: { CompatLevel , DataType } ;
7+
8+ use crate :: geoarrow:: {
9+ BoxType , GeometryCollectionType , GeometryType , LineStringType , MultiLineStringType ,
10+ MultiPointType , MultiPolygonType , PointType , PolygonType , WkbType , WktType ,
11+ } ;
312
13+ /// A factory for creating GeoArrow extension types in Polars.
414pub struct GeoArrowExtensionTypeFactory ;
515
616impl ExtensionTypeFactory for GeoArrowExtensionTypeFactory {
@@ -10,6 +20,55 @@ impl ExtensionTypeFactory for GeoArrowExtensionTypeFactory {
1020 storage : & DataType ,
1121 metadata : Option < & str > ,
1222 ) -> Box < dyn ExtensionTypeImpl > {
13- todo ! ( )
23+ let arrow_data_type = polars_storage_type_to_arrow_data_type ( storage) ;
24+
25+ // Create Arrow field with extension metadata
26+ let mut arrow_metadata = HashMap :: < String , String > :: with_capacity ( 2 ) ;
27+ arrow_metadata. insert (
28+ arrow_schema:: extension:: EXTENSION_TYPE_NAME_KEY . to_string ( ) ,
29+ name. to_string ( ) ,
30+ ) ;
31+ if let Some ( metadata) = metadata {
32+ arrow_metadata. insert (
33+ arrow_schema:: extension:: EXTENSION_TYPE_METADATA_KEY . to_string ( ) ,
34+ metadata. to_string ( ) ,
35+ ) ;
36+ }
37+
38+ let arrow_field =
39+ arrow_schema:: Field :: new ( "" , arrow_data_type, true ) . with_metadata ( arrow_metadata) ;
40+
41+ // TODO: are we assured that the name matches the type here?
42+ // What do we do if the storage type isn't compatible with the extension type?
43+ let geoarrow_type = GeoArrowType :: from_extension_field ( & arrow_field)
44+ . expect ( "Creation of GeoArrow extension type" ) ;
45+
46+ match geoarrow_type {
47+ GeoArrowType :: Point ( t) => Box :: new ( PointType :: new ( t) ) ,
48+ GeoArrowType :: LineString ( t) => Box :: new ( LineStringType :: new ( t) ) ,
49+ GeoArrowType :: Polygon ( t) => Box :: new ( PolygonType :: new ( t) ) ,
50+ GeoArrowType :: MultiPoint ( t) => Box :: new ( MultiPointType :: new ( t) ) ,
51+ GeoArrowType :: MultiLineString ( t) => Box :: new ( MultiLineStringType :: new ( t) ) ,
52+ GeoArrowType :: MultiPolygon ( t) => Box :: new ( MultiPolygonType :: new ( t) ) ,
53+ GeoArrowType :: GeometryCollection ( t) => Box :: new ( GeometryCollectionType :: new ( t) ) ,
54+ GeoArrowType :: Geometry ( t) => Box :: new ( GeometryType :: new ( t) ) ,
55+ GeoArrowType :: Rect ( t) => Box :: new ( BoxType :: new ( t) ) ,
56+ GeoArrowType :: Wkb ( t) => Box :: new ( WkbType :: new ( t) ) ,
57+ GeoArrowType :: LargeWkb ( t) => Box :: new ( WkbType :: new ( t) ) ,
58+ GeoArrowType :: WkbView ( t) => Box :: new ( WkbType :: new ( t) ) ,
59+ GeoArrowType :: Wkt ( t) => Box :: new ( WktType :: new ( t) ) ,
60+ GeoArrowType :: LargeWkt ( t) => Box :: new ( WktType :: new ( t) ) ,
61+ GeoArrowType :: WktView ( t) => Box :: new ( WktType :: new ( t) ) ,
62+ }
1463 }
1564}
65+
66+ fn polars_storage_type_to_arrow_data_type ( storage : & DataType ) -> arrow_schema:: DataType {
67+ let polars_field = polars_arrow:: datatypes:: Field :: new (
68+ "" . into ( ) ,
69+ storage. to_arrow ( CompatLevel :: newest ( ) ) ,
70+ true ,
71+ ) ;
72+ let arrow_field_from_ffi = polars_field_to_arrow ( & polars_field) ;
73+ arrow_field_from_ffi. data_type ( ) . clone ( )
74+ }
0 commit comments