Using weather forecast data of DWD for Europe

What: Extracting weather forecast data from DWD grib2 files with Java
Why: Using weather forecasts in your (Java) applications
How: Download the data from DWD and using NetCDF for parsing

Getting the data

The data (in the following, the 3-day forecast is used) is freely available via ftp from here. You have to register with a valid EMail.

There are several different data sets on the server. The interesting one is the ICON model. It contains forecasts with 0.125 and 0.25 degree resolution for wind, temperature, precipitation and more. You find the data under the path /ICON/grib/europe.

There is a list of available content for the ftp server here.

The data is published in 6hour intervalls at 5, 11, 17 and 23 o’clock. Each file is a zipped grib2 file.

For this tutorial, download and unzip the file /ICON/grib/europe/ICON_GDS_europe_reg_0.250×0.250_T_2M_[yyyyMMddhh].grib2.bz2 (replace the date) which contains the temperature 2 meters above ground and unzip it.

Parsing the data

You can find the full example here. Clone the repository, change to weatherforecastdata directory and adapt it to your needs (hard coded file name, …). After you have finished your changes run:

1
mvn clean package && java -jar target/weatherforecastdata-1.0-SNAPSHOT-jar-with-dependencies.jar

If you want to build it from scratch (it is simple) create a maven project and add the following repository and dependency to your pom.xml:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<repositories>
    <repository>
        <id>artifacts.unidata.ucar.edu</id>
        <url>https://artifacts.unidata.ucar.edu/content/repositories/unidata-releases/</url>
    </repository>
</repositories>
 
<dependencies>
    <dependency>
        <groupId>edu.ucar</groupId>
        <artifactId>netcdfAll</artifactId>
        <version>4.6.8</version>
    </dependency>
</dependencies>

NetCDF is able to read in the grib files. You can create a new instance of the data file via:

1
NetcdfFile dataFile = NetcdfFile.open("filename");

Each file contains dimensions, attributes and variables. The variables depend on the dimensions. For example: The temperature value depends on the latitude and longitude as well as on time and height above ground. The data can be retrieved in arrays, with the shape depending on the corresponding dimensions. Latitude, longitude, time and height above ground are 1-dimensional arrays while the temperature depends on all of them and thus is 4-dimensional.

You can get dimensions, attributes and variables via:

1
2
3
List<Dimension> dimensions = dataFile.getDimensions();
List<Attribute> globalAttributes = dataFile.getGlobalAttributes();
List<Variable> variables = dataFile.getVariables();

Lets concentrate on the variables. For each variable you can get name, units and dimensions it depends on:

1
2
3
4
5
for (Variable variable : variables) {
    System.out.println(variable.getFullName());
    System.out.println(variable.getUnitsString());
    System.out.println(variable.getDimensions());
}

For the example above this will give for the temperature:

Temperature_height_above_ground
K
[time = 79;, height_above_ground = 1;, lat = 301;, lon = 601;]

There is a variable called Temperature_height_above_ground, which depends on time (there are 79 different values for the time dimension), height_above_ground (with just one different value because we look at the temperature measured at 2m above ground), latitude and longitude with (301/601 different values for the respective dimension).

This is enough information to retreive the data from the file:

1
2
3
4
5
ArrayDouble.D1 time = (ArrayDouble.D1) dataFile.findVariable("time").read();
ArrayFloat.D1 height = (ArrayFloat.D1) dataFile.findVariable("height_above_ground").read();
ArrayFloat.D1 lat = (ArrayFloat.D1) dataFile.findVariable("lat").read();
ArrayFloat.D1 lon = (ArrayFloat.D1) dataFile.findVariable("lon").read();
ArrayFloat.D4 temp = (ArrayFloat.D4) dataFile.findVariable("Temperature_height_above_ground").read();

Iterating over the temperature values can now be done by iterating over each of the dimensions:

1
2
3
4
5
6
7
8
9
10
11
for (int timeIndex = 0; timeIndex < time.getShape()[0]; timeIndex++) {
    for (int heightIndex = 0; heightIndex < height.getShape()[0]; heightIndex++) {
        for (int latIndex = 0; latIndex < lat.getShape()[0]; latIndex++) {
            for (int lonIndex = 0; lonIndex < lon.getShape()[0]; lonIndex++) {
                System.out.println(String.format("%f %f %f %f %f", time.get(timeIndex),
                    height.get(heightIndex), lat.get(latIndex), lon.get(lonIndex),
                    temp.get(timeIndex, heightIndex, latIndex, lonIndex)));
            }
	}
    }
}

Have fun with the amazing DWD source of weather forecast data.