Freigeben über


Erstellen eines SpatioTemporal Asset Catalog (STAC)-Elements

Erfahren Sie, wie Sie ein SpatioTemporal Asset Catalog (STAC)-Element für ein Raster-Geospatialdatenobjekt erstellen. Jede geospatiale Datenressource, die in einen Microsoft Planetary Computer Pro GeoCatalog hochgeladen wird, muss über ein zugeordnetes STAC-kompatibles Element verfügen.

In dieser Anleitung erfahren Sie:

  • Installieren Sie die erforderlichen Python-Bibliotheken mit PIP.
  • Anzeigen und Prüfen von GOES-18-Daten mithilfe des bereitgestellten Python-Codes.
  • Extrahieren Sie Metadaten aus dem Dateinamen mithilfe regulärer Ausdrücke.
  • Erstellen Sie STAC-Elemente aus Cloud-Optimized GeoTIFF-Dateien mithilfe von rio-stac.
  • Verbessern Sie das STAC-Element mit Metadaten, die aus dem Dateinamen extrahiert wurden.
  • Fügen Sie das STAC-Element zu einer übergeordneten STAC-Auflistung hinzu.
  • Überprüfen und Speichern des STAC-Katalogs, der Sammlung und der Elemente.
  • Fügen Sie die STAC-Elemente zu Microsoft Planetary Computer Pro hinzu.

Dieses Lernprogramm zeigt und erläutert Funktionen durch Codeausschnitte, für eine interaktive Notizbuchstiloberfläche, laden Sie dieses Lernprogramm als Jupyter-Notizbuch herunter.

Voraussetzungen

Für die Durchführung dieses Schnellstarts benötigen Sie Folgendes:

Wichtige Features von STAC

Der SpatioTemporal Asset Catalog (STAC) ist ein offener Standard zum Strukturieren und Freigeben von Geospatialdaten. Es bietet eine gemeinsame Sprache und ein gemeinsames Format für die Beschreibung von geospatialen Ressourcen, wodurch es einfacher ist, diese Ressourcen auf verschiedenen Plattformen und Anwendungen zu finden, darauf zuzugreifen und sie zu verwenden. Im Folgenden sind die wichtigsten Features des STAC-Standards aufgeführt:

  • Interoperabilität: Standardisiertes JSON-basiertes Schema sorgt für einfache Integration und Verständnis über Tools und Systeme hinweg.
  • Erweiterbarkeit: Flexible Kernfelder mit benutzerdefinierten Erweiterungen für bestimmte Anforderungen.
  • Auffindbarkeit: Durch eine konsistente Struktur wird die Suche und Ermittlung von geospatialen Ressourcen verbessert.
  • Barrierefreiheit: Direkte Links zu Datenressourcen ermöglichen einen nahtlosen Abruf und eine nahtlose Integration.
  • Automatisierung: Ermöglicht die automatisierte Verarbeitung und Analyse mit standardisierten Metadaten.

Vorteile von STAC zum Standardisieren von Metadaten

  • Konsistenz zwischen Datentypen: Einheitliches Framework für verschiedene geospatiale Datentypen.
  • Verbesserte Zusammenarbeit: Vereinfacht das Teilen und die Zusammenarbeit mit einem gemeinsamen Metadatenformat.
  • Verbesserte Datenintegration: Erleichtert die Integration von Datasets aus mehreren Quellen.
  • Optimierte Datenverwaltung: Automatisierte Tools reduzieren den manuellen Aufwand bei der Verwaltung von Metadaten.
  • Zukunftssicher: Erweiterbare Natur passt sich an neue Datentypen und Technologien an.

Microsoft Planetary Computer Pro (MC Pro) verwendet STAC als Kernindizierungsstandard, um die Interoperabilität zwischen Datensätzen zu ermöglichen. In diesem Lernprogramm wird gezeigt, wie Sie STAC-Elemente ganz neu mithilfe gängiger Open Source-Bibliotheken erstellen.

Die STAC-Elementspezifikation enthält Details dazu, wie STAC-Elemente erstellt werden, und die erforderlichen Mindestmetadaten, die ausgefüllt werden müssen. STAC ist ein flexibler Standard, mit dem Benutzer entscheiden können, welche Daten sie als Teil der Metadaten einbeziehen möchten. Metadaten, die zum Befüllen eines STAC-Elements verwendet werden können, können in der Datenressource, in einer Sidecar-Datei (.XML, .JSON, .TXT usw.) oder sogar in Speicherorten wie z. B. dem Dateinamen enthalten sein. Benutzer sollten die Arten von Metadaten berücksichtigen, die Benutzer möglicherweise in Zukunft durchsuchen und sortieren möchten, wenn Sie entscheiden, welche Metadaten einbezogen werden sollen.

