最近,基于c#语言,在读取grib文件,通过nuget查找,grib.api的下载使用量很高,所以选择使用了该类库,但是其说明文件很简短,无法快速使用,通过一段时间的摸索,结合说明文档,总结如下:
1 GribApi.NET 简介
GribApi.NET 是欧洲数值预报中心的grib_api的c#封装,用于读取grib文件(包括grib1和grib2文件)。
GRIB是气象学中常用的一种数据格式,用于存储天气数据。GribApi.NET 通过一组 GRIB API 密钥提供对两个 GRIB 版本的访问,从而轻松编码和解码这些数据。GribApi.NET 和grib_api在友好的Apache许可证2.0下授权。特别感谢aWhere,Inc.的气象数据分析师John L'Heureux作为科学顾问的贡献。
具体可参考https://github.com/GribApiDotNet/GribApi.NET。
GRIB is a format commonly used in meteorology to store weather data. GribApi.NET makes it easy to encode and decode these data by providing access to both GRIB editions through a set of GRIB API keys. GribApi.NET and grib_api are licensed under the friendly Apache License 2.0.
Special thanks to John L'Heureux, Meteorological Data Analyst at aWhere, Inc., for his contributions as scientific advisor.
特性:
特征
- 读取和写入 GRIB 1 和 2 消息
- 易于理解的 API
- 支持 x86、x64 和“所有 CPU”
- 线程安全
- JPEG 和 PNG 压缩支持
- 多领域支持
2 使用方法
2.1 打开文件
打开文件,获取grib文件的信息列表。每一个GribMessage对应一个数据,比如某一个时间点的500Hpa位势高度场数据信息。
List<GribMessage> lst = new List<GribMessage>();
using (GribFile file = new GribFile(fileName))
{
lst = file.ToList<GribMessage>();
}
2.2 获取数据格点的基本参数
一般气象数据以格点方式存放,大部分数据信息可以通过GribMessage的属性来获取,下图为GribMesage的属性局部截图,由图可见,通过该属性,可得到数据名称、起报时间、层次、缺省值等信息。
但是,对于数据的经纬度坐标信息,通过其属性没有直接给出,可以通过GeoSpatialValue 遍历的方法进行记录、判定,但是效率较低。
//通过遍历,得到每一个格点的经纬度信息和数值
foreach (GeoSpatialValue val in msg.GeoSpatialValues)
{
if (val.IsMissing) { continue; }
Console.WriteLine("Lat: {0} Lon: {1} Val: {2}", val.Latitude, val.Longitude, val.Value);
}
效率较高的方法是通过如下方式,但keyName具体值只能在源代码或者ecmwf官网中查找,用于获取坐标信息的代码如下:
double x0 = msg["longitudeOfFirstGridPoint"].AsDouble();//数据第一个格点的经度
double x1 = msg["longitudeOfLastGridPoint"].AsDouble();//数据最后一个格点的经度
double xdelt = msg["iDirectionIncrement"].AsDouble();//经度方向的格距 dx
double y0 = msg["latitudeOfFirstGridPoint"].AsDouble();//数据第一个格点的纬度
double y1 = msg["latitudeOfLastGridPoint"].AsDouble();//数据最后一个格点的纬度
double ydelt = msg["jDirectionIncrement"].AsDouble();//纬度格距 dy
int xnum = msg["Ni"].AsInt();//经度方向格点数
int ynum = msg["Nj"].AsInt();//纬度方向格点数
ecmwf官方关于格点数据的一些参数说明网址为(ECMWF | Grid 1: Mercator https://apps.ecmwf.int/codes/grib/format/grib1/grids/1/),相关信息截图如下:
但是,经过实践,当格点第一格点为-180时,上述代码获取的x0=180;而在GeoSpatialValue的遍历中是正确的,实际应用中需要注意。
2.3 读取数据
读取数据集的数据,既可以遍历的方式读取,具体方法如上文所述,也可以直接拷贝的方式得到,速度较快。
获取 raw data:
GribMessage msg = gribFile.First();
double[] rawValues;
// a copy of the raw values stored in the message
msg.Values(out rawValues);
2.4 数据名称无效的情况
读取数据,一般通过msg的shortname属性来判断是否是目标数据,但是在实际使用中,发现部分数据的ShortName属性是unknown,这就给数据提取造成了困难,通过网络搜索,网上也有人遇到了类似问题(https://github.com/GribApiDotNet/GribApi.NET/issues/69),从讨论来看,没有更好的解决方法。
有人给出了使用wgrib和gribapi.net结合的方法,首先将数据拆分,然后读取拆分后的数据,wgrib对数据识别、提取是比较准确的,而后者则可以较为方便的将数据读入c#的数据结构中,便于程序使用。