Skip to content

Get assets by eo:bands common_name or name #1140

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Jun 2, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
- Updated raster extension to work with the item_assets extension's AssetDefinition objects ([#1110](https://github.com/stac-utils/pystac/pull/1110))
- Classification extension ([#1093](https://github.com/stac-utils/pystac/pull/1093)), with support for adding classification information to item_assets' `AssetDefinition`s and raster's `RasterBand` objects.
- `get_derived_from`, `add_derived_from` and `remove_derived_from` to Items ([#1136](https://github.com/stac-utils/pystac/pull/1136))
- `ItemEOExtension.get_assets` for getting assets filtered on band `name` or `common_name` ([#1140](https://github.com/stac-utils/pystac/pull/1140))

### Changed

Expand Down
29 changes: 29 additions & 0 deletions pystac/extensions/eo.py
Original file line number Diff line number Diff line change
Expand Up @@ -459,6 +459,35 @@ def _get_bands(self) -> Optional[List[Band]]:
return [Band(b) for b in bands]
return None

def get_assets(
self,
name: Optional[str] = None,
common_name: Optional[str] = None,
) -> Dict[str, pystac.Asset]:
"""Get the item's assets where eo:bands are defined.

Args:
name: If set, filter the assets such that only those with a
matching ``eo:band.name`` are returned.
common_name: If set, filter the assets such that only those with a matching
``eo:band.common_name`` are returned.

Returns:
Dict[str, Asset]: A dictionary of assets that match ``name``
and/or ``common_name`` if set or else all of this item's assets were
eo:bands are defined.
"""
kwargs = {"name": name, "common_name": common_name}
return {
key: asset
for key, asset in self.item.get_assets().items()
if BANDS_PROP in asset.extra_fields
and all(
v is None or any(v == b.get(k) for b in asset.extra_fields[BANDS_PROP])
for k, v in kwargs.items()
)
}

def __repr__(self) -> str:
return "<ItemEOExtension Item id={}>".format(self.item.id)

Expand Down
31 changes: 31 additions & 0 deletions tests/extensions/test_eo.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import json
import unittest
from typing import Dict

import pytest

Expand Down Expand Up @@ -441,3 +442,33 @@ def test_older_extension_version(ext_item: Item) -> None:
migrated_item = pystac.Item.from_dict(item_as_dict, migrate=True)
assert EOExtension.has_extension(migrated_item)
assert new in migrated_item.stac_extensions


@pytest.mark.parametrize(
"filter,count",
[
(dict(), 11),
({"name": "B4"}, 1),
({"common_name": "blue"}, 1),
({"name": "B4", "common_name": "red"}, 1),
({"name": "B4", "common_name": "green"}, 0),
],
)
def test_get_assets(ext_item: pystac.Item, filter: Dict[str, str], count: int) -> None:
assets = EOExtension.ext(ext_item).get_assets(**filter) # type:ignore
assert len(assets) == count


def test_get_assets_works_even_if_band_info_is_incomplete(
ext_item: pystac.Item,
) -> None:
name = ext_item.assets["B4"].extra_fields["eo:bands"][0].pop("name")
common_name = ext_item.assets["B2"].extra_fields["eo:bands"][0].pop("common_name")

eo_ext = EOExtension.ext(ext_item)

assets = eo_ext.get_assets(name=name) # type:ignore
assert len(assets) == 0

assets = eo_ext.get_assets(common_name=common_name) # type:ignore
assert len(assets) == 0