Skip to content

Commit 4c38f0f

Browse files
authored
Merge branch 'main' into pr/cf-axis-units
2 parents 519c94c + 3b10d51 commit 4c38f0f

6 files changed

Lines changed: 57 additions & 8 deletions

File tree

.pre-commit-config.yaml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ exclude: '^$'
22
fail_fast: false
33
repos:
44
- repo: https://github.com/astral-sh/ruff-pre-commit
5-
rev: 'v0.14.14'
5+
rev: 'v0.15.4'
66
hooks:
77
- id: ruff
88
- repo: https://github.com/pre-commit/pre-commit-hooks
@@ -13,7 +13,7 @@ repos:
1313
- id: check-yaml
1414
args: [--unsafe]
1515
- repo: https://github.com/PyCQA/bandit
16-
rev: '1.9.3' # Update me!
16+
rev: '1.9.4' # Update me!
1717
hooks:
1818
- id: bandit
1919
args: [--ini, .bandit]
@@ -32,7 +32,7 @@ repos:
3232
- pytest
3333
args: [ --warn-unused-configs ]
3434
- repo: https://github.com/pycqa/isort
35-
rev: 7.0.0
35+
rev: 8.0.1
3636
hooks:
3737
- id: isort
3838
language_version: python3

pyresample/future/geometry/_subset.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ def _get_area_boundary(area_to_cover: AreaDefinition) -> Boundary:
100100
if area_to_cover.is_geostationary:
101101
return Boundary(*get_geostationary_bounding_box_in_lonlats(area_to_cover))
102102
boundary_shape = max(max(*area_to_cover.shape) // 100 + 1, 3)
103-
return area_to_cover.boundary(frequency=boundary_shape, force_clockwise=True)
103+
return area_to_cover.boundary(vertices_per_side=boundary_shape, force_clockwise=True)
104104
except ValueError as err:
105105
raise NotImplementedError("Can't determine boundary of area to cover") from err
106106

pyresample/slicer.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,7 @@ def get_polygon_to_contain(self):
170170
from shapely.geometry import Polygon
171171

172172
try:
173-
x, y = self.area_to_contain.get_edge_bbox_in_projection_coordinates(frequency=10)
173+
x, y = self.area_to_contain.get_edge_bbox_in_projection_coordinates(vertices_per_side=10)
174174
except AttributeError:
175175
x, y = self.area_to_contain.get_edge_lonlats(vertices_per_side=10)
176176
if self.area_to_crop.is_geostationary:
@@ -202,7 +202,7 @@ def get_slices_from_polygon(self, poly_to_contain):
202202
from shapely.geometry import Polygon
203203

204204
poly_to_crop = Polygon(zip(
205-
*self.area_to_crop.get_edge_bbox_in_projection_coordinates(frequency=10),
205+
*self.area_to_crop.get_edge_bbox_in_projection_coordinates(vertices_per_side=10),
206206
strict=True))
207207
if not poly_to_crop.intersects(buffered_poly):
208208
raise IncompatibleAreas("Areas not overlapping.")

pyresample/test/test_geometry/test_area.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1088,7 +1088,7 @@ def test_area_def_geocentric_resolution_latlong(self, create_test_area):
10881088
def test_from_epsg(self, area_class):
10891089
"""Test the from_epsg class method."""
10901090
sweref = area_class.from_epsg('3006', 2000)
1091-
assert sweref.description == 'SWEREF99 TM'
1091+
assert sweref.description in ['SWEREF99 TM', 'ETRS89-SWE [SWEREF 99 TM]']
10921092
with ignore_pyproj_proj_warnings():
10931093
assert sweref.proj_dict == {'ellps': 'GRS80', 'no_defs': None,
10941094
'proj': 'utm', 'type': 'crs', 'units': 'm',

pyresample/test/test_utils/test_cf.py

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,35 @@ def _prepare_cf_llnocrs():
142142
return ds
143143

144144

145+
def _prepare_cf_projected_packed_xy():
146+
import xarray as xr
147+
148+
axis_values = np.array([-100, 0, 100], dtype=np.int16)
149+
ds = xr.Dataset({'temp': (('y', 'x'), np.ma.masked_all((3, 3)), {'grid_mapping': 'crs'})},
150+
coords={'x': ('x', axis_values),
151+
'y': ('y', axis_values[::-1])})
152+
ds['x'].attrs['standard_name'] = 'projection_x_coordinate'
153+
ds['x'].attrs['units'] = 'm'
154+
ds['x'].attrs['scale_factor'] = 10.0
155+
ds['x'].attrs['add_offset'] = 1000.0
156+
ds['y'].attrs['standard_name'] = 'projection_y_coordinate'
157+
ds['y'].attrs['units'] = 'm'
158+
ds['y'].attrs['scale_factor'] = 10.0
159+
ds['y'].attrs['add_offset'] = 1000.0
160+
161+
ds['crs'] = 0
162+
ds['crs'].attrs['grid_mapping_name'] = "stereographic"
163+
ds['crs'].attrs['false_easting'] = 0.
164+
ds['crs'].attrs['false_northing'] = 0.
165+
ds['crs'].attrs['semi_major_axis'] = 6378137.
166+
ds['crs'].attrs['inverse_flattening'] = 298.257223563
167+
ds['crs'].attrs['latitude_of_projection_origin'] = 90.
168+
ds['crs'].attrs['straight_vertical_longitude_from_pole'] = 0.
169+
ds['crs'].attrs['scale_factor_at_projection_origin'] = 1.
170+
171+
return ds
172+
173+
145174
class TestLoadCFAreaPublic:
146175
"""Test public API load_cf_area() for loading an AreaDefinition from netCDF/CF files."""
147176

@@ -244,6 +273,7 @@ def test_load_cf_latlon(self, file_func, kwargs, exp_lat, exp_lon, future_geomet
244273
_validate_lonlat_cf_area(adef, cf_info, exp_lon, exp_lat)
245274
assert_future_geometry(adef, future_geometries)
246275

276+
<<<<<<< pr/cf-axis-units
247277
def test_load_cf_axis_without_units(self):
248278
cf_file = _prepare_cf_nh10km()
249279
del cf_file['xc'].attrs['units']
@@ -264,6 +294,25 @@ def test_load_cf_axis_with_non_string_units(self):
264294
assert cf_info['x']['unit'] is None
265295
assert cf_info['y']['unit'] is None
266296

297+
=======
298+
def test_load_cf_dataset_input_decodes_cf_coordinates(self, tmp_path):
299+
import xarray as xr
300+
301+
cf_file = _prepare_cf_projected_packed_xy()
302+
file_path = tmp_path / "packed_xy.nc"
303+
cf_file.to_netcdf(file_path)
304+
305+
expected_area, expected_info = load_cf_area(file_path, variable="temp")
306+
307+
with xr.open_dataset(file_path, decode_cf=False) as raw_ds:
308+
area_from_dataset, info_from_dataset = load_cf_area(raw_ds, variable="temp")
309+
310+
np.testing.assert_allclose(area_from_dataset.area_extent, expected_area.area_extent)
311+
assert info_from_dataset['x']['first'] == expected_info['x']['first']
312+
assert info_from_dataset['x']['last'] == expected_info['x']['last']
313+
assert info_from_dataset['y']['first'] == expected_info['y']['first']
314+
assert info_from_dataset['y']['last'] == expected_info['y']['last']
315+
>>>>>>> main
267316

268317
def _validate_lonlat_cf_area(adef, cf_info, exp_lon, exp_lat):
269318
assert adef.shape == (19, 37)

pyresample/utils/cf.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -472,6 +472,6 @@ def _open_nc_file(nc_file: str | Path | xr.Dataset) -> xr.Dataset:
472472
if xr is None:
473473
raise ImportError("Xarray (pip install xarray) is required to load geometries from a NetCDF file.")
474474
if isinstance(nc_file, xr.Dataset):
475-
return nc_file
475+
return xr.decode_cf(nc_file)
476476

477477
return xr.open_dataset(nc_file)

0 commit comments

Comments
 (0)