Skip to article frontmatterSkip to article content

EODAG - A quick start with DEDL

This notebook provides a quickstart guide for using the EODAG Python API and CLI to search, discover, and download DEDL data.

🚀 Launch in JupyterHub

How to use EODAG to search and access DEDL data - quick start

EODAG is a command line tool and a Python package for searching and downloading earth observation data via a unified API.

This quickstart is to help get DEDL data using EODAG. Detailed information about the usage of EODAG can be found on the project documentation page.

Throughout this quickstart notebook, you will learn:

  1. Setup: How to configure EODAG to use the provider DEDL.

  2. Discover: How to discover DEDL datasets through EODAG.

  3. Search products: How to search DEDL data through EODAG.

  4. Download products: How to download DEDL data through EODAG.

The complete guide on how to use EODAG Python API is available via https://eodag.readthedocs.io/en/stable/api_user_guide.html.

Prequisites: Search and download dedl products : DestinE user account
Note:

Please note that the two factor authentication (2FA) is still not implemented in EODAG. The users who have enabled 2FA on DESP will not be able to run this notebook.

Setup

In this section, we set:

  • The output_dir, the directory where to store downloaded products.

  • The DEDL credentials, you’ll be asked to enter your DEDL credentials.

  • The search timeout, it is of 60 seconds to avoid any unexpected errors because of long running search queries.

import os
from getpass import getpass

workspace = 'eodag_workspace'
if not os.path.isdir(workspace):
    os.mkdir(workspace)
    
os.environ["EODAG__DEDL__DOWNLOAD__OUTPUTS_PREFIX"] = os.path.abspath(workspace)

os.environ["EODAG__DEDL__SEARCH__TIMEOUT"]="60"
os.environ["DEFAULT_STREAM_REQUESTS_TIMEOUT"] = "15"
os.environ["EODAG__DEDL__PRIORITY"]="10"


DESP_USERNAME = input("Please input your DESP username or email: ")
DESP_PASSWORD = getpass("Please input your DESP password: ")

os.environ["EODAG__DEDL__AUTH__CREDENTIALS__USERNAME"]=DESP_USERNAME
os.environ["EODAG__DEDL__AUTH__CREDENTIALS__PASSWORD"]=DESP_PASSWORD
Please input your DESP username or email:  eum-dedl-user
Please input your DESP password:  ········

EODiscover

We now need to import the EODataAccessGateway class in order to discover the available DEDL collections.

Collections are presented in a dropdown menu, selecting a collection its description will be prompted.


from eodag import EODataAccessGateway, setup_logging
dag = EODataAccessGateway()

setup_logging(1)
import ipywidgets as widgets
from IPython.display import display, clear_output, HTML
from ipywidgets import Layout, Box
import json

#default values

DATASET_ID = 'EO.EUM.DAT.SENTINEL-3.OL_2_WFR___'


# Event listeners
def on_change(change):
    with output_area:
        clear_output()
        print(f'Selected: {change["new"]}')
        print('---------------------------------------------')
        delimiter=''
        global DATASET_ID
        DATASET_ID = delimiter.join(change["new"])
        product_types=dag.list_product_types("dedl")
        index = next((i for i, d in enumerate(product_types) if d.get('ID') == DATASET_ID), None)
        
        print("TITLE: "+product_types[index]['title'])
        print("ABSTRACT: "+product_types[index]['abstract'])
        print("KEYWORDS: "+product_types[index]['abstract'])

options=[product_type["ID"] for product_type in dag.list_product_types("dedl")]

# Widgets
output_area = widgets.Output()

dropdown = widgets.Dropdown(
    options=options,
    value=options[0],
    description="Datasets:",
    disabled=False,
) 

dropdown.observe(on_change, names='value')


# Layout
# Define the layout for the dropdown
dropdown_layout = Layout(display='space-between', justify_content='center', width='80%')
# Create a box to hold the dropdown with the specified layout
box = Box([dropdown, output_area], layout=dropdown_layout)
display( box)  
Loading...

EOSearch

Once we selected our dataset of interest, we can define the search criteria to find data inside the chosen dataset.

Select bbox, start and end date to use in the search:

# Import necessary libraries
import folium, datetime
from ipywidgets import interactive, HBox, VBox, FloatText, Button, Label

#default values

START_DATE = '2024-08-11'
END_DATE = '2024-08-13'

sw_lat = 37.0
sw_lng = 14.0
ne_lat = 38.0
ne_lng = 16.0

#functions to handle the chosen values
def on_date_change(change):
    with output_area:
        clear_output()
        global START_DATE
        global END_DATE
        t1 = start_date.value
        t2 = end_date.value
        START_DATE = t1.strftime('%Y-%m-%d')
        END_DATE = t2.strftime('%Y-%m-%d')

        
