Примечание.
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Узнайте, как создать элемент каталога ресурсов SpatioTemporal (STAC) для растрового геопространственного ресурса. Каждый геопространственный набор данных, загружаемый в Microsoft Planetary Computer Pro GeoCatalog, должен иметь связанный элемент, соответствующий стандарту STAC.
В этом руководстве вы:
- Установите необходимые библиотеки Python с помощью PIP.
- Отображение и проверка данных GOES-18 с помощью предоставленного кода Python.
- Извлеките метаданные из имени файла с помощью регулярных выражений.
- Создайте элементы STAC из файлов GeoTIFF Cloud-Optimized с помощью
rio-stac. - Улучшите элемент STAC, используя метаданные, извлеченные из имени файла.
- Добавьте элемент STAC в родительскую коллекцию STAC.
- Проверьте и сохраните каталог STAC, коллекцию и объекты.
- Добавьте элементы STAC в Microsoft Planetary Computer Pro.
В этом руководстве показаны и объясняются возможности с помощью фрагментов кода для интерактивного интерфейса стиля записной книжки, скачайте это руководство в виде записной книжки Jupyter.
Предпосылки
Чтобы завершить это краткое начальное руководство, вам требуется:
- Учетная запись Azure с активной подпиской. Используйте ссылку, чтобы бесплатно создать учетную запись.
- Azure CLI: установка Azure CLI
- Среда Python с по крайней мере версией 3.8.
- Некоторые знания о стандарте STAC и его реализации в Microsoft Planetary Computer Pro STAC Overview
Ключевые функции STAC
Каталог активов SpatioTemporal (STAC) — это открытый стандарт для структурирования и совместного использования геопространственных данных. Он предоставляет общий язык и формат для описания геопространственных ресурсов, что упрощает обнаружение, доступ и использование этих ресурсов на разных платформах и приложениях. Ниже приведены ключевые функции стандарта STAC:
- Взаимодействие. Стандартизованная схема на основе JSON обеспечивает простую интеграцию и понимание между инструментами и системами.
- Расширяемость: гибкие поля ядра с пользовательскими расширениями для конкретных потребностей.
- Возможность обнаружения: согласованная структура улучшает поиск и обнаружение геопространственных ресурсов.
- Доступность: Прямые ссылки на ресурсы данных упрощают извлечение и интеграцию.
- Автоматизация. Включает автоматическую обработку и анализ с стандартизированными метаданными.
Преимущества STAC для стандартизации метаданных
- Согласованность между типами данных: единая платформа для различных геопространственных типов данных.
- Улучшенная совместная работа: упрощение общего доступа и совместной работы с общим форматом метаданных.
- Улучшенная интеграция данных: упрощает интеграцию наборов данных из нескольких источников.
- Упрощенное управление данными: автоматизированные средства сокращают усилия вручную при обслуживании метаданных.
- Подготовка к будущему: гибкость и расширяемость позволяют адаптироваться к новым типам данных и технологиям.
Microsoft Planetary Computer Pro (MC Pro) использует STAC в качестве основного стандарта индексирования для обеспечения взаимодействия между наборами данных. В этом руководстве показано, как создавать элементы STAC с нуля с помощью общих библиотек с открытым исходным кодом.
Спецификация элементов STAC описывает, как создаются элементы STAC и необходимые минимальные метаданные, которые должны быть заполнены. STAC — это гибкий стандарт, позволяющий пользователям решать, какие данные они хотят включить в рамках метаданных. Метаданные, которые можно использовать для заполнения элемента STAC, могут быть включены в ресурс данных, в сопутствующем файле (.XML, .JSON, .TXT и т. д.) или даже в таких местах, как имя файла. Пользователи должны учитывать типы метаданных, по которым они могут захотеть выполнить поиск и сортировку в будущем, решая, какие метаданные следует включить.
В этом руководстве используются образцы данных изображений GeoTIFF (COG), оптимизированных для облачного хранения, из данных Национального океанического и атмосферного агентства (NOAA) Геостационарных операционных спутников R (GOES-R) набора данных по температуре поверхности земли (LST). Эти данные включены в открытый планетарный компьютер в виде ФАЙЛОВ COG, но не хватает метаданных STAC. Спутники GOES производят множество продуктов данных. Дополнительные сведения см. в руководстве по определению продуктов и пользователям серииGOES-R.
Процесс, используемый в этом руководстве, можно обобщить для любого типа данных, в которых перечисляются поля ключевых метаданных с помощью нескольких библиотек с открытым исходным кодом.
Установка библиотек Python
Для начала мы устанавливаем необходимые библиотеки Python с помощью PIP:
rasterio: Этот пакет используется для чтения и записи геопространственных растровых данных. Он предоставляет средства для работы с форматами данных растровых данных, такими как GeoTIFF.pystac: этот пакет используется для работы со стандартом STAC. Он предоставляет средства для создания, чтения и управления метаданными STAC.rio-stac: этот пакет интегрируетrasterioсpystacдля создания элементов STAC из растровых данных. Это упрощает процесс создания метаданных STAC для растровых наборов данных.matplotlib: эта библиотека используется для создания визуализаций и графиков. В контексте геопространственных данных она помогает визуализировать и отображать растровые изображения, позволяя пользователям визуально оценивать данные перед созданием метаданных STAC.azure-storage-blob: Эта клиентская библиотека служба хранилища Azure предоставляет доступ к сервисам Хранилище BLOB-объектов Azure. Он позволяет напрямую взаимодействовать с облачными геопространственных данными, позволяя пользователям читать и работать с файлами, хранящимися в контейнерах BLOB-объектов Azure, не скачивая их сначала.
!pip install rasterio pystac rio_stac matplotlib azure-storage-blob
В следующем разделе кода отображаются некоторые данные GOES-18 с открытого планетарного компьютера. Мы выбираем набор данных GOES-R Advanced Baseline Imager level 2 Land Surface Temperature ( CONUS ) и произвольный файл из дня 208 из 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)
Просматривая данные и имя файла, мы уже видим ключевые фрагменты метаданных, необходимые для сборки элемента STAC. Имя файла содержит сведения о том, какой спутник захватил данные и когда он был записан.
Для примера имя файла — OR_ABI-L2-LSTC-M6_G18_s20232080101177_e20232080103550_c20232080104570_DQF на основе руководства по продукту, это означает:
Подробные компоненты
| Поле | Описание | Цель |
|---|---|---|
| ИЛИ | Операционная система | Указывает системную среду, в которой были собраны данные |
| ABI | Инструмент Advanced Baseline Imager | Определяет инструмент, используемый для записи данных |
| L2 | Продукт уровня 2 (производный продукт) | Указывает, что данные являются производным продуктом, обработанным из необработанных наблюдений |
| LSTC | Продукт "Температура поверхности земли" (Clear Sky) | Представляет конкретный тип продукта, фокусируясь на температуре поверхности земли в условиях ясного неба |
| M6 | Режим 6 (проверка полного диска) | Описывает режим сканирования, охватывающий полный диск Земли |
| G18 | Спутник GOES-18 (также известный как GOES-West) | Определяет спутник, из которого были собраны данные |
Сведения о времени наблюдения
Начало наблюдения (s20232080201177)-
| Поле | Описание | Цель |
|---|---|---|
| Год | 2023 | Указывает год наблюдения |
| День года | 208 | Указывает день года, когда началось наблюдение |
| Время | 02:01:17 UTC | Предоставляет точное время начала наблюдения в формате UTC |
| Десятые секунды | 7 | Добавляет точность в время начала наблюдения |
Завершение наблюдения (e2023208020203550)-
| Поле | Описание | Цель |
|---|---|---|
| Год | 2023 | Указывает год наблюдения |
| День года | 208 | Указывает день года, когда наблюдение закончилось |
| Время | 02:03:55 UTC | Предоставляет точное время окончания наблюдения в формате UTC |
| Десятые секунды | 0 | Добавляет точность к времени окончания наблюдения |
Время создания файла (c2023208020204563)-
| Поле | Описание | Цель |
|---|---|---|
| Год | 2023 | Указывает год создания файла |
| День года | 208 | Указывает день года создания файла |
| Время | 02:04:56 UTC | Предоставляет точное время создания файла в формате UTC |
| Десятые секунды | 3 | Добавляет точность во время создания файла |
Дополнительные сведения
| Поле | Описание | Цель |
|---|---|---|
| DQF | Флаг качества данных, указывающий сведения о качестве соответствующих данных | Предоставляет сведения о качестве данных |
| .tif | Расширение файла | Указывает формат файла данных |
Следующий код извлекает эти метаданные из имени файла с помощью регулярных выражений (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'}
Создание STAC элементов из файлов GeoTIFF Cloud-Optimized
Следующий блок кода использует rio-stac библиотеку для автоматизации создания элементов STAC из Cloud-Optimized GeoTIFFs (COG).
При указании на COG-файл rio-stac автоматически извлекает и упорядочивает важные метаданные, такие как пространственные границы, сведения о проекции и растровые свойства в стандартизированном формате STAC. Библиотека обрабатывает сложную задачу чтения внедренных технических метаданных из GeoTIFF и преобразует ее в поля, совместимые с STAC, включая:
- Геометрия
- Ограничивающий прямоугольник (bbox)
- Сведения о проекции
- Растровые характеристики
- Расширения STAC
Эта автоматизация значительно снижает нагрузку вручную, необходимую для создания допустимых элементов STAC, и обеспечивает согласованность в метаданных.
Замечание
GeoCatalog имеет ограничения на символы, которые можно использовать в идентификаторах элементов STAC и ключах активов. Убедитесь, что идентификаторы не содержат следующие символы: -, _, +, (, ), и .. Может потребоваться изменить логику item_id создания, чтобы заменить или удалить эти символы из имен файлов.
from rio_stac import create_stac_item
from rasterio.io import MemoryFile
import json
from urllib.parse import urlparse, unquote
def create_stac_item_from_cog(url):
"""
Create a basic STAC Item for GOES data using rio-stac with proper spatial handling
Args:
url (str): URL to the COG file
Returns:
pystac.Item: STAC Item with basic metadata and correct spatial information
"""
# Extract the filename safely from the URL
parsed_url = urlparse(url)
path = parsed_url.path # Gets just the path portion of the URL
filename = os.path.basename(path) # Get just the filename part
# Remove .tif extension if present
item_id = filename.replace('.tif', '')
response = requests.get(url, stream=True)
if response.status_code == 200:
with MemoryFile(response.content) as memfile:
with memfile.open() as dataset:
# Create base STAC item from rasterio dataset calling create_stac_item from rio_stac
stac_item = create_stac_item(
source=dataset, # The rasterio dataset object representing the COG file
id=item_id, # Generate a unique ID by extracting the filename without the .tif extension
asset_name='data', # Name of the asset, indicating it contains the primary data
asset_href=url, # URL to the COG file, used as the asset's location
with_proj=True, # Include projection metadata (e.g., CRS, bounding box, etc.)
with_raster=True, # Include raster-specific metadata (e.g., bands, resolution, etc.)
properties={
'datetime': None, # Set datetime to None since explicit start/end times may be added later
# Add rasterio-specific metadata for the raster bands
'raster:bands': [
{
'nodata': dataset.nodata, # Value representing no data in the raster
'data_type': dataset.dtypes[0], # Data type of the raster (e.g., uint16)
'spatial_resolution': dataset.res[0] # Spatial resolution of the raster in meters
}
],
'file:size': len(response.content) # Size of the file in bytes
},
extensions=[
'https://stac-extensions.github.io/file/v2.1.0/schema.json' # Add the file extension schema for additional metadata
]
)
return stac_item
else:
raise Exception(f"Failed to read .tif file: {response.status_code} - {response.text}")
# Example usage
sas_token = get_sas_token(sas_endpoint) # refresh the SAS token prior to creating STAC item
# Create file URL using the first_blob variable that's already defined
file_url = f"{blob_domain}/{container_name}/{first_blob.name}?{sas_token}"
# Create STAC item for the first blob
stac_item = create_stac_item_from_cog(file_url)
# Print the STAC item as JSON
print(json.dumps(stac_item.to_dict(), indent=2))
{
"type": "Feature",
"stac_version": "1.0.0",
"stac_extensions": [
"https://stac-extensions.github.io/file/v2.1.0/schema.json",
"https://stac-extensions.github.io/projection/v1.1.0/schema.json",
"https://stac-extensions.github.io/raster/v1.1.0/schema.json"
],
"id": "OR_ABI-L2-LSTC-M6_G18_s20232080001177_e20232080003550_c20232080004568_DQF",
"geometry": {
"type": "Polygon",
"coordinates": [
[
[
-161.57885623466754,
14.795666555826678
],
[
-112.42114380921453,
14.79566655500485
],
[
-89.5501123912648,
53.52729778421186
],
[
175.5501122574517,
53.52729779865781
],
[
-161.57885623466754,
14.795666555826678
]
]
]
},
"bbox": [
-161.57885623466754,
14.79566655500485,
175.5501122574517,
53.52729779865781
],
"properties": {
"datetime": "2025-03-26T14:46:05.484602Z",
"raster:bands": [
{
"nodata": 65535.0,
"data_type": "uint16",
"spatial_resolution": 2004.017315487541
}
],
"file:size": 118674,
"proj:epsg": null,
"proj:geometry": {
"type": "Polygon",
"coordinates": [
[
[
-2505021.6463773525,
1583173.791653181
],
[
2505021.6423414997,
1583173.791653181
],
[
2505021.6423414997,
4589199.764884492
],
[
-2505021.6463773525,
4589199.764884492
],
[
-2505021.6463773525,
1583173.791653181
]
]
]
},
"proj:bbox": [
-2505021.6463773525,
1583173.791653181,
2505021.6423414997,
4589199.764884492
],
"proj:shape": [
1500,
2500
],
"proj:transform": [
2004.017315487541,
0.0,
-2505021.6463773525,
0.0,
-2004.017315487541,
4589199.764884492,
0.0,
0.0,
1.0
],
"proj:wkt2": "PROJCS[\"unnamed\",GEOGCS[\"unknown\",DATUM[\"unnamed\",SPHEROID[\"Spheroid\",6378137,298.2572221]],PRIMEM[\"Greenwich\",0],UNIT[\"degree\",0.0174532925199433,AUTHORITY[\"EPSG\",\"9122\"]]],PROJECTION[\"Geostationary_Satellite\"],PARAMETER[\"central_meridian\",-137],PARAMETER[\"satellite_height\",35786023],PARAMETER[\"false_easting\",0],PARAMETER[\"false_northing\",0],UNIT[\"metre\",1,AUTHORITY[\"EPSG\",\"9001\"]],AXIS[\"Easting\",EAST],AXIS[\"Northing\",NORTH],EXTENSION[\"PROJ4\",\"+proj=geos +lon_0=-137 +h=35786023 +x_0=0 +y_0=0 +ellps=GRS80 +units=m +no_defs +sweep=x\"]]"
},
"links": [],
"assets": {
"data": {
"href": "https://goeseuwest.blob.core.windows.net/noaa-goes-cogs/goes-18/ABI-L2-LSTC/2023/208/00/OR_ABI-L2-LSTC-M6_G18_s20232080001177_e20232080003550_c20232080004568_DQF.tif?st=2025-03-25T14%3A46%3A03Z&se=2025-03-26T15%3A31%3A03Z&sp=rl&sv=2024-05-04&sr=c&skoid=9c8ff44a-6a2c-4dfb-b298-1c9212f64d9a&sktid=72f988bf-86f1-41af-91ab-2d7cd011db47&skt=2025-03-26T12%3A41%3A49Z&ske=2025-04-02T12%3A41%3A49Z&sks=b&skv=2024-05-04&sig=BuMxN2NUTdrhzY7Dvpd/X4yfX8gnFpHOzANHQLkKE1k%3D",
"type": "image/tiff; application=geotiff",
"raster:bands": [
{
"data_type": "uint16",
"scale": 1.0,
"offset": 0.0,
"sampling": "area",
"nodata": 65535.0,
"unit": "1",
"statistics": {
"mean": 2.780959413109756,
"minimum": 0,
"maximum": 3,
"stddev": 0.710762086175375,
"valid_percent": 100.0
},
"histogram": {
"count": 11,
"min": 0.0,
"max": 3.0,
"buckets": [
26655,
0,
0,
25243,
0,
0,
7492,
0,
0,
570370
]
}
}
],
"roles": []
}
}
}
JSON элемента STAC из rio-stac
Библиотека rio-stac считывает COG-файл GOES и автоматически извлекает метаданные ключа.
Кроме того, rio-stac добавил соответствующие расширения STAC на основе типа включаемых метаданных. Расширения STAC повышают базовую спецификацию, добавляя стандартизированные метаданные, относящиеся к домену.
- Расширение файла предоставляет основные метаданные файла, такие как размер и контрольные суммы.
- Расширение проекции фиксирует сведения о пространственной ссылке, включая системы координат и рамки.
- Расширение raster стандартизирует свойства, относящиеся к растровых данных, например сведения о полосе и пространственное разрешение.
В следующих таблицах приведено объяснение всех найденных метаданных rio-stac.
Основные поля
| Поле | Описание | Цель |
|---|---|---|
| тип | Всегда "Функция" | Определяет тип как компонент GeoJSON |
| версия stac | 1.0.0 | Указывает стандартную версию STAC |
| идентификатор | Уникальный идентификатор | Содержит сведения о спутнике, продукте и времени |
| stac_extensions | Список URL-адресов схемы | Определяет дополнительные поля метаданных |
Пространственные сведения
| Поле | Описание | Цель |
|---|---|---|
| геометрия | Многоугольник GeoJSON | Определяет объем данных в координатах WGS84 |
| bbox | Координаты ограничивающего прямоугольника | Предоставляет простую пространственные экстенты для быстрого фильтрации |
| proj:geometry | Многоугольник, специфичный для проекции | Отпечаток в собственных координатах проекции |
| proj:bbox | Границы собственной проекции | Пространственная протяженность в системе координат спутника |
| proj:shape | [1500, 2500] | Размеры изображения в пикселях |
| proj:transform | аффинное преобразование | Сопоставляет пиксель с координатным пространством |
| proj:wkt2 | текст Well-Known | Полное определение проекции |
| proj:epsg | ноль | Для этой проекции карты нет стандартного кода EPSG |
Темпоральная информация
| Поле | Описание | Цель |
|---|---|---|
| дата/время | Метка времени создания | После того как был создан этот элемент STAC |
Сведения о растре
| Поле | Описание | Цель |
|---|---|---|
| растр:полосы | Массив объектов группы | Описание свойств растровых данных |
| Тип данных | uint16 | Тип данных пикселей |
| пространственное разрешение | 2004,02 м | Дистанция измерения земного объекта |
| → масштабирование или смещение | Факторы преобразования | Преобразует значения пикселей в физические единицы (Kelvin) |
| нет данных | 65535.0 | Значение, представляющее отсутствие данных |
| статистика → | Статистическая сводка | Предоставляет сведения о распределении данных |
| гистограмма → | Распределение значений | Визуализация распределения данных |
Сведения о ресурсах
| Поле | Описание | Цель |
|---|---|---|
| данные активов | Основной ресурс данных | Указывает на фактический файл данных |
| → href | URL-адрес | Расположение файла Cloud-Optimized GeoTIFF |
| тип → | Тип мультимедиа | Определяет формат файла |
Метаданные файла
| Поле | Описание | Цель |
|---|---|---|
| файл:размер | 943 250 байт | Размер файла данных |
Добавление метаданных из имени файла
Затем мы добавим данные, найденные в имени файла, чтобы завершить заполнение метаданных для этого элемента STAC.
Важно отметить, что все значения даты и времени для элементов STAC должны соответствовать стандарту ISO 8601. Библиотека PySTAC имеет функцию datetime_to_str, которая гарантирует правильность форматирования данных.
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))
Элемент 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": []
}
}
}
Добавление элемента STAC в коллекцию
MC Pro требует, чтобы все элементы STAC имели ссылку на идентификатор родительской коллекции STAC, в которую они были добавлены. В этом руководстве идентификатор коллекции STAC — это имя спутника и продукта данных.
С помощью PySTAC можно легко использовать некоторые метаданные, собранные из исходных файлов, для заполнения ключевых полей коллекции STAC и использования встроенных функций проверки.
Следующий код создает родительскую коллекцию STAC для размещения данных GOES. Затем код сохраняет эту информацию в файлы, используемые для создания коллекции STAC Microsoft Planetary Computer Pro и интеграции элементов STAC в Microsoft 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
Дальнейшие шаги
Теперь, когда вы создали несколько элементов STAC, пришло время загрузить данные в сервис Microsoft Planetary Computer Pro.
Для приема отдельных элементов:
Для массового приема:
Используйте инструмент STAC Forge для повышения автоматизации, используя шаблоны, связанные с данными.