18 changes: 18 additions & 0 deletions src/core/raster/qgsrasterblock.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -410,6 +410,24 @@ bool QgsRasterBlock::convert( QgsRasterBlock::DataType destDataType )
return true;
}

void QgsRasterBlock::applyNodataValues( const QList<Range>& rangeList )
{
if ( rangeList.isEmpty() )
{
return;
}

size_t size = mWidth * mHeight;
for ( size_t i = 0; i < size; ++i )
{
double val = value( i );
if ( valueInRange( val, rangeList ) )
{
setValue( i, mNoDataValue );
}
}
}

QImage QgsRasterBlock::image() const
{
if ( mImage )
Expand Down
2 changes: 2 additions & 0 deletions src/core/raster/qgsrasterblock.h
Original file line number Diff line number Diff line change
Expand Up @@ -304,6 +304,8 @@ class CORE_EXPORT QgsRasterBlock

inline static void writeValue( void *data, QgsRasterBlock::DataType type, size_t index, double value );

void applyNodataValues( const QList<Range>& rangeList );

private:

static QImage::Format imageFormat( QgsRasterBlock::DataType theDataType );
Expand Down
17 changes: 1 addition & 16 deletions src/core/raster/qgsrasterdataprovider.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -194,22 +194,7 @@ QgsRasterBlock * QgsRasterDataProvider::block( int theBandNo, QgsRectangle cons

// apply user no data values
// TODO: there are other readBlock methods where no data are not applied
QList<QgsRasterBlock::Range> myNoDataRangeList = userNoDataValue( theBandNo );
if ( !myNoDataRangeList.isEmpty() )
{
double myNoDataValue = noDataValue( theBandNo );
size_t size = theWidth * theHeight;
for ( size_t i = 0; i < size; i++ )
{
double value = block->value( i );

if ( QgsRasterBlock::valueInRange( value, myNoDataRangeList ) )
{
block->setValue( i, myNoDataValue );
}
}
}

block->applyNodataValues( userNoDataValue( theBandNo ) );
return block;
}

Expand Down
13 changes: 13 additions & 0 deletions src/providers/gdal/qgsgdalprovider.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -363,6 +363,19 @@ QImage* QgsGdalProvider::draw( QgsRectangle const & viewExtent, int pixelWidth,
return image;
}

QgsRasterBlock* QgsGdalProvider::block( int theBandNo, const QgsRectangle &theExtent, int theWidth, int theHeight )
{
QgsRasterBlock *block = new QgsRasterBlock( dataType( theBandNo ), theWidth, theHeight, noDataValue( theBandNo ) );

if ( block->isEmpty() )
{
return block;
}

readBlock( theBandNo, theExtent, theWidth, theHeight, block->data() );
block->applyNodataValues( userNoDataValue( theBandNo ) );
return block;
}

void QgsGdalProvider::readBlock( int theBandNo, int xBlock, int yBlock, void *block )
{
Expand Down
2 changes: 2 additions & 0 deletions src/providers/gdal/qgsgdalprovider.h
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,8 @@ class QgsGdalProvider : public QgsRasterDataProvider, QgsGdalProviderBase
int xSize() const;
int ySize() const;

/**Reimplemented from QgsRasterDataProvider to bypass second resampling (more efficient for local file based sources)*/
QgsRasterBlock *block( int theBandNo, const QgsRectangle &theExtent, int theWidth, int theHeight );

void readBlock( int bandNo, int xBlock, int yBlock, void *data );
void readBlock( int bandNo, QgsRectangle const & viewExtent, int width, int height, void *data );
Expand Down