Skip to content

Commit

Permalink
GDALRasterWrapper: Avoid reading nodata mask if unnecessary
Browse files Browse the repository at this point in the history
  • Loading branch information
dbaston committed Aug 22, 2024
1 parent c825d82 commit 1562ab8
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 2 deletions.
6 changes: 5 additions & 1 deletion src/gdal_raster_wrapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -169,11 +169,15 @@ GDALRasterWrapper::read_box(const Box& box)
throw std::runtime_error("Error reading from raster.");
}

bool mask_needed = GDALGetMaskFlags(m_band) != GMF_ALL_VALID && GDALGetMaskFlags(m_band) != GMF_NODATA;

if (has_scale || has_offset) {
apply_scale_and_offset(static_cast<double*>(buffer), cropped_grid.size(), scale, offset);
mask_needed = mask_needed || GDALGetMaskFlags(m_band) == GMF_NODATA;
}

if (GDALRasterBandH mask = GDALGetMaskBand(m_band)) {
if (mask_needed) {
GDALRasterBandH mask = GDALGetMaskBand(m_band);
auto mask_rast = make_raster<std::int8_t>(cropped_grid);
buffer = mask_rast->data().data();

Expand Down
20 changes: 19 additions & 1 deletion test/test_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ def writer(data, *, mask=None, nodata=None, scale=None, offset=None):
if offset:
ds.GetRasterBand(i + 1).SetOffset(offset)
if mask is not None:
ds.GetRasterBand(i + 1).CreateMaskBand(gdal.GMF_ALL_VALID)
ds.GetRasterBand(i + 1).CreateMaskBand(gdal.GMF_PER_DATASET)
mb = ds.GetRasterBand(i + 1).GetMaskBand()
assert mb.WriteArray(mask) == gdal.CE_None
del mb
Expand Down Expand Up @@ -606,6 +606,24 @@ def test_scale_offset(run, write_raster, write_features):
assert float(rows[0]["d2m_values"]) == pytest.approx(278.2057, rel=1e-3)


def test_scale_offset_nodata(run, write_raster, write_features):

data = np.array([[1, 2, 3], [-999, -999, -999], [4, 5, 6]], dtype=np.int32)

rows = run(
polygons=write_features(
{"id": 1, "geom": "POLYGON ((0.5 0.5, 2.5 0.5, 2.5 2.5, 0.5 2.5, 0.5 0.5))"}
),
fid="id",
raster=f"{write_raster(data, scale=2, offset=-1, nodata=-999)}",
stat=["values"],
nested_output=True,
)

values = np.fromstring(rows[0]["values"].strip("[").strip("]"), sep=",")
np.testing.assert_array_equal(values, [1, 3, 5, 7, 9, 11])


def test_id_rename(run, write_raster, write_features):

data = np.array([[1, 2, 3, 4], [1, 2, 2, 5], [3, 3, 3, 2]], np.int16)
Expand Down

0 comments on commit 1562ab8

Please sign in to comment.