GribApi.NET is a C# wrapper around the European Centre for Medium Range Weather Forecasting's powerful ecCodes, a C library for reading, writing, and converting GRIB1 and GRIB2 files. ecCodes
is the successor to grib_api
.
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. It can handle all common GRIB formats from centres such as NOAA's NCEP and the ECMWF. GribApi.NET and grib_api are licensed under the friendly Apache License 2.0.
Special thanks to John L'Heureux, for his contributions as scientific advisor.
- Read and write GRIB 1 and 2 messages
- Easy to understand API
- Supports x86, x64, and "All CPU"
- Thread safe
- JPEG and PNG compression support
- Multi-field support
- Support for custom GRIB formats
You can also use grib_api via CLI. Checkout the GRIB tools package on Chocolatey. At the very least, you'll find it very helpful for debugging.
The documentation is very much a WIP, but you'll find the ecCodes website helpful.
Make sure you have the MSVC 2015 redistributables installed. If you don't, you can use chocolatey
,
C:\> choco install vcredist2015
Install GribApi.NET using Nuget. From Package Manager Console run
PM> Install-Package Grib.Api
In general, GribApi.NET should "just work". In rare cases, GribApi.NET may have difficulty locating the definitions
directory, which contains a number of dependencies.
To solve this problem, you can manually set the path to the definitions:
GribEnvironment.Init();
GribEnvironment.DefinitionsPath = "C:\\Some\\Path\\Grib.Api\\definitions";
using (GribFile file = new GribFile("mygrib2.grib"))
{
GribMessage msg = file.First();
Console.WriteLine("Grid Type: " + msg.GridType);
// GribApi.NET normalizes the coordinate values to degrees.
double latInDegrees = msg["latitudeOfFirstGridPoint"].AsDouble();
// values are also accessible as strings
Console.WriteLine("latitudeOfFirstGridPoint = " + msg["latitudeOfFirstGridPoint"].AsString());
}
using (GribFile file = new GribFile("mygrib1.grib"))
{
foreach (GribMessage msg in file)
{
// do something
}
}
Iterating messages in a stream Note: iterating streams is currently much slower than iterating a file:
var gribStream = new GribStream(myStream);
foreach (GribMessage msg in gribStream)
{
// do something
}
GribMessage msg = gribFile.First();
// the values in GridCoordinateValues are calculated by grid type
foreach (GridCoordinateValue val in msg.GridCoordinateValues)
{
if (val.IsMissing) { continue; }
Console.WriteLine("Lat: {0} Lon: {1} Val: {2}", val.Latitude, val.Longitude, val.Value);
}
GribMessage msg = gribFile.First();
var referencePt = msg.GridCoordinateValues.First();
Console.WriteLine("Getting the four nearest grid points to Lat: {0} Lon: {1}", referencePt.Latitude, referencePt.Longitude);
var nearest = msg.FindNearestCoordinates(referencePt);
foreach (var near in nearest)
{
GridCoordinateValue val = near.Value;
Console.WriteLine("Lat: {0} Lon: {1} Val: {2} Distance: {3}", var.Latitude, val.Longitude, val.Value, near.Distance);
}
using(GribFile file = new GribFile(@".\TestData\Pacific.wind.7days.grb"))
{
var vComp = file.Where(m => m.Name.Contains("V-component of wind m s**-1")).First();
foreach (var val in vComp.GridCoordinateValues)
{
Console.WriteLine("Lat: {0} Lon: {1} Val: {2}", val.Latitude, val.Longitude, val.Value);
}
}
using (GribFile file = new GribFile("mygrib.grb"))
{
GribMessage msg = file.First();
Console.WriteLine(msg.Dump());
}
using (GribFile file = new GribFile("mygrib.grb"))
{
GribMessage msg = file.First();
msg.WriteValuesToCsv("my\\file.csv");
}
GribMessage msg = gribFile.First();
double[] rawValues;
// get a copy of the raw values stored in the message
msg.Values(out rawValues);
string outPath = "out.grb";
string readPath = "some.grb";
using (GribFile readFile = new GribFile(readPath))
{
Console.WriteLine("Writing 1 message from {0} to {1}", readPath, outPath);
var msg = readFile.First();
msg["latitudeOfFirstGridPoint"].AsDouble(42);
double[] rawValues;
msg.Values(out rawValues);
// update the values
// ...
msg.SetValues(rawValues);
GribFile.Write(outPath, msg);
}
using (GribFile readFile = new GribFile(readPath))
{
Console.WriteLine("Appending {0} messages from {1} to {2}", readFile.MessageCount, readPath, outPath);
GribFile.Write(outPath, readFile as IEnumerable<GribMessage>, FileMode.Append);
// or, more simply:
// GribFile.Write(outPath, readFile, FileMode.Append);
}
For more examples, checkout the tests.
The current build is only designed for Windows and Visual Studio. I am eager to get it converted to CMake and make it cross-platform. Even a consistent build using make under msys2 would be great. I'd love some help doing this. :)
First, install the Nuget packages (this assumes you have nuget on PATH):
nuget install NUnit -Version 2.6.4 -O src\GribApi.NET\packages\
Install NUnit 2.6.4. Then run:
build\build_gribapi.cmd [build|rebuild] [VS version, 11|12|14] [Debug|Release] [nuget package version]
E.g., to build with Visual Studio 2015 (VS version 14):
build\build_gribapi.cmd build 14 Debug
- Install NUnit and expose it on PATH.
- Run
build/run_tests <architecture> <configuration> [optional "1" to break the tests on start]
, e.g.
build/run_tests x64 Debug
or
build/run_tests x86 Debug 1