import pystac_client
import folium
from odc import stac as odc_stac
This notebook demonstrates how to access radar data in a SpatioTemporal Asset Catalog (STAC) Catalogue using the pystac library. In this example, we use Sentinel-1 data from the EODC (earth observation data and high performance computing service provider based in Vienna) STAC catalog. In the further process, we will learn how to query a STAC catalog, select specific items, and display the metadata and the actual image.
1.1 Data Discovery
= pystac_client.Client.open("https://stac.eodc.eu/api/v1")
eodc_catalog
eodc_catalog
- type "Catalog"
- id "stac-fastapi"
- stac_version "1.0.0"
- description "A STAC-compliant API to query for metadata within the EODC Data Catalogue."
links[] 57 items
0
- rel "self"
- href "https://stac.eodc.eu/api/v1"
- type "application/json"
1
- rel "root"
- href "https://stac.eodc.eu/api/v1/"
- type "application/json"
2
- rel "data"
- href "https://stac.eodc.eu/api/v1/collections"
- type "application/json"
3
- rel "conformance"
- href "https://stac.eodc.eu/api/v1/conformance"
- type "application/json"
- title "STAC/WFS3 conformance classes implemented by this server"
4
- rel "search"
- href "https://stac.eodc.eu/api/v1/search"
- type "application/geo+json"
- title "STAC search"
- method "GET"
5
- rel "search"
- href "https://stac.eodc.eu/api/v1/search"
- type "application/geo+json"
- title "STAC search"
- method "POST"
6
- rel "child"
- href "https://stac.eodc.eu/api/v1/collections/SENTINEL2_L2A"
- type "application/json"
- title "Sentinel-2 MSI Products: Level-2A data"
7
- rel "child"
- href "https://stac.eodc.eu/api/v1/collections/SENTINEL2_GRI_L1C"
- type "application/json"
- title "Multi-Layer Copernicus Sentinel-2 GRI in L1C"
8
- rel "child"
- href "https://stac.eodc.eu/api/v1/collections/DOP_AUT_K_OSTTIROL"
- type "application/json"
- title "Digital Orthophotos (DOP) Austria - Land Kärnten: Orthofotos Flugblock Osttirol"
9
- rel "child"
- href "https://stac.eodc.eu/api/v1/collections/SENTINEL1_HPAR"
- type "application/json"
- title "SENTINEL1 Harmonic Parameters"
10
- rel "child"
- href "https://stac.eodc.eu/api/v1/collections/AUT_DEM"
- type "application/json"
- title "Austrian High Resolution DEM"
11
- rel "child"
- href "https://stac.eodc.eu/api/v1/collections/COP_DEM"
- type "application/json"
- title "Copernicus Digital Elevation Model (DEM)"
12
- rel "child"
- href "https://stac.eodc.eu/api/v1/collections/DOP_AUT_K_KLAGENFURT"
- type "application/json"
- title "Digital Orthophotos (DOP) Austria - Land Kärnten: Orthofotos Flugblock Klagenfurt"
13
- rel "child"
- href "https://stac.eodc.eu/api/v1/collections/DOP_AUT_K_WOLFSBERG"
- type "application/json"
- title "Digital Orthophotos (DOP) Austria - Land Kärnten: Orthofotos Flugblock Wolfsberg"
14
- rel "child"
- href "https://stac.eodc.eu/api/v1/collections/SENTINEL1_MPLIA"
- type "application/json"
- title "SENTINEL1 Mean PLIA"
15
- rel "child"
- href "https://stac.eodc.eu/api/v1/collections/SENTINEL1_SLC"
- type "application/json"
- title "Sentinel-1 SLC"
16
- rel "child"
- href "https://stac.eodc.eu/api/v1/collections/SENTINEL1_GRD"
- type "application/json"
- title "Sentinel-1 SAR L1 GRD"
17
- rel "child"
- href "https://stac.eodc.eu/api/v1/collections/AI4SAR_SIG0"
- type "application/json"
- title "AI4SAR Despeckled Sentinel-1 Sigma0 (20m)"
18
- rel "child"
- href "https://stac.eodc.eu/api/v1/collections/SENTINEL3_SRAL_L2"
- type "application/json"
- title "Sentinel-3 Products: SRAL Level-2 data"
19
- rel "child"
- href "https://stac.eodc.eu/api/v1/collections/SENTINEL2_L1C"
- type "application/json"
- title "Sentinel-2 MSI Products: Level-1C data"
20
- rel "child"
- href "https://stac.eodc.eu/api/v1/collections/SENTINEL1_SIG0_20M"
- type "application/json"
- title "SENTINEL1 Sigma Nought (SIG0) Backscatter in 20 meter resolution"
21
- rel "child"
- href "https://stac.eodc.eu/api/v1/collections/DOP_AUT_ST_BISCHOFSHOFEN"
- type "application/json"
- title "Digital Orthophotos (DOP) Austria - Land Steiermark: Orthophotos Flugblock Bischofshofen"
22
- rel "child"
- href "https://stac.eodc.eu/api/v1/collections/DOP_AUT_ST_MURTAL"
- type "application/json"
- title "Digital Orthophotos (DOP) Austria - Land Steiermark: Orthophotos Flugblock Murtal"
23
- rel "child"
- href "https://stac.eodc.eu/api/v1/collections/DOP_AUT_ST_MARIAZELL"
- type "application/json"
- title "Digital Orthophotos (DOP) Austria - Land Steiermark: Orthophotos Flugblock Mariazell"
24
- rel "child"
- href "https://stac.eodc.eu/api/v1/collections/DOP_AUT_ST_GRAZ"
- type "application/json"
- title "Digital Orthophotos (DOP) Austria - Land Steiermark: Orthophotos Flugblock Graz"
25
- rel "child"
- href "https://stac.eodc.eu/api/v1/collections/DOP_AUT_ST_WINDISCHGARSTEN"
- type "application/json"
- title "Digital Orthophotos (DOP) Austria - Land Steiermark: Orthophotos Flugblock Windischgarsten"
26
- rel "child"
- href "https://stac.eodc.eu/api/v1/collections/DOP_AUT_ST_KLAGENFURT"
- type "application/json"
- title "Digital Orthophotos (DOP) Austria - Land Steiermark: Orthophotos Flugblock Klagenfurt"
27
- rel "child"
- href "https://stac.eodc.eu/api/v1/collections/DOP_AUT_ST_SUEDBURGENLAND"
- type "application/json"
- title "Digital Orthophotos (DOP) Austria - Land Steiermark: Orthophotos Flugblock Suedburgenland"
28
- rel "child"
- href "https://stac.eodc.eu/api/v1/collections/DOP_AUT_ST_VILLACH"
- type "application/json"
- title "Digital Orthophotos (DOP) Austria - Land Steiermark: Orthophotos Flugblock Villach"
29
- rel "child"
- href "https://stac.eodc.eu/api/v1/collections/INTRA_FIELD_CROP_GROWTH_POTENTIAL"
- type "application/json"
- title "Intra-field Crop Growth Potential"
30
- rel "child"
- href "https://stac.eodc.eu/api/v1/collections/Sentinel-1_Reed_Extent"
- type "application/json"
- title "SENTINEL-1 Reed Extent"
31
- rel "child"
- href "https://stac.eodc.eu/api/v1/collections/AUSTRIA_GROUND_MOTION"
- type "application/json"
- title "Austria Ground Motion"
32
- rel "child"
- href "https://stac.eodc.eu/api/v1/collections/Sentinel-1_Lacken_Extent"
- type "application/json"
- title "SENTINEL-1 Lacken Extent"
33
- rel "child"
- href "https://stac.eodc.eu/api/v1/collections/DROUGHT_VULNERABILITY"
- type "application/json"
- title "Drought Vulnerability"
34
- rel "child"
- href "https://stac.eodc.eu/api/v1/collections/SENTINEL2_MFCOVER"
- type "application/json"
- title "Monthly Composite of Fraction of Vegetation Cover"
35
- rel "child"
- href "https://stac.eodc.eu/api/v1/collections/SENTINEL2_L1C_COVERAGE"
- type "application/json"
- title "Sentinel-2 L1C Coverage Maps"
36
- rel "child"
- href "https://stac.eodc.eu/api/v1/collections/SAR_IMP_1P"
- type "application/json"
- title "ERS-1/2 SAR Image Mode Precision Level-1"
37
- rel "child"
- href "https://stac.eodc.eu/api/v1/collections/SAR_IMS_1P"
- type "application/json"
- title "ERS-1/2 SAR Image Mode Single Look Complex Level-1"
38
- rel "child"
- href "https://stac.eodc.eu/api/v1/collections/ASA_IMS_1P"
- type "application/json"
- title "Envisat ASAR Image Mode Single Look Complex Level-1"
39
- rel "child"
- href "https://stac.eodc.eu/api/v1/collections/ERS_ENVISAT_NRB"
- type "application/json"
- title "ERS-1/2 SAR and ENVISAT ASAR ARD Normalized Radar Backscatter (NRB)"
40
- rel "child"
- href "https://stac.eodc.eu/api/v1/collections/SENTINEL1_ALPS_WETSNOW"
- type "application/json"
- title "Sentinel-1 Alps WetSnow"
41
- rel "child"
- href "https://stac.eodc.eu/api/v1/collections/ASA_IMP_1P"
- type "application/json"
- title "Envisat ASAR Image Mode Precision Level-1"
42
- rel "child"
- href "https://stac.eodc.eu/api/v1/collections/Sentinel-2-Greenness-Austria"
- type "application/json"
- title "Sentinel-2 Greenness Austria"
43
- rel "child"
- href "https://stac.eodc.eu/api/v1/collections/SENTINEL1_GRD_COVERAGE"
- type "application/json"
- title "Sentinel-1 Coverage Maps"
44
- rel "child"
- href "https://stac.eodc.eu/api/v1/collections/VEGETATION_CHANGE_AUSTRIA"
- type "application/json"
- title "Vegetation-Change-Austria"
45
- rel "child"
- href "https://stac.eodc.eu/api/v1/collections/sentinel2-landsat8-l2f"
- type "application/json"
- title "Harmonized Landsat and Sentinel 2 L2F"
46
- rel "child"
- href "https://stac.eodc.eu/api/v1/collections/GFM"
- type "application/json"
- title "Global Flood Monitoring"
47
- rel "child"
- href "https://stac.eodc.eu/api/v1/collections/CORINE_LAND_COVER"
- type "application/json"
- title "Corine Land Cover"
48
- rel "child"
- href "https://stac.eodc.eu/api/v1/collections/DOP_AUT_K_TAMSWEG"
- type "application/json"
- title "Digital Orthophotos (DOP) Austria - Land Kärnten: Orthofotos Flugblock Tamsweg"
49
- rel "child"
- href "https://stac.eodc.eu/api/v1/collections/DOP_AUT_K_VILLACH"
- type "application/json"
- title "Digital Orthophotos (DOP) Austria - Land Kärnten: Orthofotos Flugblock Villach"
50
- rel "child"
- href "https://stac.eodc.eu/api/v1/collections/BOA_LANDSAT_8"
- type "application/json"
- title "Bottom of Atmosphere Landsat-8 at 30m resolution."
51
- rel "child"
- href "https://stac.eodc.eu/api/v1/collections/DOP_AUT_K_ZELTWEG"
- type "application/json"
- title "Digital Orthophotos (DOP) Austria - Land Kärnten: Orthofotos Flugblock Zeltweg"
52
- rel "child"
- href "https://stac.eodc.eu/api/v1/collections/DOP_AUT_K_ZELL_AM_SEE"
- type "application/json"
- title "Digital Orthophotos (DOP) Austria - Land Kärnten: Orthofotos Flugblock Zell am See"
53
- rel "child"
- href "https://stac.eodc.eu/api/v1/collections/BOA_SENTINEL_2"
- type "application/json"
- title "Bottom of Atmosphere Sentinel-2 at 10m resolution."
54
- rel "child"
- href "https://stac.eodc.eu/api/v1/collections/CGLS_SSM_1KM"
- type "application/json"
- title "Copernicus Global Land Surface Soil Moisture"
55
- rel "service-desc"
- href "https://stac.eodc.eu/api/v1/openapi.json"
- type "application/vnd.oai.openapi+json;version=3.0"
- title "OpenAPI service description"
56
- rel "service-doc"
- href "https://stac.eodc.eu/api/v1/docs"
- type "text/html"
- title "OpenAPI service documentation"
conformsTo[] 16 items
- 0 "http://www.opengis.net/spec/ogcapi-features-3/1.0/conf/filter"
- 1 "http://www.opengis.net/spec/cql2/1.0/conf/basic-cql2"
- 2 "https://api.stacspec.org/v1.0.0/item-search"
- 3 "https://api.stacspec.org/v1.0.0/ogcapi-features"
- 4 "http://www.opengis.net/spec/cql2/1.0/conf/cql2-text"
- 5 "https://api.stacspec.org/v1.0.0-rc.2/item-search#filter"
- 6 "https://api.stacspec.org/v1.0.0-rc.2/item-search#query"
- 7 "https://api.stacspec.org/v1.0.0-rc.2/item-search#context"
- 8 "https://api.stacspec.org/v1.0.0/core"
- 9 "https://api.stacspec.org/v1.0.0/collections"
- 10 "http://www.opengis.net/spec/ogcapi-features-1/1.0/conf/core"
- 11 "https://api.stacspec.org/v1.0.0-rc.3/item-search#fields"
- 12 "http://www.opengis.net/spec/ogcapi-features-1/1.0/conf/geojson"
- 13 "http://www.opengis.net/spec/ogcapi-features-1/1.0/conf/oas30"
- 14 "https://api.stacspec.org/v1.0.0-rc.2/item-search#sort"
- 15 "http://www.opengis.net/spec/ogcapi-features-3/1.0/conf/features-filter"
- title "EODC Data Catalogue"
The URL https://stac.eodc.eu/api/v1, served over Hypertext Transfer Protocol (HTTP), is a STAC-compliant API endpoint (specific URL address where an API service is available) that leads to the EODC Catalogue. Besides EODC’s, other catalogues can be found on STAC Index, such as United States Geological Survey (USGS) Landsat imagery, Sentinel Hub, Copernicus Data Space Ecosystem, and so on. Briefly spoken, STAC can be used to search, discover, and access metadata of these datasets with the same code. The EODC Catalogue can be accessed on the web via this link as well.
Each STAC catalog, composed by different providers, has many collections. To get all collections of a catalog, we can print all of them and their ids, which are used to fetch them from the catalog.
= eodc_catalog.get_collections()
collections
# length of string of collection.id, for pretty print
= max(len(collection.id) for collection in collections)
max_length
for collection in eodc_catalog.get_collections():
print(f"{collection.id.ljust(max_length)}: {collection.title}")
SENTINEL2_L2A : Sentinel-2 MSI Products: Level-2A data
SENTINEL2_GRI_L1C : Multi-Layer Copernicus Sentinel-2 GRI in L1C
DOP_AUT_K_OSTTIROL : Digital Orthophotos (DOP) Austria - Land Kärnten: Orthofotos Flugblock Osttirol
SENTINEL1_HPAR : SENTINEL1 Harmonic Parameters
AUT_DEM : Austrian High Resolution DEM
COP_DEM : Copernicus Digital Elevation Model (DEM)
DOP_AUT_K_KLAGENFURT : Digital Orthophotos (DOP) Austria - Land Kärnten: Orthofotos Flugblock Klagenfurt
DOP_AUT_K_WOLFSBERG : Digital Orthophotos (DOP) Austria - Land Kärnten: Orthofotos Flugblock Wolfsberg
SENTINEL1_MPLIA : SENTINEL1 Mean PLIA
SENTINEL1_SLC : Sentinel-1 SLC
SENTINEL1_GRD : Sentinel-1 SAR L1 GRD
AI4SAR_SIG0 : AI4SAR Despeckled Sentinel-1 Sigma0 (20m)
SENTINEL3_SRAL_L2 : Sentinel-3 Products: SRAL Level-2 data
SENTINEL2_L1C : Sentinel-2 MSI Products: Level-1C data
SENTINEL1_SIG0_20M : SENTINEL1 Sigma Nought (SIG0) Backscatter in 20 meter resolution
DOP_AUT_ST_BISCHOFSHOFEN : Digital Orthophotos (DOP) Austria - Land Steiermark: Orthophotos Flugblock Bischofshofen
DOP_AUT_ST_MURTAL : Digital Orthophotos (DOP) Austria - Land Steiermark: Orthophotos Flugblock Murtal
DOP_AUT_ST_MARIAZELL : Digital Orthophotos (DOP) Austria - Land Steiermark: Orthophotos Flugblock Mariazell
DOP_AUT_ST_GRAZ : Digital Orthophotos (DOP) Austria - Land Steiermark: Orthophotos Flugblock Graz
DOP_AUT_ST_WINDISCHGARSTEN : Digital Orthophotos (DOP) Austria - Land Steiermark: Orthophotos Flugblock Windischgarsten
DOP_AUT_ST_KLAGENFURT : Digital Orthophotos (DOP) Austria - Land Steiermark: Orthophotos Flugblock Klagenfurt
DOP_AUT_ST_SUEDBURGENLAND : Digital Orthophotos (DOP) Austria - Land Steiermark: Orthophotos Flugblock Suedburgenland
DOP_AUT_ST_VILLACH : Digital Orthophotos (DOP) Austria - Land Steiermark: Orthophotos Flugblock Villach
INTRA_FIELD_CROP_GROWTH_POTENTIAL: Intra-field Crop Growth Potential
Sentinel-1_Reed_Extent : SENTINEL-1 Reed Extent
AUSTRIA_GROUND_MOTION : Austria Ground Motion
Sentinel-1_Lacken_Extent : SENTINEL-1 Lacken Extent
DROUGHT_VULNERABILITY : Drought Vulnerability
SENTINEL2_MFCOVER : Monthly Composite of Fraction of Vegetation Cover
SENTINEL2_L1C_COVERAGE : Sentinel-2 L1C Coverage Maps
SAR_IMP_1P : ERS-1/2 SAR Image Mode Precision Level-1
SAR_IMS_1P : ERS-1/2 SAR Image Mode Single Look Complex Level-1
ASA_IMS_1P : Envisat ASAR Image Mode Single Look Complex Level-1
ERS_ENVISAT_NRB : ERS-1/2 SAR and ENVISAT ASAR ARD Normalized Radar Backscatter (NRB)
SENTINEL1_ALPS_WETSNOW : Sentinel-1 Alps WetSnow
ASA_IMP_1P : Envisat ASAR Image Mode Precision Level-1
Sentinel-2-Greenness-Austria : Sentinel-2 Greenness Austria
SENTINEL1_GRD_COVERAGE : Sentinel-1 Coverage Maps
VEGETATION_CHANGE_AUSTRIA : Vegetation-Change-Austria
sentinel2-landsat8-l2f : Harmonized Landsat and Sentinel 2 L2F
GFM : Global Flood Monitoring
CORINE_LAND_COVER : Corine Land Cover
DOP_AUT_K_TAMSWEG : Digital Orthophotos (DOP) Austria - Land Kärnten: Orthofotos Flugblock Tamsweg
DOP_AUT_K_VILLACH : Digital Orthophotos (DOP) Austria - Land Kärnten: Orthofotos Flugblock Villach
BOA_LANDSAT_8 : Bottom of Atmosphere Landsat-8 at 30m resolution.
DOP_AUT_K_ZELTWEG : Digital Orthophotos (DOP) Austria - Land Kärnten: Orthofotos Flugblock Zeltweg
DOP_AUT_K_ZELL_AM_SEE : Digital Orthophotos (DOP) Austria - Land Kärnten: Orthofotos Flugblock Zell am See
BOA_SENTINEL_2 : Bottom of Atmosphere Sentinel-2 at 10m resolution.
CGLS_SSM_1KM : Copernicus Global Land Surface Soil Moisture
To get a specific collection from the catalog, we can use the client.get_collection()
method and provide the collection name. We can then display its description, id, temporal and spatial extent, license, etc. In this notebook, we will work with the Sentinel-1 sigma naught 20m collection.
= "SENTINEL1_SIG0_20M"
colllection_id
= eodc_catalog.get_collection(colllection_id)
collection collection
- type "Collection"
- id "SENTINEL1_SIG0_20M"
- stac_version "1.0.0"
- description "Sentinel-1 Sigma Nought (SIG0) Products are radiometric calibrated and georeferenced backscatter data generated from Sentinel-1 level-1 Interferometric Wide (IW) Swath Ground Range Detected (GRD) High resolution products using TUWien Sentinel-1 preprocesssing workflow. The preprocessing workflow includes following steps: applying precise orbit file, radiometric calibration, thermal noise removal, and range doppler terrain correction. In the end, Sigma0 backscatter image is reprojected and resampled into Equi7 Grid system at 20m pixels spacing."
links[] 5 items
0
- rel "items"
- href "https://stac.eodc.eu/api/v1/collections/SENTINEL1_SIG0_20M/items"
- type "application/geo+json"
1
- rel "parent"
- href "https://stac.eodc.eu/api/v1/"
- type "application/json"
2
- rel "root"
- href "https://stac.eodc.eu/api/v1"
- type "application/json"
- title "EODC Data Catalogue"
3
- rel "self"
- href "https://stac.eodc.eu/api/v1/collections/SENTINEL1_SIG0_20M"
- type "application/json"
4
- rel "items"
- href "https://stac.eodc.eu/ingestion/v1/collections/SENTINEL1_SIG0_20M/items"
- type "application/geo+json"
stac_extensions[] 6 items
- 0 "https://stac-extensions.github.io/sat/v1.0.0/schema.json"
- 1 "https://stac-extensions.github.io/sar/v1.0.0/schema.json"
- 2 "https://stac-extensions.github.io/eo/v1.0.0/schema.json"
- 3 "https://stac-extensions.github.io/projection/v1.1.0/schema.json"
- 4 "https://stac-extensions.github.io/item-assets/v1.0.0/schema.json"
- 5 "https://stac-extensions.github.io/datacube/v2.0.0/schema.json"
cube:dimensions
x
- axis "x"
- type "spatial"
extent[] 2 items
- 0 -180
- 1 180
y
- axis "y"
- type "spatial"
extent[] 2 items
- 0 -90
- 1 90
time
- type "temporal"
extent[] 2 items
- 0 "2014-10-01T00:00:00Z"
- 1 None
- title "SENTINEL1 Sigma Nought (SIG0) Backscatter in 20 meter resolution"
extent
spatial
bbox[] 1 items
0[] 4 items
- 0 -180
- 1 -90
- 2 180
- 3 90
temporal
interval[] 1 items
0[] 2 items
- 0 "2014-10-01T00:00:00Z"
- 1 None
- license "proprietary"
providers[] 2 items
0
- name "TU Wien"
roles[] 2 items
- 0 "processor"
- 1 "licensor"
- url "https://www.tuwien.at/mg/geo"
1
- name "EODC"
roles[] 2 items
- 0 "processor"
- 1 "host"
- url "https://eodc.eu/"
summaries
gsd[] 1 items
- 0 20
eo:bands[] 4 items
0
- name "VV"
- common_name "Sigma0_VV"
- description "Sigma Nought in VV polarization"
- center_wavelength 55465.76
1
- name "VH"
- common_name "Sigma0_VH"
- description "Sigma Nought in VH polarization"
- center_wavelength 55465.76
2
- name "HH"
- common_name "Sigma0_HH"
- description "Sigma Nought in HH polarization"
- center_wavelength 55465.76
3
- name "HV"
- common_name "Sigma0_HV"
- description "Sigma Nought in HV polarization"
- center_wavelength 55465.76
platform[] 2 items
- 0 "sentinel-1a"
- 1 "sentinel-1b"
item_assets
HH
- type "image/tiff; application=geotiff"
- title "Sigma Nought (HH)"
eo:bands[] 1 items
0
- name "HH"
- common_name "Sigma0_HH"
- center_wavelength 55465.76
- description "Sigma Nought in HH polarization"
HV
- type "image/tiff; application=geotiff"
- title "Sigma Nought (HV)"
eo:bands[] 1 items
0
- name "HV"
- common_name "Sigma0_HV"
- center_wavelength 55465.76
- description "Sigma Nought in HV polarization"
VH
- type "image/tiff; application=geotiff"
- title "Sigma Nought (VH)"
eo:bands[] 1 items
0
- name "VH"
- common_name "Sigma0_VH"
- center_wavelength 55465.76
- description "Sigma Nought in VH polarization"
VV
- type "image/tiff; application=geotiff"
- title "Sigma Nought (VV)"
eo:bands[] 1 items
0
- name "VV"
- common_name "Sigma0_VV"
- center_wavelength 55465.76
- description "Sigma Nought in VV polarization"
thumbnail
- type "image/png"
roles[] 1 items
- 0 "thumbnail"
- title "Thumbnail"
- description "A medium sized thumbnail"
- constellation "sentinel-1"
assets
thumbnail
- href "https://objectstore.eodc.eu:2222/swift/v1/AUTH_68e13833a1624f43ba2cac01376a18af/thumbnails/SENTINEL1_SIG0_20M.png"
- type "image/png"
- title "SENTINEL1_SIG0_20M collection thumbnail."
roles[] 1 items
- 0 "thumbnail"
Each collection has multiple items. An item is one spatio-temporal instance the collection, for instance a satellite image. If items are needed for a specific timeframe or for a specific region of interest, we can define this as a query.
= "2022-10-01/2022-10-07" # a closed range
time_range # time_range = "2022-01" # whole month, same can be done for a year and a day
# time_range = "2022-01-01/.." # up to the current date, an open range
# time_range = "2022-01-01T05:34:46" # a specific time instance
A spatial region of interest can be defined in different ways. One option is to define a simple bounding box:
= 46.3, 49.3 # South to North
latmin, latmax = 13.8, 17.8 # West to East
lonmin, lonmax
= [lonmin, latmin, lonmax, latmax] bounding_box
If the region of interest is not rectengular, we can also define a polygon:
# GEOJSON can be created on geojson.io
# This specific area of interest is a rectangle, but since it is
# a closed polygon it seems like it has five nodes
= {
area_of_interest "coordinates": [
[17.710928010825853, 49.257630084442496],
[13.881798300915221, 49.257630084442496],
[13.881798300915221, 46.34747715326259],
[17.710928010825853, 46.34747715326259],
[17.710928010825853, 49.257630084442496],
[
]
],"type": "Polygon",
}
Using our previously loaded STAC catalog, we can now search for items fullfilling our query. In this example we are using the bounding box. If we want to use an area of interest specified in the geojson format - one hast to use the intersects parameter as documented in the comment below.
= eodc_catalog.search(
search =colllection_id, # can also be a list of several collections
collections=bounding_box, # search by bounding box
bbox# intersects=area_of_interest, # GeoJSON search
=time_range,
datetime# max_items=1 # number of max items to load
)
# If we comment everything besides colllection_id, we will load whole
# collection for available region and time_range
= search.item_collection()
items_eodc print(f"On EODC we found {len(items_eodc)} items for the given search query")
On EODC we found 52 items for the given search query
Now, we can fetch a single item, in this case a Sentinel-1 image, from the query results. A good practice is to always check what metadata the data provider has stored on the item level. This can be done by looking into the item properties.
= items_eodc[0]
item item.properties
{'gsd': 20,
'parent': 'S1A_IW_GRDH_1SDV_20221007T170811_20221007T170836_045339_056BBA_D830.zip',
'checksum': '576abe68a715e5ee177d8b640871e873',
'datetime': '2022-10-07T17:08:11Z',
'blocksize': {'x': 15000, 'y': 5},
'proj:bbox': [4800000, 1500000, 5100000, 1800000],
'proj:wkt2': 'PROJCS["Azimuthal_Equidistant",GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS 84",6378137,298.257223563,AUTHORITY["EPSG","7030"]],AUTHORITY["EPSG","6326"]],PRIMEM["Greenwich",0],UNIT["degree",0.0174532925199433],AUTHORITY["EPSG","4326"]],PROJECTION["Azimuthal_Equidistant"],PARAMETER["latitude_of_center",53],PARAMETER["longitude_of_center",24],PARAMETER["false_easting",5837287.81977],PARAMETER["false_northing",2121415.69617],UNIT["metre",1,AUTHORITY["EPSG","9001"]]]',
'proj:shape': [15000, 15000],
'Equi7_TileID': 'EU020M_E048N015T3',
'constellation': 'sentinel-1',
'proj:geometry': {'type': 'Polygon',
'coordinates': [[[4800000.0, 1500000.0],
[4800000.0, 1800000.0],
[5100000.0, 1800000.0],
[5100000.0, 1500000.0],
[4800000.0, 1500000.0]]]},
'proj:transform': [20, 0, 4800000, 0, -20, 1800000],
'sat:orbit_state': 'ascending',
'sar:product_type': 'GRD',
'slice_gap_filled': False,
'sar:polarizations': ['VH', 'VV'],
'sar:frequency_band': 'C',
'sat:relative_orbit': 117,
'sar:instrument_mode': 'IW',
'border_noise_removed': True,
'sar:center_frequency': 5.405,
'sar:resolution_range': 40,
'thermal_noise_removed': True,
'sar:resolution_azimuth': 40,
'sar:pixel_spacing_range': 20,
'sar:observation_direction': 'right',
'sar:pixel_spacing_azimuth': 20,
'sat:platform_international_designator': '2014-016A'}
For now, let’s display only the vertical-vertical (VV) polarized band of the item and some information about the data.
"VV"].extra_fields.get("raster:bands")[0] item.assets[
{'scale': 10,
'nodata': -9999,
'offset': 0,
'data_type': 'int16',
'spatial_resolution': 20}
In the EODC STAC catalogue an item can conveniently be displayed using its thumbnail.
"thumbnail"].href item.assets[
'https://data.eodc.eu/collections/SENTINEL1_SIG0_20M/V1M1R1/EQUI7_EU020M/E048N015T3/SIG0_20221007T170811__VV_A117_E048N015T3_EU020M_V1M1R1_S1AIWGRDH_TUWIEN.tif/thumbnail'
Now we will plot the data on a map using the thumbnail and the python package folium. This is an easy way to quickly check how the data found by a search query looks on a map.
map = folium.Map(
=[(latmin + latmax) / 2, (lonmin + lonmax) / 2],
location=7,
zoom_start=False,
zoom_control=False,
scrollWheelZoom=False,
dragging
)
="Area of Interest").add_to(map)
folium.GeoJson(area_of_interest, name
for item in items_eodc:
# url leading to display of an item, can also be used as hyperlink
= item.assets["thumbnail"].href
image_url = item.bbox
bounds
folium.raster_layers.ImageOverlay(=image_url,
image=[[bounds[1], bounds[0]], [bounds[3], bounds[2]]],
boundsmap)
).add_to(
map)
folium.LayerControl().add_to(
map
Figure 1: Map of study area. Blue rectangle is the area covered by the discovered data.
1.2 Data Reading
STAC can also be a useful tool for the discovery of data, however it only loads metadata. This saves memory, but if one would like to do further analysis, the data has to be loaded into memory or downloaded on disk.
In the following, we will demonstrate this with the library odc-stac
. Here we can define what data will loaded as bands
; in this case VV sigma naught. Moreover we can resample the data by providing any coordinate reference system (CRS) and resolution as well as a method for resampling of continuos data (e.g. bilinear resampling). In the example below we use the EQUI7 Grid of Europe and a 20 meter sampling. This is the native format of sigma naught stored at EODC, so there will be no actual resampling. Note, also, that resampling is not advisable for this data, as it is provided on a logarithmic scale. More about this in notebook 2.
The chunks argument is an advancement method for performing parallel computations on the data. We will not cover this in further detail.
= "VV" # Vertical-vertical polarized
bands = "EPSG:27704" # Coordinate Reference System: EQUI7 Grid of Europe
crs = 20 # 20 meter
res = {"time": 1, "latitude": 1000, "longitude": 1000}
chunks = odc_stac.load(
sig0_dc
items_eodc,=bands,
bands=crs,
crs=res,
resolution=bounding_box,
bbox=chunks,
chunks="bilinear",
resampling )
Let’s have a look at the VV polarized band of the dataset.
sig0_dc.VV
<xarray.DataArray 'VV' (time: 31, y: 18269, x: 16725)> Size: 19GB dask.array<VV, shape=(31, 18269, 16725), dtype=int16, chunksize=(1, 18269, 16725), chunktype=numpy.ndarray> Coordinates: * y (y) float64 146kB 1.762e+06 1.762e+06 ... 1.396e+06 1.396e+06 * x (x) float64 134kB 5.052e+06 5.052e+06 ... 5.387e+06 5.387e+06 spatial_ref int32 4B 27704 * time (time) datetime64[ns] 248B 2022-10-01T05:09:56 ... 2022-10-0... Attributes: nodata: -9999
As we can see, the data is stored as a xarray
DataArray. Xarray
is a convenient package for multidimensional labeled arrays, like temperature, humidity, pressure, different bands of satellite imagery, and so on. The link provides detailed documentation. In a later notebook we will explore some more of the functionality of xarray
. As we can see in the coordinates, the data here consists of 21 time steps.
In general, data from STAC is “lazily” loaded, which means that the structure of the DataArray is constructed, but the data is not loaded yet. It is loaded only at instance when it is needed, for example, for plotting, computations, and so on.
Since the DataArray has currently a size of almost 18 GiB, we will subset it to the region of Vienna.
# Create a bounding box covering the region of Vienna
= 48, 48.4
latmin_smaller, latmax_smaller = 16, 16.5
lonmin_smaller, lonmax_smaller
= [
smaller_bounding_box
[latmin_smaller, lonmin_smaller],
[latmax_smaller, lonmax_smaller],
]
map = folium.Map(
=[
location+ latmax_smaller) / 2,
(latmin_smaller + lonmax_smaller) / 2,
(lonmin_smaller
],=8,
zoom_start=False,
zoom_control=False,
scrollWheelZoom=False,
dragging
)
="Area of Interest").add_to(map)
folium.GeoJson(area_of_interest, name
folium.Rectangle(=smaller_bounding_box,
bounds="red",
colormap)
).add_to(
for item in items_eodc:
= item.assets["thumbnail"].href
image_url = item.bbox
bounds
folium.raster_layers.ImageOverlay(=image_url,
image=[[bounds[1], bounds[0]], [bounds[3], bounds[2]]],
boundsmap)
).add_to(
map)
folium.LayerControl().add_to(
map
Figure 2: Map of study area. Blue rectangle is the area covered by the discovered data. Red rectangle covers the selected data.
Create a new dataset with the smaller bounding box covering the region of Vienna. We will leave out the arguments for resampling and directly use the native format as defined in the metadata.
= odc_stac.load(
sig0_dc
items_eodc,=bands,
bands=[lonmin_smaller, latmin_smaller, lonmax_smaller, latmax_smaller],
bbox=chunks,
chunks )
Due to the way the data is acquired and stored, some items include “no data” areas. In our case, no data has the value -9999, but this can vary from data provider to data provider. This information can usually be found in the metadata. Furthermore, to save memory, data is often stored as integer (e.g. 25) and not in float (e.g. 2.5) format. For this reason, the backscatter values are often multiplied by a scale factor, in this case factor 10.
As Sentinel-1 satellites overpasses Austria every few days, only some time steps of the dataset will have physical data. As a final step, we will now decode the data and create a plot of two consecutive Sentinel-1 acquisitions of Vienna.
# Retrieve the scale factor and NoData value from the metadata. raster:bands is
# a STAC raster extension
= item.assets["VV"].extra_fields.get("raster:bands")[0]["scale"]
scale = item.assets["VV"].extra_fields.get("raster:bands")[0]["nodata"]
nodata
# Decode data with the NoData value and the scale factor
= sig0_dc.where(sig0_dc != nodata) / scale
sig0_dc
# We should remove unnecessary dates when there was no data
# (no satellite overpass)
= sig0_dc.dropna(dim="time") sig0_dc
="time", robust=True, cmap="Greys_r", aspect=1, size=10) sig0_dc.VV.plot(col
Figure 3: Sentinel-1 microwave backscatter image for two timeslices.