Hint

You can run this notebook in a live session with Binder.

Get forecast data from meteoblue using EODAG#

In this tutorial we will show you how to use eodag to download forecast data from meteoblue. The provider configuration and this tutorial have been developed in the context of DOMINO-X.

[1]:
import datetime
from eodag import EODataAccessGateway, setup_logging

setup_logging(1)  # 0: nothing, 1: only progress bars, 2: INFO, 3: DEBUG
dag = EODataAccessGateway()
dag.set_preferred_provider("meteoblue")

1. Search (get data availability and build download request)#

There are two use-cases, a search for a product already configured in EODAG, or a search for a dataset not already configured, where you will have a little more to do.

1.a. Search from an existing product type:#

[2]:
tomorrow = (datetime.date.today() + datetime.timedelta(days=1)).isoformat()
after_tomorrow = (datetime.date.today() + datetime.timedelta(days=2)).isoformat()
aoi_bbox = [-5, 40, 10, 45]

products_from_product_type, total_count = dag.search(
    start=tomorrow,
    end=after_tomorrow,
    geom=aoi_bbox,
    productType="NEMSGLOBAL_TCDC",
)
print(
    "%s product built %s,\n using queries=%s\n"
    % (
        total_count,
        products_from_product_type[0],
        products_from_product_type[0].properties["queries"],
    )
)
1 product built EOProduct(id=NEMSGLOBAL_TCDC_20230107_df9666f4d5ad8a5bfad24e6eca78475b2359139e, provider=meteoblue),
 using queries=[{'domain': 'NEMSGLOBAL', 'gapFillDomain': None, 'timeResolution': 'daily', 'codes': [{'code': 71, 'level': 'sfc', 'aggregation': 'mean'}]}]

[3]:
products_from_product_type[0].properties["storageStatus"], products_from_product_type[0].properties["datapoints"]
[3]:
('OFFLINE', 11544)

We can see that the product is OFFLINE, which means that it is not directly avalaible for download and will need to be ordered first.

We also displayed the datapoints property (credits), needed for this download (search does not consume datapoints).

1.b. Search using a custom request:#

Here we use a set of custom parameters corresponding to NEMSGLOBAL_TCDC, which should result to the same request sent to meteoblue.

You can compose your own request using meteoblue documentation: dataset API, available datasets/models, available variables, or also meteoblue dataset API configurator.

[4]:
meteoblue_req_params = {
    "queries":[
        {
            "domain":"NEMSGLOBAL","gapFillDomain":None,"timeResolution":"daily",
            "codes":[{"code":71,"level":"sfc","aggregation":"mean"}],
        }
    ],
    "format": "netCDF",
    "units":{"temperature":"C","velocity":"km/h","length":"metric","energy":"watts"},
    "timeIntervalsAlignment": None,
}

products_from_custom_req, total_count = dag.search(
    start=tomorrow,
    end=after_tomorrow,
    geom=aoi_bbox,
    **meteoblue_req_params,
)
# downloadLink property must be the same with the two request methods,
# as they are built from the same custom request arguments
if (
    products_from_custom_req[0].properties["downloadLink"]
    == products_from_product_type[0].properties["downloadLink"]
):
    print(
        "Request using productType or directly meteoblue query result to the\n",
        "same downloadLink %s"
        % (
            products_from_custom_req[0].properties["downloadLink"],
        )
    )
Request using productType or directly meteoblue query result to the
 same downloadLink https://my.meteoblue.com/dataset/query?{"format": "netCDF", "geometry": {"coordinates": [[[-5.0, 40.0], [-5.0, 45.0], [10.0, 45.0], [10.0, 40.0], [-5.0, 40.0]]], "type": "Polygon"}, "queries": [{"codes": [{"aggregation": "mean", "code": 71, "level": "sfc"}], "domain": "NEMSGLOBAL", "gapFillDomain": null, "timeResolution": "daily"}], "timeIntervals": ["2023-01-07/2023-01-07"], "units": {"energy": "watts", "length": "metric", "temperature": "C", "velocity": "km/h"}}

2. Download product#

  • download performed using meteoblue credentials set in ~/.config/eodag/eodag.yml as for other EO providers:

    meteoblue:
        priority:
        search:
        auth:
            credentials:
                apikey: my-meteoblue-api-key
        download:
            outputs_prefix: /data/eodag_data
    
  • as the product is OFFLINE, download will be performed in 2 times:

  • first order

  • then loop to try downloading as soon as order is available

[5]:
product_path = dag.download(products_from_product_type[0], wait=1/60, timeout=10)
product_path
[Retry #1] Waiting 1s until next download try for ordered product (retry every 0.016666666666666666' for 10')
[5]:
'/data/eodag_data/NEMSGLOBAL_TCDC_20230107_df9666f4d5ad8a5bfad24e6eca78475b2359139e.nc'

3. Open dataset with xarray and plot over a map using folium#

[6]:
import numpy as np
import xarray as xr
import folium
from folium import plugins
[7]:
ds = xr.load_dataset(product_path)
ds
[7]:
<xarray.Dataset>
Dimensions:            (x: 480, y: 1, time: 1)
Coordinates:
  * time               (time) float64 1.673e+09
Dimensions without coordinates: x, y
Data variables:
    lat                (x, y) float32 40.33 40.33 40.33 40.33 ... 45.0 45.0 45.0
    lon                (x, y) float32 -4.688 -4.219 -3.75 ... 8.906 9.375 9.844
    asl                (x, y) float32 920.5 702.9 619.4 ... 363.9 332.3 167.0
    Cloud Cover Total  (x, y, time) float32 78.71 71.71 70.96 ... 100.0 100.0
Attributes:
    domain:   NEMSGLOBAL
[8]:
reshaped_data = np.dstack([ds.lat[:,0], ds.lon[:,0], ds["Cloud Cover Total"][:,0,0]]).reshape(len(ds.lon),3)
[9]:
fmap = folium.Map(
    [43.5, 5],
    zoom_start=6,
    tiles="stamentoner"
)

fmap.add_child(plugins.HeatMap(
    reshaped_data.tolist(),
    radius=19,
    blur=22,
))
folium.LayerControl().add_to(fmap)

fmap
[9]:
Make this Notebook Trusted to load map: File -> Trust Notebook
[ ]: