23 QString QgsRoundRasterValuesAlgorithm::name()
 const 
   25   return QStringLiteral( 
"roundrastervalues" );
 
   28 QString QgsRoundRasterValuesAlgorithm::displayName()
 const 
   30   return QObject::tr( 
"Round raster" );
 
   33 QStringList QgsRoundRasterValuesAlgorithm::tags()
 const 
   35   return QObject::tr( 
"data,cells,round,truncate" ).split( 
',' );
 
   38 QString QgsRoundRasterValuesAlgorithm::group()
 const 
   40   return QObject::tr( 
"Raster analysis" );
 
   43 QString QgsRoundRasterValuesAlgorithm::groupId()
 const 
   45   return QStringLiteral( 
"rasteranalysis" );
 
   48 void QgsRoundRasterValuesAlgorithm::initAlgorithm( 
const QVariantMap & )
 
   51   addParameter( 
new QgsProcessingParameterBand( QStringLiteral( 
"BAND" ), QObject::tr( 
"Band number" ), 1, QStringLiteral( 
"INPUT" ) ) );
 
   52   addParameter( 
new QgsProcessingParameterEnum( QStringLiteral( 
"ROUNDING_DIRECTION" ), QObject::tr( 
"Rounding direction" ), QStringList() << QObject::tr( 
"Round up" ) << QObject::tr( 
"Round to nearest" ) << QObject::tr( 
"Round down" ), 
false, 1 ) );
 
   55   std::unique_ptr< QgsProcessingParameterDefinition > baseParameter = std::make_unique< QgsProcessingParameterNumber >( QStringLiteral( 
"BASE_N" ), QObject::tr( 
"Base n for rounding to multiples of n" ), 
QgsProcessingParameterNumber::Integer, 10, 
true, 1 );
 
   57   addParameter( baseParameter.release() );
 
   60 QString QgsRoundRasterValuesAlgorithm::shortHelpString()
 const 
   62   return QObject::tr( 
"This algorithm rounds the cell values of a raster dataset according to the specified number of decimals.\n " 
   63                       "Alternatively, a negative number of decimal places may be used to round values to powers of a base n " 
   64                       "(specified in the advanced parameter Base n). For example, with a Base value n of 10 and Decimal places of -1 " 
   65                       "the algorithm rounds cell values to multiples of 10, -2 rounds to multiples of 100, and so on. Arbitrary base values " 
   66                       "may be chosen, the algorithm applies the same multiplicative principle. Rounding cell values to multiples of " 
   67                       "a base n may be used to generalize raster layers.\n" 
   68                       "The algorithm preserves the data type of the input raster. Therefore byte/integer rasters can only be rounded " 
   69                       "to multiples of a base n, otherwise a warning is raised and the raster gets copied as byte/integer raster" );
 
   72 QgsRoundRasterValuesAlgorithm *QgsRoundRasterValuesAlgorithm::createInstance()
 const 
   74   return new QgsRoundRasterValuesAlgorithm();
 
   80   QgsRasterLayer *inputRaster = parameterAsRasterLayer( parameters, QStringLiteral( 
"INPUT" ), context );
 
   81   mDecimalPrecision = parameterAsInt( parameters, QStringLiteral( 
"DECIMAL_PLACES" ), context );
 
   82   mBaseN = parameterAsInt( parameters, QStringLiteral( 
"BASE_N" ), context );
 
   83   mMultipleOfBaseN = pow( mBaseN, abs( mDecimalPrecision ) );
 
   84   mScaleFactor = std::pow( 10.0, mDecimalPrecision );
 
   89   mBand = parameterAsInt( parameters, QStringLiteral( 
"BAND" ), context );
 
   90   if ( mBand < 1 || mBand > inputRaster->
bandCount() )
 
   91     throw QgsProcessingException( QObject::tr( 
"Invalid band number for BAND (%1): Valid values for input raster are 1 to %2" ).arg( mBand ).arg( inputRaster->
bandCount() ) );
 
   93   mRoundingDirection = parameterAsEnum( parameters, QStringLiteral( 
"ROUNDING_DIRECTION" ), context );
 
   96   mDataType = mInterface->dataType( mBand );
 
  106       if ( mDecimalPrecision > -1 )
 
  107         feedback->
