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
[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]:
[ ]: