Description
contours() puts NaN coordinates into its output when the input raster has a +inf or -inf cell and you ask for a finite level near that cell.
The marching-squares kernel skips quads with a NaN corner using if tl != tl or tr != tr or bl != bl or br != br: continue (xrspatial/contour.py:67). That catches NaN but not infinity, since inf != inf is False. So a quad with an infinite corner is processed: the corner classifies as above any finite level via >=, and the edge interpolation t = (level - tl) / (tr - tl) either divides by an infinite denominator or computes inf - inf, which produces NaN in the emitted segment.
Reproduce
import numpy as np
from xrspatial.contour import contours
from xrspatial.tests.general_checks import create_test_raster
data = np.array([
[0., 0., 0., 0., 0.],
[0., 1., 1., 1., 0.],
[0., 1., np.inf, 1., 0.],
[0., 1., 1., 1., 0.],
[0., 0., 0., 0., 0.],
], dtype=np.float64)
agg = create_test_raster(data, backend='numpy')
result = contours(agg, levels=[1.5])
for level, coords in result:
print(coords)
The output contains NaN rows such as [nan, 1.0] and [1.0, nan].
Expected
A quad touching an infinite corner should be skipped the same way a NaN quad is, so the output never contains non-finite coordinates. The skip guard at line 67 needs to reject inf as well as NaN (e.g. a finiteness check on the four corners).
Notes
Found during a test-coverage audit of the contour module. A separate test-only PR adds an xfail test documenting this behavior; this issue tracks the source fix.
Description
contours()puts NaN coordinates into its output when the input raster has a+infor-infcell and you ask for a finite level near that cell.The marching-squares kernel skips quads with a NaN corner using
if tl != tl or tr != tr or bl != bl or br != br: continue(xrspatial/contour.py:67). That catches NaN but not infinity, sinceinf != infisFalse. So a quad with an infinite corner is processed: the corner classifies as above any finite level via>=, and the edge interpolationt = (level - tl) / (tr - tl)either divides by an infinite denominator or computesinf - inf, which produces NaN in the emitted segment.Reproduce
The output contains NaN rows such as
[nan, 1.0]and[1.0, nan].Expected
A quad touching an infinite corner should be skipped the same way a NaN quad is, so the output never contains non-finite coordinates. The skip guard at line 67 needs to reject inf as well as NaN (e.g. a finiteness check on the four corners).
Notes
Found during a test-coverage audit of the contour module. A separate test-only PR adds an xfail test documenting this behavior; this issue tracks the source fix.