odc-stac
Pourquoi utiliser odc-stac ?
odc-stac vous permet de charger des ensembles de données de Digital Earth Africa dans votre propre environnement informatique. Bien que Digital Earth Africa fournisse aux utilisateurs un environnement Jupyter Lab géré avec des ressources informatiques limitées, c’est-à-dire Analysis Sandbox, pour interagir avec et analyser les données d’observation de la Terre de Digital Earth Africa, cet environnement informatique présente les inconvénients suivants :
Étant donné qu’il s’agit d’un environnement géré, l’utilisateur est limité dans la personnalisation de l’Analysis Sandbox en fonction de ses besoins. Si vous souhaitez utiliser des modules/packages en dehors des packages préchargés dans l’Analysis Sandbox par défaut, vous devrez les réinstaller à chaque démarrage de votre environnement Analysis Sandbox car ils ne sont pas persistants.
Réaliser une analyse sur une grande zone comme un pays entier peut s’avérer difficile, même avec l’environnement plus vaste de 32 Go fourni.
L’accès aux ensembles de données provenant de sources autres que Digital Earth Africa nécessite de télécharger les données sur votre machine locale, puis de télécharger les données dans Analysis Sandbox.
Le odc-stac est une alternative appropriée à l’utilisation du Sandbox Analyis, car il s’agit d’un ensemble d’outils qui convertit les métadonnées STAC en modèle de données Open Data Cube. odc-stac vous permet de charger des éléments STAC dans xarray.Datasets et de les traiter localement ou de distribuer le chargement et le calcul des données avec Dask.
Tableau 1 : Comparaison entre les concepts ODC et STAC.
STAC |
ODC |
Description |
|---|---|---|
Recueil d’observations dans l’espace et dans le temps |
||
Observation unique (heure et lieu précis), multi-canaux |
||
Composante d’une observation unique |
||
Plan de pixels dans un élément multi-plans |
||
Alias |
Se référer au même groupe par des termes différents |
Digital Earth Africa stocke une gamme de produits de données sur le Simple Cloud Storage (S3) d’Amazon Web Service avec un accès public gratuit. Digital Earth Africa fournit également un point de terminaison de catalogue d’actifs spatio-temporels (STAC) pour répertorier ou rechercher les métadonnées, par exemple le cadre de délimitation (coordonnées de la zone d’intérêt), la collecte et la date et l’heure, pour cette archive ici : https://explorer.digitalearth.africa/stac. En utilisant le point de terminaison STAC fourni, le module odc-stac vous donne la possibilité d’accéder aux données d’observation de la Terre de Digital Earth Africa en dehors du bac à sable d’analyse, sur vos propres ressources, que ce soit localement ou sur un service cloud tel qu’Amazon Web Services (AWS), à partir de l’environnement Python de votre choix, dans le même format (en tant que xarray.Dataset) que vous le feriez dans le bac à sable d’analyse. Vous pouvez également utiliser odc-stac pour charger d’autres données d’observation de la Terre conformes à STAC en tant que xarray.Dataset.
Démarrer avec odc-stac
Les instructions sur la façon d’installer le module « odc-stac » dans votre environnement Python sont fournies ici <https://odc-stac.readthedocs.io/en/latest/intro.html#installation>.
Des exemples de blocs-notes sur la façon dont vous pouvez utiliser « odc-stac » peuvent être consultés ici :
Pour télécharger et exécuter ces blocs-notes, visitez le référentiel Github odc-stac <https://github.com/opendatacube/odc-stac/tree/develop/notebooks>`__.
Pour en savoir plus sur « odc-stac », consultez la documentation « odc-stac » <https://odc-stac.readthedocs.io/en/latest> » et le référentiel Github « odc-stac » <https://github.com/opendatacube/odc-stac> ».
Exemple complet pour Digital Earth Africa
Cet exemple illustre un flux de travail d’analyse simple basé sur le produit annuel Landsat-8 et Landsat-9 GeoMAD de Digital Earth Africa. Dans cet exemple, nous allons charger les données annuelles Landsat-8 et Landsat-9 GeoMAD à l’aide de la fonction odc.stac stac_load puis calculer l’indice d’eau normalisé modifié (MNDWI). Nous allons ensuite tracer les résultats de la classification de l’eau de l’indice MNDWI.
Remarque : pour exécuter cet exemple en dehors du sandbox d’analyse Digital Earth Africa, téléchargez cet exemple en tant que Jupyter notebook et le script Python get_product_config.py.
Charger des paquets
[1]:
import pprint
import matplotlib.pyplot as plt
import numpy as np
import seaborn as sns
from get_product_config import get_product_config
from pystac_client import Client
from odc.stac import configure_rio, stac_load
Définir la configuration de la collection
Le but du dictionnaire de configuration est de fournir certaines extensions STAC facultatives qui pourraient manquer à une source de données. Ces informations manquantes incluent le type de données de pixel, la valeur nodata, l’attribut d’unité et les alias de bande. Le dictionnaire de configuration est passé au paramètre odc.stac.load stac_cfg= afin de fournir les informations manquantes au moment du chargement.
La configuration est par collection par ressource et est déterminée à partir de la définition du produit. La définition annuelle du produit Landsat-8 et Landsat-9 GeoMAD est disponible à l’adresse https://explorer.digitalearth.africa/products/gm_ls8_ls9_annual.
[2]:
product_name = "gm_ls8_ls9_annual"
# Set the profile to specify that the product is a Digital Earth Africa product.
profile = "deafrica"
config = get_product_config(product_name, profile)
pprint.pprint(config)
{'gm_ls8_ls9_annual': {'aliases': {'BCDEV': 'BCMAD',
'EDEV': 'EMAD',
'SDEV': 'SMAD',
'band_2': 'SR_B2',
'band_3': 'SR_B3',
'band_4': 'SR_B4',
'band_5': 'SR_B5',
'band_6': 'SR_B6',
'band_7': 'SR_B7',
'bcdev': 'BCMAD',
'bcmad': 'BCMAD',
'blue': 'SR_B2',
'count': 'COUNT',
'edev': 'EMAD',
'emad': 'EMAD',
'green': 'SR_B3',
'nir': 'SR_B5',
'red': 'SR_B4',
'sdev': 'SMAD',
'smad': 'SMAD',
'swir_1': 'SR_B6',
'swir_2': 'SR_B7'},
'assets': {'BCMAD': {'data_type': 'float32',
'nodata': 'NaN',
'unit': '1'},
'COUNT': {'data_type': 'uint16',
'nodata': 0,
'unit': '1'},
'EMAD': {'data_type': 'float32',
'nodata': 'NaN',
'unit': '1'},
'SMAD': {'data_type': 'float32',
'nodata': 'NaN',
'unit': '1'},
'SR_B2': {'data_type': 'uint16',
'nodata': 0,
'unit': '1'},
'SR_B3': {'data_type': 'uint16',
'nodata': 0,
'unit': '1'},
'SR_B4': {'data_type': 'uint16',
'nodata': 0,
'unit': '1'},
'SR_B5': {'data_type': 'uint16',
'nodata': 0,
'unit': '1'},
'SR_B6': {'data_type': 'uint16',
'nodata': 0,
'unit': '1'},
'SR_B7': {'data_type': 'uint16',
'nodata': 0,
'unit': '1'}}}}
Définir la configuration AWS
Les données de Digital Earth Africa sont stockées sur S3 au Cap, en Afrique. Pour charger les données, nous devons configurer rasterio avec le point de terminaison AWS S3 approprié. Cela peut être fait avec la fonction « odc.stac.configure_rio ». La documentation de cette fonction est disponible à l’adresse https://odc-stac.readthedocs.io/en/latest/_api/odc.stac.configure_rio.html#odc.stac.configure_rio.
La configuration ci-dessous doit être utilisée lors du chargement de données Digital Earth Africa via l’API STAC.
[3]:
configure_rio(
cloud_defaults=True,
aws={"aws_unsigned": True},
AWS_S3_ENDPOINT="s3.af-south-1.amazonaws.com",
)
Connectez-vous au catalogue STAC de Digital Earth Africa
[4]:
# Open the stac catalogue.
catalog = Client.open("https://explorer.digitalearth.africa/stac")
Rechercher les éléments STAC à charger
Définir les paramètres de la requête
Remarque : La composition annuelle Landsat-8 et Landsat-9 GeoMAD est disponible pour les années 2021 - présent.
Une façon de définir la zone d’étude/la zone de délimitation consiste à définir une paire de coordonnées de latitude et de longitude centrales, « (central_lat, central_lon) », puis à spécifier le nombre de degrés à inclure de chaque côté de la latitude et de la longitude centrales, appelé « tampon ». Ensemble, ces paramètres spécifient une zone d’étude carrée, comme indiqué ci-dessous :
[5]:
# Set the central latitude and longitude.
central_lat = -5.9460
central_lon = 35.5188
# Set the buffer to load around the central coordinates.
buffer = 0.03
# Compute the bounding box for the study area
study_area_lat = (central_lat - buffer, central_lat + buffer)
study_area_lon = (central_lon - buffer, central_lon + buffer)
# Set the bounding box.
# [xmin, ymin, xmax, ymax] in latitude and longitude (EPSG:4326).
bbox = [study_area_lon[0], study_area_lat[0], study_area_lon[1], study_area_lat[1]]
[6]:
# Set a start and end date.
start_date = "2021"
end_date = "2021"
# Set the STAC collections.
collections = [product_name]
Créez une requête et obtenez des éléments du catalogue Digital Earth Africa STAC
[7]:
# Build a query with the set parameters
query = catalog.search(
bbox=bbox, collections=collections, datetime=f"{start_date}/{end_date}"
)
# Search the STAC catalog for all items matching the query
items = list(query.get_items())
print(f"Found: {len(items):d} datasets")
Found: 1 datasets
Charger les données GeoMAD
Dans cette étape, nous spécifions le système de coordonnées souhaité, la résolution (ici 30 m) et les bandes à charger. Nous allons charger 2 bandes spectrales satellites : « green » et « swir_1 ». Étant donné que les alias de bande sont contenus dans le dictionnaire « config », les bandes peuvent être chargées en utilisant ces alias au lieu du numéro de bande, par exemple « swir_1 » au lieu de « SR_B6 ».
Nous transmettons également le cadre de délimitation à la fonction « stac_load » pour charger uniquement les données demandées. Les données seront chargées de manière différée avec dask, ce qui signifie qu’elles ne seront chargées en mémoire que lorsque cela sera nécessaire, par exemple lorsqu’elles seront affichées.
[8]:
# Specify the bands to load, the desired crs and resolution.
measurements = ("green", "swir_1")
crs = "EPSG:6933"
resolution = 30
[9]:
# Load the dataset.
ds_ls = stac_load(
items,
bands=measurements,
crs=crs,
resolution=resolution,
chunks={},
stac_cfg=config,
bbox=bbox,
).squeeze()
[10]:
# View the xarray.Dataset.
ds_ls
[10]:
<xarray.Dataset>
Dimensions: (y: 255, x: 194)
Coordinates:
* y (y) float64 -7.534e+05 -7.534e+05 ... -7.61e+05 -7.61e+05
* x (x) float64 3.424e+06 3.424e+06 3.424e+06 ... 3.43e+06 3.43e+06
spatial_ref int32 6933
time datetime64[ns] 2021-01-01
Data variables:
green (y, x) uint16 dask.array<chunksize=(255, 194), meta=np.ndarray>
swir_1 (y, x) uint16 dask.array<chunksize=(255, 194), meta=np.ndarray>Calculer l’indice MNDWI
Après avoir chargé les données, vous pouvez effectuer des opérations « xarray » standard, telles que le calcul de l’indice de différence normalisée modifiée de l’eau (MNDWI).
Remarque : la méthode « .compute() » déclenche le chargement des données en mémoire par Dask.
[11]:
# Normalize the data by dividing the data by 10,000.
ds_ls = ds_ls / 10000
# Calculate the MNDWI index.
ds_ls["MNDWI"] = (ds_ls.green - ds_ls.swir_1) / (ds_ls.green + ds_ls.swir_1)
# Convert the xarray.Dataset to a DataArray.
mndwi = ds_ls.MNDWI.compute()
CPLReleaseMutex: Error = 1 (Operation not permitted)
Si la valeur « MNDWI » d’un pixel est supérieure à « 0 », c’est-à-dire « MNDWI »> « 0 », alors le pixel est classé comme eau.
[12]:
water_mndwi = mndwi.where(mndwi > 0.5, np.nan)
water_mndwi = water_mndwi.where(np.isnan(water_mndwi), 1)
Tracer les étendues d’eau du MNDWI et du MNDWI
[13]:
# Plot.
fig, ax = plt.subplots(1, 2, figsize=(14, 6))
mndwi.plot(ax=ax[0], cmap="RdBu")
water_mndwi.plot(ax=ax[1])
ax[0].set_title("Landsat 8-9 GeoMAD MNDWI 2021")
ax[1].set_title("Landsat 8-9 GeoMAD MNDWI water extent 2021")
plt.tight_layout();