Skip to content

viewshed: ValueError 'node not found' on NaN input (CPU sweep) #2792

@brendancol

Description

@brendancol

Description

The CPU sweep path of viewshed crashes on certain NaN/nodata input positions. A single NaN cell placed on the observer's row to the right of the observer raises ValueError: node not found.

Reproduction:

import numpy as np, xarray as xa
from xrspatial import viewshed

arr = np.full((5, 5), 2.0)
arr[2, 4] = np.nan        # observer is at (2, 2)
xs = np.arange(5.0); ys = np.arange(5.0)
raster = xa.DataArray(arr, coords=dict(x=xs, y=ys), dims=["y", "x"])
viewshed(raster, x=2.0, y=2.0, observer_elev=5)   # ValueError: node not found

Root cause

_init_event_list generates the three sweep events (ENTER / CENTER / EXIT) for every cell, including NaN cells. There is no nodata check, despite the comment claiming the code path is "not NODATA". When the sweep processes a NaN cell, the ENTER event inserts a node whose key is computed from the NaN elevation, and the matching EXIT event then fails to find that node in the red-black status tree, raising ValueError: node not found from _delete_from_tree.

The initial sweepline insertion loop already guards with if not np.isnan(...), so the asymmetry lives in event generation.

Proposed policy

Skip invalid cells in event generation: do not create ENTER/CENTER/EXIT events for a NaN cell, so it is never inserted into or deleted from the status tree. The visibility grid is already initialized to INVISIBLE, so a skipped NaN cell stays INVISIBLE. This applies across the numpy, dask, and cupy-CPU-fallback paths, which all route through the CPU sweep.

A strict xfail at xrspatial/tests/test_viewshed.py::test_viewshed_nan_input_crashing_position already documents this crash; the fix flips it into a passing test.

Note: supersedes closed issue #2693, which tracked the same crash.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingseverity:mediumSweep finding: MEDIUM

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions