noritada / grib-rs

GRIB format parser for Rust
Apache License 2.0
56 stars 9 forks source link

Impossible lat/long coordinates generated #106

Open c0repwn3r opened 1 week ago

c0repwn3r commented 1 week ago

Simple Description on the Bug

When using NOAA MRMS ref @ lowest altitude, it manages to extract some data (correct? not sure), however the lat/long values outputted are impossible (>180). For example, given the test file I've attached, most coordinates generated are around ~55 lat **~230 long**. I'd assume this is offset by 180, but I'm not sure and my attempts to read the code and GRIB2 specs have not given me any useful information.

Steps to Reproduce

  1. Run gribber decode MRMS_ReflectivityAtLowestAltitude.latest.grib2
  2. Observe the nonsensical longitude values

Issue is also observed with custom code which is nearly identical to to the code used by the cli/ package, so it can be used to demonstrate this issue.

Expected Behavior

The longitude values should be within the -180 to 180 degree specification

Actual Behavior

The longitude values are not within the -180 to 180 degree specification

Additional Context

MRMS_ReflectivityAtLowestAltitude.latest.grib2.gz Here's a test file that exemplifies this issue. It's retrieved from the US NOAA/NSSL MRMS data download site.

noritada commented 1 week ago

Thank you for reporting.

I am not sure if this is a mistake or not, since eccodes also use a longitude range of 180 to 360 degrees as shown in the output below, but ISO 6709 requires that a longitude range of -180 to 180 degrees be used, and it would be easier to understand if it were so, as it would correspond to east and west longitudes. I would like to change the output.

❯  grib_get_data -m missing extdata/zenmodel_171205/Z__C_RJTD_20171205000000_GSM_GPV_Rgl_FD0006_grib2.bin | tail -3
  -90.000  357.000 -5.3207576275e-04
  -90.000  358.000 -5.3207576275e-04
  -90.000  359.000 -5.3207576275e-04
c0repwn3r commented 1 week ago

Hmm, I see. I assume 0 corresponds to -180 then? E.g. this range of 0-360 is mapped 1:1 to -180 - 180? In that case we could just -180 from the output to convert it into a -180/180 range

LafeWessel commented 1 week ago

Not quite, those two ranges are the same at 0 and 0-360 wraps eastward around the planet back to 0, whereas [-180 - 180] spreads both directions around the planet to reach -180/180 at the antemeridian. Thus, [0 - 180] are the same in both ranges, but 181 = -179, 270 = -90, etc. Here is an example of the grid for -180 to 180. https://gisgeography.com/latitude-longitude-coordinates/

This example shows how the [-180, 180] and [0, 360] ranges overlap: https://medium.com/hydroinformatics/0-360-longitude-to-180-180-longitude-convention-ba5096cb6f60

Here's a snippet for converting a longitude from the range [0, 360] to [-180, 180]. If the longitude is past the antemeridian (> 180), then you have to convert from wrapping all the way around the world to wrapping backwards from 0, hence the - 360.

fn convert_longitude(longitude: f64) -> f64 {
    if longitude > 180.0 {
        longitude - 360.0
    } else {
        longitude
    }
}