Poznámka:
Přístup k této stránce vyžaduje autorizaci. Můžete se zkusit přihlásit nebo změnit adresáře.
Přístup k této stránce vyžaduje autorizaci. Můžete zkusit změnit adresáře.
Zjistěte, jak vytvořit položku katalogu SpatioTemporal Asset Catalog (STAC) pro rastrový geoprostorový datový zdroj. Každý geoprostorový datový prostředek, který je nahraný do microsoft planetárního počítače Pro GeoCatalog, musí mít přidruženou položku kompatibilní se standardem STAC.
V této příručce:
- Nainstalujte požadované knihovny Pythonu pomocí PIP.
- Pomocí poskytnutého kódu Pythonu můžete zobrazit a zkontrolovat data GOES-18.
- Extrahujte metadata z názvu souboru pomocí regulárních výrazů.
- Vytvářet položky STAC ze souborů Cloud-Optimized GeoTIFF pomocí
rio-stac. - Vylepšete položku STAC pomocí metadat extrahovaných z názvu souboru.
- Přidejte položku STAC do nadřazené kolekce STAC.
- Ověřte a uložte katalog, kolekci a položky STAC.
- Přidejte položky STAC do microsoft planetárního počítače Pro.
Tento kurz ukazuje a vysvětluje možnosti prostřednictvím fragmentů kódu pro interaktivní prostředí stylu poznámkového bloku a stáhněte si tento kurz jako poznámkový blok Jupyter.
Požadavky
K dokončení tohoto rychlého startu potřebujete:
- Účet Azure s aktivním předplatným. Pomocí odkazu můžete zdarma vytvořit účet.
- Azure CLI: Instalace Azure CLI
- Prostředí Pythonu s minimálně verzí 3.8.
- Některé znalosti standardu STAC a jeho implementace v microsoft planetárním počítači Pro STAC – přehled
Klíčové funkce STAC
SpatioTemporal Asset Catalog (STAC) je otevřený standard pro strukturování a sdílení geoprostorových dat. Poskytuje společný jazyk a formát pro popis geoprostorových prostředků, což usnadňuje zjišťování, přístup k těmto prostředkům a jejich používání napříč různými platformami a aplikacemi. Toto jsou klíčové funkce standardu STAC:
- Interoperabilita: Standardizované schéma založené na JSON zajišťuje snadnou integraci a porozumění napříč nástroji a systémy.
- Rozšiřitelnost: Flexibilní základní pole s vlastními rozšířeními pro konkrétní potřeby
- Zjistitelnost: Konzistentní struktura vylepšuje vyhledávání a zjišťování geoprostorových prostředků.
- Přístupnost: Přímé odkazy na datové prostředky usnadňují bezproblémové načítání a integraci.
- Automatizace: Umožňuje automatizované zpracování a analýzu pomocí standardizovaných metadat.
Výhody STAC pro standardizaci metadat
- Konzistence napříč datovými typy: Sjednocená architektura pro různé geoprostorové datové typy.
- Vylepšená spolupráce: Zjednodušuje sdílení a spolupráci s běžným formátem metadat.
- Vylepšená integrace dat: Usnadňuje integraci datových sad z více zdrojů.
- Zjednodušená správa dat: Automatizované nástroje snižují ruční úsilí při údržbě metadat.
- Zajištění budoucnosti: Rozšiřitelná povaha se přizpůsobuje novým datovým typům a technologiím.
Microsoft Planetární počítač Pro (MC Pro) používá STAC jako základní indexovací standard k zajištění interoperability mezi datovými sadami. V tomto kurzu se uživatelům ukáže, jak vytvářet položky STAC od začátku pomocí běžných opensourcových knihoven.
Specifikace položky STAC podrobně popisuje, jak se položky STAC vytvářejí, a požadovaná minimální metadata, která musí být vyplněna. STAC je flexibilní standard, který uživatelům umožňuje rozhodnout se, která data chtějí zahrnout jako součást metadat. Metadata, která se dají použít k naplnění položky STAC, je možné zahrnout do datového prostředku, do přidruženého souboru (.XML, .JSON, .TXT atd.) nebo dokonce na místa, jako je název souboru. Při rozhodování o tom, která metadata mají být zahrnuta, by uživatelé měli zvážit, jaké typy metadat by uživatelé mohli chtít v budoucnu prohledávat a řadit.
V tomto kurzu se používají ukázková data geoTIFF (COG) optimalizovaná pro cloud z datové sady National Oceanic and Atmospheric Agency (NOAA) Geostationary Operational Environmental Satellite R (GOES-R). Tato data jsou zahrnuta v otevřeném planetárním počítači jako COG soubory, ale chybí metadata STAC. Satelity GOES vytvářejí mnoho datových produktů. Další podrobnosti najdete v příručce k definici produktu řadyGOES-R a uživatelům.
Proces použitý v tomto kurzu lze generalizovat pro libovolný typ dat, ve kterých jsou pole klíčových metadat vyčíslována pomocí několika opensourcových knihoven.
Instalace knihoven Pythonu
Nejprve nainstalujeme požadované knihovny Pythonu pomocí pipu:
rasterio: Tento balíček slouží ke čtení a zápisu geoprostorových rastrových dat. Poskytuje nástroje pro práci s rastrovými formáty dat, jako je GeoTIFF.pystac: Tento balíček se používá pro práci se standardem STAC. Poskytuje nástroje pro vytváření, čtení a manipulaci s metadaty STAC.rio-stac: Tento balíček integrujerasteriospystacza účelem vytvoření položek STAC z rastrových dat. Zjednodušuje proces generování metadat STAC pro rastrové datové sady.matplotlib: Tato knihovna slouží k vytváření vizualizací a grafů. V kontextu geoprostorových dat pomáhá vykreslovat a zobrazovat rastrové obrázky, což uživatelům umožňuje vizuálně kontrolovat data před vytvořením metadat STAC.azure-storage-blob: Tato klientská knihovna Azure Storage poskytuje přístup ke službám Azure Blob Storage. Umožňuje přímou interakci s geoprostorovými daty uloženými v cloudu a umožňuje uživatelům číst a pracovat se soubory uloženými v kontejnerech objektů blob v Azure bez jejich prvního stažení.
!pip install rasterio pystac rio_stac matplotlib azure-storage-blob
V další části kódu se zobrazí některá data GOES-18 z otevřené planetárního počítače. Vybereme GOES-R Advanced Baseline Imager Level 2 Land Surface Temperature - CONUS datovou sadu a libovolný soubor ze dne 208 roku 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)
Od zobrazení dat a názvu souboru už vidíme klíčové části metadat potřebných k sestavení položky STAC. Název souboru obsahuje informace o tom, která satelit data zachytila a kdy byla zachycena.
Pro ukázku je název souboru OR_ABI-L2-LSTC-M6_G18_s20232080101177_e20232080103550_c20232080104570_DQF na základě průvodce produktem, což znamená:
Podrobné komponenty
| Pole | Popis | Účel |
|---|---|---|
| NEBO | Provozní prostředí systému | Určuje systémové prostředí, ve kterém byla data shromážděna. |
| ABI | Nástroj Advanced Baseline Imager | Identifikuje nástroj použitý k zachytávání dat. |
| L2 | Produkt úrovně 2 (odvozený produkt) | Označuje, že data jsou odvozeným produktem vytvořeným z původních pozorování. |
| LSTC | Produkt teploty povrchu země (jasná obloha) | Představuje konkrétní typ produktu, který se zaměřuje na teplotu povrchu země za jasných podmínek nebe. |
| M6 | Skenování v režimu 6 (úplné skenování disku) | Popisuje režim skenování, který pokrývá celý disk Země. |
| G18 | Satelit GOES-18 (označovaný také jako GOES-West) | Identifikuje satelit, ze kterého byla data shromážděna. |
Podrobnosti času pozorování
Začátek pozorování (s20232080201177)-
| Pole | Popis | Účel |
|---|---|---|
| Rok | 2023 | Určuje rok pozorování. |
| Den roku | 208 | Označuje den v roce, kdy začalo pozorování. |
| Čas | 02:01:17 UTC | Poskytuje přesný čas zahájení pozorování v UTC. |
| Desáté sekundy | 7 | Přidá přesnost k počátečnímu času pozorování. |
Konec pozorování (e20232080203550)-
| Pole | Popis | Účel |
|---|---|---|
| Rok | 2023 | Určuje rok pozorování. |
| Den roku | 208 | Označuje den v roce, kdy pozorování skončilo. |
| Čas | 02:03:55 UTC | Poskytuje přesný čas ukončení pozorování v UTC. |
| Desáté sekundy | 0 | Zvyšuje přesnost koncového času pozorování. |
Čas vytvoření souboru (c20232080204563)-
| Pole | Popis | Účel |
|---|---|---|
| Rok | 2023 | Určuje rok vytvoření souboru. |
| Den roku | 208 | Označuje den v roce, kdy byl soubor vytvořen. |
| Čas | 02:04:56 UTC | Poskytuje přesný čas vytvoření souboru v UTC. |
| Desáté sekundy | 3 | Přidá přesnost k času vytvoření souboru. |
Další informace:
| Pole | Popis | Účel |
|---|---|---|
| DQF | Příznak kvality dat označující informace o kvalitě odpovídajících dat | Poskytuje informace o kvalitě dat. |
| .tif | Přípona souboru | Označuje formát souboru dat. |
Následující kód extrahuje tato metadata z názvu souboru pomocí regulárních výrazů (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'}
Vytváření položek STAC ze souborů Cloud-Optimized GeoTIFF
Následující blok kódu používá knihovnu rio-stac k automatizaci vytváření položek STAC z Cloud-Optimized GeoTIFF (COG).
Když odkazujete na soubor COG, automaticky extrahuje a uspořádá základní metadata, rio-stac jako jsou prostorové hranice, informace o projekci a rastrové vlastnosti, do standardizovaného formátu STAC. Knihovna zpracovává složitou úlohu čtení vložených technických metadat z GeoTIFF a převádí je na pole kompatibilní se standardem STAC, včetně:
- geometrie
- Ohraničující rámeček (bbox)
- Podrobnosti projekce
- Raster Characteristics
- Rozšíření STAC
Tato automatizace výrazně snižuje ruční práci potřebnou k vytvoření platných položek STAC a zajišťuje konzistenci v metadatech.
Poznámka:
GeoCatalog má omezení pro znaky, které je možné použít v ID položek STAC a klíčích assetů. Ujistěte se, že VAŠE ID neobsahují následující znaky: -, _, +(, , )a .. Možná budete muset změnit logiku item_id generování tak, aby tyto znaky nahradila nebo odebrala z názvů souborů.
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 položky STAC z rio-stac
Knihovna rio-stac načítá soubor GOES COG a extrahuje metadata klíčů automaticky.
Kromě toho na základě typu zahrnutých metadat rio-stac přidala příslušná rozšíření STAC. Rozšíření STAC vylepšují základní specifikaci přidáním standardizovaných metadat specifických pro doménu.
- Přípona souboru poskytuje základní metadata souborů, jako jsou velikost a kontrolní součty.
- Rozšíření projekce zachycuje prostorové referenční informace, včetně souřadnicových systémů a ohraničujících rámečků.
- Rozšíření raster standardizuje vlastnosti specifické pro rastrová data, jako jsou informace o pásmu a prostorové rozlišení.
Následující tabulky obsahují vysvětlení všech nalezených metadat rio-stac.
Základní pole
| Pole | Popis | Účel |
|---|---|---|
| typ | Vždy „Funkce“ | Identifikuje typ jako funkci GeoJSON. |
| stac_version | 1.0.0 | Určuje standardní verzi STAC. |
| identifikační číslo | Jedinečný identifikátor | Obsahuje informace o satelitech, produktech a čase. |
| stac_extensions | Seznam adres URL schématu | Definuje další pole metadat. |
Prostorové informace
| Pole | Popis | Účel |
|---|---|---|
| geometrie | Mnohoúhelník GeoJSON | Definuje datovou stopu ve formátu WGS84. |
| bbox | Souřadnice ohraničujícího rámečku | Poskytuje jednoduchý prostorový rozsah pro rychlé filtrování. |
| proj:geometry | Mnohoúhelník specifický pro projekce | Stopa v nativních souřadnicích projekce |
| proj:bbox | Hranice nativní projekce | Prostorový rozsah v souřadnicovém systému satelitu |
| proj:tvar | [1500, 2500] | Rozměry obrázku v pixelech |
| proj:transform | Afinní transformace | Mapuje pixely na souřadnicový prostor. |
| proj:wkt2 | Well-Known Text | Kompletní definice projekce |
| proj:epsg | null | Pro tuto projekci mapy neexistuje žádný standardní kód EPSG. |
Časové informace
| Pole | Popis | Účel |
|---|---|---|
| datetime | Časové razítko vytvoření | Když byla tato položka STAC vytvořena |
Rastrové informace
| Pole | Popis | Účel |
|---|---|---|
| raster:pásma | Pole objektů pásma | Popisuje vlastnosti rastrových dat. |
| → datový typ | uint16 | Pixelový datový typ |
| prostorové rozlišení | 2004.02m | Pozemní vzorkovací vzdálenost |
| → měřítko/posun | Konverzní faktory | Transformuje hodnoty pixelů na fyzické jednotky (Kelvin). |
| → žádná data | 65535.0 | Hodnota představující žádné údaje |
| → statistiky | Statistický souhrn | Poskytuje informace o distribuci dat. |
| histogram → | Distribuce hodnot | Vizualizace distribuce dat |
Informace o aktivech
| Pole | Popis | Účel |
|---|---|---|
| majetek.data | Hlavní datové aktivum | Odkazuje na skutečný datový soubor. |
| → href | URL | Umístění souboru Cloud-Optimized GeoTIFF |
| typ → | Typ média | Identifikuje formát souboru. |
Metadata souborů
| Pole | Popis | Účel |
|---|---|---|
| soubor:velikost | 943 250 bajtů | Velikost datového souboru |
Přidání metadat z názvu souboru
Dále přidáme data, která jsme našli v názvu souboru a dokončíme vyplňování metadat pro tuto položku STAC.
Je třeba poznamenat, že všechny položky data a času pro položky STAC musí odpovídat normě ISO 8601. Knihovna PySTAC má funkci datetime_to_str, která zajišťuje správné formátování dat.
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))
Položka 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": []
}
}
}
Přidání položky STAC do kolekce
MC Pro vyžaduje, aby všechny položky STAC měly odkaz na nadřazené ID kolekce STAC, do kterých jsou ingestovány. V tomto kurzu je ID kolekce STAC název satelitu a datového produktu.
S PySTAC je snadné použít některá metadata shromážděná ze zdrojových souborů k naplnění klíčových polí kolekce STAC a použití integrovaných ověřovacích funkcí.
Následující kód vytvoří nadřazenou kolekci STAC k uložení dat GOES. Kód pak uloží tyto informace do souborů použitých k vytvoření kolekce Microsoft Planety Computer Pro STAC a ingestování položek STAC do planetárního počítače 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
Další kroky
Teď, když jste vytvořili nějaké položky STAC, je čas načíst data do Microsoft Planetary Computer Pro.
Příjem jedné položky:
Pro hromadný příjem dat:
Nabízíme také nástroj STAC Forge , který poskytuje zvýšenou automatizaci pomocí šablon kolem dat.