reportError( QObject::tr( 
"Input raster is of byte or integer type. The cell values cannot be rounded and will be output using the same data type." ), 
false );
 
  115   mExtent = inputRaster->
extent();
 
  116   mLayerWidth = inputRaster->
width();
 
  117   mLayerHeight = inputRaster->
height();
 
  118   mCrs = inputRaster->
crs();
 
  119   mNbCellsXProvider = mInterface->xSize();
 
  120   mNbCellsYProvider = mInterface->ySize();
 
  127   const QString outputFile = parameterAsOutputLayer( parameters, QStringLiteral( 
"OUTPUT" ), context );
 
  128   QFileInfo fi( outputFile );
 
  130   std::unique_ptr< QgsRasterFileWriter > writer = std::make_unique< QgsRasterFileWriter >( outputFile );
 
  131   writer->setOutputProviderKey( QStringLiteral( 
"gdal" ) );
 
  132   writer->setOutputFormat( outputFormat );
 
  133   std::unique_ptr<QgsRasterDataProvider > provider( writer->createOneBandRaster( mInterface->dataType( mBand ), mNbCellsXProvider, mNbCellsYProvider, mExtent, mCrs ) );
 
  136   if ( !provider->isValid() )
 
  141   destinationRasterProvider = provider.get();
 
  143   destinationRasterProvider->
setNoDataValue( 1, mInputNoDataValue );
 
  147   int nbBlocksWidth = 
static_cast< int >( std::ceil( 1.0 * mLayerWidth / maxWidth ) );
 
  148   int nbBlocksHeight = 
static_cast< int >( std::ceil( 1.0 * mLayerHeight / maxHeight ) );
 
  149   int nbBlocks = nbBlocksWidth * nbBlocksHeight;
 
  152   iter.startRasterRead( mBand, mLayerWidth, mLayerHeight, mExtent );
 
  157   std::unique_ptr< QgsRasterBlock > analysisRasterBlock;
 
  158   while ( iter.readNextRasterPart( mBand, iterCols, iterRows, analysisRasterBlock, iterLeft, iterTop ) )
 
  161       feedback->
setProgress( 100 * ( ( iterTop / maxHeight * nbBlocksWidth ) + iterLeft / maxWidth ) / nbBlocks );
 
  162     if ( mIsInteger && mDecimalPrecision > -1 )
 
  165       analysisRasterBlock->setNoDataValue( mInputNoDataValue );
 
  166       destinationRasterProvider->
writeBlock( analysisRasterBlock.get(), mBand, iterLeft, iterTop );
 
  170       for ( 
int row = 0; row < iterRows; row++ )
 
  174         for ( 
int column = 0; column < iterCols; column++ )
 
  176           bool isNoData = 
false;
 
  177           double val = analysisRasterBlock->valueAndNoData( row, column, isNoData );
 
  180             analysisRasterBlock->setValue( row, column, mInputNoDataValue );
 
  184             double roundedVal = mInputNoDataValue;
 
  185             if ( mRoundingDirection == 0 && mDecimalPrecision < 0 )
 
  187               roundedVal = roundUpBaseN( val );
 
  189             else if ( mRoundingDirection == 0 && mDecimalPrecision > -1 )
 
  191               double m = ( val < 0.0 ) ? -1.0 : 1.0;
 
  192               roundedVal = roundUp( val, m );
 
  194             else if ( mRoundingDirection == 1 && mDecimalPrecision < 0 )
 
  196               roundedVal = roundNearestBaseN( val );
 
  198             else if ( mRoundingDirection == 1 && mDecimalPrecision > -1 )
 
  200               double m = ( val < 0.0 ) ? -1.0 : 1.0;
 
  201               roundedVal = roundNearest( val, m );
 
  203             else if ( mRoundingDirection == 2 && mDecimalPrecision < 0 )
 
  205               roundedVal = roundDownBaseN( val );
 
  209               double m = ( val < 0.0 ) ? -1.0 : 1.0;
 
  210               roundedVal = roundDown( val,  m );
 
  213             analysisRasterBlock->setValue( row, column, roundedVal );
 
  217       destinationRasterProvider->
