Catatan
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba masuk atau mengubah direktori.
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba mengubah direktori.
Pelajari cara membuat item SpatioTemporal Asset Catalog (STAC) untuk aset data geospasial raster. Setiap aset data geospasial yang diunggah ke Microsoft Planetary Computer Pro GeoCatalog harus memiliki Item terkait yang mematuhi STAC.
Dalam panduan ini, Anda:
- Instal pustaka Python yang diperlukan menggunakan PIP.
- Tampilkan dan periksa data GOES-18 menggunakan kode Python yang disediakan.
- Ekstrak metadata dari nama file menggunakan ekspresi reguler.
- Buat Item STAC dari Cloud-Optimized file GeoTIFF menggunakan
rio-stac
. - Tingkatkan Item STAC dengan metadata yang diekstrak dari nama file.
- Tambahkan Item STAC ke Koleksi STAC induk.
- Validasi dan simpan katalog, koleksi, dan item STAC.
- Tambahkan Item STAC ke Microsoft Planetary Computer Pro.
Tutorial ini menunjukkan dan menjelaskan kemampuan melalui cuplikan kode, untuk pengalaman gaya notebook interaktif, unduh tutorial ini sebagai notebook Jupyter.
Prasyarat
Untuk menyelesaikan panduan singkat ini, Anda memerlukan:
- Sebuah akun Azure dengan langganan aktif. Gunakan tautan untuk Membuat akun secara gratis.
- Azure CLI: Menginstal Azure CLI
- Lingkungan Python dengan setidaknya versi 3.8.
- Sebagian pengetahuan tentang standar STAC dan implementasinya di Microsoft Planetary Computer Pro Gambaran Umum STAC
Fitur Utama STAC
Katalog Aset SpatioTemporal (STAC) adalah standar terbuka untuk menyusun dan berbagi data geospasial. Ini menyediakan bahasa dan format umum untuk menjelaskan aset geospasial, sehingga lebih mudah untuk menemukan, mengakses, dan menggunakan sumber daya ini di berbagai platform dan aplikasi. Berikut ini adalah fitur utama dari standar STAC:
- Interoperabilitas: Skema berbasis JSON standar memastikan integrasi dan pemahaman yang mudah di seluruh alat dan sistem.
- Ekstensibilitas: Bidang inti fleksibel dengan ekstensi kustom untuk kebutuhan tertentu.
- Kemudahan ditemukan: Struktur yang konsisten meningkatkan pencarian dan penemuan aset geospasial.
- Aksesibilitas: Tautan langsung ke aset data memfasilitasi pengambilan dan integrasi yang mulus.
- Otomatisasi: Memungkinkan pemrosesan dan analisis otomatis dengan metadata standar.
Manfaat STAC untuk Standardisasi Metadata
- Konsistensi Di Seluruh Jenis Data: Kerangka kerja terpadu untuk berbagai jenis data geospasial.
- Kolaborasi yang Ditingkatkan: Menyederhanakan berbagi dan kolaborasi dengan format metadata umum.
- Integrasi Data yang Ditingkatkan: Memfasilitasi integrasi himpunan data dari beberapa sumber.
- Manajemen Data Yang Disederhanakan: Alat otomatis mengurangi upaya manual dalam mempertahankan metadata.
- Memastikan Masa Depan: Sifat yang fleksibel memungkinkan adaptasi terhadap jenis data dan teknologi baru.
Microsoft Planetary Computer Pro (MC Pro) menggunakan STAC sebagai standar pengindeksan intinya untuk memberikan interoperabilitas antar himpunan data. Tutorial ini menunjukkan kepada pengguna cara membuat Item STAC dari awal menggunakan pustaka sumber terbuka umum.
Spesifikasi Item STAC merinci bagaimana Item STAC dibangun dan metadata minimum yang diperlukan yang harus diisi. STAC adalah standar yang fleksibel, memungkinkan pengguna untuk memutuskan data mana yang ingin mereka sertakan sebagai bagian dari metadata. Metadata yang dapat digunakan untuk mengisi Item STAC mungkin disertakan dalam aset data, dalam file sidecar (.XML, . JSON, .TXT dll.), atau bahkan di lokasi seperti nama file. Pengguna harus mempertimbangkan jenis metadata yang mungkin ingin dicari dan diurutkan di masa mendatang saat memutuskan metadata mana yang akan disertakan.
Tutorial ini menggunakan sampel data citra Cloud Optimized GeoTIFF (COG) dari himpunan data National Oceanic and Atmospheric Agency (NOAA) Geostationary Operational Environmental Satellite R (GOES-R) satelit Land Surface Temperature (LST). Data ini disertakan dalam Komputer Planetary terbuka sebagai file COG, tetapi tidak memiliki metadata STAC. Satelit GOES menghasilkan banyak produk data. Detail selengkapnya dapat ditemukan di Panduan Definisi Produk dan Pengguna SeriGOES-R.
Proses yang digunakan dalam tutorial ini dapat digeneralisasi untuk semua jenis data di mana bidang metadata kunci dijumlahkan menggunakan beberapa pustaka sumber terbuka.
Menginstal pustaka Python
Untuk memulai, kami menginstal pustaka Python yang diperlukan menggunakan PIP:
rasterio
: Paket ini digunakan untuk membaca dan menulis data geospasial raster. Ini menyediakan alat untuk bekerja dengan format data raster seperti GeoTIFF.pystac
: Paket ini digunakan untuk bekerja dengan standar STAC. Ini menyediakan alat untuk membuat, membaca, dan memanipulasi metadata STAC.rio-stac
: Paket ini terintegrasirasterio
denganpystac
untuk membuat Item STAC dari data raster. Ini menyederhanakan proses pembuatan metadata STAC untuk himpunan data raster.matplotlib
: Pustaka ini digunakan untuk membuat visualisasi dan plot. Dalam konteks data geospasial, ini membantu merender dan menampilkan gambar raster, memungkinkan pengguna untuk memeriksa data secara visual sebelum membuat metadata STAC.azure-storage-blob
: Pustaka klien Azure Storage ini menyediakan akses ke layanan Azure Blob Storage. Ini memungkinkan interaksi langsung dengan data geospasial yang disimpan cloud, memungkinkan pengguna untuk membaca dan bekerja dengan file yang disimpan dalam kontainer Azure Blob tanpa mengunduhnya terlebih dahulu.
!pip install rasterio pystac rio_stac matplotlib azure-storage-blob
Bagian kode berikutnya menampilkan beberapa data GOES-18 dari Komputer Planetary yang terbuka. Kami memilih set data GOES-R Advanced Baseline Imager Level 2 Land Surface Temperature - CONUS, dan file sembarang dari hari ke-208 tahun 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)
Dari melihat data dan nama file, kita sudah dapat melihat potongan-potongan kunci metadata yang diperlukan untuk membangun Item STAC. Nama file berisi informasi tentang satelit mana yang mengambil data dan kapan diambil.
Untuk sampel, nama file OR_ABI-L2-LSTC-M6_G18_s20232080101177_e20232080103550_c20232080104570_DQF, berdasarkan panduan produk, ini berarti:
Komponen Terperinci
Bidang | Deskripsi | Tujuan |
---|---|---|
ATAU | Lingkungan sistem operasional | Menentukan lingkungan sistem tempat data dikumpulkan |
ABI | Instrumen Baseline Imager Tingkat Lanjut | Mengidentifikasi instrumen yang digunakan untuk menangkap data |
L2 | Produk tingkat 2 (produk turunan) | Menunjukkan bahwa data adalah produk turunan, diproses dari pengamatan mentah |
LSTC | Produk Suhu Permukaan Tanah (Langit Cerah) | Mewakili jenis produk tertentu, berfokus pada suhu permukaan darat di bawah kondisi langit yang cerah |
M6 | Pemindaian Mode 6 (Pemindaian Disk Penuh) | Menjelaskan mode pemindaian, mencakup disk lengkap Bumi |
G18 | Satelit GOES-18 (juga dikenal sebagai GOES-West) | Mengidentifikasi satelit tempat data dikumpulkan |
Detail Waktu Pengamatan
Mulai Pengamatan (s20232080201177)-
Bidang | Deskripsi | Tujuan |
---|---|---|
Tahun | 2023 | Menentukan tahun pengamatan |
Hari Dalam Setahun | 208 | Menunjukkan hari dalam setahun ketika pengamatan dimulai |
Waktu | 02:01:17 UTC | Menyediakan waktu tepat ketika pengamatan dimulai dalam UTC |
Persepuluh Detik | 7 | Menambahkan presisi ke waktu mulai pengamatan |
Akhir Pengamatan (e20232080203550)-
Bidang | Deskripsi | Tujuan |
---|---|---|
Tahun | 2023 | Menentukan tahun pengamatan |
Hari Dalam Setahun | 208 | Menunjukkan hari dalam setahun ketika pengamatan berakhir |
Waktu | 02:03:55 UTC | Menyediakan waktu yang tepat pengamatan berakhir di UTC |
Persepuluh Detik | 0 | Menambahkan presisi ke waktu akhir pengamatan |
Waktu Pembuatan File (c20232080204563)-
Bidang | Deskripsi | Tujuan |
---|---|---|
Tahun | 2023 | Menentukan tahun file dibuat |
Hari Dalam Setahun | 208 | Menunjukkan hari dalam setahun ketika file dibuat |
Waktu | 02:04:56 UTC | Menyediakan waktu yang tepat file dibuat di UTC |
Persepuluh Detik | 3 | Menambahkan presisi ke waktu pembuatan file |
Informasi Tambahan:
Bidang | Deskripsi | Tujuan |
---|---|---|
DQF | Bendera Kualitas Data, menunjukkan informasi kualitas untuk data yang sesuai | Menyediakan informasi tentang kualitas data |
.tif | Ekstensi berkas | Menunjukkan format file dari data |
Kode berikut mengekstrak metadata ini dari nama file menggunakan ekspresi reguler (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'}
Membuat Item STAC dari Cloud-Optimized File GeoTIFF
Blok kode berikut menggunakan rio-stac
pustaka untuk mengotomatiskan pembuatan item STAC dari Cloud-Optimized GeoTIFFs (COGs).
Ketika diarahkan ke file COG, rio-stac
secara otomatis mengekstrak dan mengatur metadata penting seperti batas spasial, informasi proyeksi, dan properti raster ke dalam format STAC standar. Pustaka menangani tugas kompleks membaca metadata teknis yang disematkan dari GeoTIFF dan mengonversinya menjadi bidang yang mematuhi STAC, termasuk:
- Geometri
- Kotak Pembatas (bbox)
- Detail Proyeksi
- Karakteristik Raster
- Ekstensi STAC
Otomatisasi ini secara signifikan mengurangi pekerjaan manual yang diperlukan untuk membuat Item STAC yang valid dan memastikan konsistensi dalam metadata
Nota
GeoCatalog memiliki batasan pada karakter yang dapat digunakan dalam ID Item STAC dan Kunci aset. Pastikan ID Anda tidak berisi karakter berikut: -
, , _
, +
(
, )
, dan .
. Anda mungkin perlu mengubah item_id
logika pembuatan untuk mengganti atau menghapus karakter ini dari nama file Anda.
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": []
}
}
}
item STAC JSON dari rio-stac
Pustaka rio-stac membaca file GOES COG dan secara otomatis mengekstrak metadata kunci.
Selain itu, berdasarkan jenis metadata yang disertakan, rio-stac menambahkan Ekstensi STAC yang relevan. Ekstensi STAC meningkatkan spesifikasi inti dengan menambahkan metadata khusus domain standar.
- Ekstensi File menyediakan metadata file penting seperti ukuran dan checksum.
- Ekstensi Proyeksi menangkap informasi referensi spasial termasuk sistem koordinat dan kotak pembatas.
- Ekstensi Raster menstandarkan properti khusus untuk data raster, seperti informasi band dan resolusi spasial.
Tabel berikut memberikan penjelasan tentang semua metadata rio-stac yang ditemukan.
Bidang Inti
Bidang | Deskripsi | Tujuan |
---|---|---|
jenis | Selalu "Fitur" | Mengidentifikasi jenis sebagai Fitur GeoJSON |
stac_version | 1.0.0 | Menentukan versi standar STAC |
Id | Pengidentifikasi unik | Berisi informasi satelit, produk, dan waktu |
stac_extensions | Daftar URL skema | Menentukan bidang metadata tambahan |
Informasi Spasial
Bidang | Deskripsi | Tujuan |
---|---|---|
geometri | Poligon GeoJSON | Menentukan jejak data dalam koordinat WGS84 |
bbox | Koordinat kotak pembatas | Menyediakan tingkat spasial sederhana untuk pemfilteran cepat |
proj:geometri | Poligon khusus proyeksi | Tapak dalam koordinat proyeksi asli |
proj:bbox | Batas proyeksi bawaan | Tingkat spasial dalam sistem koordinat satelit |
proj:bentuk | [1500, 2500] | Dimensi gambar dalam piksel |
proj:transform | Transformasi affine | Memetakan piksel untuk mengoordinasikan ruang |
proj:wkt2 | Well-Known Text | Menyelesaikan definisi proyeksi |
proj:epsg | nol | Tidak ada kode EPSG standar untuk proyeksi peta ini |
Informasi Temporal
Bidang | Deskripsi | Tujuan |
---|---|---|
tanggalwaktu | Tanda waktu pembuatan | Ketika item STAC ini dibuat |
Informasi Raster
Bidang | Deskripsi | Tujuan |
---|---|---|
raster:bands | Array objek pita | Menjelaskan properti data raster |
→ data_type | uint16 | Jenis data piksel |
→ spatial_resolution | 2004,02m | Jarak sampel tanah |
→ skala/offset | Faktor konversi | Mengubah nilai piksel menjadi unit fisik (Kelvin) |
nodata | 65535.0 | Nilai yang tidak mewakili data |
statistik → | Ringkasan statistik | Menyediakan informasi distribusi data |
→ histogram | Distribusi nilai | Memvisualisasikan distribusi data |
Informasi Aset
Bidang | Deskripsi | Tujuan |
---|---|---|
aset.data | Aset data utama | Menunjuk ke file data aktual |
→ href | URL | Lokasi GeoTIFF Cloud-Optimized |
jenis → | Tipe media | Mengidentifikasi format file |
File Metadata
Bidang | Deskripsi | Tujuan |
---|---|---|
file:size | 943.250 byte | Ukuran file data |
Menambahkan metadata dari Nama File
Selanjutnya, kami menambahkan data yang kami temukan dalam nama file untuk menyelesaikan pengisian metadata untuk Item STAC ini.
Satu hal yang perlu diperhatikan adalah semua tanggalwaktu untuk Item STAC harus sesuai dengan ISO 8601. Pustaka PySTAC memiliki fungsi datetime_to_str yang memastikan data diformat dengan benar.
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))
Item 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": []
}
}
}
Menambahkan Item STAC ke Koleksi
MC Pro mewajibkan semua Item STAC memiliki referensi ke ID Koleksi STAC induk yang dimasukkan. Untuk tutorial ini, ID Koleksi STAC adalah nama satelit dan produk data.
Dengan PySTAC, mudah untuk menggunakan beberapa metadata yang dikumpulkan dari file sumber untuk mengisi bidang kunci untuk Koleksi STAC dan menggunakan fungsi validasi bawaan.
Kode berikut membuat Koleksi STAC induk untuk menampung data GOES. Kode kemudian menyimpan informasi ini ke file yang digunakan untuk membuat koleksi Microsoft Planetary Computer Pro STAC dan menyerap item STAC ke 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
Langkah selanjutnya
Sekarang setelah Anda membuat beberapa Item STAC, saatnya untuk menyerap data ke Microsoft Planetary Computer Pro.
Untuk Penyerapan Item Tunggal:
Untuk Penyerapan Massal:
Kami juga menawarkan alat STAC Forge yang menyediakan peningkatan otomatisasi menggunakan templat di sekitar data.