Describe the bug
viewshed() does not validate its scalar parameters before dispatching to a backend. Passing max_distance=-1 falls through into an empty spatial window and raises a cryptic error from deep inside the dask path:
ValueError: zero-size array to reduction operation minimum which has no identity
The same loose validation applies to observer_elev and target_elev: NaN, inf, or non-numeric values are not caught up front and produce confusing downstream errors instead of a clear message.
Expected behavior
The public viewshed() entry point should validate its scalar parameters before any backend dispatch:
observer_elev and target_elev must be finite numeric scalars (reject NaN, inf, and non-numeric types) with a ValueError that names the offending parameter.
max_distance must be a finite numeric scalar and >= 0. A negative value such as -1 should raise a clear message like max_distance must be >= 0, got -1.
Additional context
Validation lives before dispatch, so a single guard covers all four backends (numpy, cupy, dask+numpy, dask+cupy). This matches the existing scalar-validation style in sibling modules such as curvature.py (the cell-size finite check).
Describe the bug
viewshed()does not validate its scalar parameters before dispatching to a backend. Passingmax_distance=-1falls through into an empty spatial window and raises a cryptic error from deep inside the dask path:The same loose validation applies to
observer_elevandtarget_elev: NaN, inf, or non-numeric values are not caught up front and produce confusing downstream errors instead of a clear message.Expected behavior
The public
viewshed()entry point should validate its scalar parameters before any backend dispatch:observer_elevandtarget_elevmust be finite numeric scalars (reject NaN, inf, and non-numeric types) with a ValueError that names the offending parameter.max_distancemust be a finite numeric scalar and>= 0. A negative value such as-1should raise a clear message likemax_distance must be >= 0, got -1.Additional context
Validation lives before dispatch, so a single guard covers all four backends (numpy, cupy, dask+numpy, dask+cupy). This matches the existing scalar-validation style in sibling modules such as
curvature.py(the cell-size finite check).