23QString QgsRoundRasterValuesAlgorithm::name()
 const 
   25  return QStringLiteral( 
"roundrastervalues" );
 
   28QString QgsRoundRasterValuesAlgorithm::displayName()
 const 
   30  return QObject::tr( 
"Round raster" );
 
   33QStringList QgsRoundRasterValuesAlgorithm::tags()
 const 
   35  return QObject::tr( 
"data,cells,round,truncate" ).split( 
',' );
 
   38QString QgsRoundRasterValuesAlgorithm::group()
 const 
   40  return QObject::tr( 
"Raster analysis" );
 
   43QString QgsRoundRasterValuesAlgorithm::groupId()
 const 
   45  return QStringLiteral( 
"rasteranalysis" );
 
   48void 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 ) );
 
   54  std::unique_ptr<QgsProcessingParameterDefinition> baseParameter = std::make_unique<QgsProcessingParameterNumber>( QStringLiteral( 
"BASE_N" ), QObject::tr( 
"Base n for rounding to multiples of n" ), 
Qgis::ProcessingNumberParameterType::Integer, 10, 
true, 1 );
 
   56  addParameter( baseParameter.release() );
 
   60  auto createOptsParam = std::make_unique<QgsProcessingParameterString>( QStringLiteral( 
"CREATE_OPTIONS" ), QObject::tr( 
"Creation options" ), QVariant(), 
false, 
true );
 
   61  createOptsParam->setMetadata( QVariantMap( { { QStringLiteral( 
"widget_wrapper" ), QVariantMap( { { QStringLiteral( 
"widget_type" ), QStringLiteral( 
"rasteroptions" ) } } ) } } ) );
 
   63  addParameter( createOptsParam.release() );
 
   65  auto creationOptsParam = std::make_unique<QgsProcessingParameterString>( QStringLiteral( 
"CREATION_OPTIONS" ), QObject::tr( 
"Creation options" ), QVariant(), 
false, 
true );
 
   66  creationOptsParam->setMetadata( QVariantMap( { { QStringLiteral( 
"widget_wrapper" ), QVariantMap( { { QStringLiteral( 
"widget_type" ), QStringLiteral( 
"rasteroptions" ) } } ) } } ) );
 
   68  addParameter( creationOptsParam.release() );
 
   73QString QgsRoundRasterValuesAlgorithm::shortHelpString()
 const 
   75  return QObject::tr( 
"This algorithm rounds the cell values of a raster dataset to the specified number of decimals.\n " 
   76                      "Alternatively, a negative number of decimal places may be used to round values to powers of a base n " 
   77                      "(specified in the advanced parameter Base n). For example, with a Base value n of 10 and Decimal places of -1 " 
   78                      "the algorithm rounds cell values to multiples of 10, -2 rounds to multiples of 100, and so on. Arbitrary base values " 
   79                      "may be chosen, the algorithm applies the same multiplicative principle. Rounding cell values to multiples of " 
   80                      "a base n may be used to generalize raster layers.\n" 
   81                      "The algorithm preserves the data type of the input raster. Therefore byte/integer rasters can only be rounded " 
   82                      "to multiples of a base n, otherwise a warning is raised and the raster gets copied as byte/integer raster." );
 
   85QString QgsRoundRasterValuesAlgorithm::shortDescription()
 const 
   87  return QObject::tr( 
"Rounds the cell values of a raster dataset to a specified number of decimals." );
 
   90QgsRoundRasterValuesAlgorithm *QgsRoundRasterValuesAlgorithm::createInstance()
 const 
   92  return new QgsRoundRasterValuesAlgorithm();
 
   98  QgsRasterLayer *inputRaster = parameterAsRasterLayer( parameters, QStringLiteral( 
"INPUT" ), context );
 
   99  mDecimalPrecision = parameterAsInt( parameters, QStringLiteral( 
"DECIMAL_PLACES" ), context );
 
  100  mBaseN = parameterAsInt( parameters, QStringLiteral( 
"BASE_N" ), context );
 
  101  mMultipleOfBaseN = pow( mBaseN, abs( mDecimalPrecision ) );
 
  102  mScaleFactor = std::pow( 10.0, mDecimalPrecision );
 
  107  mBand = parameterAsInt( parameters, QStringLiteral( 
"BAND" ), context );
 
  108  if ( mBand < 1 || mBand > inputRaster->
bandCount() )
 
  109    throw QgsProcessingException( QObject::tr( 
"Invalid band number for BAND (%1): Valid values for input raster are 1 to %2" ).arg( mBand ).arg( inputRaster->
bandCount() ) );
 
  111  mRoundingDirection = parameterAsEnum( parameters, QStringLiteral( 
"ROUNDING_DIRECTION" ), context );
 
  114  mDataType = mInterface->dataType( mBand );
 
  124      if ( mDecimalPrecision > -1 )
 
  125        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 );
 
  133  mExtent = inputRaster->
extent();
 
  134  mLayerWidth = inputRaster->
width();
 
  135  mLayerHeight = inputRaster->
height();
 
  136  mCrs = inputRaster->
