Expose multi_stop_search on the .xrs DataArray and Dataset accessors#3564
Merged
Conversation
brendancol
commented
Jun 27, 2026
brendancol
left a comment
Contributor
Author
There was a problem hiding this comment.
PR Review: Expose multi_stop_search on the .xrs DataArray accessor
Blockers (must fix before merge)
None.
Suggestions (should fix, not blocking)
None.
Nits (optional improvements)
None.
What looks good
- The accessor method (
xrspatial/accessor.py:1213) mirrors the siblinga_star_searchdelegate:waypointspositional, the rest forwarded as**kwargs. The lazyfrom .pathfinding importmatches every other method in the class, so it costs nothing at import time. - DataArray-only placement is right.
a_star_searchis also absent from the Dataset accessor, andmulti_stop_searchis a DataArray operation (it builds a single cost surface). - The tests check the real contract: accessor output is
assert_identicalto the direct call, including theoptimize_order=Truekeyword path. The newtest_da_a_star_searchcloses a gap, since the sibling previously had only a presence check. - The method sits under the existing
# ---- Pathfinding ----banner, so it appears in the accessor repr and passes the category-banner guard test. - The docs RST gets a matching entry, and the section underline length is correct, so Sphinx stays quiet.
Notes
- No README change needed.
multi_stop_searchis already in the feature matrix and exported from__init__. No new algorithm, so no benchmark or user-guide notebook. - Backend coverage is inherited from
multi_stop_searchunchanged (numpy, cupy, dask+numpy, dask+cupy).
Checklist
- Algorithm matches reference/paper (no algorithm change; pure delegation)
- All implemented backends produce consistent results (inherited)
- NaN handling is correct (unchanged)
- Edge cases are covered by tests (delegation parity tested)
- Dask chunk boundaries handled correctly (unchanged)
- No premature materialization or unnecessary copies
- Benchmark exists or is not needed (not needed)
- README feature matrix updated (already present)
- Docstrings present and accurate (delegate inherits documentation)
brendancol
commented
Jun 27, 2026
brendancol
left a comment
Contributor
Author
There was a problem hiding this comment.
PR Review (follow-up): Dataset accessor support for multi_stop_search
Blockers (must fix before merge)
None.
Suggestions (should fix, not blocking)
None.
Nits (optional improvements)
None.
What looks good
@supports_datasetonmulti_stop_search(xrspatial/pathfinding.py:1328) is the same mechanismcost_distanceandproximityalready use, so the Dataset accessor delegate (xrspatial/accessor.py:1952) forwards directly with no special-casing.- The decorator only injects
namewhen the wrapped function has anameparameter.multi_stop_searchhas none, so the wrapper callsfunc(da, waypoints, **kwargs)per variable without passing an unsupported kwarg. Confirmednameis absent from the signature. - The DataArray path keeps its old behavior: the wrapper passes a DataArray straight through. The 51 pathfinding tests still pass, so the decorator did not regress single-array routing.
test_ds_multi_stop_searchchecks the real contract:assert_identicalagainst the directmulti_stop_search(ds, ...)call, plus a per-variabledata_varsassertion. Both accessor presence lists are updated.- Docstring extended to
xr.DataArray or xr.Datasetin Parameters and Returns, matching howcost_distancedocuments the same decorator.
Notes
a_star_searchstays DataArray-only by design. It is not@supports_datasetand was out of scope here. The asymmetry is intentional and called out in the PR body.- The unused import
has_dask_array(pathfinding.py:21) is already on main, unrelated to this change, left as-is. - Dataset application iterates every data variable, so a Dataset carrying a non-2D variable would raise on that variable. That matches the existing behavior of
cost_distance/proximityon Datasets, so it is not a new sharp edge.
Checklist
- Algorithm matches reference/paper (no algorithm change; delegation + decorator)
- All implemented backends produce consistent results (inherited)
- NaN handling is correct (unchanged)
- Edge cases are covered by tests (DataArray and Dataset parity tested)
- Dask chunk boundaries handled correctly (unchanged)
- No premature materialization or unnecessary copies
- Benchmark exists or is not needed (thin delegation; not needed)
- README feature matrix updated (already present)
- Docstrings present and accurate (updated for Dataset input)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #3563
Exposes
multi_stop_searchon the.xrsaccessor, alongside the existinga_star_searchmethod, so multi-waypoint routing is reachable asraster.xrs.multi_stop_search(waypoints, ...)without dropping to the module-level function.XrsSpatialDataArrayAccessor.waypointsis positional, everything else forwards as keyword args.multi_stop_searchis decorated with@supports_dataset, matchingcost_distanceandproximity, sods.xrs.multi_stop_search(...)routes each data variable through the same waypoints and returns a Dataset of per-variable results.multi_stop_searchto the pathfinding reference docs, which previously listed onlya_star_search.a_star_searchstays DataArray-only (it is not@supports_datasetand was not requested here).Backend coverage: the accessor is a thin delegate, so backend support is whatever
multi_stop_searchalready provides (numpy, cupy, dask+numpy, dask+cupy). No change to the routing implementation.Test plan:
test_da_multi_stop_search: DataArray accessor matches the direct calltest_da_multi_stop_search_kwargs: keyword forwarding (optimize_order=True)test_ds_multi_stop_search: Dataset accessor matches the direct call, per-variabletest_da_a_star_search: functional parity test for the sibling methodtest_accessor.py(90) andtest_pathfinding.py(51) pass