27using namespace Qt::StringLiterals;
31QString QgsRescaleRasterAlgorithm::name()
const
33 return u
"rescaleraster"_s;
36QString QgsRescaleRasterAlgorithm::displayName()
const
38 return QObject::tr(
"Rescale raster" );
41QStringList QgsRescaleRasterAlgorithm::tags()
const
43 return QObject::tr(
"raster,rescale,minimum,maximum,range" ).split(
',' );
46QString QgsRescaleRasterAlgorithm::group()
const
48 return QObject::tr(
"Raster analysis" );
51QString QgsRescaleRasterAlgorithm::groupId()
const
53 return u
"rasteranalysis"_s;
56QString QgsRescaleRasterAlgorithm::shortHelpString()
const
58 return QObject::tr(
"This algorithm rescales a raster layer to a new value range, while preserving the shape "
59 "(distribution) of the raster's histogram (pixel values). Input values "
60 "are mapped using a linear interpolation from the source raster's minimum "
61 "and maximum pixel values to the destination minimum and maximum pixel range.\n\n"
62 "By default the algorithm preserves the original NoData value, but there is "
63 "an option to override it." );
66QString QgsRescaleRasterAlgorithm::shortDescription()
const
68 return QObject::tr(
"Rescales a raster layer to a new value range, while preserving the shape "
69 "(distribution) of the raster's histogram (pixel values)." );
72QgsRescaleRasterAlgorithm *QgsRescaleRasterAlgorithm::createInstance()
const
74 return new QgsRescaleRasterAlgorithm();
77void QgsRescaleRasterAlgorithm::initAlgorithm(
const QVariantMap & )
87 auto createOptsParam = std::make_unique<QgsProcessingParameterString>( u
"CREATE_OPTIONS"_s, QObject::tr(
"Creation options" ), QVariant(),
false,
true );
88 createOptsParam->setMetadata( QVariantMap( { { u
"widget_wrapper"_s, QVariantMap( { { u
"widget_type"_s, u
"rasteroptions"_s } } ) } } ) );
90 addParameter( createOptsParam.release() );
92 auto creationOptsParam = std::make_unique<QgsProcessingParameterString>( u
"CREATION_OPTIONS"_s, QObject::tr(
"Creation options" ), QVariant(),
false,
true );
93 creationOptsParam->setMetadata( QVariantMap( { { u
"widget_wrapper"_s, QVariantMap( { { u
"widget_type"_s, u
"rasteroptions"_s } } ) } } ) );
95 addParameter( creationOptsParam.release() );
102 Q_UNUSED( feedback );
104 QgsRasterLayer *layer = parameterAsRasterLayer( parameters, u
"INPUT"_s, context );
108 mBand = parameterAsInt( parameters, u
"BAND"_s, context );
109 if ( mBand < 1 || mBand > layer->
bandCount() )
110 throw QgsProcessingException( QObject::tr(
"Invalid band number for BAND (%1): Valid values for input raster are 1 to %2" )
114 mMinimum = parameterAsDouble( parameters, u
"MINIMUM"_s, context );
115 mMaximum = parameterAsDouble( parameters, u
"MAXIMUM"_s, context );
120 mLayerWidth = layer->
width();
121 mLayerHeight = layer->
height();
122 mExtent = layer->
extent();
123 if ( parameters.value( u
"NODATA"_s ).isValid() )
125 mNoData = parameterAsDouble( parameters, u
"NODATA"_s, context );
132 if ( std::isfinite( mNoData ) )
135 if ( mNoData < std::numeric_limits<float>::lowest() )
136 mNoData = std::numeric_limits<float>::lowest();
137 else if ( mNoData > std::numeric_limits<float>::max() )
138 mNoData = std::numeric_limits<float>::max();
141 mXSize = mInterface->xSize();
142 mYSize = mInterface->ySize();
149 feedback->
pushInfo( QObject::tr(
"Calculating raster minimum and maximum values…" ) );
152 feedback->
pushInfo( QObject::tr(
"Rescaling values…" ) );
154 QString creationOptions = parameterAsString( parameters, u
"CREATION_OPTIONS"_s, context ).trimmed();
156 const QString optionsString = parameterAsString( parameters, u
"CREATE_OPTIONS"_s, context );
157 if ( !optionsString.isEmpty() )
158 creationOptions = optionsString;
160 const QString outputFile = parameterAsOutputLayer( parameters, u
"OUTPUT"_s, context );
161 const QString outputFormat = parameterAsOutputRasterFormat( parameters, u
"OUTPUT"_s, context );
162 auto writer = std::make_unique<QgsRasterFileWriter>( outputFile );
163 writer->setOutputProviderKey( u
"gdal"_s );
164 if ( !creationOptions.isEmpty() )
166 writer->setCreationOptions( creationOptions.split(
'|' ) );
169 writer->setOutputFormat( outputFormat );
170 std::unique_ptr<QgsRasterDataProvider> provider( writer->createOneBandRaster(
Qgis::DataType::Float32, mXSize, mYSize, mExtent, mCrs ) );
173 if ( !provider->isValid() )
180 const bool hasReportsDuringClose = provider->hasReportsDuringClose();
181 const double maxProgressDuringBlockWriting = hasReportsDuringClose ? 50.0 : 100.0;
184 iter.startRasterRead( mBand, mLayerWidth, mLayerHeight, mExtent );
189 std::unique_ptr<QgsRasterBlock> inputBlock;
190 while ( iter.readNextRasterPart( mBand, iterCols, iterRows, inputBlock, iterLeft, iterTop ) )
192 auto outputBlock = std::make_unique<QgsRasterBlock>( destProvider->
dataType( 1 ), iterCols, iterRows );
193 feedback->
setProgress( maxProgressDuringBlockWriting * iter.progress( mBand ) );
195 for (
int row = 0; row < iterRows; row++ )
200 for (
int col = 0; col < iterCols; col++ )
202 bool isNoData =
false;
203 const double val = inputBlock->valueAndNoData( row, col, isNoData );
206 outputBlock->setValue( row, col, mNoData );
211 outputBlock->setValue( row, col, newValue );
215 if ( !destProvider->
writeBlock( outputBlock.get(), mBand, iterLeft, iterTop ) )
222 if ( hasReportsDuringClose )
225 if ( !provider->closeWithProgress( scaledFeedback.get() ) )
234 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 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.