28#define EXCLUDE_CPPCHECK
29#ifdef EXCLUDE_CPPCHECK
31using namespace Qt::StringLiterals;
35QString QgsRescaleRasterAlgorithm::name()
const
37 return u
"rescaleraster"_s;
40QString QgsRescaleRasterAlgorithm::displayName()
const
42 return QObject::tr(
"Rescale raster" );
45QStringList QgsRescaleRasterAlgorithm::tags()
const
47 return QObject::tr(
"raster,rescale,minimum,maximum,range" ).split(
',' );
50QString QgsRescaleRasterAlgorithm::group()
const
52 return QObject::tr(
"Raster analysis" );
55QString QgsRescaleRasterAlgorithm::groupId()
const
57 return u
"rasteranalysis"_s;
60QString QgsRescaleRasterAlgorithm::shortHelpString()
const
63 "This algorithm rescales a raster layer to a new value range, while preserving the shape "
64 "(distribution) of the raster's histogram (pixel values). Input values "
65 "are mapped using a linear interpolation from the source raster's minimum "
66 "and maximum pixel values to the destination minimum and maximum pixel range.\n\n"
67 "By default the algorithm preserves the original NoData value, but there is "
68 "an option to override it."
72QString QgsRescaleRasterAlgorithm::shortDescription()
const
75 "Rescales a raster layer to a new value range, while preserving the shape "
76 "(distribution) of the raster's histogram (pixel values)."
80QgsRescaleRasterAlgorithm *QgsRescaleRasterAlgorithm::createInstance()
const
82 return new QgsRescaleRasterAlgorithm();
85void QgsRescaleRasterAlgorithm::initAlgorithm(
const QVariantMap & )
95 auto createOptsParam = std::make_unique<QgsProcessingParameterString>( u
"CREATE_OPTIONS"_s, QObject::tr(
"Creation options" ), QVariant(),
false,
true );
96 createOptsParam->setMetadata( QVariantMap( { { u
"widget_wrapper"_s, QVariantMap( { { u
"widget_type"_s, u
"rasteroptions"_s } } ) } } ) );
98 addParameter( createOptsParam.release() );
100 auto creationOptsParam = std::make_unique<QgsProcessingParameterString>( u
"CREATION_OPTIONS"_s, QObject::tr(
"Creation options" ), QVariant(),
false,
true );
101 creationOptsParam->setMetadata( QVariantMap( { { u
"widget_wrapper"_s, QVariantMap( { { u
"widget_type"_s, u
"rasteroptions"_s } } ) } } ) );
103 addParameter( creationOptsParam.release() );
110 Q_UNUSED( feedback );
112 QgsRasterLayer *layer = parameterAsRasterLayer( parameters, u
"INPUT"_s, context );
116 mBand = parameterAsInt( parameters, u
"BAND"_s, context );
117 if ( mBand < 1 || mBand > layer->
bandCount() )
118 throw QgsProcessingException( QObject::tr(
"Invalid band number for BAND (%1): Valid values for input raster are 1 to %2" ).arg( mBand ).arg( layer->
bandCount() ) );
120 mMinimum = parameterAsDouble( parameters, u
"MINIMUM"_s, context );
121 mMaximum = parameterAsDouble( parameters, u
"MAXIMUM"_s, context );
126 mLayerWidth = layer->
width();
127 mLayerHeight = layer->
height();
128 mExtent = layer->
extent();
129 if ( parameters.value( u
"NODATA"_s ).isValid() )
131 mNoData = parameterAsDouble( parameters, u
"NODATA"_s, context );
138 if ( std::isfinite( mNoData ) )
141 if ( mNoData < std::numeric_limits<float>::lowest() )
142 mNoData = std::numeric_limits<float>::lowest();
143 else if ( mNoData > std::numeric_limits<float>::max() )
144 mNoData = std::numeric_limits<float>::max();
147 mXSize = mInterface->xSize();
148 mYSize = mInterface->ySize();
155 QGS_MARK_ALGORITHM_SOURCE
157 feedback->
pushInfo( QObject::tr(
"Calculating raster minimum and maximum values…" ) );
160 feedback->
pushInfo( QObject::tr(
"Rescaling values…" ) );
162 QString creationOptions = parameterAsString( parameters, u
"CREATION_OPTIONS"_s, context ).trimmed();
164 const QString optionsString = parameterAsString( parameters, u
"CREATE_OPTIONS"_s, context );
165 if ( !optionsString.isEmpty() )
166 creationOptions = optionsString;
168 const QString outputFile = parameterAsOutputLayer( parameters, u
"OUTPUT"_s, context );
169 const QString outputFormat = parameterAsOutputRasterFormat( parameters, u
"OUTPUT"_s, context );
170 auto writer = std::make_unique<QgsRasterFileWriter>( outputFile );
171 writer->setOutputProviderKey( u
"gdal"_s );
172 if ( !creationOptions.isEmpty() )
174 writer->setCreationOptions( creationOptions.split(
'|' ) );
177 writer->setOutputFormat( outputFormat );
178 std::unique_ptr<QgsRasterDataProvider> provider( writer->createOneBandRaster(
Qgis::DataType::Float32, mXSize, mYSize, mExtent, mCrs ) );
181 if ( !provider->isValid() )
188 const bool hasReportsDuringClose = provider->hasReportsDuringClose();
189 const double maxProgressDuringBlockWriting = hasReportsDuringClose ? 50.0 : 100.0;
192 iter.startRasterRead( mBand, mLayerWidth, mLayerHeight, mExtent );
197 std::unique_ptr<QgsRasterBlock> inputBlock;
198 while ( iter.readNextRasterPart( mBand, iterCols, iterRows, inputBlock, iterLeft, iterTop ) )
200 auto outputBlock = std::make_unique<QgsRasterBlock>( destProvider->
dataType( 1 ), iterCols, iterRows );
201 feedback->
setProgress( maxProgressDuringBlockWriting * iter.progress( mBand ) );
203 for (
int row = 0; row < iterRows; row++ )
208 for (
int col = 0; col < iterCols; col++ )
210 bool isNoData =
false;
211 const double val = inputBlock->valueAndNoData( row, col, isNoData );
214 outputBlock->setValue( row, col, mNoData );
219 outputBlock->setValue( row, col, newValue );
223 if ( !destProvider->
writeBlock( outputBlock.get(), mBand, iterLeft, iterTop ) )
230 if ( hasReportsDuringClose )
233 if ( !provider->closeWithProgress( scaledFeedback.get() ) )
242 outputs.insert( u
"OUTPUT"_s, outputFile );
@ Float32
Thirty two bit floating point (float).
@ 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.
@ Double
Double/float values.
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.
static std::unique_ptr< QgsFeedback > createScaledFeedback(QgsFeedback *parentFeedback, double startPercentage, double endPercentage)
Returns a feedback object whose [0, 100] progression range will be mapped to parentFeedback [startPer...
virtual Q_INVOKABLE 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 pushInfo(const QString &info)
Pushes a general informational message from the algorithm.
A raster band parameter for Processing algorithms.
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.
The RasterBandStats struct is a container for statistics about a single raster band.
double minimumValue
The minimum cell value in the raster band.
double maximumValue
The maximum cell value in the raster band.
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.
Qgis::DataType dataType(int bandNo) const override=0
Returns data type for the band specified by number.
virtual bool setEditable(bool enabled)
Turns on/off editing mode of the provider.
Iterator for sequentially processing raster cells.
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.
A rectangle specified with double values.