This program is written by Gary Wee.
Date: 2022 Jul 28
This program uses Grib.Api
Nuget package to extract messages in Grib files, it is based on .NET Framework because the package cannot be used in .NET 6.
- Import Grib file. (ERA5 Grib file is used as example)
GribFile file = new GribFile(file_name)
- Get the messages in the GribFile.
Remark: Some of the grib files may cause error when runningmsg.GeoSpatialValues
due to difference of meta-data in the grib file.
foreach (GribMessage msg in file)
{
var Time = msg.Time;
var Parameter_Name = msg.Name;
var Level = msg.Level;
var GeoSpatialValues = msg.GeoSpatialValues;
foreach (var point in GeoSpatialValues)
{
if (point.IsMissing)
continue;
var Longitude = point.Longitude;
var Latitude = point.Latitude;
var Value = point.Value;
}
}
-
If if
msg.GeoSpatialValues
cannot be used, we can read the keys and values in the message, then figure out the grid's position and value using another method. -
Get keys and values in a Grib message.
DataTable dt = new DataTable();
dt.Columns.Add("no");
dt.Columns.Add("key");
dt.Columns.Add("value");
using (GribFile file = new GribFile(file_name))
{
GribMessage msg = file.First();
double[] rawValues;
msg.Values(out rawValues);
int i = 0;
foreach (var m in msg)
{
DataRow row = dt.NewRow();
row["no"] = i;
row["key"] = m.Key;
row["value"] = m.ToString();
t.Rows.Add(row);
i++;
}
}
- Some keys can be selected to calculate the position of grid.
- longitudeOfFirstGridPoint 第一個點經度
- latitudeOfFirstGridPoint 第一個點緯度
- Ni 經度方向資料個數
- Nj 緯度方向資料個數
- iDirectionIncrement 經度方向間距
- jDirectionIncrement 緯度方向間距
- iScansPositively 經度間距是否為正值
- jScansPositively 緯度間距是否為正值
Remarks: Some of the keys of grid information can be found at ECMWF's website.
Therefore, we can calculate the location of each grid. And msg.Values(out rawValues)
can be used to extract the readings of certain paramter.
DataTable dt = new DataTable();
dt.Columns.Add("no");
dt.Columns.Add("lon");
dt.Columns.Add("lat");
dt.Columns.Add("value");
using (GribFile file = new GribFile(file_name))
{
GribMessage msg = file.First();
double[] rawValues;
msg.Values(out rawValues);
string msg_str = msg.ToString();
var lon_first_grid = msg["longitudeOfFirstGridPoint"].AsDouble();
var lat_first_grid = msg["latitudeOfFirstGridPoint"].AsDouble();
var Ni = msg["Ni"].AsInt();
var Nj = msg["Nj"].AsInt();
var interval_i = msg["iDirectionIncrement"].AsDouble();
var interval_j = msg["jDirectionIncrement"].AsDouble();
if (msg["iScansPositively"].AsString() == "0")
interval_i = -interval_i;
if (msg["jScansPositively"].AsString() == "0")
interval_j = -interval_j;
double lon, lat;
int index_raw_data = 0;
for (int j = 0; j < Nj; j += 1)
{
lat = lat_first_grid + j * interval_j;
for (int i = 0; i < Ni; i += 1)
{
lon = lon_first_grid + i * interval_i;
DataRow row = dt.NewRow();
row["no"] = index_raw_data;
row["lon"] = lon;
row["lat"] = lat;
row["value"] = rawValues[index_raw_data];
dt.Rows.Add(row);
index_raw_data++;
}
}