Skip to content

Commit 48f83a9

Browse files
committed
[WIP] test wraparound indexing
Closes #26
1 parent 9fd5556 commit 48f83a9

File tree

4 files changed

+39
-18
lines changed

4 files changed

+39
-18
lines changed

src/rasterix/raster_index.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -288,6 +288,8 @@ def isel( # type: ignore[override]
288288
# return PandasIndex(values, new_dim, coord_dtype=values.dtype)
289289

290290
def sel(self, labels, method=None, tolerance=None):
291+
# CoordinateTransformIndex only supports "nearest"
292+
method = method or "nearest"
291293
coord_name = self.axis_transform.coord_name
292294
label = labels[coord_name]
293295

@@ -520,8 +522,8 @@ def from_transform(
520522
affine = affine * Affine.translation(0.5, 0.5)
521523

522524
if affine.is_rectilinear and affine.b == affine.d == 0:
523-
x_transform = AxisAffineTransform(affine, width, "x", x_dim, is_xaxis=True)
524-
y_transform = AxisAffineTransform(affine, height, "y", y_dim, is_xaxis=False)
525+
x_transform = AxisAffineTransform(affine, width, x_dim, x_dim, is_xaxis=True)
526+
y_transform = AxisAffineTransform(affine, height, y_dim, y_dim, is_xaxis=False)
525527
index = (
526528
AxisAffineTransformIndex(x_transform),
527529
AxisAffineTransformIndex(y_transform),

src/rasterix/rasterize/utils.py

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
import geopandas as gpd
77
import numpy as np
88
import xarray as xr
9-
from affine import Affine
109

1110
if TYPE_CHECKING:
1211
import dask.array
@@ -34,20 +33,6 @@ def clip_to_bbox(
3433
return obj
3534

3635

37-
def get_affine(obj: xr.Dataset | xr.DataArray, *, xdim="x", ydim="y") -> Affine:
38-
spatial_ref = obj.coords["spatial_ref"]
39-
if "GeoTransform" in spatial_ref.attrs:
40-
return Affine.from_gdal(*map(float, spatial_ref.attrs["GeoTransform"].split(" ")))
41-
else:
42-
x = obj.coords[xdim]
43-
y = obj.coords[ydim]
44-
dx = (x[1] - x[0]).item()
45-
dy = (y[1] - y[0]).item()
46-
return Affine.translation(
47-
x[0].item() - dx / 2, (y[0] if dy < 0 else y[-1]).item() - dy / 2
48-
) * Affine.scale(dx, dy)
49-
50-
5136
def is_in_memory(*, obj, geometries) -> bool:
5237
return not obj.chunks and isinstance(geometries, gpd.GeoDataFrame)
5338

src/rasterix/rioxarray_compat.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,8 @@ def guess_dims(obj: T_Xarray) -> tuple[str, str]:
204204
x_dim = "longitude"
205205
y_dim = "latitude"
206206
else:
207+
x_dim = None
208+
y_dim = None
207209
# look for coordinates with CF attributes
208210
for coord in obj.coords:
209211
# make sure to only look in 1D coordinates
@@ -213,12 +215,18 @@ def guess_dims(obj: T_Xarray) -> tuple[str, str]:
213215
if (obj.coords[coord].attrs.get("axis", "").upper() == "X") or (
214216
obj.coords[coord].attrs.get("standard_name", "").lower()
215217
in ("longitude", "projection_x_coordinate")
218+
or obj.coords[coord].attrs.get("units", "").lower() in ("degrees_east",)
216219
):
217220
x_dim = coord
218221
elif (obj.coords[coord].attrs.get("axis", "").upper() == "Y") or (
219222
obj.coords[coord].attrs.get("standard_name", "").lower()
220223
in ("latitude", "projection_y_coordinate")
224+
or obj.coords[coord].attrs.get("units", "").lower() in ("degrees_north",)
221225
):
222226
y_dim = coord
223227

228+
if not x_dim or not y_dim:
229+
raise ValueError(
230+
"Could not guess names of x, y coordinate variables. Please explicitly pass `x_dim` and `y_dim`."
231+
)
224232
return x_dim, y_dim

tests/test_raster_index.py

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
import rioxarray # noqa
77
import xarray as xr
88
from affine import Affine
9-
from xarray.testing import assert_identical
9+
from xarray.testing import assert_equal, assert_identical
1010

1111
from rasterix import RasterIndex, assign_index
1212

@@ -363,3 +363,29 @@ def test_repr() -> None:
363363

364364
index3 = RasterIndex.from_transform(Affine.identity(), width=12, height=10, crs="epsg:31370")
365365
assert repr(index3).startswith("RasterIndex(crs=EPSG:31370)")
366+
367+
368+
def test_assign_index_cant_guess_error():
369+
ds = xr.Dataset(
370+
{"sst": (("time", "lat", "lon"), np.ones((1, 89, 180)))},
371+
coords={"lat": np.arange(88, -89, -2), "lon": np.arange(0, 360, 2)},
372+
)
373+
with pytest.raises(ValueError, match="guess"):
374+
assign_index(ds)
375+
376+
377+
def test_wraparound_indexing_longitude():
378+
ds = xr.Dataset(
379+
{"sst": (("time", "lat", "lon"), np.random.random((1, 89, 180)))},
380+
coords={
381+
"lat": ("lat", np.arange(88, -89, -2), {"axis": "Y"}),
382+
"lon": ("lon", np.arange(0, 360, 2), {"axis": "X"}),
383+
},
384+
)
385+
indexed = ds.pipe(assign_index)
386+
# We lose existing attrs when calling ``assign_index``.
387+
assert_equal(ds.sel(lon=[220, 240]), indexed.sel(lon=[-140, -120]))
388+
assert_equal(ds.sel(lon=220), indexed.sel(lon=-140))
389+
assert_equal(ds.sel(lon=slice(220, 240)), indexed.sel(lon=slice(-140, -120)))
390+
assert_equal(ds.sel(lon=slice(240, 220)), indexed.sel(lon=slice(-120, -140)))
391+
# assert_equal(ds.sel(lon=[220]), indexed.sel(lon=[-140])) # FIXME

0 commit comments

Comments
 (0)