Notatka
Dostęp do tej strony wymaga autoryzacji. Może spróbować zalogować się lub zmienić katalogi.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
Dowiedz się, jak utworzyć element wykazu zasobów spatioTemporal (STAC) dla zasobu danych geoprzestrzennych rastrowych. Każdy zasób danych geoprzestrzennych przekazany do komputera Microsoft Planetary Computer Pro GeoCatalog musi mieć skojarzony element zgodny ze standardem STAC.
W tym przewodniku:
- Zainstaluj wymagane biblioteki języka Python przy użyciu narzędzia PIP.
- Wyświetlaj i sprawdzaj dane goes-18 przy użyciu podanego kodu języka Python.
- Wyodrębnij metadane z nazwy pliku przy użyciu wyrażeń regularnych.
- Utwórz elementy STAC z Cloud-Optimized plików GeoTIFF przy użyciu
rio-stac. - Ulepsz element STAC za pomocą metadanych wyodrębnionych z nazwy pliku.
- Dodaj element STAC do nadrzędnej kolekcji STAC.
- Sprawdź poprawność i zapisz katalog STAC, kolekcję i pozycje.
- Dodaj elementy STAC do Microsoft Planetary Computer Pro.
W tym samouczku pokazano i wyjaśniono możliwości za pomocą fragmentów kodu, aby uzyskać interaktywne doświadczenie w stylu notesu, pobierz ten samouczek jako notebook Jupyter.
Wymagania wstępne
Aby ukończyć tę instrukcję szybkiego startu, potrzebujesz:
- Konto Azure z aktywną subskrypcją. Użyj linku , aby bezpłatnie utworzyć konto.
- Interfejs wiersza polecenia Azure: Zainstaluj interfejs wiersza polecenia Azure
- Środowisko języka Python z co najmniej wersją 3.8.
- Znajomość standardu STAC i jego implementacji w microsoft Planetary Computer Pro STAC Overview
Kluczowe funkcje stac
SpatioTemporal Asset Catalog (STAC) to otwarty standard do tworzenia struktury i udostępniania danych geoprzestrzennych. Udostępnia wspólny język i format opisujący zasoby geoprzestrzenne, co ułatwia odnajdywanie i uzyskiwanie dostępu do tych zasobów na różnych platformach i aplikacjach oraz korzystanie z nich. Poniżej przedstawiono kluczowe funkcje standardu STAC:
- Współdziałanie: ustandaryzowany schemat oparty na formacie JSON zapewnia łatwą integrację i zrozumienie w różnych narzędziach i systemach.
- Rozszerzalność: elastyczne pola podstawowe z rozszerzeniami niestandardowymi dla określonych potrzeb.
- Odnajdywanie: Spójna struktura zwiększa wyszukiwanie i odnajdywanie zasobów geoprzestrzennych.
- Ułatwienia dostępu: bezpośrednie linki do zasobów danych ułatwiają bezproblemowe pobieranie i integrację.
- Automatyzacja: umożliwia automatyczne przetwarzanie i analizę za pomocą ustandaryzowanych metadanych.
Zalety standardyzacji metadanych STAC
- Spójność między typami danych: ujednolicona struktura dla różnych typów danych geoprzestrzennych.
- Rozszerzona współpraca: upraszcza udostępnianie i współpracę z typowym formatem metadanych.
- Ulepszona integracja danych: ułatwia integrację zestawów danych z wielu źródeł.
- Uproszczone zarządzanie danymi: zautomatyzowane narzędzia zmniejszają nakład pracy ręcznej w zakresie obsługi metadanych.
- Odporność na przyszłość: rozszerzalny charakter dostosowuje się do nowych typów danych i technologii.
Microsoft Planetary Computer Pro (MC Pro) używa STAC jako podstawowego standardu indeksowania w celu zapewnienia współdziałania między zestawami danych. W tym samouczku pokazano użytkownikom, jak utworzyć elementy STAC od podstaw przy użyciu typowych bibliotek typu open source.
Specyfikacja elementu STAC zawiera szczegółowe informacje na temat konstruowania elementów STAC oraz wymaganych minimalnych metadanych, które muszą zostać wypełnione. STAC to elastyczny standard, który umożliwia użytkownikom podjęcie decyzji o tym, które dane mają zostać uwzględnione w ramach metadanych. Metadane, które mogą być użyte do wypełnienia elementu STAC, mogą być zawarte w zasobie danych, w pliku towarzyszącym (.XML, .JSON, .TXT itp.), a nawet w miejscach, takich jak nazwa pliku. Użytkownicy powinni rozważyć typy metadanych, które użytkownicy mogą chcieć wyszukiwać i sortować w przyszłości podczas podejmowania decyzji o tym, które metadane mają zostać uwzględnione.
W tym samouczku wykorzystano przykładowe obrazy GeoTIFF zoptymalizowane pod kątem chmury (COG) pochodzące z zestawu danych dotyczących temperatury powierzchni ziemi (LST) z satelitów geostacjonarnych operacyjnych NOAA (National Oceanic and Atmospheric Agency) R (GOES-R). Te dane są uwzględniane w otwartym komputerze planetarnym jako pliki COG, ale brakuje metadanych STAC. Satelity GOES produkują wiele produktów danych. Więcej szczegółów można znaleźć w przewodniku po definicjach produktów i użytkownikach seriiGOES-R.
Proces używany w tym samouczku można uogólnić dla dowolnego typu danych, w których pola metadanych klucza są wyliczane przy użyciu kilku bibliotek typu open source.
Instalowanie bibliotek języka Python
Aby rozpocząć, zainstalujemy wymagane biblioteki języka Python przy użyciu narzędzia:
rasterio: Ten pakiet służy do odczytywania i zapisywania danych rasterów geoprzestrzennych. Udostępnia narzędzia do pracy z formatami danych rasterowych, takimi jak GeoTIFF.pystac: ten pakiet jest używany do pracy ze standardem STAC. Udostępnia narzędzia do tworzenia, odczytywania i manipulowania metadanymi STAC.rio-stac: ten pakiet integrujerasteriosię zpystacprogramem w celu utworzenia elementów STAC na podstawie danych rasterowych. Upraszcza to proces generowania metadanych STAC dla zestawów danych rasterowych.matplotlib: Ta biblioteka służy do tworzenia wizualizacji i kreśleń. W kontekście danych geoprzestrzennych ułatwia renderowanie i wyświetlanie obrazów rastrowych, dzięki czemu użytkownicy mogą wizualnie sprawdzać dane przed utworzeniem metadanych STAC.azure-storage-blob: Ta biblioteka klienta usługi Azure Storage zapewnia dostęp do usług Azure Blob Storage. Umożliwia ona bezpośrednią interakcję z danymi geoprzestrzennymi przechowywanymi w chmurze, umożliwiając użytkownikom odczytywanie i pracę z plikami przechowywanymi w kontenerach obiektów blob platformy Azure bez uprzedniego pobierania ich.
!pip install rasterio pystac rio_stac matplotlib azure-storage-blob
W następnej sekcji kodu są wyświetlane niektóre dane goes-18 z otwartego komputera planetarnego. Wybieramy zestaw danych GOES-R Advanced Baseline Imager Level 2 Land Surface Temperature — CONUS oraz dowolny plik z dnia 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)
Patrząc na dane i nazwę pliku, możemy już zobaczyć kluczowe elementy metadanych potrzebne do skompilowania elementu STAC. Nazwa pliku zawiera informacje o tym, które satelity przechwyciły dane i kiedy zostały przechwycone.
W przykładzie nazwa pliku to OR_ABI-L2-LSTC-M6_G18_s20232080101177_e20232080103550_c20232080104570_DQF, na podstawie przewodnika po produkcie, oznacza to:
Szczegółowe składniki
| (No changes needed) | Opis | Przeznaczenie |
|---|---|---|
| LUB | Środowisko systemu operacyjnego | Określa środowisko systemowe, w którym zebrano dane |
| ABI | Zaawansowany instrument obrazujący typu Baseline | Identyfikuje instrument używany do przechwytywania danych |
| L2 | Produkt poziomu 2 (produkt pochodny) | Wskazuje, że dane są produktem pochodnym przetworzonym z pierwotnych obserwacji |
| LSTC | Produkt temperatury powierzchni ziemi (Bezchmurne niebo) | Przedstawia określony typ produktu, koncentrując się na temperaturze powierzchni lądowej w warunkach jasnego nieba |
| M6 | Skanowanie w trybie 6 (skanowanie na pełnym dysku) | Opisuje tryb skanowania obejmujący pełny dysk Ziemi |
| G18 | Satelita GOES-18 (znany również jako GOES-West) | Identyfikuje satelitę, z którego zebrano dane |
Szczegóły czasu obserwacji
Początek obserwacji (s2023208020177)-
| (No changes needed) | Opis | Przeznaczenie |
|---|---|---|
| Rok | 2023 | Określa rok obserwacji |
| Dzień Roku | 208 | Wskazuje dzień roku rozpoczęcia obserwacji |
| Czas | 02:01:17 UTC | Zawiera dokładny czas rozpoczęcia obserwacji w formacie UTC |
| Dziesiąte części sekundy | 7 | Dodaje precyzję do czasu rozpoczęcia obserwacji |
Koniec obserwacji (e20232080203550)-
| (No changes needed) | Opis | Przeznaczenie |
|---|---|---|
| Rok | 2023 | Określa rok obserwacji |
| Dzień Roku | 208 | Wskazuje dzień roku, w których zakończyła się obserwacja |
| Czas | 02:03:55 UTC | Zawiera dokładny czas, w jaki obserwacja zakończyła się w formacie UTC |
| Dziesiąte części sekundy | 0 | Dodaje precyzję do czasu zakończenia obserwacji |
Czas tworzenia pliku (c20232080204563)-
| (No changes needed) | Opis | Przeznaczenie |
|---|---|---|
| Rok | 2023 | Określa rok utworzenia pliku |
| Dzień Roku | 208 | Wskazuje dzień roku utworzenia pliku |
| Czas | 02:04:56 UTC | Zawiera dokładny czas utworzenia pliku w formacie UTC |
| Dziesiąte części sekundy | 3 | Dodaje precyzję do czasu tworzenia pliku |
Dodatkowe informacje:
| (No changes needed) | Opis | Przeznaczenie |
|---|---|---|
| DQF | Flaga jakości danych wskazująca informacje o jakości odpowiednich danych | Zawiera informacje o jakości danych |
| .tif | Rozszerzenie pliku | Wskazuje format pliku danych |
Poniższy kod wyodrębnia te metadane z nazwy pliku przy użyciu wyrażeń regularnych (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'}
Tworzenie elementów STAC na podstawie plików geoTIFF Cloud-Optimized
Poniższy blok kodu używa rio-stac biblioteki do zautomatyzowania tworzenia elementów STAC z Cloud-Optimized GeoTIFFs (COGs).
Po wskazaniu pliku COG, rio-stac automatycznie wyodrębnia i organizuje podstawowe metadane, takie jak granica przestrzenna, informacje o projekcji i właściwości rastra w ustandaryzowany format STAC. Biblioteka obsługuje złożone zadanie odczytywania osadzonych metadanych technicznych z geoTIFF i konwertuje je na pola zgodne ze standardem STAC, w tym:
- Geometria
- Ramka ograniczająca (bbox)
- Szczegóły projekcji
- Cechy rasterowe
- Rozszerzenia STAC
Ta automatyzacja znacznie zmniejsza ręczną pracę wymaganą do utworzenia prawidłowych elementów STAC i zapewnia spójność metadanych
Uwaga / Notatka
GeoCatalog ma ograniczenia dotyczące znaków, których można używać w identyfikatorach elementów STAC i kluczach zasobów. Upewnij się, że identyfikatory nie zawierają następujących znaków: -, _, +, (, ) i .. Może być konieczne zmodyfikowanie logiki generowania w item_id celu zastąpienia lub usunięcia tych znaków z nazw plików.
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": []
}
}
}
Kod JSON elementu STAC z rio-stac
Biblioteka rio-stac odczytuje plik GOES COG i automatycznie wyodrębnia kluczowe metadane.
Ponadto, na podstawie typu uwzględnionych metadanych, rio-stac dodało odpowiednie rozszerzenia STAC. Rozszerzenia STAC rozszerzają podstawową specyfikację przez dodanie ustandaryzowanych metadanych specyficznych dla domeny.
- Rozszerzenie pliku udostępnia podstawowe metadane plików, takie jak rozmiar i sumy kontrolne.
- Rozszerzenie projekcji przechwytuje informacje o odwołaniach przestrzennych, w tym układy współrzędnych i pola ograniczenia.
- Rozszerzenie rasteru standandaryzuje właściwości specyficzne dla danych rasterowych, takich jak informacje o pasmie i rozdzielczość przestrzenna.
Poniższe tabele zawierają wyjaśnienie wszystkich znalezionych metadanych rio-stac.
Podstawowe pola
| (No changes needed) | Opis | Przeznaczenie |
|---|---|---|
| typ | Zawsze "funkcja" | Identyfikuje typ jako funkcję GeoJSON |
| stac_version | 1.0.0 | Określa wersję standardową STAC |
| id | Unikatowy identyfikator | Zawiera informacje dotyczące satelity, produktu i czasu |
| stac_extensions | Lista adresów URL schematu | Definiuje dodatkowe pola metadanych |
Informacje przestrzenne
| (No changes needed) | Opis | Przeznaczenie |
|---|---|---|
| geometria | Wielokąt GeoJSON | Definiuje ślad danych we współrzędnych WGS84 |
| bbox | Współrzędne ramki ograniczającej | Zapewnia prosty zakres przestrzenny na potrzeby szybkiego filtrowania |
| proj:geometry | Wielokąt specyficzny dla projekcji | Ślad we współrzędnych projekcji natywnej |
| proj:bbox | Granice projekcji natywnej | Zakres przestrzenny w układzie współrzędnych satelity |
| proj:shape | [1500, 2500] | Wymiary obrazu w pikselach |
| proj:transform | Przekształcenie afiniczne | Mapuje piksel na przestrzeń współrzędnych |
| proj:wkt2 | Well-Known Text | Kompletna definicja projekcji |
| proj:epsg | null | Nie istnieje standardowy kod EPSG dla tej projekcji mapy |
Informacje czasowe
| (No changes needed) | Opis | Przeznaczenie |
|---|---|---|
| data/godzina | Sygnatura czasowa tworzenia | Gdy ten element STAC został utworzony |
Informacje o rasterze
| (No changes needed) | Opis | Przeznaczenie |
|---|---|---|
| raster:bands | Tablica obiektów pasmowych | Opisuje właściwości danych rastrowych |
| → typ_danych | uint16 | Typ danych pikseli |
| rozdzielczość przestrzenna | 2004,02 m | Odległość próbki ziemi |
| skalowanie/przesunięcie → | Przeliczniki | Przekształca wartości pikseli w jednostki fizyczne (Kelvin) |
| → brak danych | 65535.0 | Wartość reprezentująca brak danych |
| → statystyk | Podsumowanie statystyczne | Udostępnia informacje o dystrybucji danych |
| histogram → | Rozkład wartości | Wizualizowanie dystrybucji danych |
Informacje o zasobach
| (No changes needed) | Opis | Przeznaczenie |
|---|---|---|
| Dane.zasobów | Główny zasób danych | Wskazuje rzeczywisty plik danych |
| → href | adres URL | Lokalizacja GeoTIFF Cloud-Optimized |
| typ → | Typ nośnika | Identyfikuje format pliku |
Metadane pliku
| (No changes needed) | Opis | Przeznaczenie |
|---|---|---|
| rozmiar pliku | 943 250 bajtów | Rozmiar pliku danych |
Dodawanie metadanych z nazwy pliku
Następnie dodamy dane znalezione w nazwie pliku, aby zakończyć wypełnianie metadanych dla tego elementu STAC.
Należy pamiętać, że wszystkie daty i czas w elementach STAC muszą być zgodne z normą ISO 8601. Biblioteka PySTAC ma funkcję datetime_to_str, która zapewnia poprawne formatowanie danych.
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))
Element 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": []
}
}
}
Dodawanie elementu STAC do kolekcji
Program MC Pro wymaga, aby wszystkie elementy STAC miały odwołanie do ID nadrzędnej kolekcji STAC, do której są włączane. W tym samouczku identyfikator kolekcji STAC oznacza nazwę satelity oraz produktu danych.
Dzięki funkcji PySTAC można łatwo użyć niektórych metadanych zebranych z plików źródłowych w celu wypełnienia pól kluczy dla kolekcji STAC i używania wbudowanych funkcji weryfikacji.
Poniższy kod tworzy nadrzędną kolekcję STAC do gromadzenia danych GOES. Następnie kod zapisuje te informacje w plikach, które są używane do tworzenia kolekcji Microsoft Planetary Computer Pro STAC oraz do pozyskiwania elementów STAC w ramach 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
Dalsze kroki
Teraz, po utworzeniu niektórych obiektów STAC, nadszedł czas na wczytanie danych do Microsoft Planetary Computer Pro.
W przypadku przyjmowania pojedynczego przedmiotu:
Dla zbiorczego wprowadzania:
Oferujemy również narzędzie STAC Forge , które zapewnia zwiększoną automatyzację przy użyciu szablonów dotyczących danych.