Skip to content

Commit 0ae3cc4

Browse files
committed
Fix some grid_spec warnings
Make a private function that extracts the same product information that was previously gotten from the now deprecated grid_spec, and then use that helper instead of grid_spec. The helper should be removed once there are suitable replacements in some part of the opendatacube-API.
1 parent 4eda554 commit 0ae3cc4

File tree

1 file changed

+29
-13
lines changed

1 file changed

+29
-13
lines changed

cubedash/summary/_extents.py

Lines changed: 29 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
from dataclasses import dataclass
55
from datetime import date, datetime
66
from pathlib import Path
7-
from typing import Dict, Iterable, List, Optional, TypeAlias
7+
from typing import Any, Dict, Iterable, List, Optional, TypeAlias
88

99
import fiona
1010
import structlog
@@ -15,6 +15,7 @@
1515
from datacube.model import Dataset, Field, MetadataType, Product
1616
from geoalchemy2 import Geometry, WKBElement
1717
from geoalchemy2.shape import to_shape
18+
from odc.geo import CRS
1819
from psycopg2._range import Range as PgRange
1920
from shapely.geometry import shape
2021
from sqlalchemy import (
@@ -287,12 +288,9 @@ def _select_dataset_extent_columns(
287288
# Some time-series-derived products have seemingly-rectangular but *huge* footprints
288289
# (because they union many almost-indistinguishable footprints)
289290
# If they specify a resolution, we can simplify the geometry based on it.
290-
if (
291-
footprint_expression is not None
292-
and product.grid_spec
293-
and product.grid_spec.resolution
294-
):
295-
resolution = min(abs(r) for r in product.grid_spec.resolution)
291+
info = _product_info(product)
292+
if footprint_expression is not None and info is not None:
293+
resolution = min(abs(r) for r in info.resolution)
296294
footprint_expression = func.ST_SimplifyPreserveTopology(
297295
footprint_expression, resolution / 4
298296
)
@@ -442,15 +440,15 @@ def for_product(
442440
"region_code"
443441
)
444442

445-
grid_spec = product.grid_spec
446443
# Ingested grids trump the "region_code" field because they've probably sliced it up smaller.
447444
#
448445
# hltc has a grid spec, but most attributes are missing, so grid_spec functions fail.
449446
# Therefore: only assume there's a grid if tile_size is specified.
450447
if region_code_field is not None:
451448
# Generic region info
452449
return RegionInfo(product, known_regions)
453-
elif grid_spec is not None and grid_spec.tile_size:
450+
info = _product_info(product)
451+
if info is not None and info.get("tile_size") is not None:
454452
return GridRegionInfo(product, known_regions)
455453
elif "sat_path" in product.metadata_type.dataset_fields:
456454
return SceneRegionInfo(product, known_regions)
@@ -523,7 +521,6 @@ def alchemy_expression(self):
523521
524522
"""
525523
product = self.product
526-
grid_spec = product.grid_spec
527524

528525
doc = jsonb_doc_expression(product.metadata_type)
529526
projection_offset = _projection_doc_offset(product.metadata_type)
@@ -536,9 +533,10 @@ def alchemy_expression(self):
536533
)
537534
)
538535

539-
# todo: look at grid_spec crs. Use it for defaults, conversion.
540-
size_x, size_y = grid_spec.tile_size or (1000.0, 1000.0)
541-
origin_x, origin_y = grid_spec.origin
536+
info = _product_info(product) or {}
537+
# todo: use the CRS for defaults, conversion.
538+
size_x, size_y = info.get("tile_size") or (1000.0, 1000.0)
539+
origin_x, origin_y = info.get("origin") or (0.0, 0.0)
542540
return func.concat(
543541
func.floor((func.ST_X(center_point) - origin_x) / size_x).cast(String),
544542
"_",
@@ -561,6 +559,24 @@ def dataset_region_code(self, dataset: Dataset) -> Optional[str]:
561559
return f"{x}_{y}"
562560

563561

562+
def _product_info(product: Product) -> dict[str, Any] | None:
563+
storage = product.definition.get("storage")
564+
if storage is None:
565+
return None
566+
storage_crs = storage.get("crs")
567+
if storage_crs is None:
568+
return None
569+
crs = CRS(str(storage_crs).strip())
570+
571+
def extract_point(name: str) -> tuple[str] | None:
572+
xx = storage.get(name)
573+
return None if xx is None else tuple(xx[dim] for dim in crs.dimensions)
574+
575+
info = {name: extract_point(name) for name in ("tile_size", "resolution", "origin")}
576+
complete = all(info[k] is not None for k in ("tile_size", "resolution"))
577+
return info if complete else None
578+
579+
564580
def _from_xy_region_code(region_code: str):
565581
"""
566582
>>> _from_xy_region_code('95_3')

0 commit comments

Comments
 (0)