SpatioTemporal Asset Catalog (STAC) elem létrehozása

Megtudhatja, hogyan hozhat létre SpatioTemporal Asset Catalog (STAC) elemet egy raszteres térinformatikai adategységhez. A Microsoft Planetary Computer Pro GeoCatalogba feltöltött minden térinformatikai adategységnek rendelkeznie kell egy STAC-kompatibilis elempel.

Ebben az útmutatóban a következőt találja:

  • Telepítse a szükséges Python-kódtárakat a PIP használatával.
  • GOES-18-adatok megjelenítése és vizsgálata a megadott Python-kóddal.
  • Metaadatok kinyerése a fájlnévből normál kifejezések használatával.
  • STAC-elemek létrehozása Cloud-Optimized GeoTIFF-fájlokból a használatával rio-stac.
  • Javítsa a STAC-elemet a fájlnévből kinyert metaadatokkal.
  • Adja hozzá a STAC-elemet a szülő STAC gyűjteményhez.
  • Ellenőrizze és mentse a STAC-katalógust, a gyűjteményt és az elemeket.
  • Adja hozzá a STAC-elemeket a Microsoft Planetary Computer Pro-hoz.

Ez az oktatóanyag kódrészleteken keresztül mutatja be és ismerteti a képességeket. Az interaktív jegyzetfüzetstílus használatához töltse le ezt az oktatóanyagot Jupyter-jegyzetfüzetként.

Előfeltételek

A gyors kezdéshez ezekre lesz szüksége:

A STAC főbb jellemzői

A SpatioTemporal Asset Catalog (STAC) nyílt szabvány a térinformatikai adatok strukturálására és megosztására. Általános nyelvet és formátumot biztosít a térinformatikai eszközök leírásához, így könnyebben felderíthetők, elérhetők és használhatók ezek az erőforrások különböző platformokon és alkalmazásokban. A STAC szabvány főbb jellemzői a következők:

  • Interoperabilitás: A szabványos JSON-alapú séma egyszerű integrációt és megértést biztosít az eszközök és rendszerek között.
  • Bővíthetőség: Rugalmas magmezők egyéni bővítményekkel adott igényekhez.
  • Felderíthetőség: A konzisztens struktúra javítja a térinformatikai eszközök keresését és felderítését.
  • Akadálymentesség: Az adategységekre mutató közvetlen hivatkozások megkönnyítik a zökkenőmentes lekérést és integrációt.
  • Automatizálás: Lehetővé teszi az automatizált feldolgozást és elemzést szabványosított metaadatokkal.

A STAC előnyei a metaadatok szabványosításához

  • Konzisztencia adattípusok között: Egységes keretrendszer a különböző térinformatikai adattípusokhoz.
  • Továbbfejlesztett együttműködés: Leegyszerűsíti a közös metaadat-formátumokkal való megosztást és együttműködést.
  • Továbbfejlesztett adatintegráció: Megkönnyíti a több forrásból származó adathalmazok integrációját.
  • Egyszerűsített adatkezelés: Az automatizált eszközök csökkentik a metaadatok karbantartására fordított manuális erőfeszítéseket.
  • Jövőbiztosítás: A bővíthető természet alkalmazkodik az új adattípusokhoz és technológiákhoz.

A Microsoft Planetary Computer Pro (MC Pro) a STAC-t használja alapvető indexelési szabványként az adathalmazok közötti együttműködés biztosításához. Ez az oktatóanyag bemutatja a felhasználóknak, hogyan hozhatnak létre teljesen új STAC-elemeket közös nyílt forráskódú kódtárak használatával.

A STAC-elem specifikációja részletesen ismerteti a STAC-elemek létrehozásának módját és a kötelező minimális metaadatokat, amelyeket fel kell tölteni. A STAC egy rugalmas szabvány, amely lehetővé teszi a felhasználók számára, hogy eldöntsék, mely adatokat szeretnék belefoglalni a metaadatokba. Olyan metaadatok, amelyek felhasználhatók egy STAC-elem kitöltésére, szerepelhetnek az adatállományban, egy kísérő fájlban (.XML, .JSON, .TXT stb.), vagy akár olyan helyeken is, mint a fájlnév. A felhasználóknak figyelembe kell venniük, hogy milyen típusú metaadatokat szeretnének a felhasználók a jövőben keresni és rendezni, amikor eldöntik, hogy mely metaadatokat kell tartalmazniuk.

