Skip to content

Commit e30a35c

Browse files
committed
fix: add axis, proj:code and proj:bbox; use extend + step
1 parent 8c31b7b commit e30a35c

1 file changed

Lines changed: 57 additions & 13 deletions

File tree

eodag_cube/api/product/_product.py

Lines changed: 57 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
from urllib.parse import urlparse
2727

2828
import fsspec
29+
import numpy as np
2930
import rasterio
3031
from boto3 import Session
3132
from boto3.resources.base import ServiceResource
@@ -360,6 +361,17 @@ def _build_cube_metadata(self, ds_dict: XarrayDict) -> tuple[dict, dict]:
360361
variables = {}
361362

362363
for ds in ds_dict.values():
364+
epsg_code = None
365+
proj_bbox = None
366+
367+
if hasattr(ds, "rio") and ds.rio.crs is not None:
368+
epsg_code = ds.rio.crs.to_epsg()
369+
try:
370+
proj_bbox = list(ds.rio.bounds())
371+
except Exception:
372+
proj_bbox = None
373+
epsg_code = epsg_code or 4326
374+
363375
# Dimensions
364376
for dim_name in ds.sizes.keys():
365377
dim_name_str = str(dim_name)
@@ -375,20 +387,52 @@ def _build_cube_metadata(self, ds_dict: XarrayDict) -> tuple[dict, dict]:
375387

376388
dim_entry: dict[str, Any] = {"type": dim_type}
377389

378-
# Extent or values
379-
if dim_name_str in ds.coords:
380-
values = ds[dim_name_str].values
381-
if values.ndim == 1:
382-
dim_entry["values"] = values.tolist()
383-
else:
384-
dim_entry["extent"] = [float(values.min()), float(values.max())]
385-
386-
if dim_type != "temporal":
387-
# Reference system
388-
epsg_code = 4326 # default
389-
if hasattr(ds, "rio") and hasattr(ds.rio, "crs") and ds.rio.crs is not None:
390-
epsg_code = ds.rio.crs.to_epsg()
390+
if dim_type == "spatial":
391+
# Axis
392+
if dim_name_str in ("x", "lon"):
393+
dim_entry["axis"] = "x"
394+
elif dim_name_str in ("y", "lat"):
395+
dim_entry["axis"] = "y"
396+
elif dim_name_str == "z":
397+
dim_entry["axis"] = "z"
398+
391399
dim_entry["reference_system"] = epsg_code
400+
dim_entry["proj:code"] = epsg_code
401+
402+
if proj_bbox is not None:
403+
dim_entry["proj:bbox"] = proj_bbox
404+
405+
# Extent + step
406+
if dim_name_str in ds.coords:
407+
values = ds[dim_name_str].values
408+
dim_entry["extent"] = [
409+
float(np.nanmin(values)),
410+
float(np.nanmax(values)),
411+
]
412+
413+
if values.ndim == 1 and values.size > 1:
414+
diffs = np.diff(values)
415+
dim_entry["step"] = (
416+
float(diffs[0]) if np.allclose(diffs, diffs[0]) else None
417+
)
418+
419+
elif dim_type == "temporal":
420+
values = ds[dim_name_str].values
421+
dim_entry["extent"] = [
422+
str(values.min()),
423+
str(values.max()),
424+
]
425+
426+
if values.size > 1:
427+
diffs = np.diff(values.astype("datetime64[ns]"))
428+
dim_entry["step"] = (
429+
str(diffs[0]) if np.all(diffs == diffs[0]) else None
430+
)
431+
else:
432+
if dim_name_str in ds.coords:
433+
values = ds[dim_name_str].values
434+
if values.ndim == 1:
435+
dim_entry["values"] = values.tolist()
392436

393437
dimensions[dim_name_str] = dim_entry
394438

0 commit comments

Comments
 (0)