@@ -91,7 +91,7 @@ def test_dataarray_accessor_has_expected_methods(elevation):
9191 'morph_erode' , 'morph_dilate' , 'morph_opening' , 'morph_closing' ,
9292 'morph_gradient' , 'morph_white_tophat' , 'morph_black_tophat' ,
9393 'proximity' , 'allocation' , 'direction' , 'cost_distance' ,
94- 'a_star_search' ,
94+ 'a_star_search' , 'multi_stop_search' ,
9595 'zonal_stats' , 'zonal_apply' , 'zonal_crosstab' , 'crop' , 'trim' ,
9696 'regions' ,
9797 'generate_terrain' , 'perlin' ,
@@ -118,6 +118,7 @@ def test_dataset_accessor_has_expected_methods():
118118 'morph_erode' , 'morph_dilate' , 'morph_opening' , 'morph_closing' ,
119119 'morph_gradient' , 'morph_white_tophat' , 'morph_black_tophat' ,
120120 'proximity' , 'allocation' , 'direction' , 'cost_distance' ,
121+ 'multi_stop_search' ,
121122 'ndvi' , 'evi' , 'arvi' , 'savi' , 'nbr' , 'sipi' ,
122123 'rasterize' ,
123124 'validate' ,
@@ -272,6 +273,45 @@ def test_ds_morph_gradient(elevation):
272273 xr .testing .assert_identical (result , expected )
273274
274275
276+ # ---------------------------------------------------------------------------
277+ # 4c. DataArray pathfinding — accessor matches direct call
278+ # ---------------------------------------------------------------------------
279+
280+ def test_da_a_star_search (elevation ):
281+ from xrspatial .pathfinding import a_star_search
282+ start , goal = (0 , 0 ), (9 , 9 )
283+ expected = a_star_search (elevation , start , goal )
284+ result = elevation .xrs .a_star_search (start , goal )
285+ xr .testing .assert_identical (result , expected )
286+
287+
288+ def test_da_multi_stop_search (elevation ):
289+ from xrspatial .pathfinding import multi_stop_search
290+ waypoints = [(0 , 0 ), (5 , 5 ), (9 , 9 )]
291+ expected = multi_stop_search (elevation , waypoints )
292+ result = elevation .xrs .multi_stop_search (waypoints )
293+ xr .testing .assert_identical (result , expected )
294+
295+
296+ def test_da_multi_stop_search_kwargs (elevation ):
297+ from xrspatial .pathfinding import multi_stop_search
298+ waypoints = [(0 , 0 ), (9 , 0 ), (9 , 9 )]
299+ expected = multi_stop_search (elevation , waypoints , optimize_order = True )
300+ result = elevation .xrs .multi_stop_search (waypoints , optimize_order = True )
301+ xr .testing .assert_identical (result , expected )
302+
303+
304+ def test_ds_multi_stop_search (elevation ):
305+ from xrspatial .pathfinding import multi_stop_search
306+ ds = xr .Dataset ({'a' : elevation , 'b' : elevation + 100 })
307+ waypoints = [(0 , 0 ), (5 , 5 ), (9 , 9 )]
308+ expected = multi_stop_search (ds , waypoints )
309+ result = ds .xrs .multi_stop_search (waypoints )
310+ xr .testing .assert_identical (result , expected )
311+ # supports_dataset routes each variable through its own surface
312+ assert set (result .data_vars ) == {'a' , 'b' }
313+
314+
275315# ---------------------------------------------------------------------------
276316# 5. Dataset single-input — accessor matches direct call
277317# ---------------------------------------------------------------------------
0 commit comments