Ez az oktatóanyag a National Oceanic and Atmospheric Agency (NOAA) Geostationary Operational Environmental Satellite R (GOES-R) műholdak Land Surface Temperature (LST) adatkészletéből származó, felhőoptimalizált GeoTIFF (COG) mintaképadatokat használja. Ezek az adatok COG-fájlokként szerepelnek a megnyitott Planetary Computerben, de nem rendelkeznek STAC-metaadatokkal. A GOES műholdak számos adatterméket állítanak elő. További részletek a GOES-R sorozat termékdefiníciós és felhasználói útmutatójában találhatók.

Az oktatóanyagban használt folyamat minden olyan adattípusra általánosítható, ahol a fő metaadatmezők több nyílt forráskódú kódtár használatával vannak számba véve.

Python-kódtárak telepítése

Első lépésként a szükséges Python-kódtárakat a PIP használatával telepítjük:

  • rasterio: Ez a csomag térinformatikai raszteradatok olvasására és írására szolgál. Eszközöket biztosít a raszteres adatformátumok, például a GeoTIFF használatához.

  • pystac: Ez a csomag a STAC szabvány használatára szolgál. Eszközöket biztosít a STAC-metaadatok létrehozásához, olvasásához és kezeléséhez.

  • rio-stac: Ez a csomag integrálja rasterio-t pystac-vel a STAC-elemek raszteres adatokból való létrehozására. Leegyszerűsíti a raszteres adathalmazok STAC-metaadatainak létrehozásának folyamatát.

  • matplotlib: Ez a kódtár vizualizációk és diagramok létrehozásához használható. A térinformatikai adatok kontextusában segít a raszterképek megjelenítésében és megjelenítésében, így a felhasználók vizuálisan megvizsgálhatják az adatokat a STAC-metaadatok létrehozása előtt.

  • azure-storage-blob: Ez az Azure Storage-ügyfélkódtár hozzáférést biztosít az Azure Blob Storage-szolgáltatásokhoz. Közvetlen interakciót tesz lehetővé a felhőben tárolt térinformatikai adatokkal, így a felhasználók anélkül olvashatják és dolgozhatnak az Azure Blob-tárolókban tárolt fájlokkal, hogy először letöltenék őket.

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

A kód következő szakasza néhány GOES-18-adatot jelenít meg a megnyitott Planetary Computerből. Kiválasztjuk a GOES-R Advanced Baseline Imager Level 2 Land Surface Temperature – CONUS adatkészletet, valamint egy tetszőleges fájlt 2023. 208. napjától.

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

Egy GOES-18 műhold térinformatikai raszteradatainak szürkeárnyalatos vizualizációja, amely a földfelszín hőmérsékleti mintáit mutatja egy régióban.

Az adatok és a fájlnév megtekintéséből már láthatjuk a STAC-elem létrehozásához szükséges metaadatok legfontosabb darabjait. A fájlnév információkat tartalmaz arról, hogy melyik műhold rögzítette az adatokat, és mikor rögzítették őket.

A minta esetében a fájlnév OR_ABI-L2-LSTC-M6_G18_s20232080101177_e20232080103550_c20232080104570_DQF, a termékútmutató alapján ez a következőt jelenti:

Részletes összetevők

szakterület Leírás Cél
vagy Működési rendszerkörnyezet Azt a rendszerkörnyezetet adja meg, amelyben az adatokat gyűjtötték
ABI Fejlett alapszintű képkészítő műszer Azonosítja az adatok rögzítéséhez használt eszközt
L2 2. szintű termék (származtatott termék) Azt jelzi, hogy az adatok nyers megfigyelésekből feldolgozott származtatott termékek
LSTC Felszíni hőmérséklet (derült égbolt) termék Az adott terméktípust jelöli, amely a felszíni hőmérsékletre összpontosít tiszta égi körülmények között
M6 6. módú vizsgálat (teljes lemezes vizsgálat) A föld teljes lemezét lefedő vizsgálati módot ismerteti
G18 GOES-18 műhold (más néven GOES-West) Azonosítja azt a műholdat, amelyről az adatokat gyűjtötték

