Skip to content

Python bindings: Add Dataset.ReadAsMaskedArray #12172

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

dbaston
Copy link
Member

@dbaston dbaston commented Apr 18, 2025

Resolves #12005

xoff=xoff, yoff=yoff,
win_xsize=xsize, win_ysize=ysize,
buf_xsize=buf_xsize, buf_ysize=buf_ysize,
resample_alg=gdalconst.GRIORA_Mode) != 255
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps indicate in the doc that when downsampling the mask resampling algorithm is Mode (ie majority) ?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Documented this and also changed behavior of Band.ReadAsMaskedArray to match.

@dbaston dbaston marked this pull request as draft April 18, 2025 16:10
@dbaston
Copy link
Member Author

dbaston commented Apr 18, 2025

Hmm, I'm not sure how my tests were passing locally before. Right now I'm puzzled by

(Pdb) band.GetMaskBand().ReadAsArray()
array([[  0, 255],
       [  0,   0]], dtype=uint8)
(Pdb) band.GetMaskBand().ReadAsArray(buf_xsize=1, buf_ysize=1, resample_alg=gdal.GRIORA_Mode)
array([[255]], dtype=uint8)

@rouault
Copy link
Member

rouault commented Apr 18, 2025

@dbaston
Copy link
Member Author

dbaston commented Apr 18, 2025

I don't think GRA_Mode downscaling works for NoData mask bands. If I'm following the code right, it performs a downscaled read from the parent band (using GRA_Mode, and excluding NoData pixels) and then sets all valid pixels to 255. Which is different from performing a full resolution read on the parent, setting valid pixels to 255, and then downscaling.

@rouault
Copy link
Member

rouault commented Apr 19, 2025

I don't think GRA_Mode downscaling works for NoData mask bands.

yes the logic I pointed out where the mask band of the mask band is the mask band itself should probably be modified for Mode, and just get the GetMaskBand() of the mask band, which would be a AllValid mask band

@dbaston
Copy link
Member Author

dbaston commented Apr 21, 2025

I believe this is due to: https://github.com/OSGeo/gdal/blob/master/gcore/overview.cpp#L4453 / https://github.com/OSGeo/gdal/blob/master/gcore/overview.cpp#L5798

I don't see either of these lines hit in this case. The issue I see is

eErr = m_poParent->RasterIO(
GF_Read, nXOff, nYOff, nXSize, nYSize, pTemp, nBufXSize, nBufYSize,
eWrkDT, nWrkDTSize, static_cast<GSpacing>(nBufXSize) * nWrkDTSize,
psExtraArg);

where a downscaled read is performed from the parent band, and the result reclassified to 0/255. To get a correct result for GRIORA_Mode, I think we need to read from the parent band at full resolution, reclassify, and then downscale.

All this said, the current behavior of GRIORA_Mode is essentially GRIORA_Max and not necessarily undesirable as a default.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Python: Add Dataset.ReadAsMaskedArray
2 participants