Skip to main content
  • »
  • EODATA »
  • Integracja z narzędziami obserwacji Ziemi (EODATA)

Integracja z narzędziami obserwacji Ziemi (EODATA)

Spis treści

  1. Wprowadzenie

  2. Wymagania wstępne

  3. ESA SNAP

  4. GDAL (cmd)

  5. Python Rasterio

Wprowadzenie

W tej sekcji przedstawione zostaną praktyczne scenariusze integracji danych z repozytorium EODATA z popularnymi narzędziami do przetwarzania danych obserwacji Ziemi (EO tools). Zawarte przykłady obejmują różne poziomy złożoności – od prostych operacji na plikach (GDAL), przez przetwarzanie wsadowe w środowisku ESA SNAP, aż po integrację z Pythonem przy użyciu Rasterio.

Celem jest pokazanie, jak dane EODATA mogą być włączone do procesu analizy EO (Earth Observation) w zależności od potrzeb:

  • szybkiej inspekcji i konwersji,

  • automatyzacji łańcuchów przetwarzania,

  • integracji z ekosystemem analityki Pythona.

Do tego celu wykorzystuje się trzy grupy narzędzi:

  • ESA SNAP – bogaty zestaw algorytmów do przetwarzania satelitarnego, szczególnie dla misji Sentinel.

  • GDAL – uniwersalny zestaw narzędzi wiersza poleceń do operacji na danych rastrowych i wektorowych.

  • Rasterio – pythonowa biblioteka wysokiego poziomu, idealna do integracji z analizą danych.

Wymagania wstępne

  • Dostęp do danych z EODATA (np. Sentinel-1/2/3).

  • Zainstalowane narzędzia:

    • Docker (dla SNAP),

    • GDAL (≥ 3.x),

    • Python 3.x + rasterio.

ESA SNAP

SNAP (Sentinel Application Platform) jest narzędziem dedykowanym do analizy danych z misji Sentinel. Wyróżnia się:

  • Graph Processing Framework (GPF) – definiowanie przepływów przetwarzania w formacie XML,

  • możliwością uruchamiania w trybie wsadowym (CLI, Docker),

  • integracją z Pythonem przez moduł snappy.

Przykład użycia w Dockerze

SNAP można uruchomić w kontenerze, co eliminuje problem konfiguracji.

Uruchomienie SNAP w Dockerze

docker run -it --rm --name snap esa/snap:latest

Uruchamianie grafów przetwarzania w ESA SNAP

docker run -it --rm mundialis/esa-snap:latest /usr/local/snap/bin/gpt <GraphFile.xml> [options] [<source-file-1> <source-file-2> ...]

Integracja z Pythonem (snappy)

import snappy
from snappy import ProductIO, GPF

product = ProductIO.readProduct('/eodata/Sentinel-2/MSI/L2A/2025/09/26/S2C_MSIL2A_20250926T100041_N0511_R122_T34UCD_20250926T152116.SAFE')
parameters = snappy.HashMap()
parameters.put('targetBands', 'B4,B8')
result = GPF.createProduct('Subset', parameters, product)
ProductIO.writeProduct(result, 'subset.dim', 'BEAM-DIMAP')

Automatyzacja schematów XML (workflow)

gpt GraphProcessing.xml -Pinput="/eodata/Sentinel-2/MSI/L2A/...SAFE" -Poutput="output.dim"

(gdzie GraphProcessing.xml to plik zdefiniowanego przepływu operacji, np. korekcja atmosferyczna, resampling)

GDAL (cmd)

GDAL to zestaw narzędzi wiersza poleceń, które pozwalają na szybkie operacje na danych rastrowych. Jest wydajne, proste do automatyzacji i nie wymaga dodatkowych zależności.

Przykładowe zastosowania:

Sprawdzenie wersji

gdalinfo --version

Wyświetlenie metadanych

gdalinfo /eodata/Sentinel-2/MSI/L2A/2025/09/26/S2C_MSIL2A_20250926T100041_N0511_R122_T34UCD_20250926T152116.SAFE/GRANULE/L2A_T34UCD_A005526_20250926T100041/IMG_DATA/R10m/T34UCD_20250926T100041_B02_10m.jp2

Konwersja do GeoTIFF