writeBlock( analysisRasterBlock.get(), mBand, iterLeft, iterTop );
 
  223   outputs.insert( QStringLiteral( 
"OUTPUT" ), outputFile );
 
  227 double QgsRoundRasterValuesAlgorithm::roundNearest( 
double value, 
double m )
 
  229   return ( std::round( value * m * mScaleFactor ) / mScaleFactor ) * m;
 
  232 double QgsRoundRasterValuesAlgorithm::roundUp( 
double value, 
double m )
 
  234   return ( std::ceil( value * m * mScaleFactor ) / mScaleFactor ) * m;
 
  237 double QgsRoundRasterValuesAlgorithm::roundDown( 
double value, 
double m )
 
  239   return ( std::floor( value * m * mScaleFactor ) / mScaleFactor ) * m;
 
  243 double QgsRoundRasterValuesAlgorithm::roundNearestBaseN( 
double value )
 
  245   return static_cast<double>( mMultipleOfBaseN * round( value / mMultipleOfBaseN ) );
 
  248 double QgsRoundRasterValuesAlgorithm::roundUpBaseN( 
double value )
 
  250   return static_cast<double>( mMultipleOfBaseN * ceil( value / mMultipleOfBaseN ) );
 
  253 double QgsRoundRasterValuesAlgorithm::roundDownBaseN( 
double value )
 
  255   return static_cast<double>( mMultipleOfBaseN * floor( value / mMultipleOfBaseN ) );
 
@ Int16
Sixteen bit signed integer (qint16)
@ UInt16
Sixteen bit unsigned integer (quint16)
@ Byte
Eight bit unsigned integer (quint8)
@ Int32
Thirty two bit signed integer (qint32)
@ UInt32
Thirty two bit unsigned integer (quint32)
bool isCanceled() const SIP_HOLDGIL
Tells whether the operation has been canceled already.
void setProgress(double progress)
Sets the current progress for the feedback object.
virtual QgsRectangle extent() const
Returns the extent of the layer.
QgsCoordinateReferenceSystem crs
Contains information about the context in which a processing algorithm is executed.
Custom exception class for processing related exceptions.
Base class for providing feedback from a processing algorithm.
virtual void reportError(const QString &error, bool fatalError=false)
Reports that the algorithm encountered an error while executing.
A raster band parameter for Processing algorithms.
@ FlagAdvanced
Parameter is an advanced parameter which should be hidden from users by default.
An enum based parameter for processing algorithms, allowing for selection from predefined values.
A numeric parameter for processing algorithms.
A raster layer destination parameter, for specifying the destination path for a raster layer created ...
A raster layer parameter for processing algorithms.
Base class for raster data providers.
virtual bool setNoDataValue(int bandNo, double noDataValue)
Set no data value on created dataset.
virtual double sourceNoDataValue(int bandNo) const
Value representing no data value.
QgsRasterDataProvider * clone() const override=0
Clone itself, create deep copy.
bool writeBlock(QgsRasterBlock *block, int band, int xOffset=0, int yOffset=0)
Writes pixel data from a raster block into the provider data source.
virtual bool setEditable(bool enabled)
Turns on/off editing mode of the provider.
static QString driverForExtension(const QString &extension)
Returns the GDAL driver name for a specified file extension.
Iterator for sequentially processing raster cells.
static const int DEFAULT_MAXIMUM_TILE_WIDTH
Default maximum tile width.
static const int DEFAULT_MAXIMUM_TILE_HEIGHT
Default maximum tile height.
Represents a raster layer.
int height() const
Returns the height of the (unclipped) raster.
int bandCount() const
Returns the number of bands in this layer.
QgsRasterDataProvider * dataProvider() override
Returns the source data provider.
int width() const
Returns the width of the (unclipped) raster.