Skip to content

Commit

Permalink
Flip sequential calls to QgsRasterBlock::isNoData/value to single
Browse files Browse the repository at this point in the history
unified call

Because... speed!
  • Loading branch information
nyalldawson committed Jan 22, 2019
1 parent ddd357c commit fc99669
Show file tree
Hide file tree
Showing 12 changed files with 52 additions and 36 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@ QVariantMap QgsRasterLayerUniqueValuesReportAlgorithm::processAlgorithm( const Q
int iterTop = 0;
int iterCols = 0;
int iterRows = 0;
bool isNoData = false;
std::unique_ptr< QgsRasterBlock > rasterBlock;
while ( iter.readNextRasterPart( mBand, iterCols, iterRows, rasterBlock, iterLeft, iterTop ) )
{
Expand All @@ -146,13 +147,13 @@ QVariantMap QgsRasterLayerUniqueValuesReportAlgorithm::processAlgorithm( const Q
break;
for ( int column = 0; column < iterCols; column++ )
{
if ( mHasNoDataValue && rasterBlock->isNoData( row, column ) )
double value = rasterBlock->valueAndNoData( row, column, isNoData );
if ( mHasNoDataValue && isNoData )
{
noDataCount += 1;
noDataCount++;
}
else
{
double value = rasterBlock->value( row, column );
uniqueValues[ value ]++;
}
}
Expand Down
15 changes: 9 additions & 6 deletions src/analysis/processing/qgsalgorithmrasterzonalstats.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,7 @@ QVariantMap QgsRasterLayerZonalStatsAlgorithm::processAlgorithm( const QVariantM
QgsRectangle blockExtent;
std::unique_ptr< QgsRasterBlock > rasterBlock;
std::unique_ptr< QgsRasterBlock > zonesRasterBlock;
bool isNoData = false;
while ( true )
{
if ( mRefLayer == Source )
Expand Down Expand Up @@ -249,17 +250,19 @@ QVariantMap QgsRasterLayerZonalStatsAlgorithm::processAlgorithm( const QVariantM

for ( int column = 0; column < iterCols; column++ )
{
if ( ( mHasNoDataValue && rasterBlock->isNoData( row, column ) ) ||
( mZonesHasNoDataValue && zonesRasterBlock->isNoData( row, column ) ) )
double value = rasterBlock->valueAndNoData( row, column, isNoData );
if ( mHasNoDataValue && isNoData )
{
noDataCount += 1;
continue;
}
else
double zone = zonesRasterBlock->valueAndNoData( row, column, isNoData );
if ( mZonesHasNoDataValue && isNoData )
{
double value = rasterBlock->value( row, column );
double zone = zonesRasterBlock->value( row, column );
zoneStats[ zone ].s.addValue( value );
noDataCount += 1;
continue;
}
zoneStats[ zone ].s.addValue( value );
}
}
}
Expand Down
5 changes: 3 additions & 2 deletions src/analysis/processing/qgsalgorithmvectorize.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ QVariantMap QgsVectorizeAlgorithmBase::processAlgorithm( const QVariantMap &para
int iterRows = 0;
std::unique_ptr< QgsRasterBlock > rasterBlock;
QgsRectangle blockExtent;
bool isNoData = false;
while ( iter.readNextRasterPart( mBand, iterCols, iterRows, rasterBlock, iterLeft, iterTop, &blockExtent ) )
{
if ( feedback )
Expand All @@ -111,10 +112,10 @@ QVariantMap QgsVectorizeAlgorithmBase::processAlgorithm( const QVariantMap &para

for ( int column = 0; column < iterCols; column++ )
{
if ( !rasterBlock->isNoData( row, column ) )
const double value = rasterBlock->valueAndNoData( row, column, isNoData );
if ( !isNoData )
{
QgsGeometry pixelRectGeometry = createGeometryForPixel( currentX, currentY, mRasterUnitsPerPixelX, mRasterUnitsPerPixelY );
double value = rasterBlock->value( row, column );

QgsFeature f;
f.setGeometry( pixelRectGeometry );
Expand Down
10 changes: 6 additions & 4 deletions src/analysis/processing/qgsrasteranalysisutils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ void QgsRasterAnalysisUtils::statisticsFromMiddlePointTest( QgsRasterInterface *
int iterCols = 0;
int iterRows = 0;
QgsRectangle blockExtent;
bool isNoData = false;
while ( iter.readNextRasterPart( rasterBand, iterCols, iterRows, block, iterLeft, iterTop, &blockExtent ) )
{
double cellCenterY = blockExtent.yMaximum() - 0.5 * cellSizeY;
Expand All @@ -83,8 +84,8 @@ void QgsRasterAnalysisUtils::statisticsFromMiddlePointTest( QgsRasterInterface *
double cellCenterX = blockExtent.xMinimum() + 0.5 * cellSizeX;
for ( int col = 0; col < iterCols; ++col )
{
double pixelValue = block->value( row, col );
if ( validPixel( pixelValue ) && ( !skipNodata || !block->isNoData( row, col ) ) )
const double pixelValue = block->valueAndNoData( row, col, isNoData );
if ( validPixel( pixelValue ) && ( !skipNodata || !isNoData ) )
{
QgsPoint cellCenter( cellCenterX, cellCenterY );
if ( polyEngine->contains( &cellCenter ) )
Expand Down Expand Up @@ -124,6 +125,7 @@ void QgsRasterAnalysisUtils::statisticsFromPreciseIntersection( QgsRasterInterfa
int iterCols = 0;
int iterRows = 0;
QgsRectangle blockExtent;
bool isNoData = false;
while ( iter.readNextRasterPart( rasterBand, iterCols, iterRows, block, iterLeft, iterTop, &blockExtent ) )
{
double currentY = blockExtent.yMaximum() - 0.5 * cellSizeY;
Expand All @@ -132,8 +134,8 @@ void QgsRasterAnalysisUtils::statisticsFromPreciseIntersection( QgsRasterInterfa
double currentX = blockExtent.xMinimum() + 0.5 * cellSizeX;
for ( int col = 0; col < iterCols; ++col )
{
double pixelValue = block->value( row, col );
if ( validPixel( pixelValue ) && ( !skipNodata || !block->isNoData( row, col ) ) )
const double pixelValue = block->valueAndNoData( row, col, isNoData );
if ( validPixel( pixelValue ) && ( !skipNodata || !isNoData ) )
{
pixelRectGeometry = QgsGeometry::fromRect( QgsRectangle( currentX - hCellSizeX, currentY - hCellSizeY, currentX + hCellSizeX, currentY + hCellSizeY ) );
// GEOS intersects tests on prepared geometry is MAGNITUDES faster than calculating the intersection itself,
Expand Down
5 changes: 3 additions & 2 deletions src/analysis/processing/qgsreclassifyutils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ void QgsReclassifyUtils::reclassify( const QVector<QgsReclassifyUtils::RasterCla
destinationRaster->setEditable( true );
std::unique_ptr< QgsRasterBlock > rasterBlock;
bool reclassed = false;
bool isNoData = false;
while ( iter.readNextRasterPart( band, iterCols, iterRows, rasterBlock, iterLeft, iterTop ) )
{
if ( feedback )
Expand All @@ -96,11 +97,11 @@ void QgsReclassifyUtils::reclassify( const QVector<QgsReclassifyUtils::RasterCla
break;
for ( int column = 0; column < iterCols; column++ )
{
if ( rasterBlock->isNoData( row, column ) )
const double value = rasterBlock->valueAndNoData( row, column, isNoData );
if ( isNoData )
reclassifiedBlock->setValue( row, column, destNoDataValue );
else
{
double value = rasterBlock->value( row, column );
double newValue = reclassifyValue( classes, value, reclassed );
if ( reclassed )
reclassifiedBlock->setValue( row, column, newValue );
Expand Down
4 changes: 3 additions & 1 deletion src/analysis/raster/qgsrastercalcnode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -73,11 +73,13 @@ bool QgsRasterCalcNode::calculate( QMap<QString, QgsRasterBlock * > &rasterData,
//convert input raster values to double, also convert input no data to result no data

int outRow = 0;
bool isNoData = false;
for ( int dataRow = startRow; dataRow < endRow ; ++dataRow, ++outRow )
{
for ( int dataCol = 0; dataCol < nCols; ++dataCol )
{
data[ dataCol + nCols * outRow] = ( *it )->isNoData( dataRow, dataCol ) ? result.nodataValue() : ( *it )->value( dataRow, dataCol );
const double value = ( *it )->valueAndNoData( dataRow, dataCol, isNoData );
data[ dataCol + nCols * outRow] = isNoData ? result.nodataValue() : value;
}
}
result.setData( nCols, nRows, data, result.nodataValue() );
Expand Down
9 changes: 3 additions & 6 deletions src/core/raster/qgsmultibandcolorrenderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -294,18 +294,15 @@ QgsRasterBlock *QgsMultiBandColorRenderer::block( int bandNo, QgsRectangle cons
double blueVal = 0;
if ( mRedBand > 0 )
{
redVal = redBlock->value( i );
if ( redBlock->isNoData( i ) ) isNoData = true;
redVal = redBlock->valueAndNoData( i, isNoData );
}
if ( !isNoData && mGreenBand > 0 )
{
greenVal = greenBlock->value( i );
if ( greenBlock->isNoData( i ) ) isNoData = true;
greenVal = greenBlock->valueAndNoData( i, isNoData );
}
if ( !isNoData && mBlueBand > 0 )
{
blueVal = blueBlock->value( i );
if ( blueBlock->isNoData( i ) ) isNoData = true;
blueVal = blueBlock->valueAndNoData( i, isNoData );
}
if ( isNoData )
{
Expand Down
6 changes: 4 additions & 2 deletions src/core/raster/qgspalettedrasterrenderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -167,14 +167,16 @@ QgsRasterBlock *QgsPalettedRasterRenderer::block( int bandNo, QgsRectangle cons
unsigned int *outputData = ( unsigned int * )( outputBlock->bits() );

qgssize rasterSize = ( qgssize )width * height;
bool isNoData = false;
for ( qgssize i = 0; i < rasterSize; ++i )
{
if ( inputBlock->isNoData( i ) )
const double value = inputBlock->valueAndNoData( i, isNoData );
if ( isNoData )
{
outputData[i] = myDefaultColor;
continue;
}
int val = ( int ) inputBlock->value( i );
int val = static_cast< int >( value );
if ( !mColors.contains( val ) )
{
outputData[i] = myDefaultColor;
Expand Down
11 changes: 7 additions & 4 deletions src/core/raster/qgsrasterinterface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,7 @@ QgsRasterBandStats QgsRasterInterface::bandStatistics( int bandNo,
double mySumOfSquares = 0;

bool myFirstIterationFlag = true;
bool isNoData = false;
for ( int myYBlock = 0; myYBlock < myNYBlocks; myYBlock++ )
{
for ( int myXBlock = 0; myXBlock < myNXBlocks; myXBlock++ )
Expand All @@ -185,9 +186,10 @@ QgsRasterBandStats QgsRasterInterface::bandStatistics( int bandNo,
// Collect the histogram counts.
for ( qgssize i = 0; i < ( static_cast< qgssize >( myBlockHeight ) ) * myBlockWidth; i++ )
{
if ( blk->isNoData( i ) ) continue; // NULL
double myValue = blk->valueAndNoData( i, isNoData );
if ( isNoData )
continue; // NULL

double myValue = blk->value( i );
myRasterBandStats.sum += myValue;
myRasterBandStats.elementCount++;

Expand Down Expand Up @@ -448,6 +450,7 @@ QgsRasterHistogram QgsRasterInterface::histogram( int bandNo,
double myBinSize = ( myMaximum - myMinimum ) / myBinCount;

// TODO: progress signals
bool isNoData = false;
for ( int myYBlock = 0; myYBlock < myNYBlocks; myYBlock++ )
{
for ( int myXBlock = 0; myXBlock < myNXBlocks; myXBlock++ )
Expand All @@ -470,11 +473,11 @@ QgsRasterHistogram QgsRasterInterface::histogram( int bandNo,
// Collect the histogram counts.
for ( qgssize i = 0; i < ( static_cast< qgssize >( myBlockHeight ) ) * myBlockWidth; i++ )
{
if ( blk->isNoData( i ) )
double myValue = blk->valueAndNoData( i, isNoData );
if ( isNoData )
{
continue; // NULL
}
double myValue = blk->value( i );

int myBinIndex = static_cast <int>( std::floor( ( myValue - myMinimum ) / myBinSize ) );

Expand Down
4 changes: 2 additions & 2 deletions src/core/raster/qgsrasternuller.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -100,13 +100,13 @@ QgsRasterBlock *QgsRasterNuller::block( int bandNo, QgsRectangle const &extent,
outputBlock->setNoDataValue( noDataValue );
}

bool isNoData = false;
for ( int i = 0; i < height; i++ )
{
for ( int j = 0; j < width; j++ )
{
double value = inputBlock->value( i, j );
double value = inputBlock->valueAndNoData( i, j, isNoData );

bool isNoData = inputBlock->isNoData( i, j );
if ( QgsRasterRange::contains( value, mNoData.value( bandNo - 1 ) ) )
{
isNoData = true;
Expand Down
6 changes: 4 additions & 2 deletions src/core/raster/qgssinglebandgrayrenderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -117,14 +117,16 @@ QgsRasterBlock *QgsSingleBandGrayRenderer::block( int bandNo, const QgsRectangle
}

QRgb myDefaultColor = NODATA_COLOR;
bool isNoData = false;
for ( qgssize i = 0; i < ( qgssize )width * height; i++ )
{
if ( inputBlock->isNoData( i ) )
double grayVal = inputBlock->valueAndNoData( i, isNoData );

if ( isNoData )
{
outputBlock->setColor( i, myDefaultColor );
continue;
}
double grayVal = inputBlock->value( i );

double currentAlpha = mOpacity;
if ( mRasterTransparency )
Expand Down
6 changes: 4 additions & 2 deletions src/core/raster/qgssinglebandpseudocolorrenderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -238,14 +238,16 @@ QgsRasterBlock *QgsSingleBandPseudoColorRenderer::block( int bandNo, QgsRectangl
const QgsRasterShaderFunction *fcn = mShader->rasterShaderFunction();

qgssize count = ( qgssize )width * height;
bool isNoData = false;
for ( qgssize i = 0; i < count; i++ )
{
if ( inputBlock->isNoData( i ) )
double val = inputBlock->valueAndNoData( i, isNoData );
if ( isNoData )
{
outputBlockData[i] = myDefaultColor;
continue;
}
double val = inputBlock->value( i );

int red, green, blue, alpha;
if ( !fcn->shade( val, &red, &green, &blue, &alpha ) )
{
Expand Down

0 comments on commit fc99669

Please sign in to comment.