Remarque
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de vous connecter ou de modifier des répertoires.
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de modifier des répertoires.
Découvrez comment créer un élément SpatioTemporal Asset Catalog (STAC) pour une ressource de données géospatiales raster. Chaque ressource de données géospatiales chargée sur un ordinateur Microsoft Planetary Pro GeoCatalog doit avoir un élément compatible STAC associé.
Dans ce guide, vous allez :
- Installez les bibliothèques Python requises à l’aide de PIP.
- Affichez et inspectez les données GOES-18 à l’aide du code Python fourni.
- Extrayez les métadonnées du nom de fichier à l’aide d’expressions régulières.
- Créez des éléments STAC à partir de fichiers GeoTIFF Cloud-Optimized à l’aide de
rio-stac. - Améliorez l’élément STAC avec les métadonnées extraites du nom de fichier.
- Ajoutez l’élément STAC à une collection STAC parente.
- Validez et enregistrez le catalogue, la collection et les éléments STAC.
- Ajoutez les éléments STAC à Microsoft Planetary Computer Pro.
Ce tutoriel présente et explique les fonctionnalités par le biais d’extraits de code, pour une expérience de style de bloc-notes interactive, téléchargez ce didacticiel en tant que notebook Jupyter.
Conditions préalables
Pour effectuer ce démarrage rapide, les éléments suivants sont requis :
- Un compte Azure avec un abonnement actif. Utilisez le lien pour créer un compte gratuitement.
- Azure CLI : Installer Azure CLI
- Un environnement Python avec au moins la version 3.8.
- Une certaine connaissance de la norme STAC et de son implémentation dans Microsoft Planetary Computer Pro STAC Overview
Fonctionnalités clés de STAC
Le catalogue de ressources SpatioTemporal (STAC) est une norme ouverte pour structurer et partager des données géospatiales. Il fournit un langage et un format communs pour décrire les ressources géospatiales, ce qui facilite la découverte, l’accès et l’utilisation de ces ressources sur différentes plateformes et applications. Voici les principales fonctionnalités de la norme STAC :
- Interopérabilité : le schéma json standardisé garantit une intégration et une compréhension faciles entre les outils et systèmes.
- Extensibilité : champs principaux flexibles avec des extensions personnalisées pour des besoins spécifiques.
- Détectabilité : une structure cohérente améliore la recherche et la découverte des ressources géospatiales.
- Accessibilité : les liens directs vers les ressources de données facilitent la récupération et l’intégration transparentes.
- Automatisation : permet le traitement et l’analyse automatisés avec des métadonnées standardisées.
Avantages de STAC pour la normalisation des métadonnées
- Cohérence entre les types de données : infrastructure unifiée pour divers types de données géospatiales.
- Collaboration améliorée : simplifie le partage et la collaboration avec un format de métadonnées commun.
- Intégration améliorée des données : facilite l’intégration des jeux de données à partir de plusieurs sources.
- Gestion simplifiée des données : les outils automatisés réduisent les efforts manuels en matière de maintenance des métadonnées.
- Future-Proofing : la nature extensible s’adapte aux nouveaux types et technologies de données.
Microsoft Planetary Computer Pro (MC Pro) utilise STAC comme norme d’indexation principale pour assurer l’interopérabilité entre les jeux de données. Ce tutoriel montre aux utilisateurs comment créer des éléments STAC à partir de zéro à l’aide de bibliothèques open source courantes.
La spécification de l’élément STAC détaille la façon dont les éléments STAC sont construits et les métadonnées minimales requises qui doivent être remplies. STAC est une norme flexible, ce qui permet aux utilisateurs de décider des données qu’ils souhaitent inclure dans le cadre des métadonnées. Les métadonnées qui peuvent être utilisées pour remplir un élément STAC peuvent être inclues dans la ressource de données, dans un fichier sidecar (.XML, .JSON, .TXT, etc.), ou même dans des emplacements tels que le nom de fichier. Les utilisateurs doivent prendre en compte les types d’utilisateurs de métadonnées peuvent souhaiter effectuer des recherches et effectuer un tri à l’avenir lors du choix des métadonnées à inclure.
Ce tutoriel utilise des échantillons de données d’imagerie COG (GeoTIFF optimisé pour le cloud) provenant du jeu de données LST (Land Surface Temperature) des satellites GOES-R (Geostationary Operational Environmental Satellite R) de la NOAA (National Oceanic and Atmospheric Agency). Ces données sont incluses dans l’ordinateur planetaire ouvert en tant que fichiers COG, mais ne disposent pas de métadonnées STAC. Les satellites GOES produisent de nombreux produits de données. Vous trouverez plus d’informations dans le guide de définition de produit et d’utilisateurs de la sérieGOES-R.
Le processus utilisé dans ce didacticiel peut être généralisé pour tout type de données où les champs de métadonnées clés sont énumérés à l’aide de plusieurs bibliothèques open source.
Installer des bibliothèques Python
Pour commencer, nous installons les bibliothèques Python requises à l’aide de PIP :
rasterio: ce package est utilisé pour lire et écrire des données raster géospatiales. Il fournit des outils permettant d’utiliser des formats de données raster tels que GeoTIFF.pystac: ce package est utilisé pour utiliser la norme STAC. Il fournit des outils pour créer, lire et manipuler des métadonnées STAC.rio-stac: Ce package intègrerasterioetpystacafin de créer des éléments STAC à partir de données raster. Il simplifie le processus de génération de métadonnées STAC pour les jeux de données raster.matplotlib: cette bibliothèque est utilisée pour créer des visualisations et des tracés. Dans le contexte des données géospatiales, il permet de restituer et d’afficher des images raster, ce qui permet aux utilisateurs d’inspecter visuellement les données avant de créer des métadonnées STAC.azure-storage-blob: Cette bibliothèque cliente de Stockage Azure fournit l'accès aux services Azure Blob Storage. Il permet une interaction directe avec les données géospatiales stockées dans le cloud, ce qui permet aux utilisateurs de lire et d’utiliser des fichiers stockés dans des conteneurs d’objets blob Azure sans les télécharger en premier.
!pip install rasterio pystac rio_stac matplotlib azure-storage-blob
La section suivante du code affiche des données GOES-18 de l’ordinateur planetaire ouvert. Nous sélectionnons le jeu de données GOES-R Advanced Baseline Imager Level 2 Land Surface Temperature - CONUS et un fichier arbitraire du jour 208 de 2023.
# Import Necessary Libraries
import requests
from azure.storage.blob import ContainerClient
import matplotlib.pyplot as plt
from rasterio.io import MemoryFile
import os
from urllib.parse import urlparse
# Function to get the SAS token
def get_sas_token(endpoint):
response = requests.get(endpoint)
if response.status_code == 200:
data = response.json()
return data.get("token")
else:
raise Exception(f"Failed to get SAS token: {response.status_code} - {response.text}")
# Define Azure Blob Storage parameters
storage_account_name = "goeseuwest"
container_name = "noaa-goes-cogs"
blob_domain = f"https://{storage_account_name}.blob.core.windows.net"
sas_endpoint = f"https://planetarycomputer.microsoft.com/api/sas/v1/token/{storage_account_name}/{container_name}/"
# Get the SAS token
sas_token = get_sas_token(sas_endpoint)
# Construct the container URL with the SAS token
container_url = f"{blob_domain}/{container_name}?{sas_token}"
# Create a ContainerClient
container_client = ContainerClient.from_container_url(container_url)
# Define data you want, this can be changed for other datasets that are in storage in the open Planetary Computer
satellite = "goes-18" # The specific GOES satellite (GOES-18, also known as GOES-West)
product = "ABI-L2-LSTC" # The data product type (Advanced Baseline Imager Level 2 Land Surface Temperature - CONUS)
year = "2023" # The year the data was collected
day_of_year = "208" # The day of year (DOY) - day 208 corresponds to July 27, 2023
# Construct the directory path
directory_path = f"{satellite}/{product}/{year}/{day_of_year}/"
# Get just the first blob by using next() and limiting the iterator
first_blob = next(container_client.list_blobs(name_starts_with=directory_path))
# Function to read and display a .tif file from a URL
def display_tif_from_url(url, title):
response = requests.get(url, stream=True)
if response.status_code == 200:
with MemoryFile(response.content) as memfile:
with memfile.open() as dataset:
plt.figure(figsize=(10, 10))
plt.imshow(dataset.read(1), cmap='gray')
plt.title(title)
plt.colorbar()
plt.show()
else:
raise Exception(f"Failed to read .tif file: {response.status_code} - {response.text}")
# Create the URL for the blob using the container_url components
file_url = f"{blob_domain}/{container_name}/{first_blob.name}?{sas_token}"
# Extract the filename safely from the URL without the SAS token
parsed_url = urlparse(file_url)
path = parsed_url.path # Gets just the path portion of the URL
filename = os.path.basename(path) # Get just the filename part
# Remove .tif extension if present
file_name = filename.replace('.tif', '')
print(f"Extracted File Name: {file_name}")
display_tif_from_url(file_url, file_name)
En examinant les données et le nom du fichier, nous pouvons déjà voir les éléments clés des métadonnées nécessaires pour générer l’élément STAC. Le nom du fichier contient des informations sur les satellites qui ont capturé les données et quand elles ont été capturées.
Pour l’exemple, le nom de fichier est OR_ABI-L2-LSTC-M6_G18_s20232080101177_e20232080103550_c20232080104570_DQF, en fonction du guide du produit, cela signifie :
Composants détaillés
| Champ | Descriptif | Objectif |
|---|---|---|
| OU | Environnement du système opérationnel | Spécifie l’environnement système dans lequel les données ont été collectées |
| ABI | Instrument Advanced Baseline Imager | Identifie l’instrument utilisé pour capturer les données |
| L2 | Produit de niveau 2 (produit dérivé) | Indique que les données sont un produit dérivé, traité à partir d’observations brutes |
| LSTC | Produit de température de surface terrestre (Clear Sky) | Représente le type de produit spécifique, en se concentrant sur la température de la surface terrestre dans des conditions de ciel claires |
| M6 | Analyse en mode 6 (analyse de disque complet) | Décrit le mode d’analyse, couvrant le disque complet de la Terre |
| G18 | SATELLITE GOES-18 (également appelé GOES-West) | Identifie le satellite à partir duquel les données ont été collectées |
Détails du temps d’observation
Début de l’observation (s20232080201177)-
| Champ | Descriptif | Objectif |
|---|---|---|
| Année | 2023 | Spécifie l’année de l’observation |
| Jour de l’année | 208 | Indique le jour de l’année où l’observation a commencé |
| Heure | 02:01:17 UTC | Fournit l’heure exacte à laquelle l’observation a démarré au format UTC |
| Dixièmes de seconde | 7 | Ajoute une précision à l’heure de début de l’observation |
Fin de l’observation (e20232080203550)-
| Champ | Descriptif | Objectif |
|---|---|---|
| Année | 2023 | Spécifie l’année de l’observation |
| Jour de l’année | 208 | Indique le jour de l’année où l’observation s’est terminée |
| Heure | 02:03:55 UTC | Fournit l’heure exacte à laquelle l’observation s’est terminée au format UTC |
| Dixièmes de seconde | 0 | Ajoute une précision à l’heure de fin de l’observation |
Heure de création de fichier (c20232080204563)-
| Champ | Descriptif | Objectif |
|---|---|---|
| Année | 2023 | Spécifie l’année de création du fichier |
| Jour de l’année | 208 | Indique le jour de l’année où le fichier a été créé |
| Heure | 02:04:56 UTC | Fournit l’heure exacte de création du fichier au format UTC |
| Dixièmes de seconde | 3 | Ajoute une précision à l’heure de création de fichier |
Informations supplémentaires :
| Champ | Descriptif | Objectif |
|---|---|---|
| DQF | Indicateur de qualité des données, indiquant des informations de qualité pour les données correspondantes | Fournit des informations sur la qualité des données |
| .tif | Extension de fichier | Indique le format de fichier des données |
Le code suivant extrait ces métadonnées du nom de fichier à l’aide d’expressions régulières (regex).
import re
from datetime import datetime, timedelta
def extract_goes_metadata(filename):
"""
Extracts key metadata from a NOAA GOES satellite filename using regular expressions.
Args:
filename (str): The filename to parse.
Returns:
dict: A dictionary containing the extracted metadata.
"""
# Regular expression pattern to match the filename format
pattern = re.compile(
r"^(OR)_" # System (OR)
r"(ABI)-(L\d)-(LSTC)-(M\d)_" # Instrument, Level, Product, Mode
r"(G\d{2})_" # Satellite (G18)
r"s(\d{4})(\d{3})(\d{2})(\d{2})(\d{2})(\d)_" # Start time
r"e(\d{4})(\d{3})(\d{2})(\d{2})(\d{2})(\d)_" # End time
r"c(\d{4})(\d{3})(\d{2})(\d{2})(\d{2})(\d)_" # Creation time
r"([A-Z0-9]+)$" # Data quality flag
)
match = pattern.match(filename)
if not match:
return None # Or raise an exception if you prefer
# Extract all fields from the regular expression match groups
(
system, # Operational system environment
instrument, # Advanced Baseline Imager
level, # Product level (L2)
product_type, # Product type (LSTC - Land Surface Temperature)
mode, # Scanning mode (M6)
satellite, # Satellite identifier (G18)
s_year, s_doy, s_hour, s_minute, s_second, s_tenth, # Start time components
e_year, e_doy, e_hour, e_minute, e_second, e_tenth, # End time components
c_year, c_doy, c_hour, c_minute, c_second, c_tenth, # Creation time components
data_quality_flag # Quality flag indicator
) = match.groups()
def parse_goes_time(year, doy, hour, minute, second, tenth):
"""Parses GOES time components into an ISO format string."""
try:
dt = datetime(int(year), 1, 1) + timedelta(
days=int(doy) - 1,
hours=int(hour),
minutes=int(minute),
seconds=int(second),
microseconds=int(tenth) * 100000,
)
return dt
except ValueError:
return None
# Parse the time components into datetime objects
start_time = parse_goes_time(s_year, s_doy, s_hour, s_minute, s_second, s_tenth)
end_time = parse_goes_time(e_year, e_doy, e_hour, e_minute, e_second, e_tenth)
creation_time = parse_goes_time(c_year, c_doy, c_hour, c_minute, c_second, c_tenth)
# Create a dictionary to organize all extracted metadata
metadata = {
"system": system, # Operational system environment (e.g., "OR" for operational)
"instrument": instrument, # Instrument used to capture data (e.g., "ABI" for Advanced Baseline Imager)
"level": level, # Processing level of the data (e.g., "L2" for Level 2)
"product_type": product_type, # Type of product (e.g., "LSTC" for Land Surface Temperature Clear Sky)
"mode": mode, # Scanning mode (e.g., "M6" for Mode 6, full disk scan)
"satellite": satellite, # Satellite identifier (e.g., "G18" for GOES-18)
"start_time": start_time, # Observation start time as datetime object
"end_time": end_time, # Observation end time as datetime object
"creation_time": creation_time, # File creation time as datetime object
"data_quality_flag": data_quality_flag, # Quality flag for the data (e.g., "DQF")
}
return metadata
# Example usage:
print(file_name)
metadata_from_filename = extract_goes_metadata(file_name)
print(metadata_from_filename)
OR_ABI-L2-LSTC-M6_G18_s20232080001177_e20232080003550_c20232080004568_DQF
{'system': 'OR', 'instrument': 'ABI', 'level': 'L2', 'product_type': 'LSTC', 'mode': 'M6', 'satellite': 'G18', 'start_time': datetime.datetime(2023, 7, 27, 0, 1, 17, 700000), 'end_time': datetime.datetime(2023, 7, 27, 0, 3, 55), 'creation_time': datetime.datetime(2023, 7, 27, 0, 4, 56, 800000), 'data_quality_flag': 'DQF'}
Créer des éléments STAC à partir des fichiers GeoTIFF Cloud-Optimized
Le bloc de code suivant utilise la bibliothèque rio-stac pour automatiser la création d’éléments STAC à partir de GeoTIFF optimisés pour le cloud (COG).
En cas de pointage vers un fichier COG, rio-stac extrait et organise automatiquement les métadonnées essentielles telles que les limites spatiales, les informations de projection et les propriétés raster dans un format STAC standardisé. La bibliothèque gère la tâche complexe de lecture des métadonnées techniques incorporées à partir du GeoTIFF et la convertit en champs conformes STAC, notamment :
- Géométrie
- Cadre englobant (bbox)
- Détails de la projection
- Caractéristiques de la trame
- STAC Extensions
Cette automatisation réduit considérablement le travail manuel nécessaire pour créer des éléments STAC valides et garantit la cohérence dans les métadonnées
Note
GeoCatalog présente des limitations sur les caractères qui peuvent être utilisés dans les ID d’élément STAC et les clés de ressource. Vérifiez que vos ID ne contiennent pas les caractères suivants : -, , _, +, (, )et .. Vous devrez peut-être modifier la item_id logique de génération pour remplacer ou supprimer ces caractères de vos noms de fichiers.
from rio_stac import create_stac_item
from rasterio.io import MemoryFile
import json
from urllib.parse import urlparse, unquote
def create_stac_item_from_cog(url):
"""
Create a basic STAC Item for GOES data using rio-stac with proper spatial handling
Args:
url (str): URL to the COG file
Returns:
pystac.Item: STAC Item with basic metadata and correct spatial information
"""
# Extract the filename safely from the URL
parsed_url = urlparse(url)
path = parsed_url.path # Gets just the path portion of the URL
filename = os.path.basename(path) # Get just the filename part
# Remove .tif extension if present
item_id = filename.replace('.tif', '')
response = requests.get(url, stream=True)
if response.status_code == 200:
with MemoryFile(response.content) as memfile:
with memfile.open() as dataset:
# Create base STAC item from rasterio dataset calling create_stac_item from rio_stac
stac_item = create_stac_item(
source=dataset, # The rasterio dataset object representing the COG file
id=item_id, # Generate a unique ID by extracting the filename without the .tif extension
asset_name='data', # Name of the asset, indicating it contains the primary data
asset_href=url, # URL to the COG file, used as the asset's location
with_proj=True, # Include projection metadata (e.g., CRS, bounding box, etc.)
with_raster=True, # Include raster-specific metadata (e.g., bands, resolution, etc.)
properties={
'datetime': None, # Set datetime to None since explicit start/end times may be added later
# Add rasterio-specific metadata for the raster bands
'raster:bands': [
{
'nodata': dataset.nodata, # Value representing no data in the raster
'data_type': dataset.dtypes[0], # Data type of the raster (e.g., uint16)
'spatial_resolution': dataset.res[0] # Spatial resolution of the raster in meters
}
],
'file:size': len(response.content) # Size of the file in bytes
},
extensions=[
'https://stac-extensions.github.io/file/v2.1.0/schema.json' # Add the file extension schema for additional metadata
]
)
return stac_item
else:
raise Exception(f"Failed to read .tif file: {response.status_code} - {response.text}")
# Example usage
sas_token = get_sas_token(sas_endpoint) # refresh the SAS token prior to creating STAC item
# Create file URL using the first_blob variable that's already defined
file_url = f"{blob_domain}/{container_name}/{first_blob.name}?{sas_token}"
# Create STAC item for the first blob
stac_item = create_stac_item_from_cog(file_url)
# Print the STAC item as JSON
print(json.dumps(stac_item.to_dict(), indent=2))
{
"type": "Feature",
"stac_version": "1.0.0",
"stac_extensions": [
"https://stac-extensions.github.io/file/v2.1.0/schema.json",
"https://stac-extensions.github.io/projection/v1.1.0/schema.json",
"https://stac-extensions.github.io/raster/v1.1.0/schema.json"
],
"id": "OR_ABI-L2-LSTC-M6_G18_s20232080001177_e20232080003550_c20232080004568_DQF",
"geometry": {
"type": "Polygon",
"coordinates": [
[
[
-161.57885623466754,
14.795666555826678
],
[
-112.42114380921453,
14.79566655500485
],
[
-89.5501123912648,
53.52729778421186
],
[
175.5501122574517,
53.52729779865781
],
[
-161.57885623466754,
14.795666555826678
]
]
]
},
"bbox": [
-161.57885623466754,
14.79566655500485,
175.5501122574517,
53.52729779865781
],
"properties": {
"datetime": "2025-03-26T14:46:05.484602Z",
"raster:bands": [
{
"nodata": 65535.0,
"data_type": "uint16",
"spatial_resolution": 2004.017315487541
}
],
"file:size": 118674,
"proj:epsg": null,
"proj:geometry": {
"type": "Polygon",
"coordinates": [
[
[
-2505021.6463773525,
1583173.791653181
],
[
2505021.6423414997,
1583173.791653181
],
[
2505021.6423414997,
4589199.764884492
],
[
-2505021.6463773525,
4589199.764884492
],
[
-2505021.6463773525,
1583173.791653181
]
]
]
},
"proj:bbox": [
-2505021.6463773525,
1583173.791653181,
2505021.6423414997,
4589199.764884492
],
"proj:shape": [
1500,
2500
],
"proj:transform": [
2004.017315487541,
0.0,
-2505021.6463773525,
0.0,
-2004.017315487541,
4589199.764884492,
0.0,
0.0,
1.0
],
"proj:wkt2": "PROJCS[\"unnamed\",GEOGCS[\"unknown\",DATUM[\"unnamed\",SPHEROID[\"Spheroid\",6378137,298.2572221]],PRIMEM[\"Greenwich\",0],UNIT[\"degree\",0.0174532925199433,AUTHORITY[\"EPSG\",\"9122\"]]],PROJECTION[\"Geostationary_Satellite\"],PARAMETER[\"central_meridian\",-137],PARAMETER[\"satellite_height\",35786023],PARAMETER[\"false_easting\",0],PARAMETER[\"false_northing\",0],UNIT[\"metre\",1,AUTHORITY[\"EPSG\",\"9001\"]],AXIS[\"Easting\",EAST],AXIS[\"Northing\",NORTH],EXTENSION[\"PROJ4\",\"+proj=geos +lon_0=-137 +h=35786023 +x_0=0 +y_0=0 +ellps=GRS80 +units=m +no_defs +sweep=x\"]]"
},
"links": [],
"assets": {
"data": {
"href": "https://goeseuwest.blob.core.windows.net/noaa-goes-cogs/goes-18/ABI-L2-LSTC/2023/208/00/OR_ABI-L2-LSTC-M6_G18_s20232080001177_e20232080003550_c20232080004568_DQF.tif?st=2025-03-25T14%3A46%3A03Z&se=2025-03-26T15%3A31%3A03Z&sp=rl&sv=2024-05-04&sr=c&skoid=9c8ff44a-6a2c-4dfb-b298-1c9212f64d9a&sktid=72f988bf-86f1-41af-91ab-2d7cd011db47&skt=2025-03-26T12%3A41%3A49Z&ske=2025-04-02T12%3A41%3A49Z&sks=b&skv=2024-05-04&sig=BuMxN2NUTdrhzY7Dvpd/X4yfX8gnFpHOzANHQLkKE1k%3D",
"type": "image/tiff; application=geotiff",
"raster:bands": [
{
"data_type": "uint16",
"scale": 1.0,
"offset": 0.0,
"sampling": "area",
"nodata": 65535.0,
"unit": "1",
"statistics": {
"mean": 2.780959413109756,
"minimum": 0,
"maximum": 3,
"stddev": 0.710762086175375,
"valid_percent": 100.0
},
"histogram": {
"count": 11,
"min": 0.0,
"max": 3.0,
"buckets": [
26655,
0,
0,
25243,
0,
0,
7492,
0,
0,
570370
]
}
}
],
"roles": []
}
}
}
JSON de l’élément STAC à partir de rio-stac
La bibliothèque rio-stac lit automatiquement le fichier GOES COG et extrait les métadonnées de clé.
En outre, en fonction du type de métadonnées inclus, rio-stac a ajouté les extensions STAC pertinentes. Les extensions STAC améliorent la spécification principale en ajoutant des métadonnées standardisées et spécifiques au domaine.
- L’extension de fichier fournit des métadonnées de fichier essentielles telles que la taille et les sommes de contrôle.
- L’extension de projection capture des informations de référence spatiales, notamment des systèmes de coordonnées et des cadres englobants.
- L’extension Raster standardise les propriétés spécifiques aux données raster, telles que les informations de bande et la résolution spatiale.
Les tableaux suivants fournissent une explication de toutes les métadonnées rio-stac trouvées.
Champs principaux
| Champ | Descriptif | Objectif |
|---|---|---|
| type | Toujours « Fonctionnalité » | Identifie le type en tant que fonctionnalité GeoJSON |
| stac_version | « 1.0.0 » | Spécifie la version standard STAC |
| id | Identificateur unique | Contient des informations sur le satellite, le produit et l’heure |
| stac_extensions | Liste des URL de schéma | Définit des champs de métadonnées supplémentaires |
Informations spatiales
| Champ | Descriptif | Objectif |
|---|---|---|
| géométrie | Polygone GeoJSON | Définit l’empreinte des données dans les coordonnées WGS84 |
| bbox | Coordonnées du cadre englobant | Fournit une étendue spatiale simple pour le filtrage rapide |
| proj :geometry | Polygone spécifique à la projection | Empreinte dans les coordonnées de projection natives |
| proj:bbox | Limites de projection natives | Étendue spatiale dans le système de coordonnées du satellite |
| proj : forme | [1500, 2500] | Dimensions d’image en pixels |
| proj:transform | Transformation affine | Mappe le pixel à l’espace de coordonnées |
| proj:wkt2 | Well-Known Text | Définition de la projection complète |
| proj:epsg | zéro | Aucun code EPSG standard n’existe pour cette projection de carte |
Informations temporelles
| Champ | Descriptif | Objectif |
|---|---|---|
| date/heure | Horodateur de création | Lorsque cet élément STAC a été créé |
Informations relatives à la trame
| Champ | Descriptif | Objectif |
|---|---|---|
| raster:bands | Tableau des objets de bande | Décrit les propriétés de données raster |
| → type_de_données | « uint16 » | Type de données pixel |
| → résolution_spatiale | 2004.02 mètres | Distance de l’échantillon de sol |
| → mise à l’échelle/décalage | Facteurs de conversion | Transforme les valeurs de pixels en unités physiques (Kelvin) |
| → nodata | 65535.0 | Valeur représentant aucune donnée |
| statistiques → | Résumé statistique | Fournit des informations de distribution de données |
| → histogram | Distribution des valeurs | Visualise la distribution des données |
Informations sur les ressources
| Champ | Descriptif | Objectif |
|---|---|---|
| assets.data | Ressource de données principale | Pointe vers le fichier de données réel |
| → href | URL | Emplacement du GeoTIFF optimisé pour le cloud |
| → type | Type de support | Identifie le format de fichier |
Métadonnées de fichier
| Champ | Descriptif | Objectif |
|---|---|---|
| fichier : taille | 943 250 octets | Taille du fichier de données |
Ajout des métadonnées à partir du nom de fichier
Ensuite, nous ajoutons les données que nous avons trouvées dans le nom de fichier pour remplir les métadonnées de cet élément STAC.
Il convient de noter que les dates et heures des éléments STAC doivent être conformes à la norme ISO 8601. La bibliothèque PySTAC a une fonction datetime_to_str qui garantit que les données sont correctement mises en forme.
import pystac
def enhance_stac_item_with_metadata(stac_item, metadata_from_filename):
"""
Enhances a STAC Item with additional metadata from GOES filename.
Args:
stac_item (pystac.Item): Existing STAC Item created by rio-stac
metadata_from_filename (dict): Metadata extracted from filename
Returns:
pystac.Item: Enhanced STAC Item
"""
# Add satellite/sensor properties to the STAC item
stac_item.properties.update({
'platform': f"GOES-{metadata_from_filename['satellite'][1:]}",
'instruments': [metadata_from_filename['instrument']],
'constellation': 'GOES'
})
# Add temporal properties to the STAC item, use pystac to ensure time conforms to ISO 8601
stac_item.datetime = None # Clear the default datetime
stac_item.properties.update({
'start_datetime': pystac.utils.datetime_to_str(metadata_from_filename['start_time']),
'end_datetime': pystac.utils.datetime_to_str(metadata_from_filename['end_time']),
'created': pystac.utils.datetime_to_str(metadata_from_filename['creation_time'])
})
# Add GOES-specific properties to the STAC item
stac_item.properties.update({
'goes:system': metadata_from_filename['system'],
'goes:level': metadata_from_filename['level'],
'goes:product_type': metadata_from_filename['product_type'],
'goes:mode': metadata_from_filename['mode'],
'goes:processing_level': metadata_from_filename['level'],
'goes:data_quality_flag': metadata_from_filename['data_quality_flag']
})
return stac_item
# Example usage in new cell
stac_item = enhance_stac_item_with_metadata(stac_item, metadata_from_filename)
print(json.dumps(stac_item.to_dict(), indent=2))
Élément STAC :
{
"type": "Feature",
"stac_version": "1.0.0",
"stac_extensions": [
"https://stac-extensions.github.io/file/v2.1.0/schema.json",
"https://stac-extensions.github.io/projection/v1.1.0/schema.json",
"https://stac-extensions.github.io/raster/v1.1.0/schema.json"
],
"id": "OR_ABI-L2-LSTC-M6_G18_s20232080001177_e20232080003550_c20232080004568_DQF",
"geometry": {
"type": "Polygon",
"coordinates": [
[
[
-161.57885623466754,
14.795666555826678
],
[
-112.42114380921453,
14.79566655500485
],
[
-89.5501123912648,
53.52729778421186
],
[
175.5501122574517,
53.52729779865781
],
[
-161.57885623466754,
14.795666555826678
]
]
]
},
"bbox": [
-161.57885623466754,
14.79566655500485,
175.5501122574517,
53.52729779865781
],
"properties": {
"datetime": null,
"raster:bands": [
{
"nodata": 65535.0,
"data_type": "uint16",
"spatial_resolution": 2004.017315487541
}
],
"file:size": 118674,
"proj:epsg": null,
"proj:geometry": {
"type": "Polygon",
"coordinates": [
[
[
-2505021.6463773525,
1583173.791653181
],
[
2505021.6423414997,
1583173.791653181
],
[
2505021.6423414997,
4589199.764884492
],
[
-2505021.6463773525,
4589199.764884492
],
[
-2505021.6463773525,
1583173.791653181
]
]
]
},
"proj:bbox": [
-2505021.6463773525,
1583173.791653181,
2505021.6423414997,
4589199.764884492
],
"proj:shape": [
1500,
2500
],
"proj:transform": [
2004.017315487541,
0.0,
-2505021.6463773525,
0.0,
-2004.017315487541,
4589199.764884492,
0.0,
0.0,
1.0
],
"proj:wkt2": "PROJCS[\"unnamed\",GEOGCS[\"unknown\",DATUM[\"unnamed\",SPHEROID[\"Spheroid\",6378137,298.2572221]],PRIMEM[\"Greenwich\",0],UNIT[\"degree\",0.0174532925199433,AUTHORITY[\"EPSG\",\"9122\"]]],PROJECTION[\"Geostationary_Satellite\"],PARAMETER[\"central_meridian\",-137],PARAMETER[\"satellite_height\",35786023],PARAMETER[\"false_easting\",0],PARAMETER[\"false_northing\",0],UNIT[\"metre\",1,AUTHORITY[\"EPSG\",\"9001\"]],AXIS[\"Easting\",EAST],AXIS[\"Northing\",NORTH],EXTENSION[\"PROJ4\",\"+proj=geos +lon_0=-137 +h=35786023 +x_0=0 +y_0=0 +ellps=GRS80 +units=m +no_defs +sweep=x\"]]",
"platform": "GOES-18",
"instruments": [
"ABI"
],
"constellation": "GOES",
"start_datetime": "2023-07-27T00:01:17.700000Z",
"end_datetime": "2023-07-27T00:03:55Z",
"created": "2023-07-27T00:04:56.800000Z",
"goes:system": "OR",
"goes:level": "L2",
"goes:product_type": "LSTC",
"goes:mode": "M6",
"goes:processing_level": "L2",
"goes:data_quality_flag": "DQF"
},
"links": [],
"assets": {
"data": {
"href": "https://goeseuwest.blob.core.windows.net/noaa-goes-cogs/goes-18/ABI-L2-LSTC/2023/208/00/OR_ABI-L2-LSTC-M6_G18_s20232080001177_e20232080003550_c20232080004568_DQF.tif?st=2025-03-25T14%3A46%3A03Z&se=2025-03-26T15%3A31%3A03Z&sp=rl&sv=2024-05-04&sr=c&skoid=9c8ff44a-6a2c-4dfb-b298-1c9212f64d9a&sktid=72f988bf-86f1-41af-91ab-2d7cd011db47&skt=2025-03-26T12%3A41%3A49Z&ske=2025-04-02T12%3A41%3A49Z&sks=b&skv=2024-05-04&sig=BuMxN2NUTdrhzY7Dvpd/X4yfX8gnFpHOzANHQLkKE1k%3D",
"type": "image/tiff; application=geotiff",
"raster:bands": [
{
"data_type": "uint16",
"scale": 1.0,
"offset": 0.0,
"sampling": "area",
"nodata": 65535.0,
"unit": "1",
"statistics": {
"mean": 2.780959413109756,
"minimum": 0,
"maximum": 3,
"stddev": 0.710762086175375,
"valid_percent": 100.0
},
"histogram": {
"count": 11,
"min": 0.0,
"max": 3.0,
"buckets": [
26655,
0,
0,
25243,
0,
0,
7492,
0,
0,
570370
]
}
}
],
"roles": []
}
}
}
Ajouter l’élément STAC à une collection
MC Pro exige que tous les éléments STAC contiennent une référence à l'ID de collection STAC parent dans lequel ils sont intégrés. Pour ce tutoriel, l’ID de collection STAC est le nom du satellite et du produit de données.
Avec PySTAC, il est facile d’utiliser certaines des métadonnées collectées à partir des fichiers sources pour remplir les champs clés de la collection STAC et utiliser les fonctions de validation intégrées.
Le code suivant crée une collection STAC parente pour héberger les données GOES. Le code enregistre ensuite ces informations dans les fichiers utilisés pour créer la collection Microsoft Planetary Computer Pro STAC et ingérer des éléments STAC dans Planetary Computer Pro.
# Define collection properties
collection_id = f"{satellite}-{product}"
collection_title = f"{satellite.upper()} {product} Collection"
collection_desc = f"Collection of {satellite} {product} Earth observation data"
# Create spatial extent
bbox = [-180, -60, 10, 60] # placeholder, replace with actual data at a later date
spatial_extent = pystac.SpatialExtent([bbox])
# Create temporal extent, use current date time or replace with existing datetimes in stac_item
start_datetime = datetime.now()
if hasattr(metadata_from_filename, 'get'):
if metadata_from_filename.get('start_time'):
start_datetime = metadata_from_filename.get('start_time')
temporal_extent = pystac.TemporalExtent([[start_datetime, None]])
extent = pystac.Extent(spatial=spatial_extent, temporal=temporal_extent)
# Create the STAC Collection
collection = pystac.Collection(
id=collection_id,
description=collection_desc,
extent=extent,
title=collection_title,
license="public-domain",
)
# Add keywords and provider
collection.keywords = ["GOES", "satellite", "weather", "NOAA", satellite, product]
collection.providers = [
pystac.Provider(
name="NOAA",
roles=["producer", "licensor"],
url="https://www.noaa.gov/"
)
]
# Create output directories
output_dir = "stac_catalog"
collection_dir = os.path.join(output_dir, collection_id)
items_dir = os.path.join(collection_dir, "items")
os.makedirs(items_dir, exist_ok=True)
# Important: Save the collection first to generate proper file paths
collection_path = os.path.join(collection_dir, "collection.json")
collection.set_self_href(collection_path)
# Extract filename for the item
original_filename = first_blob.name.split('/')[-1]
base_filename = original_filename.replace('.tif', '')
item_path = os.path.join(items_dir, f"{base_filename}.json")
# Set the item's proper href
stac_item.set_self_href(item_path)
# Now associate the item with the collection (after setting hrefs)
collection.add_item(stac_item)
# Create a catalog to contain the collection
catalog = pystac.Catalog(
id="goes-data-catalog",
description="GOES Satellite Data Catalog",
title="GOES Data"
)
catalog_path = os.path.join(output_dir, "catalog.json")
catalog.set_self_href(catalog_path)
catalog.add_child(collection)
# Validate the collection and contained items
print("Validating collection and items...")
try:
collection.validate_all()
print("✅ Collection and items validated successfully")
# Save everything to disk
catalog.normalize_and_save(catalog_path, pystac.CatalogType.SELF_CONTAINED)
print(f"✅ STAC catalog saved at: {catalog_path}")
print(f"✅ STAC collection saved at: {collection_path}")
print(f"✅ STAC item saved at: {item_path}")
except Exception as e:
print(f"❌ Validation error: {str(e)}")
Validating collection and items...
✅ Collection and items validated successfully
✅ STAC catalog saved at: stac_catalog/catalog.json
✅ STAC collection saved at: stac_catalog/goes-18-ABI-L2-LSTC/collection.json
✅ STAC item saved at: stac_catalog/goes-18-ABI-L2-LSTC/items/OR_ABI-L2-LSTC-M6_G18_s20232080001177_e20232080003550_c20232080004568_DQF.json
Étapes suivantes
Maintenant que vous avez créé certains éléments STAC, il est temps d’ingérer les données dans Microsoft Planetary Computer Pro.
Pour l’ingestion d’un seul élément :
Pour l’ingestion en bloc :
Nous offrons également l’outil STAC Forge qui fournit une automatisation accrue à l’aide de modèles autour des données.