def update_map(sw_lat, sw_lng, ne_lat, ne_lng):
    # Clear the map
    m = folium.Map(location=[(sw_lat + ne_lat) / 2, (sw_lng + ne_lng) / 2], zoom_start=4, tiles=None)

    nasa_wms = folium.WmsTileLayer(
        url='https://gibs.earthdata.nasa.gov/wms/epsg4326/best/wms.cgi',
        name='NASA Blue Marble',
        layers='BlueMarble_ShadedRelief',
        format='image/png',
        transparent=True,
        attr='NASA'
    )
    nasa_wms.add_to(m)
    
    # Add the bounding box rectangle
    folium.Rectangle(
        bounds=[[sw_lat, sw_lng], [ne_lat, ne_lng]],
        color="#ff7800",
        fill=True,
        fill_opacity=0.3
    ).add_to(m)
    
    # Display the map
    display(m)
    return (sw_lat, sw_lng, ne_lat, ne_lng)

def save_bbox(button):
    global sw_lat 
    global sw_lng  
    global ne_lat 
    global ne_lng 

    sw_lat = sw_lat_input.value
    sw_lng = sw_lng_input.value
    ne_lat = ne_lat_input.value
    ne_lng = ne_lng_input.value
    
    with output:
        clear_output()
        print(f"BBox: sw_lat {sw_lat} sw_lng {sw_lng} ne_lat {ne_lat} ne_lng {ne_lng}")


# Create a base map
m = folium.Map(location=[40, 20], zoom_start=4)
        
        
# Widgets
output = widgets.Output()

# Widgets for bbox coordinates input
sw_lat_input = FloatText(value=sw_lat, description='SW Latitude:')
sw_lng_input = FloatText(value=sw_lng, description='SW Longitude:')
ne_lat_input = FloatText(value=ne_lat, description='NE Latitude:')
ne_lng_input = FloatText(value=ne_lng, description='NE Longitude:')

save_button = Button(description="Save BBox")


# Create DatePicker widgets
start_date = widgets.DatePicker(
    description='Start Date',value = datetime.date(2024,8,11),
    disabled=False
)

end_date = widgets.DatePicker(
    description='End Date',value = datetime.date(2024,8,13),
    disabled=False
)


ui = VBox([
   # HBox([sw_lat_input, sw_lng_input]),
  #  HBox([ne_lat_input, ne_lng_input]),
    save_button,
    output,
    start_date, 
    end_date
])

# Display the interactive map and UI
interactive_map = interactive(update_map, sw_lat=sw_lat_input, sw_lng=sw_lng_input,
                              ne_lat=ne_lat_input, ne_lng=ne_lng_input)


display(interactive_map, ui)

     
#Events

start_date.observe(on_date_change, names='value')
end_date.observe(on_date_change, names='value')
save_button.on_click(save_bbox)
Loading...

Selected criteria:

search_criteria = {
    "productType": DATASET_ID,
    "start": START_DATE,
    "end": END_DATE,
    "geom": {"lonmin": sw_lng, "latmin": sw_lat, "lonmax": ne_lng, "latmax": ne_lat},
    "count": True
}

print(json.dumps(search_criteria, indent=2))
{
  "productType": "EO.EUM.DAT.SENTINEL-3.OL_2_WFR___",
  "start": "2024-08-11",
  "end": "2024-08-13",
  "geom": {
    "lonmin": 14.0,
    "latmin": 37.0,
    "lonmax": 16.0,
    "latmax": 38.0
  },
  "count": true
}

Use selected criteria to search data:

products_first_page = dag.search(**search_criteria)
print(f"Got {len(products_first_page)} products and an estimated total number of {products_first_page.number_matched} products.")
products_first_page
Loading...

See the available metadata:


if(len(products_first_page)>0):
    one_product = products_first_page[0]
    print(one_product.properties.keys())
dict_keys(['alias', 'abstract', 'instrument', 'platform', 'platformSerialIdentifier', 'processingLevel', 'keywords', 'sensorType', 'license', 'title', 'missionStartDate', '_id', 'productType', 'publicationDate', 'orbitNumber', 'orbitDirection', 'modificationDate', 'sensorMode', 'startTimeFromAscendingNode', 'completionTimeFromAscendingNode', 'id', 'downloadLink', 'storageStatus', 'defaultGeometry', 'providers', 'start_datetime', 'sat:absolute_orbit', 'sar:product_type', 'dedl:baselineCollection', 'dedl:timeliness', 'dedl:scope', 'dedl:productIdentifier', 'dedl:alias', 'dedl:endingDateTime', 'dedl:uid', 'dedl:beginningDateTime'])

EODownload

EOProducts can be downloaded individually. The last image is going to be downloaded.

if(len(products_first_page)>0):
    product_to_download = one_product
    product_path = dag.download(product_to_download)
    print(product_path)
Loading...