23 QString QgsFillNoDataAlgorithm::name()
const
25 return QStringLiteral(
"fillnodata" );
28 QString QgsFillNoDataAlgorithm::displayName()
const
30 return QObject::tr(
"Fill NoData cells" );
33 QStringList QgsFillNoDataAlgorithm::tags()
const
35 return QObject::tr(
"data,cells,fill,set" ).split(
',' );
38 QString QgsFillNoDataAlgorithm::group()
const
40 return QObject::tr(
"Raster tools" );
43 QString QgsFillNoDataAlgorithm::groupId()
const
45 return QStringLiteral(
"rastertools" );
48 void QgsFillNoDataAlgorithm::initAlgorithm(
const QVariantMap & )
51 addParameter(
new QgsProcessingParameterBand( QStringLiteral(
"BAND" ), QObject::tr(
"Band Number" ), 1, QStringLiteral(
"INPUT" ) ) );
56 QString QgsFillNoDataAlgorithm::shortHelpString()
const
58 return QObject::tr(
"This algorithm resets the NoData values in the input raster "
59 "to a chosen value, resulting in a raster dataset with no NoData pixels. "
60 "This value can be set by the user using the Fill value parameter. "
61 "The algorithm respects the input raster data type (eg. a floating point fill value will be truncated "
62 "when applied to an integer raster)." );
65 QgsFillNoDataAlgorithm *QgsFillNoDataAlgorithm::createInstance()
const
67 return new QgsFillNoDataAlgorithm();
73 mInputRaster = parameterAsRasterLayer( parameters, QStringLiteral(
"INPUT" ), context );
74 mFillValue = parameterAsDouble( parameters, QStringLiteral(
"FILL_VALUE" ), context );
79 mBand = parameterAsInt( parameters, QStringLiteral(
"BAND" ), context );
80 if ( mBand < 1 || mBand > mInputRaster->bandCount() )
81 throw QgsProcessingException( QObject::tr(
"Invalid band number for BAND (%1): Valid values for input raster are 1 to %2" ).arg( mBand ).arg( mInputRaster->bandCount() ) );
83 mInterface.reset( mInputRaster->dataProvider()->clone() );
84 mInputNoDataValue = mInputRaster->dataProvider()->sourceNoDataValue( mBand );
85 mExtent = mInputRaster->extent();
86 mLayerWidth = mInputRaster->width();
87 mLayerHeight = mInputRaster->height();
88 mCrs = mInputRaster->crs();
89 mNbCellsXProvider = mInterface->xSize();
90 mNbCellsYProvider = mInterface->ySize();
97 if ( !mInputRaster->dataProvider()->sourceHasNoDataValue( mBand ) )
98 feedback->
reportError( QObject::tr(
"Input raster has no NoData values. There exist no NoData cells to fill." ),
false );
101 const QString outputFile = parameterAsOutputLayer( parameters, QStringLiteral(
"OUTPUT" ), context );
102 const QFileInfo fi( outputFile );
104 std::unique_ptr< QgsRasterFileWriter > writer = std::make_unique< QgsRasterFileWriter >( outputFile );
105 writer->setOutputProviderKey( QStringLiteral(
"gdal" ) );
106 writer->setOutputFormat( outputFormat );
107 std::unique_ptr<QgsRasterDataProvider > provider( writer->createOneBandRaster( mInterface->dataType( mBand ), mNbCellsXProvider, mNbCellsYProvider, mExtent, mCrs ) );
110 if ( !provider->isValid() )
115 destinationRasterProvider = provider.get();
120 const int nbBlocksWidth =
static_cast< int >( std::ceil( 1.0 * mLayerWidth / maxWidth ) );
121 const int nbBlocksHeight =
static_cast< int >( std::ceil( 1.0 * mLayerHeight / maxHeight ) );
122 const int nbBlocks = nbBlocksWidth * nbBlocksHeight;
125 iter.startRasterRead( mBand, mLayerWidth, mLayerHeight, mExtent );
130 std::unique_ptr< QgsRasterBlock > filledRasterBlock;
131 while ( iter.readNextRasterPart( mBand, iterCols, iterRows, filledRasterBlock, iterLeft, iterTop ) )
134 feedback->
setProgress( 100 * ( ( iterTop / maxHeight * nbBlocksWidth ) + iterLeft / maxWidth ) / nbBlocks );
139 if ( !filledRasterBlock->hasNoDataValue() )
141 destinationRasterProvider->
writeBlock( filledRasterBlock.get(), mBand, iterLeft, iterTop );
145 for (
int row = 0; row < iterRows; row++ )
149 for (
int column = 0; column < iterCols; column++ )
151 if ( filledRasterBlock->isNoData( row, column ) )
152 filledRasterBlock->setValue( row, column, mFillValue );
155 destinationRasterProvider->
writeBlock( filledRasterBlock.get(), mBand, iterLeft, iterTop );
160 outputs.insert( QStringLiteral(
"OUTPUT" ), outputFile );