@@ -349,49 +349,80 @@ def to_xarray(
349349
350350 return xd
351351
352+
353+ def _build_cube_metadata (self , ds_dict : dict ) -> tuple [dict , dict ]:
354+ """
355+ Build cube:dimensions and cube:variables from a dict of xarray.Dataset.
356+
357+ :param ds_dict: dictionary of xarray.Dataset
358+ :return: tuple (dimensions_dict, variables_dict)
359+ """
360+ dimensions = {}
361+ variables = {}
362+
363+ for ds in ds_dict .values ():
364+ # Dimensions
365+ for dim_name in ds .sizes .keys ():
366+ dim_name_str = str (dim_name )
367+
368+ # Type
369+ dim_type = (
370+ "spatial" if dim_name_str in ("x" , "y" , "lon" , "lat" ) else
371+ "temporal" if dim_name_str == "time" else
372+ "other"
373+ )
374+
375+ dim_entry : dict [str , Any ] = {"type" : dim_type }
376+
377+ # Extent or values
378+ if dim_name_str in ds .coords :
379+ values = ds [dim_name_str ].values
380+ if values .ndim == 1 :
381+ dim_entry ["values" ] = values .tolist ()
382+ else :
383+ dim_entry ["extent" ] = [float (values .min ()), float (values .max ())]
384+
385+ if dim_type != "temporal" :
386+ # Reference system
387+ epsg_code = 4326 # default
388+ if hasattr (ds , "rio" ) and hasattr (ds .rio , "crs" ) and ds .rio .crs is not None :
389+ epsg_code = ds .rio .crs .to_epsg ()
390+ dim_entry ["reference_system" ] = epsg_code
391+
392+ dimensions [dim_name_str ] = dim_entry
393+
394+ # Variables
395+ for var_name , var in ds .data_vars .items ():
396+ variables [str (var_name )] = {"dimensions" : list (var .dims ), "type" : "data" }
397+
398+ return dimensions , variables
399+
400+
352401 def augment_from_xarray (self ) -> EOProduct :
353402 """
354403 Annotate the product properties with dimensions and variables
355404 information from its xarray representation.
356405 :returns: updated EOProduct
357406 """
358- for asset_key , asset in self .assets . items () :
407+ if not self .assets :
359408 try :
360- xd = self .to_xarray (asset_key = asset_key )
409+ xd = self .to_xarray ()
361410 except Exception :
362- continue
411+ return self
412+
413+ dimensions , variables = self ._build_cube_metadata (xd )
414+ self .properties ["cube:dimensions" ] = dimensions
415+ self .properties ["cube:variables" ] = variables
416+
417+ else :
418+ for asset_key , asset in self .assets .items ():
419+ try :
420+ xd = self .to_xarray (asset_key = asset_key )
421+ except Exception :
422+ continue
363423
364- dimensions = {}
365- variables = {}
366-
367- for _ , ds in xd .items ():
368- # Dimensions
369- for dim_name , _ in ds .sizes .items ():
370- dim_name_str = str (dim_name )
371- dim_entry : dict [str , Any ] = {
372- "type" : "spatial"
373- if dim_name_str in ("x" , "y" , "lon" , "lat" )
374- else "temporal"
375- if dim_name_str == "time"
376- else "other"
377- }
378-
379- # Add extent or values if available
380- if dim_name_str in ds .coords :
381- values = ds [dim_name_str ].values
382- if values .ndim == 1 :
383- dim_entry ["values" ] = values .tolist ()
384- else :
385- dim_entry ["extent" ] = [float (values .min ()), float (values .max ())]
386-
387- dimensions [dim_name_str ] = dim_entry
388-
389- # Variables
390- for var_name , var in ds .data_vars .items ():
391- variables [str (var_name )] = {"dimensions" : list (var .dims ), "type" : "data" }
392-
393- asset .setdefault ("properties" , {})
394- asset ["properties" ]["cube:dimensions" ] = dimensions
395- asset ["properties" ]["cube:variables" ] = variables
424+ dimensions , variables = self ._build_cube_metadata (xd )
425+ asset ["cube:dimensions" ] = dimensions
426+ asset ["cube:variables" ] = variables
396427
397428 return self
0 commit comments