@@ -505,13 +505,19 @@ def extract(self, md: Any) -> RasterGroupMetadata:
505505 # disabled that filter with `ignore_proj=True` option
506506 check_proj = has_proj_ext (item ) and not c .ignore_proj
507507
508- def _keep (kv : tuple [str , pystac .asset .Asset ]) -> bool :
508+ def _keep (kv : tuple [str , pystac .asset .Asset ], check_proj : bool ) -> bool :
509509 name , asset = kv
510510 if name in c .band_cfg :
511511 return True
512512 return is_raster_data (asset , check_proj = check_proj )
513513
514- data_bands = dicttoolz .itemfilter (_keep , item .assets )
514+ data_bands = dicttoolz .itemfilter (lambda kv : _keep (kv , check_proj ), item .assets )
515+
516+ if len (data_bands ) == 0 and check_proj :
517+ # If no data bands found with check_proj=True, fallback to check_proj=False
518+ # This handles items that declare proj extension at item level but don't have
519+ # per-asset proj data (shape/transform)
520+ data_bands = dicttoolz .itemfilter (lambda kv : _keep (kv , False ), item .assets )
515521
516522 bands : dict [BandKey , RasterBandMetadata | AuxBandMetadata ] = {}
517523 aliases = alias_map_from_eo (item )
@@ -665,6 +671,15 @@ def _bootstrap(self, item: pystac.item.Item) -> None:
665671 data_asset_names = set (n for n , _ in meta .bands if n in item .assets )
666672 data_assets = {n : item .assets [n ] for n in data_asset_names }
667673
674+ # Check if any data assets have proj data.
675+ # If item declares proj extension but assets don't have proj data, fall back to has_proj=False
676+ if (
677+ has_proj
678+ and data_assets
679+ and not any (has_proj_data (a ) for a in data_assets .values ())
680+ ):
681+ has_proj = False
682+
668683 # We assume that grouping of data bands into grids is consistent across
669684 # entire collection, so we compute it once and keep it
670685 if has_proj :
0 commit comments