crs();
 
  137  mNbCellsXProvider = mInterface->xSize();
 
  138  mNbCellsYProvider = mInterface->ySize();
 
  145  QString creationOptions = parameterAsString( parameters, QStringLiteral( 
"CREATION_OPTIONS" ), context ).trimmed();
 
  147  const QString optionsString = parameterAsString( parameters, QStringLiteral( 
"CREATE_OPTIONS" ), context );
 
  148  if ( !optionsString.isEmpty() )
 
  149    creationOptions = optionsString;
 
  151  const QString outputFile = parameterAsOutputLayer( parameters, QStringLiteral( 
"OUTPUT" ), context );
 
  152  const QFileInfo fi( outputFile );
 
  154  auto writer = std::make_unique<QgsRasterFileWriter>( outputFile );
 
  155  writer->setOutputProviderKey( QStringLiteral( 
"gdal" ) );
 
  156  if ( !creationOptions.isEmpty() )
 
  158    writer->setCreationOptions( creationOptions.split( 
'|' ) );
 
  160  writer->setOutputFormat( outputFormat );
 
  161  std::unique_ptr<QgsRasterDataProvider> provider( writer->createOneBandRaster( mInterface->dataType( mBand ), mNbCellsXProvider, mNbCellsYProvider, mExtent, mCrs ) );
 
  164  if ( !provider->isValid() )
 
  169  destinationRasterProvider = provider.get();
 
  171  destinationRasterProvider->
setNoDataValue( 1, mInputNoDataValue );
 
  175  const int nbBlocksWidth = 
static_cast<int>( std::ceil( 1.0 * mLayerWidth / maxWidth ) );
 
  176  const int nbBlocksHeight = 
static_cast<int>( std::ceil( 1.0 * mLayerHeight / maxHeight ) );
 
  177  const int nbBlocks = nbBlocksWidth * nbBlocksHeight;
 
  180  iter.startRasterRead( mBand, mLayerWidth, mLayerHeight, mExtent );
 
  185  std::unique_ptr<QgsRasterBlock> analysisRasterBlock;
 
  186  while ( iter.readNextRasterPart( mBand, iterCols, iterRows, analysisRasterBlock, iterLeft, iterTop ) )
 
  189      feedback->
setProgress( 100 * ( ( iterTop / maxHeight * nbBlocksWidth ) + iterLeft / maxWidth ) / nbBlocks );
 
  190    if ( mIsInteger && mDecimalPrecision > -1 )
 
  193      analysisRasterBlock->setNoDataValue( mInputNoDataValue );
 
  194      if ( !destinationRasterProvider->
writeBlock( analysisRasterBlock.get(), mBand, iterLeft, iterTop ) )
 
  201      for ( 
int row = 0; row < iterRows; row++ )
 
  205        for ( 
int column = 0; column < iterCols; column++ )
 
  207          bool isNoData = 
false;
 
  208          const double val = analysisRasterBlock->valueAndNoData( row, column, isNoData );
 
  211            analysisRasterBlock->setValue( row, column, mInputNoDataValue );
 
  215            double roundedVal = mInputNoDataValue;
 
  216            if ( mRoundingDirection == 0 && mDecimalPrecision < 0 )
 
  218              roundedVal = roundUpBaseN( val );
 
  220            else if ( mRoundingDirection == 0 && mDecimalPrecision > -1 )
 
  222              const double m = ( val < 0.0 ) ? -1.0 : 1.0;
 
  223              roundedVal = roundUp( val, m );
 
  225            else if ( mRoundingDirection == 1 && mDecimalPrecision < 0 )
 
  227              roundedVal = roundNearestBaseN( val );
 
  229            else if ( mRoundingDirection == 1 && mDecimalPrecision > -1 )
 
  231              const double m = ( val < 0.0 ) ? -1.0 : 1.0;
 
  232              roundedVal = roundNearest( val, m );
 
  234            else if ( mRoundingDirection == 2 && mDecimalPrecision < 0 )
 
  236              roundedVal = roundDownBaseN( val );
 
  240              const double m = ( val < 0.0 ) ? -1.0 : 1.0;
 
  241              roundedVal = roundDown( val, m );
 
  244            analysisRasterBlock->setValue( row, column, roundedVal );
 
  248      if ( !destinationRasterProvider->
writeBlock( analysisRasterBlock.get(), mBand, iterLeft, iterTop ) )
 
  257  outputs.insert( QStringLiteral( 
"OUTPUT" ), outputFile );
 
  261double QgsRoundRasterValuesAlgorithm::roundNearest( 
double value, 
double m )
 
  263  return ( std::round( value * m * mScaleFactor ) / mScaleFactor ) * m;
 
  266double QgsRoundRasterValuesAlgorithm::roundUp( 
double value, 
double m )
 
  268  return ( std::ceil( value * m * mScaleFactor ) / mScaleFactor ) * m;
 
  271double QgsRoundRasterValuesAlgorithm::roundDown( 
double value, 
double m )
 
  273  return ( std::floor( value * m * mScaleFactor ) / mScaleFactor ) * m;
 
  276double QgsRoundRasterValuesAlgorithm::roundNearestBaseN( 
double value )
 
  278  return static_cast<double>( mMultipleOfBaseN * round( value / mMultipleOfBaseN ) );
 
  281double QgsRoundRasterValuesAlgorithm::roundUpBaseN( 
double value )
 
  283  return static_cast<double>( mMultipleOfBaseN * ceil( value / mMultipleOfBaseN ) );
 
  286double QgsRoundRasterValuesAlgorithm::roundDownBaseN( 
double value )
 
  288  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)
 
@ Hidden
Parameter is hidden and should not be shown to users.
 
@ Advanced
Parameter is an advanced parameter which should be hidden from users by default.
 
virtual QgsError error() const
Gets current status error.
 
QString summary() const
Short error description, usually the first error in chain, the real error.
 
bool isCanceled() const
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.
 
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.
 
QgsRasterDataProvider * clone() const override=0
Clone itself, create deep copy.
 
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.
 
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.