From 8f5fe3bd03f924238ba3e1d2fb28cad55f25bd66 Mon Sep 17 00:00:00 2001 From: BENR0 Date: Fri, 4 Aug 2023 11:51:55 +0200 Subject: [PATCH 01/10] feat: add to_odc_geobox method --- pyresample/geometry.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/pyresample/geometry.py b/pyresample/geometry.py index 04cdd886d..c647ebd44 100644 --- a/pyresample/geometry.py +++ b/pyresample/geometry.py @@ -1961,6 +1961,16 @@ def _cartopy_proj_params(self): return "EPSG:{}".format(self.crs.to_epsg()) return self.crs.to_proj4() + def to_odc_geobox(self): + """Convert AreaDefinition to ODC GeoBox. + + See: https://odc-geo.readthedocs.io/en/latest/ + """ + from odc.geo.geobox import GeoBox + + return GeoBox.from_bbox(bbox=self.area_extent, crs=self.crs, resolution=np.mean([self.pixel_size_x, + self.pixel_size_y])) + def create_areas_def(self): """Generate YAML formatted representation of this area. From 4b02a0255a1139af7a844c66b2ee2efeb0a34bc0 Mon Sep 17 00:00:00 2001 From: BENR0 Date: Fri, 4 Aug 2023 11:54:26 +0200 Subject: [PATCH 02/10] Add: odc-geo to extras list. --- setup.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/setup.py b/setup.py index b5a28b19b..6552b3a2f 100644 --- a/setup.py +++ b/setup.py @@ -40,8 +40,14 @@ 'cf': ['xarray'], 'gradient_search': ['shapely'], 'xarray_bilinear': ['xarray', 'dask', 'zarr'], + 'odc-geo': ['odc-geo'], 'tests': test_requires} +all_extras = [] +for extra_deps in extras_require.values(): + all_extras.extend(extra_deps) +extras_require['all'] = list(set(all_extras)) + setup_requires = ['numpy>=1.10.0', 'cython'] if sys.platform.startswith("win"): From bb4d79cbc54a9413cb5bde2a06a71aa524206aa2 Mon Sep 17 00:00:00 2001 From: BENR0 Date: Wed, 9 Aug 2023 10:19:28 +0200 Subject: [PATCH 03/10] fix: geobox pixel snapping. --- pyresample/geometry.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pyresample/geometry.py b/pyresample/geometry.py index c647ebd44..74bdd5790 100644 --- a/pyresample/geometry.py +++ b/pyresample/geometry.py @@ -1968,8 +1968,8 @@ def to_odc_geobox(self): """ from odc.geo.geobox import GeoBox - return GeoBox.from_bbox(bbox=self.area_extent, crs=self.crs, resolution=np.mean([self.pixel_size_x, - self.pixel_size_y])) + return GeoBox.from_bbox(bbox=self.area_extent, crs=self.crs, + resolution=np.mean([self.pixel_size_x, self.pixel_size_y]), tight=True) def create_areas_def(self): """Generate YAML formatted representation of this area. From 5e600a15a22a51ad723edf028be01efb3fb667c0 Mon Sep 17 00:00:00 2001 From: BENR0 Date: Wed, 9 Aug 2023 10:20:20 +0200 Subject: [PATCH 04/10] test: add geobox conversion test. --- pyresample/test/test_geometry/test_area.py | 29 ++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/pyresample/test/test_geometry/test_area.py b/pyresample/test/test_geometry/test_area.py index d19b44944..6798cc53e 100644 --- a/pyresample/test/test_geometry/test_area.py +++ b/pyresample/test/test_geometry/test_area.py @@ -403,6 +403,35 @@ def test_cartopy_crs_latlon_bounds(self, create_test_area): latlong_crs = area_def.to_cartopy_crs() np.testing.assert_allclose(latlong_crs.bounds, [-180, 180, -90, 90]) + def test_to_odc_geobox(self, stere_area, create_test_area): + """Test conversion from area definition to odc GeoBox.""" + from odc.geo.geobox import GeoBox + + europe = stere_area + seviri = create_test_area( + { + 'proj': 'geos', + 'lon_0': 0.0, + 'a': 6378169.00, + 'b': 6356583.80, + 'h': 35785831.00, + 'units': 'm'}, + 123, + 123, + (-5500000, -5500000, 5500000, 5500000)) + + for area_def in [europe, seviri]: + geobox = area_def.to_odc_geobox() + + assert isinstance(geobox, GeoBox) + + # Affine coefficiants + af = geobox.affine + assert af.a == area_def.pixel_size_x + assert af.e == -area_def.pixel_size_y + assert af.xoff == area_def.area_extent[0] + assert af.yoff == area_def.area_extent[3] + def test_dump(self, create_test_area): """Test exporting area defs.""" from io import StringIO From fcf296bbd06570ce238ad63c84c6979035553234 Mon Sep 17 00:00:00 2001 From: BENR0 Date: Wed, 9 Aug 2023 10:29:29 +0200 Subject: [PATCH 05/10] refactor: add exception for none installed odc-geo. --- pyresample/geometry.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/pyresample/geometry.py b/pyresample/geometry.py index 74bdd5790..c03306181 100644 --- a/pyresample/geometry.py +++ b/pyresample/geometry.py @@ -1966,7 +1966,10 @@ def to_odc_geobox(self): See: https://odc-geo.readthedocs.io/en/latest/ """ - from odc.geo.geobox import GeoBox + try: + from odc.geo.geobox import GeoBox + except ModuleNotFoundError: + raise ModuleNotFoundError("Please install 'odc-geo' to use this method.") return GeoBox.from_bbox(bbox=self.area_extent, crs=self.crs, resolution=np.mean([self.pixel_size_x, self.pixel_size_y]), tight=True) From ec53f26c78a3494e9b5d01f7bacfbb7603f12b40 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20R=C3=B6sner?= Date: Thu, 10 Aug 2023 10:52:03 +0200 Subject: [PATCH 06/10] fix: odc-geo not in ci environment dependency list. --- continuous_integration/environment.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/continuous_integration/environment.yaml b/continuous_integration/environment.yaml index 2b659a606..27c1d9ff0 100644 --- a/continuous_integration/environment.yaml +++ b/continuous_integration/environment.yaml @@ -28,3 +28,4 @@ dependencies: - pytest-lazy-fixture - importlib-metadata - sphinx-reredirects + - odc-geo From 84a6debf748f72827a1b7745b1ea157bf228cd05 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20R=C3=B6sner?= Date: Tue, 24 Oct 2023 13:23:18 +0200 Subject: [PATCH 07/10] refactor: remove unnecessary setup_requires. --- setup.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/setup.py b/setup.py index 25de95c61..049fc0575 100644 --- a/setup.py +++ b/setup.py @@ -48,8 +48,6 @@ all_extras.extend(extra_deps) extras_require['all'] = list(set(all_extras)) -setup_requires = ['numpy>=1.10.0', 'cython'] - if sys.platform.startswith("win"): extra_compile_args = [] else: From 28c6f80cca8263fbe111425c12df58c169fbf3be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20R=C3=B6sner?= Date: Tue, 24 Oct 2023 13:28:05 +0200 Subject: [PATCH 08/10] fix: odc-geo not in test_requires list. --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 049fc0575..42dcc3efb 100644 --- a/setup.py +++ b/setup.py @@ -32,7 +32,7 @@ requirements.append('importlib_metadata') test_requires = ['rasterio', 'dask', 'xarray', 'cartopy>=0.20.0', 'pillow', 'matplotlib', 'scipy', 'zarr', - 'pytest-lazy-fixtures', 'shapely'] + 'pytest-lazy-fixtures', 'shapely', 'odc-geo'] extras_require = {'numexpr': ['numexpr'], 'quicklook': ['matplotlib', 'cartopy>=0.20.0', 'pillow'], 'rasterio': ['rasterio'], From c043b977a43898a4e684643b2ce2555074fd29c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20R=C3=B6sner?= Date: Tue, 7 Nov 2023 10:45:58 +0100 Subject: [PATCH 09/10] refactor: use odc Resolution class. --- pyresample/geometry.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pyresample/geometry.py b/pyresample/geometry.py index 77e09baa3..40af52458 100644 --- a/pyresample/geometry.py +++ b/pyresample/geometry.py @@ -1978,12 +1978,13 @@ def to_odc_geobox(self): See: https://odc-geo.readthedocs.io/en/latest/ """ try: + from odc.geo import Resolution from odc.geo.geobox import GeoBox except ModuleNotFoundError: raise ModuleNotFoundError("Please install 'odc-geo' to use this method.") return GeoBox.from_bbox(bbox=self.area_extent, crs=self.crs, - resolution=np.mean([self.pixel_size_x, self.pixel_size_y]), tight=True) + resolution=Resolution(x=self.pixel_size_x, y=-self.pixel_size_y), tight=True) def create_areas_def(self): """Generate YAML formatted representation of this area. From 09c35fd0fe077bd363f05d932d68098550176472 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20R=C3=B6sner?= Date: Tue, 7 Nov 2023 12:55:00 +0100 Subject: [PATCH 10/10] refactor: move odc-geo import to top, add test for missing odc-geo. --- pyresample/geometry.py | 15 +++++++++------ pyresample/test/test_geometry/test_area.py | 10 ++++++++++ 2 files changed, 19 insertions(+), 6 deletions(-) diff --git a/pyresample/geometry.py b/pyresample/geometry.py index 40af52458..0a45b3f38 100644 --- a/pyresample/geometry.py +++ b/pyresample/geometry.py @@ -56,6 +56,11 @@ except ImportError: da = None +try: + import odc.geo as odc_geo +except ModuleNotFoundError: + odc_geo = None + from pyproj import CRS from pyproj.enums import TransformDirection @@ -1977,14 +1982,12 @@ def to_odc_geobox(self): See: https://odc-geo.readthedocs.io/en/latest/ """ - try: - from odc.geo import Resolution - from odc.geo.geobox import GeoBox - except ModuleNotFoundError: + if odc_geo is None: raise ModuleNotFoundError("Please install 'odc-geo' to use this method.") - return GeoBox.from_bbox(bbox=self.area_extent, crs=self.crs, - resolution=Resolution(x=self.pixel_size_x, y=-self.pixel_size_y), tight=True) + return odc_geo.geobox.GeoBox.from_bbox(bbox=self.area_extent, crs=self.crs, + resolution=odc_geo.Resolution(x=self.pixel_size_x, y=-self.pixel_size_y), + tight=True) def create_areas_def(self): """Generate YAML formatted representation of this area. diff --git a/pyresample/test/test_geometry/test_area.py b/pyresample/test/test_geometry/test_area.py index 73307cdf4..0f84533ee 100644 --- a/pyresample/test/test_geometry/test_area.py +++ b/pyresample/test/test_geometry/test_area.py @@ -403,6 +403,16 @@ def test_cartopy_crs_latlon_bounds(self, create_test_area): latlong_crs = area_def.to_cartopy_crs() np.testing.assert_allclose(latlong_crs.bounds, [-180, 180, -90, 90]) + def test_to_odc_geobox_odc_missing(self, monkeypatch, stere_area): + """Test odc-geo not installed.""" + area = stere_area + + with monkeypatch.context() as m: + m.setattr(pyresample.geometry, "odc_geo", None) + + with pytest.raises(ModuleNotFoundError): + area.to_odc_geobox() + def test_to_odc_geobox(self, stere_area, create_test_area): """Test conversion from area definition to odc GeoBox.""" from odc.geo.geobox import GeoBox