08.2 STAC¶
STAC (SpatioTemporal Asset Catalog; https://stacspec.org/) jestiť standardem, jehož cílem je usnadniti vyhledávání produktů a dotazování se na ně. Jeho výhodou je značná jednoduchost a modulárnost umožňující snadné začlenění různých rozšíření.
Komponenty STAC¶
STAC se skládá ze tří komponent - item, catalog a collection. Každá z nich je použitelná i sama o sobě, zpravidla se však v praxi setkáváme s jejich kombinacemi.
Item¶
Základní prvek představující jeden produkt, např. jednu scénu Sentinel-2. Jedná se o GeoJSON obsahující metadata o daném produktu. Tato metadata představují klasická metadata formátu GeoJSON rozšířená o 3 povinná a další nepovinná metadata specifická pro STAC.
Jeden item může odkazovat na více souborů (tzv. assets) - jedna scéna Sentinel-2 se skládá ze samostatných souborů pro jednotlivé kanály a dodatečných souborů.
Catalog¶
Strukturní prvky sloužící k propojení items a collections sloužící k
navigaci skrze nabízené produkty. Jedná se o JSON soubor nazvaný catalog.json.
Catalog může spojovaným itemům a kolekcím přidávat další metadata. Catalog může obsahovat i jiné catalogs, kterým se pak přezdívá sub-catalogs.
Catalog může být dvou typů:
ABSOLUTE_PUBLISHED: Používá absolutní cesty pro links a HREFsRELATIVE_PUBLISHED: Používá relativní cesty pro links a absolutní cestu pro kořenový catalogSELF_CONTAINED: Používá relativní cesty pro vše (ideální pro přenositelnost)
Collection¶
Skupina sdružující související items, např. collection Sentinel-2 by mohla sdružovat nabízené dlaždice jmenovaného satelitního systému. Collection může hromadně rozšiřovat jejich metadata.Jedná se o JSON soubor.
PySTAC¶
Jednou z možností, jak se STACem komunikovati, jestiť Python klient zvaný PySTAC. PySTAC je balíček programovacího jazyku Python pod Apache licencí umožňující nejen STAC prvky a systém vytvářeti, nýbrž se na něj také dotazovati.
Vývojář - Tvorba¶
V této sekci si ukážeme, jak vytvořit a sdílet STAC catalog s testovacími
daty. Testovací data nalezneme v Repository/155FGIS/05/DTM.tif. Zkopírujme
si je do pracovních adresářů (v materiálech používáme /tmp/stac_lesson)
Načtěme si data a získejme potřebná metadata:
import os
import datetime
import rasterio
from shapely.geometry import Polygon, mapping
img_dir = '/tmp/stac_lesson'
filename = 'DTM.tif'
img_path = os.path.join(img_dir, filename)
def get_geometry_metadata(raster: str):
with rasterio.open(raster) as r:
bounds = r.bounds
bbox = (bounds.left, bounds.bottom, bounds.right, bounds.top)
footprint = mapping(
Polygon(
[
[bounds.left, bounds.bottom],
[bounds.left, bounds.top],
[bounds.right, bounds.top],
[bounds.right, bounds.bottom],
]
)
)
return bbox, footprint
bbox, geometry = get_geometry_metadata(img_path)
timestamp = datetime.datetime.now(tz=datetime.timezone.utc)
item_name = os.path.splitext(filename)[0]
Vytvořme si catalog a přesvědčme se, že je v pořádku a čitelný:
import pystac
catalog = pystac.Catalog(
id='fgis-catalog',
description='Tohle je testovaci catalog pro predmet 155FGIS.'
)
# vypis strukturu catalogu
print(f'catalog: \n{catalog.to_dict()}')
# catalog by mel byt prazdny
print(f'popis: {catalog.describe()}')
print(f'childrens: {catalog.get_children()}')
print(f'items: {catalog.get_items()}')
Vytvořme STAC Item, naplnme jej a vložme jej do catalogu:
import pystac
item = pystac.Item(
id=item_name,
geometry=geometry,
bbox=bbox,
datetime=timestamp,
)
print(f'item: {item.to_dict()}')
# vztahy mezi vytvorenymi catalog a item
print(f'parent: {item.get_parent()}')
catalog.add_item(item)
# vztahy mezi vytvorenymi catalog a item
print(f'parent: {item.get_parent()}')
print(f'popis: {catalog.describe()}')
print(f'childrens: {catalog.get_children()}')
print(f'items: {catalog.get_items()}')
# pridejme soubor
item.add_asset(
key='file',
asset=pystac.Asset(
href=img_path,
media_type=pystac.MediaType.GEOTIFF
)
)
print(f'item: {item.to_dict()}')
# normalizujme HREF v links
catalog.normalize_hrefs(os.path.join(img_dir, 'stac'))
print(f'item po normalizaci HREFs: {item.to_dict()}')
# ulozme catalog (ulozi se v adresari stac uvnitr adresare s items)
catalog.save(catalog_type=pystac.CatalogType.SELF_CONTAINED)
# make_all_asset_hrefs_relative()
Nyní bude zapotřebí spustiti STAC. Tak učiníme tím, že se přesuneme do
složky obsahující catalog.json (v našem případě
/tmp/stac_lesson/stac) a spustíme python3 -m http.server. Náš lokální
STAC nyní běží na serveru http://localhost:8000.
Uživatel - Komunikace a dotazy¶
STAC catalog můžeme prozkoumat v pohlížeči, ale pro systematičtější stahování a průzkum dat je zajisté lepší dělati vše automatizovaně. Napišme si tedy za tímto účelem Python skript.
import pystac
catalog = pystac.Catalog.from_file('http://localhost:8000/catalog.json')
print(f'Catalog - popis: {catalog.describe()}')
print(f'Catalog - id: {catalog.id}')
# projdeme si vsechny items a ulozme si je
for item in catalog.get_all_items():
print(f'item: {item.id}')
print(f'extensions: {item.stac_extensions}')
# projdeme si jednotlive assets
for asset_key in item.assets:
print(f'asset: {asset_key}')
print(f'asset - href: {item.assets[asset_key].href}')
# cesta k assetu je lokalni u nas na pocitaci, jinak bychom produkt
# stahovali pres requests


