Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 2 additions & 27 deletions xrspatial/mcda/combine.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@

from __future__ import annotations

import warnings

import numpy as np
import xarray as xr
Expand Down Expand Up @@ -253,11 +252,9 @@ def wpm(

def owa(
criteria: xr.Dataset,
weights: dict[str, float] | None = None,
order_weights: list[float] | None = None,
weights: dict[str, float],
order_weights: list[float],
name: str = "owa",
*,
criterion_weights: dict[str, float] | None = None,
) -> xr.DataArray:
"""Ordered Weighted Averaging.

Expand All @@ -272,40 +269,18 @@ def owa(
weights : dict
Criterion weights as ``{criterion_name: weight}``, must sum
to ~1.0. Same convention as :func:`wlc` and :func:`wpm`.
Required; the ``None`` default exists only to support the
deprecated ``criterion_weights`` alias.
order_weights : list of float
Weights applied by rank position (index 0 = highest value).
Must have the same length as the number of criteria and
sum to ~1.0.
name : str
Name of the output DataArray.
criterion_weights : dict, optional
Deprecated alias for ``weights``. Emits ``DeprecationWarning``.

Returns
-------
xr.DataArray
Composite suitability surface.
"""
if criterion_weights is not None:
if weights is not None:
raise TypeError(
"owa() got values for both 'weights' and its deprecated "
"alias 'criterion_weights'"
)
warnings.warn(
"The 'criterion_weights' argument of owa() is deprecated; "
"use 'weights' instead.",
DeprecationWarning,
stacklevel=2,
)
weights = criterion_weights
if weights is None:
raise TypeError("owa() missing required argument: 'weights'")
if order_weights is None:
raise TypeError("owa() missing required argument: 'order_weights'")

_validate_criteria(criteria)
_validate_weights(weights, criteria)

Expand Down
6 changes: 1 addition & 5 deletions xrspatial/polygon_clip.py
Original file line number Diff line number Diff line change
Expand Up @@ -220,11 +220,7 @@ def clip_polygon(
# the task graph that xarray.where then has to align (#3191).
kw.setdefault('chunks', (max(rc), max(cc)))
if has_cuda_and_cupy() and is_dask_cupy(raster):
# Respect a legacy ``use_cuda`` passed via rasterize_kw --
# defaulting ``gpu`` as well would make rasterize() see both
# names and raise.
if 'use_cuda' not in kw:
kw.setdefault('gpu', True)
kw.setdefault('gpu', True)

mask = rasterize(geom_pairs, **kw)

Expand Down
21 changes: 0 additions & 21 deletions xrspatial/rasterize.py
Original file line number Diff line number Diff line change
Expand Up @@ -4139,7 +4139,6 @@ def rasterize(
chunks: Optional[Union[int, Tuple[int, int]]] = None,
max_pixels: int = MAX_PIXELS_DEFAULT,
check_crs: bool = True,
use_cuda: Optional[bool] = None,
) -> xr.DataArray:
"""Rasterize vector geometries into a 2D DataArray.

Expand Down Expand Up @@ -4337,10 +4336,6 @@ def rasterize(
them yourself to match the template. Pass ``check_crs=False`` to
skip the comparison (the output still inherits the template CRS).
The check is a no-op when either side lacks a CRS.
use_cuda : bool, optional
Deprecated alias for ``gpu``; emits a ``DeprecationWarning``
when passed. Passing both ``gpu=True`` and ``use_cuda`` raises
``TypeError``.

Returns
-------
Expand Down Expand Up @@ -4374,22 +4369,6 @@ def rasterize(
>>> density = rasterize(gdf, width=100, height=100,
... column='pop', merge='sum', fill=0)
"""
# Deprecation shim: ``use_cuda`` was renamed to ``gpu`` so the GPU
# opt-in matches ``open_geotiff(gpu=True)`` (issue #3089). The old
# keyword still works but warns; asking for both is ambiguous.
if use_cuda is not None:
if gpu:
raise TypeError(
"rasterize() got both 'gpu' and its deprecated alias "
"'use_cuda'; pass only 'gpu'")
warnings.warn(
"rasterize(use_cuda=...) is deprecated; use gpu=... instead "
"(same convention as open_geotiff).",
DeprecationWarning,
stacklevel=2,
)
gpu = use_cuda

# Fail early with a clear message if the optional ``vector`` extra
# (shapely) is not installed, rather than deep inside a helper.
_require_shapely()
Expand Down
46 changes: 0 additions & 46 deletions xrspatial/reproject/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,34 +67,6 @@
'ellipsoidal': 4979, # WGS 84 (3D, ellipsoidal height)
}

# Sentinel marking the deprecated ``src_vertical_crs`` / ``tgt_vertical_crs``
# kwargs as "not passed". Distinct from None so we can tell an explicit
# ``src_vertical_crs=None`` apart from the default and only warn when the
# caller actually used the old name.
_DEPRECATED = object()


def _resolve_deprecated_vertical_kwarg(old_name, old_val, new_name, new_val):
"""Map a deprecated vertical-CRS kwarg onto its renamed replacement.

Emits a ``DeprecationWarning`` when the old name is used and rejects
passing both the old and new spellings at once.
"""
if old_val is _DEPRECATED:
return new_val
import warnings
warnings.warn(
f"reproject(): {old_name!r} is deprecated, use {new_name!r} instead.",
DeprecationWarning,
stacklevel=3,
)
if new_val is not None:
raise TypeError(
f"reproject(): pass either {new_name!r} or the deprecated "
f"{old_name!r}, not both."
)
return old_val


def _find_spatial_dims(raster):
"""Find the y and x dimension names, handling multi-band rasters.
Expand Down Expand Up @@ -725,8 +697,6 @@ def reproject(
source_vertical_crs=None,
target_vertical_crs=None,
bounds_policy="auto",
src_vertical_crs=_DEPRECATED,
tgt_vertical_crs=_DEPRECATED,
):
"""Reproject a raster DataArray to a new coordinate reference system.

Expand Down Expand Up @@ -788,12 +758,6 @@ def reproject(
target_vertical_crs : str or None
Target vertical datum. Same options as *source_vertical_crs*.
Both must be set to trigger a vertical transformation.
src_vertical_crs : str or None
Deprecated alias for *source_vertical_crs*. Passing it emits a
``DeprecationWarning``.
tgt_vertical_crs : str or None
Deprecated alias for *target_vertical_crs*. Passing it emits a
``DeprecationWarning``.
bounds_policy : {"auto", "raw", "clamp", "percentile"}, default "auto"
How to derive the output extent from the source extent when
``bounds`` is not supplied. Only relevant when projecting near a
Expand Down Expand Up @@ -868,16 +832,6 @@ def reproject(
>>> result.attrs['crs'].startswith(('PROJCRS', 'PROJCS'))
True
"""
# Back-compat shim for the old abbreviated kwarg names. These were
# renamed to source_vertical_crs / target_vertical_crs to match the
# source_crs / target_crs spelling used by the rest of the signature.
source_vertical_crs = _resolve_deprecated_vertical_kwarg(
'src_vertical_crs', src_vertical_crs,
'source_vertical_crs', source_vertical_crs)
target_vertical_crs = _resolve_deprecated_vertical_kwarg(
'tgt_vertical_crs', tgt_vertical_crs,
'target_vertical_crs', target_vertical_crs)

_validate_raster(raster, func_name='reproject', name='raster',
ndim=(2, 3))

Expand Down
19 changes: 4 additions & 15 deletions xrspatial/tests/test_mcda.py
Original file line number Diff line number Diff line change
Expand Up @@ -2391,8 +2391,8 @@ def test_error_message_names_dimensions_and_count(


class TestOWAWeightsParam3148:
"""owa() takes its criterion-weight dict as `weights` like wlc/wpm,
with `criterion_weights` kept as a deprecated alias."""
"""owa() takes its criterion-weight dict as `weights` like wlc/wpm.
The `criterion_weights` alias was removed in 1.0.0 (#3763)."""

def test_weights_keyword(self, criteria_dataset, weights_3):
result = owa(
Expand All @@ -2401,21 +2401,10 @@ def test_weights_keyword(self, criteria_dataset, weights_3):
expected = owa(criteria_dataset, weights_3, [0.5, 0.3, 0.2])
np.testing.assert_allclose(result.values, expected.values)

def test_criterion_weights_deprecated(self, criteria_dataset, weights_3):
with pytest.warns(DeprecationWarning, match="criterion_weights"):
result = owa(
criteria_dataset,
criterion_weights=weights_3,
order_weights=[0.5, 0.3, 0.2],
)
expected = owa(criteria_dataset, weights_3, [0.5, 0.3, 0.2])
np.testing.assert_allclose(result.values, expected.values)

def test_both_names_raise(self, criteria_dataset, weights_3):
with pytest.raises(TypeError, match="both"):
def test_criterion_weights_removed(self, criteria_dataset, weights_3):
with pytest.raises(TypeError, match="criterion_weights"):
owa(
criteria_dataset,
weights=weights_3,
criterion_weights=weights_3,
order_weights=[0.5, 0.3, 0.2],
)
Expand Down
4 changes: 2 additions & 2 deletions xrspatial/tests/test_rasterize_coverage_2026_06_09.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,10 +80,10 @@ def _materialise(result):

_BACKENDS = [
pytest.param('numpy', {}, id='numpy'),
pytest.param('cupy', {'use_cuda': True}, marks=skip_no_cuda, id='cupy'),
pytest.param('cupy', {'gpu': True}, marks=skip_no_cuda, id='cupy'),
pytest.param('dask_numpy', {'chunks': (3, 3)}, marks=skip_no_dask,
id='dask_numpy'),
pytest.param('dask_cupy', {'use_cuda': True, 'chunks': (3, 3)},
pytest.param('dask_cupy', {'gpu': True, 'chunks': (3, 3)},
marks=[skip_no_cuda, skip_no_dask], id='dask_cupy'),
]

Expand Down
4 changes: 2 additions & 2 deletions xrspatial/tests/test_rasterize_geom_crs_3087.py
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ def test_dask_numpy_backend(self):
def test_cupy_backend(self):
result = rasterize(
_gdf(crs='EPSG:32610'), width=10, height=10,
bounds=(0, 0, 10, 10), column='value', fill=0, use_cuda=True,
bounds=(0, 0, 10, 10), column='value', fill=0, gpu=True,
)
assert result.attrs.get('crs') == 32610

Expand All @@ -177,6 +177,6 @@ def test_dask_cupy_backend(self):
result = rasterize(
_gdf(crs='EPSG:32610'), width=10, height=10,
bounds=(0, 0, 10, 10), column='value', fill=0,
use_cuda=True, chunks=5,
gpu=True, chunks=5,
)
assert result.attrs.get('crs') == 32610
45 changes: 11 additions & 34 deletions xrspatial/tests/test_rasterize_gpu_alias_3089.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
"""Issue #3089: rasterize() renamed its GPU opt-in from ``use_cuda`` to
``gpu`` to match ``open_geotiff(gpu=True)``.

``use_cuda`` stays as a deprecated keyword alias: it still selects the GPU
backend but emits a ``DeprecationWarning``, and combining it with
``gpu=True`` raises ``TypeError``. These tests pin the shim and the
positional-compatibility guarantee (``gpu`` occupies the slot ``use_cuda``
used to, so positional callers are unaffected).
The ``use_cuda`` alias was deprecated through 0.10.x and removed in 1.0.0
(#3763). These tests pin the positional-compatibility guarantee (``gpu``
occupies the slot ``use_cuda`` used to) and that the old name is gone.
"""
import inspect
import warnings
Expand Down Expand Up @@ -59,8 +57,7 @@ def test_gpu_is_tenth_positional_param():
positional callers keep selecting the GPU backend."""
params = list(inspect.signature(rasterize).parameters)
assert params[9] == 'gpu'
# the deprecated alias is appended last so it shifts nothing
assert params[-1] == 'use_cuda'
assert 'use_cuda' not in params


def test_default_emits_no_deprecation_warning():
Expand All @@ -69,17 +66,10 @@ def test_default_emits_no_deprecation_warning():
rasterize(_pairs(), **_kw())


def test_use_cuda_false_warns_and_runs_cpu():
with pytest.warns(DeprecationWarning, match='use gpu='):
result = rasterize(_pairs(), use_cuda=False, **_kw())
assert isinstance(result.data, np.ndarray)


def test_gpu_true_and_use_cuda_raises():
with pytest.raises(TypeError, match="deprecated alias"):
rasterize(_pairs(), gpu=True, use_cuda=True, **_kw())
with pytest.raises(TypeError, match="deprecated alias"):
rasterize(_pairs(), gpu=True, use_cuda=False, **_kw())
def test_use_cuda_removed():
"""The 0.x alias is gone in 1.0: plain unexpected-keyword TypeError."""
with pytest.raises(TypeError, match="use_cuda"):
rasterize(_pairs(), use_cuda=False, **_kw())


@requires_gpu
Expand All @@ -91,28 +81,15 @@ def test_gpu_true_matches_numpy():


@requires_gpu
def test_use_cuda_true_warns_and_matches_gpu_true():
expected = rasterize(_pairs(), gpu=True, **_kw())
with pytest.warns(DeprecationWarning, match='use gpu='):
result = rasterize(_pairs(), use_cuda=True, **_kw())
assert isinstance(result.data, cupy.ndarray)
np.testing.assert_array_equal(_to_numpy(result), _to_numpy(expected))


@requires_gpu
def test_dask_cupy_via_gpu_and_alias():
def test_dask_cupy_via_gpu():
import dask.array as da

expected = rasterize(_pairs(), gpu=True, **_kw())
lazy = rasterize(_pairs(), gpu=True, chunks=5, **_kw())
assert isinstance(lazy.data, da.Array)
assert isinstance(lazy.data._meta, cupy.ndarray)

with pytest.warns(DeprecationWarning, match='use gpu='):
lazy_alias = rasterize(_pairs(), use_cuda=True, chunks=5, **_kw())
assert isinstance(lazy_alias.data._meta, cupy.ndarray)

np.testing.assert_array_equal(
_to_numpy(lazy.compute()), _to_numpy(lazy_alias.compute()))
_to_numpy(lazy.compute()), _to_numpy(expected))


@requires_gpu
Expand Down
4 changes: 2 additions & 2 deletions xrspatial/tests/test_rasterize_nonfinite_burn_3085.py
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ def test_nan_burn_int_raises_cupy():
with pytest.raises(ValueError, match=_MATCH):
rasterize([(box(0, 0, 5, 5), np.nan)],
width=4, height=4, bounds=(0, 0, 5, 5),
fill=0, dtype=np.int32, use_cuda=True)
fill=0, dtype=np.int32, gpu=True)


@skip_no_shapely
Expand All @@ -193,4 +193,4 @@ def test_nan_burn_int_raises_dask_cupy():
with pytest.raises(ValueError, match=_MATCH):
rasterize([(box(0, 0, 5, 5), np.nan)],
width=4, height=4, bounds=(0, 0, 5, 5),
fill=0, dtype=np.int32, use_cuda=True, chunks=2)
fill=0, dtype=np.int32, gpu=True, chunks=2)
4 changes: 2 additions & 2 deletions xrspatial/tests/test_rasterize_nonfinite_burn_3088.py
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ def test_nan_burn_int_dtype_raises_cupy():
with pytest.raises(ValueError, match="cannot be represented"):
rasterize([(box(2, 2, 8, 8), float('nan'))],
width=10, height=10, bounds=(0, 0, 10, 10),
fill=0, dtype=np.int32, use_cuda=True)
fill=0, dtype=np.int32, gpu=True)


@skip_no_shapely
Expand All @@ -143,7 +143,7 @@ def test_nan_burn_int_dtype_raises_dask_cupy():
with pytest.raises(ValueError, match="cannot be represented"):
rasterize([(box(2, 2, 8, 8), float('nan'))],
width=10, height=10, bounds=(0, 0, 10, 10),
fill=0, dtype=np.int32, use_cuda=True, chunks=5)
fill=0, dtype=np.int32, gpu=True, chunks=5)


@skip_no_shapely
Expand Down
Loading
Loading