Skip to content

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

@brendancol

Description

@brendancol

Description

viewshed on a numpy raster crashes with ValueError: node not found when a NaN (nodata) cell sits at certain positions relative to the observer. The CPU sweep has explicit NaN handling in _calc_event_elev (it falls back to the center elevation when any of the four bilinear-interpolation neighbours is NaN), but the handling is incomplete: a NaN elevation can still produce a NaN event angle/key, and when the sweep later tries to remove that event from the red-black status tree, _delete_from_tree searches for a node that was never inserted and raises.

How to reproduce

import numpy as np
import xarray as xr
from xrspatial import viewshed

arr = np.full((5, 5), 2.0)
arr[2, 4] = np.nan          # NaN cell on the observer's row, to the right
r = xr.DataArray(arr, coords=dict(x=np.arange(5.0), y=np.arange(5.0)), dims=["y", "x"])
viewshed(r, x=2.0, y=2.0, observer_elev=5)   # ValueError: node not found

The failure is position-dependent. With the same 5x5 raster and observer at (2, 2):

  • NaN at (1, 1), (0, 0), (4, 4): runs fine, no NaN propagated into the output.
  • NaN at (2, 4): raises ValueError: node not found.

Traceback

  File ".../xrspatial/viewshed.py", line 1715, in viewshed
    return _viewshed_cpu(raster, x, y, observer_elev, target_elev)
  File ".../xrspatial/viewshed.py", line 1595, in _viewshed_cpu
    viewshed_img = _viewshed_cpu_sweep(...)
  File ".../xrspatial/viewshed.py", line 562, in _delete_from_tree
    raise ValueError("node not found")
ValueError: node not found

Expected behavior

A NaN/nodata cell should be treated as nodata. The GRASS r.viewshed algorithm this is ported from skips nodata cells when building events. The function should either skip NaN cells when generating events or mark them INVISIBLE/NaN in the output, not crash. Behaviour should not depend on where the NaN sits.

Notes

Found during the viewshed test-coverage sweep. A test that documents the working NaN positions plus an xfail marking the crashing position is being added in a separate test-only PR; this issue tracks the underlying source fix.

Environment

  • xarray-spatial: current main
  • numpy backend (CPU sweep path)

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions