Search code examples
javagrib

GRIB file to text in Java


I am trying to create a small library to read grib data from a flight simulator using Java.

Created a code to read a binary file and convert it into a string.

public class MainClass 
{
    final static String FILE_NAME = "PATH\\global_winds.grib";

    public static void main(String... aArgs) throws IOException
    {

        MainClass binary = new MainClass();
        byte[] bytes = binary.readFile(FILE_NAME);

        String myString = asciiBytesToString(bytes);

        System.out.println(myString);
    }

    byte[] readFile(String aFileName) throws IOException 
    {
        Path path = Paths.get(aFileName);
        return Files.readAllBytes(path);
    }


    public static String asciiBytesToString( byte[] bytes )
    {
          if ( (bytes == null) || (bytes.length == 0 ) )
          {
              return "";
          }

          char[] result = new char[bytes.length];

          for ( int i = 0; i < bytes.length; i++ )
          {
              result[i] = (char)bytes[i];
          }

          return new String( result );
      }
}

The file is read and returns gibberish. Is anyone familiar with the grib format? I thought it is using ASCII...

I do know about third-party libraries like NetCDF. The grib file I am trying to process includes limited data and I really wanted to make a small API for reading this file.

Thank you!


Solution

  • GRIB files are binary, not in ASCII format. Furthermore, the data is packed and you need to do some math to obtain the original values.

    To answer your question, GRIB2 uses

    • a Reference Value R (in IEEE 32-bit floating-point format)
    • a Binary Scale Factor E (signed integer, see comments below)
    • a Decimal Scale Factor D (signed integer, see comments below)

    to pack the original data. The Reference Value R is used to eliminate negative numbers, the Scale Factors are used to achieve the required precision. According to the specification, the original value v is recovered from the packed value p using the formula

    v = R + p * 2^E / 10^D
    

    Note that GRIB2 uses a special representation for signed integers, which is not compatible with the two's complement. Instead, GRIB2 uses the most significant bit to represent the sign and the remaining bits to represent the magnitude of the signed integer. If the most significant bit is set, the number is negative.

    If you want to look more into detail you can find a list of the relevant literature and specifications at http://www.theweatherserver.com/#grib2.

    If you don't want to look into details, you can use the GRIB2Tools Java library from https://github.com/philippphb/GRIB2Tools, it does all the math and allows accessing the data using longitude and latitude.