From f9ae569ecdb8f4c51e6334187c82b312fa0ef60f Mon Sep 17 00:00:00 2001 From: Sandor Kertesz Date: Thu, 11 Jun 2026 15:09:10 +0100 Subject: [PATCH] Support south-north sacanning for bounding box and area --- src/earthkit/data/field/grib/geography.py | 19 ++++++-- tests/data/ll_sn_scanning_mode.grib | Bin 0 -> 8100 bytes tests/grib/test_grib_geography.py | 55 +++++++++------------- 3 files changed, 37 insertions(+), 37 deletions(-) create mode 100644 tests/data/ll_sn_scanning_mode.grib diff --git a/src/earthkit/data/field/grib/geography.py b/src/earthkit/data/field/grib/geography.py index 0f7488be..450d7e43 100644 --- a/src/earthkit/data/field/grib/geography.py +++ b/src/earthkit/data/field/grib/geography.py @@ -86,11 +86,19 @@ def bounding_box(self): """ from earthkit.data.utils.bbox import BoundingBox + north = self.handle.get("latitudeOfFirstGridPointInDegrees", default=None) + south = self.handle.get("latitudeOfLastGridPointInDegrees", default=None) + if south is not None and north is not None and south > north: + # latitudes are in the wrong order, swap them + north, south = south, north + west = self.handle.get("longitudeOfFirstGridPointInDegrees", default=None) + east = self.handle.get("longitudeOfLastGridPointInDegrees", default=None) + return BoundingBox( - north=self.handle.get("latitudeOfFirstGridPointInDegrees", default=None), - south=self.handle.get("latitudeOfLastGridPointInDegrees", default=None), - west=self.handle.get("longitudeOfFirstGridPointInDegrees", default=None), - east=self.handle.get("longitudeOfLastGridPointInDegrees", default=None), + north=north, + south=south, + west=west, + east=east, ) def projection(self): @@ -164,6 +172,9 @@ def _get_grid_spec_from_handle(self): def area(self): north = self.handle.get("latitudeOfFirstGridPointInDegrees") south = self.handle.get("latitudeOfLastGridPointInDegrees") + if south is not None and north is not None and south > north: + # latitudes are in the wrong order, swap them + north, south = south, north west = self.handle.get("longitudeOfFirstGridPointInDegrees") east = self.handle.get("longitudeOfLastGridPointInDegrees") return tuple([north, west, south, east]) diff --git a/tests/data/ll_sn_scanning_mode.grib b/tests/data/ll_sn_scanning_mode.grib new file mode 100644 index 0000000000000000000000000000000000000000..d743137dcdb7255972a0e17148486c0e824d1ae5 GIT binary patch literal 8100 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