Dieses Lernprogramm verwendet Beispieldaten für cloudoptimierte GeoTIFF (COG)-Bilddaten aus dem Dataset National Oceanic and Atmospheric Agency (NOAA) Geostational Operational Environmental Satellite R (GOES-R) land surface temperature (LST). Diese Daten sind im offenen Planetarischen Computer als COG-Dateien enthalten, aber es fehlen STAC-Metadaten. Die GOES-Satelliten produzieren viele Datenprodukte. Weitere Details finden Sie im GOES-R Series Product Definition and Users Guide.

Der in diesem Lernprogramm verwendete Prozess kann für jeden Datentyp generalisiert werden, bei dem die wichtigsten Metadatenfelder mithilfe mehrerer Open Source-Bibliotheken aufgezählt werden.

Installieren von Python-Bibliotheken

Zunächst installieren wir die erforderlichen Python-Bibliotheken mit PIP:

  • rasterio: Dieses Paket wird zum Lesen und Schreiben von Geospatialrasterdaten verwendet. Es bietet Tools zum Arbeiten mit Rasterdatenformaten wie GeoTIFF.

  • pystac: Dieses Paket wird für die Arbeit mit dem STAC-Standard verwendet. Es bietet Tools zum Erstellen, Lesen und Bearbeiten von STAC-Metadaten.

  • rio-stac: Dieses Paket integriert rasterio mit pystac, um STAC-Elemente aus Rasterdaten zu erstellen. Es vereinfacht das Generieren von STAC-Metadaten für Raster-Datasets.

  • matplotlib: Diese Bibliothek wird zum Erstellen von Visualisierungen und Plots verwendet. Im Kontext von Geospatialdaten hilft es, Rasterbilder zu rendern und anzuzeigen, sodass Benutzer die Daten vor dem Erstellen von STAC-Metadaten visuell prüfen können.

  • azure-storage-blob: Diese Azure Storage-Clientbibliothek bietet Zugriff auf Azure Blob Storage-Dienste. Sie ermöglicht die direkte Interaktion mit in der Cloud gespeicherten Geospatialdaten, sodass Benutzer Dateien lesen und bearbeiten können, die in Azure Blob-Containern gespeichert sind, ohne sie zuerst herunterzuladen.

!pip install rasterio pystac rio_stac matplotlib azure-storage-blob 

Im nächsten Codeabschnitt werden einige GOES-18-Daten vom offenen Planetarischen Computer angezeigt. Wir wählen den GOES-R Advanced Baseline Imager Level 2 Land Surface Temperature - CONUS-Datensatz und eine beliebige Datei von Tag 208 im Jahr 2023 aus.

# 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)

Eine Graustufenvisualisierung von Geospatialrasterdaten von einem GOES-18-Satelliten mit Oberflächentemperaturmustern in einer Region.

Beim Betrachten der Daten und des Dateinamens können wir bereits die wichtigsten Metadatenelemente sehen, die zum Erstellen des STAC-Elements erforderlich sind. Der Dateiname enthält Informationen dazu, welcher Satellit die Daten erfasst hat und wann er erfasst wurde.

Für das Beispiel ist der Dateiname OR_ABI-L2-LSTC-M6_G18_s20232080101177_e20232080103550_c20232080104570_DQF, und basierend auf dem Produkthandbuch bedeutet dies:

Detaillierte Komponenten

Feld BESCHREIBUNG Zweck
ODER Betriebssystemumgebung Gibt die Systemumgebung an, in der die Daten gesammelt wurden.
ABI Advanced Baseline Imager Instrument Identifiziert das Instrument, das zum Erfassen der Daten verwendet wird.
L2 Produkt der Ebene 2 (abgeleitetes Produkt) Gibt an, dass es sich bei den Daten um ein abgeleitetes Produkt handelt, das aus rohen Beobachtungen verarbeitet wird.
LSTC Produkt "Land Surface Temperature" (Clear Sky) Stellt den spezifischen Produkttyp dar, der sich auf die Oberflächentemperatur unter klaren Himmelsbedingungen konzentriert.
M6 Modus 6 Scan (Vollständiger Datenträgerscan) Beschreibt den Scanmodus, der die gesamte Erdkugel abdeckt
G18 GOES-18 Satelliten (auch bekannt als GOES-West) Identifiziert den Satelliten, aus dem die Daten gesammelt wurden.