Megfigyelési idő részletei

Megfigyelés kezdete (s20232080201177)-

szakterület Leírás Cél
Év 2023 A megfigyelés évét határozza meg
Az év napja 208 Az év azon napját jelzi, amikor a megfigyelés elkezdődött
Idő 02:01:17 UTC Pontos időpontot biztosít a megfigyelés UTC-ben történő indításához
A másodperc tizede 7 Pontosságot ad a megfigyelés kezdő időpontjához

Megfigyelés vége (e20232080203550)-

szakterület Leírás Cél
Év 2023 A megfigyelés évét határozza meg
Az év napja 208 Az év azon napját jelzi, amikor a megfigyelés befejeződött
Idő 02:03:55 UTC Pontos időpontot ad meg, amikor a megfigyelés UTC-ben véget ért
A másodperc tizede 0 Pontosságot ad a megfigyelés befejezési időpontjához

Fájllétrehozás ideje (c20232080204563)-

szakterület Leírás Cél
Év 2023 A fájl létrehozásának évét adja meg
Az év napja 208 A fájl létrehozásának napját jelzi
Idő 02:04:56 UTC Megadja a fájl létrehozásának pontos időpontját UTC-ben
A másodperc tizede 3 Pontosság hozzáadása a fájllétrehozás időpontjához

További információ:

szakterület Leírás Cél
DQF Adatminőség-jelző, amely a megfelelő adatok minőségére vonatkozó információkat jelzi Információ az adatok minőségéről
.tif Fájlkiterjesztés Az adatok fájlformátumát jelzi

Az alábbi kód normál kifejezések (regex) használatával kinyeri ezeket a metaadatokat a fájlnévből.

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'}

STAC-elemek létrehozása Cloud-Optimized GeoTIFF-fájlokból

Az alábbi kódblokk a rio-stac kódtár használatával automatizálja a STAC-elemek létrehozását Cloud-Optimized GeoTIFF-ekből (COG-kból).

Ha egy COG-fájlra mutat, rio-stac automatikusan kinyeri és rendszerezi az alapvető metaadatokat, például a térbeli korlátokat, a vetítési információkat és a rasztertulajdonságokat szabványosított STAC-formátumba. A kódtár kezeli a beágyazott műszaki metaadatok GeoTIFF-ből való beolvasásának összetett feladatát, és STAC-kompatibilis mezőkké alakítja, beleértve a következőket:

  • Geometria
  • Határoló keret (bbox)
  • Vetítés részletei
  • Raszter jellemzői
  • STAC-bővítmények

Ez az automatizálás jelentősen csökkenti az érvényes STAC-elemek létrehozásához szükséges manuális munkát, és biztosítja a metaadatok konzisztenciáját

Megjegyzés:

A GeoCatalog korlátozásokat tartalmaz a STAC-elemazonosítókban és az eszközkulcsokban használható karakterekre. Győződjön meg arról, hogy az azonosítók nem tartalmazzák a következő karaktereket: -, _, +, (, )és .. Előfordulhat, hogy módosítania kell a item_id létrehozási logikát, hogy lecserélje vagy eltávolítsa ezeket a karaktereket a fájlnevekből.

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

A rio-stac STAC elemének JSON fájlja

A rio-stac kódtár felolvassa a GOES COG-fájlt, és automatikusan kinyerte a kulcs metaadatait.

Emellett a benne foglalt metaadatok típusa alapján a Rio-Stac hozzáadta a releváns STAC-bővítményeket. A STAC-bővítmények szabványosított, tartományspecifikus metaadatok hozzáadásával növelik az alapvető specifikációt.

  • A Fájlbővítmény alapvető fájl metaadatokat biztosít, például a méretet és az ellenőrzőösszegeket.
  • A Projection Extension a térbeli referenciaadatokat rögzíti, beleértve a koordinátarendszereket és a határolókereteket.
  • A Raster-bővítmény szabványosítja a raszteradatokra jellemző tulajdonságokat, például a sávinformációkat és a térbeli felbontást.

