STAC#
Let’s use EOReader to create SpatioTemporal Asset Catalog (STAC) items.
Note: This is experimental for now, use it at your own risk !
Warning:
You will need to install pystac[validation]
,
folium
and eodag
(version != 2.6.0) to run this notebook
Imports#
# Imports
import os
import pystac
import geopandas as gpd
from tempfile import TemporaryDirectory
from shapely.geometry import mapping
from eodag import setup_logging
from eodag.api.core import EODataAccessGateway
from eoreader.reader import Reader
/home/docs/checkouts/readthedocs.org/user_builds/eoreader/envs/stable/lib/python3.9/site-packages/dask/dataframe/__init__.py:42: FutureWarning:
Dask dataframe query planning is disabled because dask-expr is not installed.
You can install it with `pip install dask[dataframe]` or `conda install dask`.
This will raise in a future version.
warnings.warn(msg, FutureWarning)
Create logger#
# Create logger
import logging
from sertit import logs
logger = logging.getLogger("eoreader")
logs.init_logger(logger)
Linking some data#
Let’s take 3 products covering approximately the same area (over DAX city in France):
One Landsat-8 OLI-TIRS collection 2
One Landsat-5 TM collection 2
One Sentinel-2 L1C
prod_folder = os.path.join("/home", "prods")
paths = [
# Landsat-8 OLI-TIRS collection 2
os.path.join(prod_folder, "LANDSATS_COL2", "LC08_L1TP_200030_20201220_20210310_02_T1.tar"),
# Landsat-5 TM collection 2
os.path.join(prod_folder, "LANDSATS_COL2", "LT05_L1TP_200030_20111110_20200820_02_T1.tar"),
# Sentinel-2 L2A
os.path.join(prod_folder, "S2", "PB 02.07+", "S2A_MSIL1C_20191215T110441_N0208_R094_T30TXP_20191215T114155.SAFE"),
]
Create STAC catalog#
Create a STAC catalog and add 3 STAC items to it.
# Create the reader
reader = Reader()
# Work in a temporary directory
tmp = TemporaryDirectory()
# Create STAC catalog
catalog_path = os.path.join(tmp.name, "catalog.json")
catalog = pystac.Catalog(
id='SERTIT_101',
description="SERTIT's Catalog",
title='SERTIT Catalog',
href=catalog_path
)
# Add all the products into the STAC catalog
for path in paths:
logger.info(f"*** {os.path.basename(path)} ***")
# Open the product
prod = reader.open(path, remove_tmp=True)
# Get item
item = prod.stac.create_item()
# Add item to catalogue
catalog.add_item(item)
2025-04-18 15:55:56,796 - [INFO] - *** LC08_L1TP_200030_20201220_20210310_02_T1.tar ***
2025-04-18 15:55:56,800 - [WARNING] - There is no existing products in EOReader corresponding to /home/prods/LANDSATS_COL2/LC08_L1TP_200030_20201220_20210310_02_T1.tar.
2025-04-18 15:55:56,801 - [INFO] - Your given path may not be a satellite image. If it is, maybe the product isn't handled by EOReader. If you are sure this product is handled, it is either corrupted or you may need to go deeper in the filetree to find the correct path to give.
2025-04-18 15:55:56,802 - [DEBUG] - Please look at what folder you should give to EOReader by accessing the documentation: https://eoreader.readthedocs.io/latest/main_features.html#recognized-paths
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
Cell In[6], line 9
6 prod = reader.open(path, remove_tmp=True)
8 # Get item
----> 9 item = prod.stac.create_item()
11 # Add item to catalogue
12 catalog.add_item(item)
AttributeError: 'NoneType' object has no attribute 'stac'
# Save catalog
catalog.describe()
catalog.normalize_and_save(tmp.name, catalog_type=pystac.CatalogType.SELF_CONTAINED)
* <Catalog id=SERTIT_101>
* <Item id=20201220T104856_L8_200030_OLI_TIRS>
* <Item id=20111110T103612_L5_200030_TM>
* <Item id=20191215T110441_S2_T30TXP_L1C_114155>
list(catalog.get_items())[0]
Item: 20201220T104856_L8_200030_OLI_TIRS
id: 20201220T104856_L8_200030_OLI_TIRS |
bbox: [-2.744857724803896, 42.09665285173287, 0.14785265624107427, 44.2467651307631] |
tilename: 200030 |
eo:cloud_cover: 16.36 |
proj:epsg: 32630 |
proj:wkt2: PROJCS["WGS 84 / UTM zone 30N",GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS 84",6378137,298.257223563,AUTHORITY["EPSG","7030"]],AUTHORITY["EPSG","6326"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9122"]],AUTHORITY["EPSG","4326"]],PROJECTION["Transverse_Mercator"],PARAMETER["latitude_of_origin",0],PARAMETER["central_meridian",-3],PARAMETER["scale_factor",0.9996],PARAMETER["false_easting",500000],PARAMETER["false_northing",0],UNIT["metre",1,AUTHORITY["EPSG","9001"]],AXIS["Easting",EAST],AXIS["Northing",NORTH],AUTHORITY["EPSG","32630"]] |
proj:geometry: {'type': 'Polygon', 'coordinates': (((704535.0, 4665915.0), (703755.0, 4666095.0), (690465.0, 4669185.0), (630855.0, 4683045.0), (526215.0, 4707375.0), (523635.0, 4707975.0), (523125.0, 4708095.0), (523005.0, 4708125.0), (522945.0, 4708155.0), (522945.0, 4708275.0), (522975.0, 4708425.0), (523185.0, 4709355.0), (566355.0, 4898205.0), (566445.0, 4898595.0), (566475.0, 4898715.0), (566505.0, 4898715.0), (567045.0, 4898595.0), (567975.0, 4898385.0), (573405.0, 4897155.0), (586515.0, 4894185.0), (697485.0, 4869045.0), (748335.0, 4857525.0), (748575.0, 4857465.0), (748575.0, 4857375.0), (748455.0, 4856835.0), (747285.0, 4851675.0), (747135.0, 4851015.0), (745305.0, 4842975.0), (744675.0, 4840215.0), (742125.0, 4829055.0), (741315.0, 4825515.0), (739995.0, 4819755.0), (738825.0, 4814655.0), (729945.0, 4775955.0), (705225.0, 4668735.0), (704685.0, 4666395.0), (704565.0, 4665915.0), (704535.0, 4665915.0)),)} |
proj:bbox: [521085.0, 4664985.0, 751515.0, 4899315.0] |
proj:centroid: {'lat': 43.183607660455536, 'lon': -1.3295876133318103} |
proj:shape: [7811, 7681] |
proj:transform: [30.0, 0.0, 521085.0, 0.0, -30.0, 4899315.0, 0.0, 0.0, 1.0] |
view:sun_azimuth: 161.76832577 |
view:sun_elevation: 68.76909132 |
title: 20201220T104856_L8_200030_OLI_TIRS |
created: 2023-05-31T11:47:34.966933Z |
updated: 2023-05-31T11:47:34.966943Z |
start_datetime: 2020-12-20T10:48:56Z |
end_datetime: 2020-12-20T10:48:56Z |
instruments: ['OLI-TIRS'] |
constellation: landsat-8 |
gsd: 30.0 |
datetime: 2020-12-20T10:48:56Z |
STAC Extensions
https://stac-extensions.github.io/eo/v1.0.0/schema.json |
https://stac-extensions.github.io/projection/v1.1.0/schema.json |
https://stac-extensions.github.io/view/v1.0.0/schema.json |
Assets
Asset: Coastal aerosol
href: tar+file:///home/data/DATA/PRODS/LANDSATS_COL2/LC08_L1TP_200030_20201220_20210310_02_T1.tar!LC08_L1TP_200030_20201220_20210310_02_T1_B1.TIF |
type: image/tiff; application=geotiff |
title: Coastal aerosol |
description: Coastal and aerosol studies |
roles: ['reflectance'] |
owner: 20201220T104856_L8_200030_OLI_TIRS |
eoreader_name: COASTAL_AEROSOL |
eo:bands: [{'name': 'Coastal aerosol', 'common_name': 'coastal', 'description': 'Coastal and aerosol studies', 'center_wavelength': 0.44, 'full_width_half_max': 0.02}] |
created: 2023-05-31T11:47:34.965925Z |
updated: 2023-05-31T11:47:34.965980Z |
start_datetime: 2020-12-20T10:48:56Z |
end_datetime: 2020-12-20T10:48:56Z |
instruments: ['OLI-TIRS'] |
constellation: landsat-8 |
gsd: 30 |
Asset: Blue
href: tar+file:///home/data/DATA/PRODS/LANDSATS_COL2/LC08_L1TP_200030_20201220_20210310_02_T1.tar!LC08_L1TP_200030_20201220_20210310_02_T1_B2.TIF |
type: image/tiff; application=geotiff |
title: Blue |
description: Bathymetric mapping, distinguishing soil from vegetation and deciduous from coniferous vegetation |
roles: ['reflectance'] |
owner: 20201220T104856_L8_200030_OLI_TIRS |
eoreader_name: BLUE |
eo:bands: [{'name': 'Blue', 'common_name': 'blue', 'description': 'Bathymetric mapping, distinguishing soil from vegetation and deciduous from coniferous vegetation', 'center_wavelength': 0.48, 'full_width_half_max': 0.06}] |
created: 2023-05-31T11:47:34.966111Z |
updated: 2023-05-31T11:47:34.966126Z |
start_datetime: 2020-12-20T10:48:56Z |
end_datetime: 2020-12-20T10:48:56Z |
instruments: ['OLI-TIRS'] |
constellation: landsat-8 |
gsd: 30 |
Asset: Green
href: tar+file:///home/data/DATA/PRODS/LANDSATS_COL2/LC08_L1TP_200030_20201220_20210310_02_T1.tar!LC08_L1TP_200030_20201220_20210310_02_T1_B3.TIF |
type: image/tiff; application=geotiff |
title: Green |
description: Emphasizes peak vegetation, which is useful for assessing plant vigor |
roles: ['reflectance'] |
owner: 20201220T104856_L8_200030_OLI_TIRS |
eoreader_name: GREEN |
eo:bands: [{'name': 'Green', 'common_name': 'green', 'description': 'Emphasizes peak vegetation, which is useful for assessing plant vigor', 'center_wavelength': 0.56, 'full_width_half_max': 0.06}] |
created: 2023-05-31T11:47:34.966204Z |
updated: 2023-05-31T11:47:34.966215Z |
start_datetime: 2020-12-20T10:48:56Z |
end_datetime: 2020-12-20T10:48:56Z |
instruments: ['OLI-TIRS'] |
constellation: landsat-8 |
gsd: 30 |
Asset: Red
href: tar+file:///home/data/DATA/PRODS/LANDSATS_COL2/LC08_L1TP_200030_20201220_20210310_02_T1.tar!LC08_L1TP_200030_20201220_20210310_02_T1_B4.TIF |
type: image/tiff; application=geotiff |
title: Red |
description: Discriminates vegetation slopes |
roles: ['reflectance'] |
owner: 20201220T104856_L8_200030_OLI_TIRS |
eoreader_name: RED |
eo:bands: [{'name': 'Red', 'common_name': 'red', 'description': 'Discriminates vegetation slopes', 'center_wavelength': 0.655, 'full_width_half_max': 0.03}] |
created: 2023-05-31T11:47:34.966278Z |
updated: 2023-05-31T11:47:34.966290Z |
start_datetime: 2020-12-20T10:48:56Z |
end_datetime: 2020-12-20T10:48:56Z |
instruments: ['OLI-TIRS'] |
constellation: landsat-8 |
gsd: 30 |
Asset: Near Infrared (NIR)
href: tar+file:///home/data/DATA/PRODS/LANDSATS_COL2/LC08_L1TP_200030_20201220_20210310_02_T1.tar!LC08_L1TP_200030_20201220_20210310_02_T1_B5.TIF |
type: image/tiff; application=geotiff |
title: Near Infrared (NIR) |
description: Emphasizes biomass content and shorelines |
roles: ['reflectance'] |
owner: 20201220T104856_L8_200030_OLI_TIRS |
eoreader_name: NARROW_NIR |
eo:bands: [{'name': 'Near Infrared (NIR)', 'common_name': 'nir08', 'description': 'Emphasizes biomass content and shorelines', 'center_wavelength': 0.865, 'full_width_half_max': 0.03}] |
created: 2023-05-31T11:47:34.966381Z |
updated: 2023-05-31T11:47:34.966388Z |
start_datetime: 2020-12-20T10:48:56Z |
end_datetime: 2020-12-20T10:48:56Z |
instruments: ['OLI-TIRS'] |
constellation: landsat-8 |
gsd: 30 |
Asset: Cirrus
href: tar+file:///home/data/DATA/PRODS/LANDSATS_COL2/LC08_L1TP_200030_20201220_20210310_02_T1.tar!LC08_L1TP_200030_20201220_20210310_02_T1_B9.TIF |
type: image/tiff; application=geotiff |
title: Cirrus |
description: Improved detection of cirrus cloud contamination |
roles: ['reflectance'] |
owner: 20201220T104856_L8_200030_OLI_TIRS |
eoreader_name: CIRRUS |
eo:bands: [{'name': 'Cirrus', 'common_name': 'cirrus', 'description': 'Improved detection of cirrus cloud contamination', 'center_wavelength': 1.37, 'full_width_half_max': 0.02}] |
created: 2023-05-31T11:47:34.966427Z |
updated: 2023-05-31T11:47:34.966433Z |
start_datetime: 2020-12-20T10:48:56Z |
end_datetime: 2020-12-20T10:48:56Z |
instruments: ['OLI-TIRS'] |
constellation: landsat-8 |
gsd: 30 |
Asset: SWIR 1
href: tar+file:///home/data/DATA/PRODS/LANDSATS_COL2/LC08_L1TP_200030_20201220_20210310_02_T1.tar!LC08_L1TP_200030_20201220_20210310_02_T1_B6.TIF |
type: image/tiff; application=geotiff |
title: SWIR 1 |
description: Discriminates moisture content of soil and vegetation; penetrates thin clouds |
roles: ['reflectance'] |
owner: 20201220T104856_L8_200030_OLI_TIRS |
eoreader_name: SWIR_1 |
eo:bands: [{'name': 'SWIR 1', 'common_name': 'swir16', 'description': 'Discriminates moisture content of soil and vegetation; penetrates thin clouds', 'center_wavelength': 1.61, 'full_width_half_max': 0.08}] |
created: 2023-05-31T11:47:34.966473Z |
updated: 2023-05-31T11:47:34.966479Z |
start_datetime: 2020-12-20T10:48:56Z |
end_datetime: 2020-12-20T10:48:56Z |
instruments: ['OLI-TIRS'] |
constellation: landsat-8 |
gsd: 30 |
Asset: SWIR 2
href: tar+file:///home/data/DATA/PRODS/LANDSATS_COL2/LC08_L1TP_200030_20201220_20210310_02_T1.tar!LC08_L1TP_200030_20201220_20210310_02_T1_B7.TIF |
type: image/tiff; application=geotiff |
title: SWIR 2 |
description: Improved moisture content of soil and vegetation; penetrates thin clouds |
roles: ['reflectance'] |
owner: 20201220T104856_L8_200030_OLI_TIRS |
eoreader_name: SWIR_2 |
eo:bands: [{'name': 'SWIR 2', 'common_name': 'swir22', 'description': 'Improved moisture content of soil and vegetation; penetrates thin clouds', 'center_wavelength': 2.2, 'full_width_half_max': 0.18}] |
created: 2023-05-31T11:47:34.966521Z |
updated: 2023-05-31T11:47:34.966530Z |
start_datetime: 2020-12-20T10:48:56Z |
end_datetime: 2020-12-20T10:48:56Z |
instruments: ['OLI-TIRS'] |
constellation: landsat-8 |
gsd: 30 |
Asset: Thermal Infrared (TIRS) 1
href: tar+file:///home/data/DATA/PRODS/LANDSATS_COL2/LC08_L1TP_200030_20201220_20210310_02_T1.tar!LC08_L1TP_200030_20201220_20210310_02_T1_B10.TIF |
type: image/tiff; application=geotiff |
title: Thermal Infrared (TIRS) 1 |
description: 100 meter resolution, thermal mapping and estimated soil moisture |
roles: ['brightness_temperature'] |
owner: 20201220T104856_L8_200030_OLI_TIRS |
eoreader_name: THERMAL_IR_1 |
eo:bands: [{'name': 'Thermal Infrared (TIRS) 1', 'common_name': 'lwir11', 'description': '100 meter resolution, thermal mapping and estimated soil moisture', 'center_wavelength': 10.895, 'full_width_half_max': 0.59}] |
created: 2023-05-31T11:47:34.966593Z |
updated: 2023-05-31T11:47:34.966601Z |
start_datetime: 2020-12-20T10:48:56Z |
end_datetime: 2020-12-20T10:48:56Z |
instruments: ['OLI-TIRS'] |
constellation: landsat-8 |
gsd: 100 |
Asset: Thermal Infrared (TIRS) 2
href: tar+file:///home/data/DATA/PRODS/LANDSATS_COL2/LC08_L1TP_200030_20201220_20210310_02_T1.tar!LC08_L1TP_200030_20201220_20210310_02_T1_B11.TIF |
type: image/tiff; application=geotiff |
title: Thermal Infrared (TIRS) 2 |
description: 100 meter resolution, improved thermal mapping and estimated soil moisture |
roles: ['brightness_temperature'] |
owner: 20201220T104856_L8_200030_OLI_TIRS |
eoreader_name: THERMAL_IR_2 |
eo:bands: [{'name': 'Thermal Infrared (TIRS) 2', 'common_name': 'lwir12', 'description': '100 meter resolution, improved thermal mapping and estimated soil moisture', 'center_wavelength': 12.005, 'full_width_half_max': 1.01}] |
created: 2023-05-31T11:47:34.966640Z |
updated: 2023-05-31T11:47:34.966647Z |
start_datetime: 2020-12-20T10:48:56Z |
end_datetime: 2020-12-20T10:48:56Z |
instruments: ['OLI-TIRS'] |
constellation: landsat-8 |
gsd: 100 |
Asset: Panchromatic
href: tar+file:///home/data/DATA/PRODS/LANDSATS_COL2/LC08_L1TP_200030_20201220_20210310_02_T1.tar!LC08_L1TP_200030_20201220_20210310_02_T1_B8.TIF |
type: image/tiff; application=geotiff |
title: Panchromatic |
description: 15 meter resolution, sharper image definition |
roles: ['reflectance'] |
owner: 20201220T104856_L8_200030_OLI_TIRS |
eoreader_name: PANCHROMATIC |
eo:bands: [{'name': 'Panchromatic', 'common_name': 'pan', 'description': '15 meter resolution, sharper image definition', 'center_wavelength': 0.59, 'full_width_half_max': 0.18}] |
created: 2023-05-31T11:47:34.966691Z |
updated: 2023-05-31T11:47:34.966698Z |
start_datetime: 2020-12-20T10:48:56Z |
end_datetime: 2020-12-20T10:48:56Z |
instruments: ['OLI-TIRS'] |
constellation: landsat-8 |
gsd: 30 |
Links
Link: SERTIT Catalog
rel: root |
href: /tmp/tmpgyucfjoj/catalog.json |
type: application/json |
title: SERTIT Catalog |
Link:
rel: self |
href: /tmp/tmpgyucfjoj/20201220T104856_L8_200030_OLI_TIRS/20201220T104856_L8_200030_OLI_TIRS.json |
type: application/json |
Link: SERTIT Catalog
rel: parent |
href: /tmp/tmpgyucfjoj/catalog.json |
type: application/json |
title: SERTIT Catalog |
Query the catalog#
EODAG
is an opensource python library that implements STAC and allows you to query your local STAC catalog.
Look at here for a detailed tutorial.
# Create an EODAG custom STAC provider
dag = EODataAccessGateway()
# Set EODAG logging level to WARNING
setup_logging(verbose=1)
# Add the custom STAC provider, exactly like in the tutorial mentioned above
dag.update_providers_config("""
stac_http_provider:
search:
type: StaticStacSearch
api_endpoint: %s
products:
GENERIC_PRODUCT_TYPE:
productType: '{productType}'
download:
type: HTTPDownload
base_uri: %s
flatten_top_dirs: True
outputs_prefix: %s
""" % (catalog_path, tmp.name, tmp.name))
# Set the custom STAC provider as preferred
dag.set_preferred_provider("stac_http_provider")
# Query every product from inside the catalog
all_products, _ = dag.search()
---------------------------------------------------------------------------
KeyError Traceback (most recent call last)
File /opt/conda/lib/python3.10/site-packages/eodag/plugins/manager.py:156, in PluginManager.get_search_plugins(self, product_type, provider)
155 try:
--> 156 config = self.providers_config[provider]
157 except KeyError:
KeyError: 'stac_http_provider'
During handling of the above exception, another exception occurred:
UnsupportedProvider Traceback (most recent call last)
Cell In[10], line 2
1 # Query every product from inside the catalog
----> 2 all_products, _ = dag.search()
File /opt/conda/lib/python3.10/site-packages/eodag/api/core.py:887, in EODataAccessGateway.search(self, page, items_per_page, raise_errors, start, end, geom, locations, **kwargs)
825 def search(
826 self,
827 page=DEFAULT_PAGE,
(...)
834 **kwargs,
835 ):
836 """Look for products matching criteria on known providers.
837
838 The default behaviour is to look for products on the provider with the
(...)
885 enforced here.
886 """
--> 887 search_kwargs = self._prepare_search(
888 start=start, end=end, geom=geom, locations=locations, **kwargs
889 )
890 search_plugin = search_kwargs.pop("search_plugin", None)
891 if search_kwargs.get("id"):
892 # adds minimal pagination to be able to check only 1 product is returned
File /opt/conda/lib/python3.10/site-packages/eodag/api/core.py:1306, in EODataAccessGateway._prepare_search(self, start, end, geom, locations, **kwargs)
1299 if (
1300 product_type
1301 not in self._plugins_manager.product_type_to_provider_config_map.keys()
1302 ):
1303 logger.debug(
1304 f"Fetching external product types sources to find {product_type} product type"
1305 )
-> 1306 self.fetch_product_types_list()
1308 search_plugin = next(
1309 self._plugins_manager.get_search_plugins(product_type=product_type)
1310 )
1311 if search_plugin.provider != self.get_preferred_provider()[0]:
File /opt/conda/lib/python3.10/site-packages/eodag/api/core.py:613, in EODataAccessGateway.fetch_product_types_list(self, provider)
608 continue
609 # providers not skipped here should be user-modified
610 # or not in ext_product_types_conf (if eodag system conf != eodag conf used for ext_product_types_conf)
611
612 # discover product types for user configured provider
--> 613 provider_ext_product_types_conf = self.discover_product_types(
614 provider=provider
615 )
617 # update eodag product types list with new conf
618 self.update_product_types_list(provider_ext_product_types_conf)
File /opt/conda/lib/python3.10/site-packages/eodag/api/core.py:648, in EODataAccessGateway.discover_product_types(self, provider)
646 return
647 if getattr(search_plugin_config, "discover_product_types", None):
--> 648 search_plugin = next(
649 self._plugins_manager.get_search_plugins(provider=provider)
650 )
651 # append auth to search plugin if needed
652 if getattr(search_plugin.config, "need_auth", False):
File /opt/conda/lib/python3.10/site-packages/eodag/plugins/manager.py:158, in PluginManager.get_search_plugins(self, product_type, provider)
156 config = self.providers_config[provider]
157 except KeyError:
--> 158 raise UnsupportedProvider
159 yield get_plugin()
160 # Signal the end of iteration as we already have what we wanted (see PEP-479)
UnsupportedProvider:
# Load an AOI
aoi_path = os.path.join("/home", "aois", "DAX.geojson")
aoi = gpd.read_file(aoi_path)
aoi_geojson = mapping(aoi.geometry.values[0])
# Query spatially with the AOI and temporally with a time period
query_args = {"start": "2020-05-01", "end": "2022-05-06", "geom": aoi.geometry.values[0]}
query_products, _ = dag.search(**query_args)
query_products[0]
query_products[0].assets
Display the results#
We can use folium
to display the results geometry over a map.
import folium
# Create a map zoomed over the search area
fmap = folium.Map((43.2, -1.05), zoom_start=7)
# Add a layer green layer for the query over the AOI
folium.GeoJson(
data=all_products.as_geojson_object(),
tooltip = "All products stored in the catalog",
style_function=lambda x: {'color': 'green'}
).add_to(fmap)
# Add a layer green layer for the query over the AOI
folium.GeoJson(
data=query_products.as_geojson_object(),
tooltip = "Retrieved products with the query",
style_function=lambda x: {'color': 'red'}
).add_to(fmap)
# Add a layer blue layer for the AOI
folium.GeoJson(
data=aoi_geojson,
tooltip = "DAX AOI",
style_function=lambda x: {'color': 'blue'}
).add_to(fmap)
fmap
# Clean the tmp directory
tmp.cleanup()