Beobachtungszeitdetails

Beginn der Beobachtung (s20232080201177)-

Feld BESCHREIBUNG Zweck
Jahr 2023 Gibt das Jahr der Beobachtung an.
Tag des Jahres 208 Gibt den Tag des Jahres an, an dem die Beobachtung gestartet wurde.
Uhrzeit 02:01:17 UTC Liefert die genaue Uhrzeit, zu der die Beobachtung in UTC gestartet wurde.
Zehntel der Sekunde 7 Fügt der Startzeit der Beobachtung Präzision hinzu

Beobachtungsende (e20232080203550)-

Feld BESCHREIBUNG Zweck
Jahr 2023 Gibt das Jahr der Beobachtung an.
Tag des Jahres 208 Gibt den Tag des Jahres an, an dem die Beobachtung endete.
Uhrzeit 02:03:55 UTC Liefert die genaue Uhrzeit, zu der die Beobachtung in UTC beendet wurde.
Zehntel der Sekunde 0 Fügt der Endzeit der Beobachtung Genauigkeit hinzu

Dateierstellungszeit (c20232080204563)-

Feld BESCHREIBUNG Zweck
Jahr 2023 Gibt das Jahr an, in dem die Datei erstellt wurde.
Tag des Jahres 208 Gibt den Tag des Jahres an, an dem die Datei erstellt wurde.
Uhrzeit 02:04:56 UTC Gibt den genauen Zeitpunkt an, zu dem die Datei in UTC erstellt wurde.
Zehntel der Sekunde 3 Fügt der Dateierstellungszeit Genauigkeit hinzu

Weitere Informationen:

Feld BESCHREIBUNG Zweck
DQF Datenqualitätskennzeichnung, die Qualitätsinformationen für die entsprechenden Daten angibt Stellt Informationen zur Qualität der Daten bereit.
.tif Dateierweiterung Gibt das Dateiformat der Daten an.

Der folgende Code extrahiert diese Metadaten aus dem Dateinamen mithilfe regulärer Ausdrücke (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'}

Erstellen von STAC-Elementen aus Cloud-Optimized GeoTIFF-Dateien

Der folgende Codeblock verwendet die rio-stac Bibliothek, um die Erstellung von STAC-Elementen aus Cloud-Optimized GeoTIFFs (COGs) zu automatisieren.

Wenn auf eine COG-Datei verwiesen wird, rio-stac extrahiert und organisiert automatisch wichtige Metadaten wie räumliche Grenzen, Projektionsinformationen und Rastereigenschaften in ein standardisiertes STAC-Format. Die Bibliothek übernimmt die komplexe Aufgabe, die eingebetteten technischen Metadaten aus dem GeoTIFF zu lesen und in STAC-kompatible Felder zu konvertieren, darunter:

  • Geometrie
  • Begrenzungsrahmen (bbox)
  • Projektionsdetails
  • Rastermerkmale
  • STAC-Erweiterungen

Diese Automatisierung reduziert die manuelle Arbeit, die zum Erstellen gültiger STAC-Elemente erforderlich ist, und sorgt für Konsistenz in Metadaten.

Hinweis

GeoCatalog hat Einschränkungen für Zeichen, die in STAC-Element-IDs und Objektschlüsseln verwendet werden können. Stellen Sie sicher, dass Ihre IDs nicht die folgenden Zeichen enthalten: -, , _, , +, (, und ).. Möglicherweise müssen Sie die Generierungslogik item_id ändern, um diese Zeichen aus Ihren Dateinamen zu ersetzen oder zu entfernen.

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": []
        }
      }
    }

STAC-Element-JSON aus rio-stac

Die Rio-Stac-Bibliothek liest die GOES COG-Datei und extrahiert schlüsselmetadaten automatisch.

Darüber hinaus hat rio-stac basierend auf dem Typ der enthaltenen Metadaten die relevanten STAC-Erweiterungen hinzugefügt. STAC-Erweiterungen verbessern die Kernspezifikation durch Hinzufügen standardisierter domänenspezifischer Metadaten.

  • Die Dateierweiterung bietet wichtige Dateimetadaten wie Größe und Prüfsummen.
  • Die Projektionserweiterung erfasst Räumliche Referenzinformationen einschließlich Koordinatensystemen und umgebenden Feldern.
  • Die Rastererweiterung standardisiert Eigenschaften, die für Rasterdaten spezifisch sind, z. B. Bandinformationen und räumliche Auflösung.