Az alábbi táblázatok a rio-stac összes metaadatának magyarázatát tartalmazzák.

Alapvető mezők

szakterület Leírás Cél
típus Mindig "Funkció" A típust GeoJSON-funkcióként azonosítja
stac_version 1.0.0 A STAC standard verzióját adja meg
azonosító Egyedi azonosító Műholdas, termék- és időinformációkat tartalmaz
STAC kiterjesztések Séma URL-címeinek listája További metaadatmezők definiálása

Térbeli információk

szakterület Leírás Cél
geometry GeoJSON-sokszög Meghatározza az adatlábnyomot a WGS84 koordinátáiban
bbox Határolókeret koordinátái Egyszerű térbeli kiterjedést biztosít a gyors szűréshez
proj:geometria Vetülethez kötött sokszög Lábnyom natív koordináta-vetítési rendszerben
proj:bbox Natív vetületi korlátok Térbeli kiterjedés a műhold koordinátarendszerében
proj:alak [1500, 2500] Képméretek képpontokban
proj:transform Affine transzformáció Képpont leképezése a térköz koordinálásához
proj:wkt2 Well-Known Text Teljes vetületdefiníció
proj:epsg null Ehhez a térképvetítéshez nincs szabványos EPSG-kód

Időbeli információk

szakterület Leírás Cél
datetime Létrehozási időbélyeg A STAC-elem létrehozásakor

Raszteradatok

szakterület Leírás Cél
raszter:sávok Sávobjektumok tömbje A raszter adattulajdonságainak ismertetése
adat_típus uint16 Pixel adattípus
→ térbeli felbontás 2004.02 m Földi minta távolsága
→ méretezés/eltolás Konverziós tényezők A képpontértékeket fizikai egységekké alakítja át (Kelvin)
nincs adat 65535.0 Adatok nélküli értéket képviselő érték
→ statisztikák Statisztikai összegzés Adatterjesztési információkat biztosít
hisztogram → Értékeloszlás Az adateloszlás megjelenítése

Eszközadatok

szakterület Leírás Cél
assets.data Fő adategység A tényleges adatfájlra mutat
href URL A Cloud-Optimized GeoTIFF helye
→ típus Médiatípus Fájlformátum azonosítása

Fájl metaadatai

szakterület Leírás Cél
fájl:méret 943 250 bájt Az adatfájl mérete

Metaadatok hozzáadása a fájlnévből

Ezután hozzáadjuk a fájlnévben talált adatokat a STAC-elem metaadatainak kitöltéséhez.

Fontos megjegyezni, hogy a STAC-elemekhez tartozó összes dátumidőnek meg kell felelnie az ISO 8601 szabványnak. A PySTAC-kódtár datetime_to_str függvénnyel rendelkezik, amely biztosítja az adatok megfelelő formázását.

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

A STAC-elem:

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

A STAC-elem hozzáadása gyűjteményhez

Az MC Pro előírja, hogy az összes STAC-elem hivatkozzon arra a szülő STAC-gyűjteményazonosítóra, amelybe be vannak illesztve. Ebben az oktatóanyagban a STAC-gyűjtemény azonosítója a műhold és az adattermék nevét jelöli.

A PySTAC használatával a forrásfájlokból gyűjtött metaadatok egy része egyszerűen feltölthető a STAC-gyűjtemény kulcsmezőivel, és használhatja a beépített érvényesítési függvényeket.

Az alábbi kód létrehoz egy szülő STAC gyűjteményt a GOES-adatok tárolására. A kód ezután menti ezeket az adatokat a Microsoft Planetary Computer Pro STAC gyűjtemény létrehozásához használt fájlokba, és betölti a STAC-elemeket a Planetary Computer Pro-ba.

# 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

Következő lépések

Most, hogy létrehozott néhány STAC-elemet, itt az ideje, hogy betöltse az adatokat a Microsoft Planetary Computer Pro-ba.

Egyelemes betöltés esetén:

Tömeges betöltés esetén:

Használd a STAC Forge eszközt az automatizálás növelésére, sablonok használatával adat körül.