Skip to content

Commit bf58b35

Browse files
Add backend statement and Examples to cost_distance docstring (#3587) (#3642)
1 parent 59ef9d2 commit bf58b35

2 files changed

Lines changed: 73 additions & 0 deletions

File tree

xrspatial/cost_distance.py

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1226,6 +1226,12 @@ def cost_distance(
12261226
to reach the nearest target pixel, where traversal cost along each
12271227
edge equals ``geometric_distance * mean_friction_of_endpoints``.
12281228
1229+
Cost-distance supports NumPy, CuPy, Dask with NumPy, and Dask with CuPy
1230+
backed xarray DataArray. The return values of `cost_distance`
1231+
are of the same type as the input type: a NumPy-backed input gives a
1232+
NumPy-backed result, a CuPy-backed input gives a CuPy-backed result,
1233+
and a Dask-backed input gives a Dask-backed result.
1234+
12291235
Parameters
12301236
----------
12311237
raster : xr.DataArray or xr.Dataset
@@ -1254,6 +1260,38 @@ def cost_distance(
12541260
xr.DataArray or xr.Dataset
12551261
2-D array of accumulated cost-distance values (float32).
12561262
Source pixels have cost 0. Unreachable pixels are NaN.
1263+
1264+
Examples
1265+
--------
1266+
.. sourcecode:: python
1267+
1268+
>>> import numpy as np
1269+
>>> import xarray as xr
1270+
>>> source = np.array([
1271+
... [0., 0., 0.],
1272+
... [0., 1., 0.],
1273+
... [0., 0., 0.],
1274+
... ])
1275+
>>> friction = np.ones((3, 3))
1276+
>>> n, m = source.shape
1277+
>>> raster = xr.DataArray(source, dims=['y', 'x'], name='raster')
1278+
>>> raster['y'] = np.arange(n)[::-1]
1279+
>>> raster['x'] = np.arange(m)
1280+
>>> friction_da = xr.DataArray(
1281+
... friction, dims=['y', 'x'], name='friction')
1282+
>>> friction_da['y'] = np.arange(n)[::-1]
1283+
>>> friction_da['x'] = np.arange(m)
1284+
1285+
>>> from xrspatial import cost_distance
1286+
>>> result = cost_distance(raster, friction_da)
1287+
>>> result
1288+
<xarray.DataArray (y: 3, x: 3)>
1289+
array([[1.4142135, 1. , 1.4142135],
1290+
[1. , 0. , 1. ],
1291+
[1.4142135, 1. , 1.4142135]], dtype=float32)
1292+
Coordinates:
1293+
* y (y) int64 2 1 0
1294+
* x (x) int64 0 1 2
12571295
"""
12581296
# --- validation ---
12591297
_validate_raster(raster, func_name='cost_distance', name='raster')

xrspatial/tests/test_cost_distance.py

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1276,3 +1276,38 @@ def test_iterative_heap_no_overflow_variable_friction(connectivity):
12761276
raster, friction, connectivity=connectivity))
12771277
expected = _reference_dijkstra(source, friction_data, connectivity)
12781278
np.testing.assert_allclose(out, expected, equal_nan=True, atol=1e-3)
1279+
1280+
1281+
def test_docstring_states_all_backends():
1282+
doc = cost_distance.__doc__
1283+
assert "CuPy" in doc
1284+
assert "Dask with CuPy" in doc
1285+
assert "support NumPy backed, and Dask with NumPy backed" not in doc
1286+
1287+
1288+
def test_docstring_example_matches_output():
1289+
source = np.array([
1290+
[0., 0., 0.],
1291+
[0., 1., 0.],
1292+
[0., 0., 0.],
1293+
])
1294+
friction = np.ones((3, 3))
1295+
n, m = source.shape
1296+
raster = xr.DataArray(source, dims=['y', 'x'], name='raster')
1297+
raster['y'] = np.arange(n)[::-1]
1298+
raster['x'] = np.arange(m)
1299+
friction_da = xr.DataArray(
1300+
friction, dims=['y', 'x'], name='friction')
1301+
friction_da['y'] = np.arange(n)[::-1]
1302+
friction_da['x'] = np.arange(m)
1303+
1304+
result = cost_distance(raster, friction_da)
1305+
out = _compute(result)
1306+
1307+
expected = np.array([
1308+
[np.sqrt(2), 1., np.sqrt(2)],
1309+
[1., 0., 1.],
1310+
[np.sqrt(2), 1., np.sqrt(2)],
1311+
], dtype=np.float32)
1312+
np.testing.assert_allclose(out, expected, atol=1e-5)
1313+
assert result.dtype == np.float32

0 commit comments

Comments
 (0)