@@ -459,11 +459,8 @@ def shapely_to_cf(
459
459
"and set the grid mapping variable as a coordinate" ,
460
460
)
461
461
462
- # Get all types to call the appropriate translation function.
463
- types = {
464
- geom .item ().geom_type if isinstance (geom , xr .DataArray ) else geom .geom_type
465
- for geom in geometries
466
- }
462
+ as_data = geometries .data if isinstance (geometries , xr .DataArray ) else geometries
463
+ type_ = as_data [0 ].geom_type
467
464
468
465
grid_mapping_varname = None
469
466
if (
@@ -482,16 +479,21 @@ def shapely_to_cf(
482
479
suffix = suffix , grid_mapping_name = grid_mapping , grid_mapping = grid_mapping_varname
483
480
)
484
481
485
- if types .issubset ({"Point" , "MultiPoint" }):
486
- ds = points_to_cf (geometries , names = names )
487
- elif types .issubset ({"LineString" , "MultiLineString" }):
488
- ds = lines_to_cf (geometries , names = names )
489
- elif types .issubset ({"Polygon" , "MultiPolygon" }):
490
- ds = polygons_to_cf (geometries , names = names )
491
- else :
482
+ try :
483
+ if type_ in ["Point" , "MultiPoint" ]:
484
+ ds = points_to_cf (geometries , names = names )
485
+ elif type_ in ["LineString" , "MultiLineString" ]:
486
+ ds = lines_to_cf (geometries , names = names )
487
+ elif type_ in ["Polygon" , "MultiPolygon" ]:
488
+ ds = polygons_to_cf (geometries , names = names )
489
+ else :
490
+ raise ValueError (
491
+ f"This geometry type is not supported in CF-compliant datasets. Got { type_ } "
492
+ )
493
+ except NotImplementedError as e :
492
494
raise ValueError (
493
- f"Mixed geometry types are not supported in CF-compliant datasets. Got { types } "
494
- )
495
+ "Error converting geometries. Possibly you have provided mixed geometry types. "
496
+ ) from e
495
497
496
498
return ds
497
499
@@ -841,7 +843,7 @@ def polygons_to_cf(
841
843
node_count = part_node_count
842
844
elif len (offsets ) >= 2 :
843
845
indices = np .take (offsets [0 ], offsets [1 ])
844
- interior_ring = np .isin (offsets [0 ], indices , invert = True )[:- 1 ]. astype ( int )
846
+ interior_ring = np .isin (offsets [0 ], indices , invert = True )[:- 1 ]
845
847
846
848
if len (offsets ) == 3 :
847
849
indices = np .take (indices , offsets [2 ])
@@ -852,29 +854,32 @@ def polygons_to_cf(
852
854
crdX = geom_coords [:, 0 ]
853
855
crdY = geom_coords [:, 1 ]
854
856
857
+ data_vars = {names .node_count : (dim , node_count )}
858
+ geometry_attrs = names .geometry_container_attrs
859
+
860
+ # Special case when we have no MultiPolygons and no holes
861
+ if len (part_node_count ) != len (node_count ):
862
+ data_vars [names .part_node_count ] = (names .part_dim , part_node_count )
863
+ geometry_attrs ["part_node_count" ] = names .part_node_count
864
+
865
+ # Special case when we have no holes
866
+ if interior_ring .any ():
867
+ data_vars [names .interior_ring ] = (names .part_dim , interior_ring )
868
+ geometry_attrs ["interior_ring" ] = names .interior_ring
869
+
870
+ data_vars [names .container_name ] = ( # type: ignore[assignment]
871
+ (),
872
+ np .nan ,
873
+ {"geometry_type" : "polygon" , ** geometry_attrs },
874
+ )
855
875
ds = xr .Dataset (
856
- data_vars = {
857
- names .node_count : xr .DataArray (node_count , dims = (dim ,)),
858
- names .container_name : xr .DataArray (
859
- data = np .nan ,
860
- attrs = {"geometry_type" : "polygon" , ** names .geometry_container_attrs },
861
- ),
862
- },
876
+ data_vars = data_vars ,
863
877
coords = names .coords (x = x , y = y , crdX = crdX , crdY = crdY , dim = dim ),
864
878
)
865
879
866
880
if coord is not None :
867
881
ds = ds .assign_coords ({dim : coord })
868
882
869
- # Special case when we have no MultiPolygons and no holes
870
- if len (part_node_count ) != len (node_count ):
871
- ds [names .part_node_count ] = xr .DataArray (part_node_count , dims = names .part_dim )
872
- ds [names .container_name ].attrs ["part_node_count" ] = names .part_node_count
873
-
874
- # Special case when we have no holes
875
- if (interior_ring != 0 ).any ():
876
- ds [names .interior_ring ] = xr .DataArray (interior_ring , dims = names .part_dim )
877
- ds [names .container_name ].attrs ["interior_ring" ] = names .interior_ring
878
883
return ds
879
884
880
885
0 commit comments