Skip to content

Fix read_vrt dropping SimpleSource <NODATA>0</NODATA> (#1655)#1663

Merged
brendancol merged 1 commit into
mainfrom
deep-sweep-accuracy-geotiff-2026-05-12
May 12, 2026
Merged

Fix read_vrt dropping SimpleSource <NODATA>0</NODATA> (#1655)#1663
brendancol merged 1 commit into
mainfrom
deep-sweep-accuracy-geotiff-2026-05-12

Conversation

@brendancol
Copy link
Copy Markdown
Contributor

Summary

Closes #1655.

xrspatial.geotiff._vrt.read_vrt silently treated <NODATA>0</NODATA> on a SimpleSource as if the element were absent. The per-source nodata fallback used src.nodata or nodata; Python evaluates 0.0 or <anything> to <anything> because 0.0 is falsy. The in-code comment described the behaviour as "backward compatibility" but the result is silent data corruption on VRTs that mosaic sources using 0 as a sentinel (a common remote-sensing convention for unsigned imagery).

Switch to an explicit is not None check so a legitimate zero sentinel survives the fallback. The behaviour now matches the per-source nodata semantics that GDAL applies.

Test plan

  • New regression tests in test_vrt_source_nodata_zero_1655.py (5 tests): source NODATA=0 with no band fallback, integer XML literal <NODATA>0</NODATA>, non-zero unchanged, band-level <NoDataValue>0</NoDataValue> still honoured, per-source NODATA precedence over a different band sentinel.
  • All 100 existing vrt-related geotiff tests still pass.
  • Full geotiff suite: 1475 passed (3 pre-existing matplotlib palette failures unrelated to this change).

Notes

Found via /deep-sweep accuracy pass 19 on the geotiff module. State file updated in the same commit.

The per-source nodata fallback used `src.nodata or nodata`, and Python
treats `0.0` as falsy. A SimpleSource that declared `<NODATA>0</NODATA>`
silently picked up the band-level `<NoDataValue>` (or `None` when none
was set), so pixels equal to 0.0 in the source file survived as valid
data instead of being masked to NaN. The in-code comment described the
behaviour as "backward compatibility" but the result is silent data
corruption on VRTs that mosaic sources using 0 as a sentinel (a common
remote-sensing convention).

Switch to an explicit `is not None` check so a legitimate zero sentinel
survives the fallback.

Add `test_vrt_source_nodata_zero_1655.py` covering five cases: source
NODATA=0 with no band fallback, integer XML literal, non-zero unchanged,
band-level NoDataValue=0 still honoured when no per-source NODATA is
set, and per-source precedence over a different band-level sentinel.
@github-actions github-actions Bot added the performance PR touches performance-sensitive code label May 12, 2026
@brendancol brendancol merged commit 2d0e067 into main May 12, 2026
12 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

performance PR touches performance-sensitive code

Projects

None yet

Development

Successfully merging this pull request may close these issues.

geotiff: read_vrt silently drops SimpleSource <NODATA>0</NODATA>

1 participant