Die folgenden Tabellen enthalten eine Erläuterung aller gefundenen Metadaten rio-stac.

Kernfelder

Feld BESCHREIBUNG Zweck
Typ Immer "Feature" Identifiziert den Typ als GeoJSON-Feature
stac_version "1.0.0" Gibt die STAC-Standardversion an.
id Eindeutiger Bezeichner Enthält Satelliten-, Produkt- und Zeitinformationen
stac_extensions Liste der Schema-URLs Definiert zusätzliche Metadatenfelder

Räumliche Informationen

Feld BESCHREIBUNG Zweck
Geometrie GeoJSON-Polygon Definiert den Datenbedarf in WGS84-Koordinaten
BBox Begrenzungsrahmenkoordinaten Bietet ein einfaches räumliches Ausmaß für schnelle Filterung
proj:geometry Projektionsspezifisches Polygon Fußabdruck in systemeigenen Projektionskoordinaten
proj:bbox Systemeigene Projektionsgrenzen Räumliches Ausmaß im Satellitenkoordinatensystem
proj:shape [1500, 2500] Bildabmessungen in Pixeln
Projekt:Transformation Affine Transformation Ordnet Pixel dem Koordinatenbereich zu
proj:wkt2 Well-Known Text Vollständige Projektionsdefinition
proj:epsg NULL Für diese Kartenprojektion ist kein standardmäßiger EPSG-Code vorhanden.

Zeitliche Informationen

Feld BESCHREIBUNG Zweck
Datum/Uhrzeit Erstellungszeitstempel Wann dieses STAC-Element erstellt wurde

Rasterinformationen

Feld BESCHREIBUNG Zweck
Raster:Bänder Array von Bandobjekten Beschreibt Rasterdateneigenschaften
→ Datentyp "uint16" Pixeldatentyp
→ spatial_resolution 2004.02m Bodenprobenabstand
→ Skalierung/Offset Konvertierungsfaktoren Transformiert Pixelwerte in physische Einheiten (Kelvin)
→ keine Daten 65535.0 Wert, der keine Daten darstellt
→ Statistiken Statistische Zusammenfassung Stellt Datenverteilungsinformationen bereit.
→ Histogramm Wertverteilung Visualisiert die Datenverteilung

Objektinformationen

Feld BESCHREIBUNG Zweck
assets.data Hauptdatenressource Verweist auf die tatsächliche Datendatei
→ href URL Standort des cloudoptimierten GeoTIFF
→ Typ Medientyp Identifiziert Dateiformat

Dateimetadaten

Feld BESCHREIBUNG Zweck
Dateigröße 943.250 Bytes Größe der Datendatei

Hinzufügen der Metadaten aus dem Dateinamen

Als Nächstes fügen wir die Im Dateinamen gefundenen Daten hinzu, um das Ausfüllen der Metadaten für dieses STAC-Element abzuschließen.

Beachten Sie, dass alle Datetimes für STAC-Elemente iso 8601 entsprechen müssen. Die PySTAC-Bibliothek verfügt über eine datetime_to_str Funktion, mit der sichergestellt wird, dass die Daten korrekt formatiert sind.

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))

Das STAC-Element:

    {
      "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": []
        }
      }
    }

Hinzufügen des STAC-Elements zu einer Auflistung

MC Pro erfordert, dass alle STAC-Elemente einen Verweis auf die übergeordnete STAC-Sammlungs-ID haben, in die sie aufgenommen werden. In diesem Lernprogramm ist die STAC Collection ID der Name des Satelliten und des Datenprodukts.

Mit PySTAC können Sie ganz einfach einige der Metadaten verwenden, die aus den Quelldateien gesammelt werden, um die Schlüsselfelder für die STAC-Auflistung aufzufüllen und die integrierten Überprüfungsfunktionen zu verwenden.

Der folgende Code erstellt eine übergeordnete STAC-Sammlung, um die GOES-Daten zu beherbergen. Der Code speichert diese Informationen dann in Dateien, mit denen die Microsoft Planetary Computer Pro STAC-Sammlung erstellt und STAC-Elemente in Planetary Computer Pro aufgenommen werden.

# 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

Nächste Schritte

Nachdem Sie nun einige STAC-Elemente erstellt haben, ist es an der Zeit, die Daten in Microsoft Planetary Computer Pro aufzunehmen.

Für die Aufnahme einzelner Elemente:

Für Massenaufnahme:

Darüber hinaus bieten wir das STAC Forge-Tool an, das eine erhöhte Automatisierung mit Vorlagen rund um Daten bietet.