gdal_translate /eodata/Sentinel-2/MSI/L2A/2025/09/26/S2C_MSIL2A_20250926T100041_N0511_R122_T34UCD_20250926T152116.SAFE/GRANULE/L2A_T34UCD_A005526_20250926T100041/IMG_DATA/R10m/T34UCD_20250926T100041_B02_10m.jp2 output.tif

Reprojekcja do WGS84

gdalwarp -t_srs EPSG:4326 /eodata/Sentinel-2/MSI/L2A/2025/09/26/S2C_MSIL2A_20250926T100041_N0511_R122_T34UCD_20250926T152116.SAFE/GRANULE/L2A_T34UCD_A005526_20250926T100041/IMG_DATA/R10m/T34UCD_20250926T100041_B02_10m.jp2 T34UCD_20250926T100041_B02_10m_wgs84.tif

Resampling do 10m

gdalwarp -tr 10 10 /eodata/Sentinel-2/MSI/L2A/2025/09/26/S2C_MSIL2A_20250926T100041_N0511_R122_T34UCD_20250926T152116.SAFE/GRANULE/L2A_T34UCD_A005526_20250926T100041/IMG_DATA/R20m/T34UCD_20250926T100041_B12_20m.jp2 T34UCD_20250926T100041_B12_10m_resampled.tif

Wycinanie AOI (na podstawie shapefile)

gdalwarp -cutline aoi.shp -crop_to_cutline /eodata/Sentinel-2/MSI/L2A/2025/09/26/S2C_MSIL2A_20250926T100041_N0511_R122_T34UCD_20250926T152116.SAFE/GRANULE/L2A_T34UCD_A005526_20250926T100041/IMG_DATA/R20m/T34UCD_20250926T100041_B12_20m.jp2 T34UCD_20250926T100041_B12_10m_resampled.jp2 clipped.tif

Obliczanie NDVI (np. Sentinel-2, B8 = NIR, B4 = RED)

gdal_calc.py \
  -A /eodata/Sentinel-2/MSI/L2A/2025/09/26/S2C_MSIL2A_20250926T100041_N0511_R122_T34UCD_20250926T152116.SAFE/GRANULE/L2A_T34UCD_A005526_20250926T100041/IMG_DATA/R10m/T34UCD_20250926T100041_B08_10m.jp2 \
  -B /eodata/Sentinel-2/MSI/L2A/2025/09/26/S2C_MSIL2A_20250926T100041_N0511_R122_T34UCD_20250926T152116.SAFE/GRANULE/L2A_T34UCD_A005526_20250926T100041/IMG_DATA/R10m/T34UCD_20250926T100041_B04_10m.jp2 \
  --outfile=/SSDCUBE/ndvi.tif \
  --calc="(A.astype(float)-B.astype(float))/(A.astype(float)+B.astype(float))" \
  --type=Float32 \
  --NoDataValue=-9999

Kompresja i optymalizacja (COG)

gdal_translate /eodata/Sentinel-2/MSI/L2A/2025/09/26/S2C_MSIL2A_20250926T100041_N0511_R122_T34UCD_20250926T152116.SAFE/GRANULE/L2A_T34UCD_A005526_20250926T100041/IMG_DATA/R10m/T34UCD_20250926T100041_B04_10m.jp2 T34UCD_20250926T100041_B04_10m_output_cog.tif -of COG

Python Rasterio

Rasterio to pythonowa biblioteka oparta na GDAL, ale oferująca wygodny interfejs wysokiego poziomu. Łatwo integruje się z ekosystemem naukowym (NumPy, Pandas, GeoPandas, scikit-learn).

Przykład zastosowania

import rasterio

with rasterio.open("S2A_MSIL1C_20210901_B04.jp2") as src:
    print(src.meta)
    print(src.bounds)

# Konwersja do GeoTIFF
with rasterio.open("input.jp2") as src:
    profile = src.profile
    with rasterio.open("output.tif", "w", **profile) as dst:
        dst.write(src.read())

# Wycinanie AOI
import geopandas as gpd
from rasterio.mask import mask

shp = gpd.read_file("aoi.shp")
with rasterio.open("input.tif") as src:
    out_image, out_transform = mask(src, shp.geometry, crop=True)

# Obliczanie NDVI
with rasterio.open("B8.tif") as nir, rasterio.open("B4.tif") as red:
    nir_arr = nir.read(1).astype('float32')
    red_arr = red.read(1).astype('float32')
    ndvi = (nir_arr - red_arr) / (nir_arr + red_arr)