30using namespace Qt::StringLiterals;
39QString QgsReclassifyAlgorithmBase::group()
const
41 return QObject::tr(
"Raster analysis" );
44QString QgsReclassifyAlgorithmBase::groupId()
const
46 return u
"rasteranalysis"_s;
49void QgsReclassifyAlgorithmBase::initAlgorithm(
const QVariantMap & )
58 addParameter( noDataValueParam.release() );
60 auto boundsHandling = std::make_unique<QgsProcessingParameterEnum>( u
"RANGE_BOUNDARIES"_s, QObject::tr(
"Range boundaries" ), QStringList() << QObject::tr(
"min < value <= max" ) << QObject::tr(
"min <= value < max" ) << QObject::tr(
"min <= value <= max" ) << QObject::tr(
"min < value < max" ),
false, 0 );
62 addParameter( boundsHandling.release() );
64 auto missingValuesParam = std::make_unique<QgsProcessingParameterBoolean>( u
"NODATA_FOR_MISSING"_s, QObject::tr(
"Use NoData when no range matches value" ),
false,
false );
66 addParameter( missingValuesParam.release() );
68 std::unique_ptr<QgsProcessingParameterDefinition> typeChoice = QgsRasterAnalysisUtils::createRasterTypeParameter( u
"DATA_TYPE"_s, QObject::tr(
"Output data type" ),
Qgis::DataType::Float32 );
70 addParameter( typeChoice.release() );
74 auto createOptsParam = std::make_unique<QgsProcessingParameterString>( u
"CREATE_OPTIONS"_s, QObject::tr(
"Creation options" ), QVariant(),
false,
true );
75 createOptsParam->setMetadata( QVariantMap( { { u
"widget_wrapper"_s, QVariantMap( { { u
"widget_type"_s, u
"rasteroptions"_s } } ) } } ) );
77 addParameter( createOptsParam.release() );
79 auto creationOptsParam = std::make_unique<QgsProcessingParameterString>( u
"CREATION_OPTIONS"_s, QObject::tr(
"Creation options" ), QVariant(),
false,
true );
80 creationOptsParam->setMetadata( QVariantMap( { { u
"widget_wrapper"_s, QVariantMap( { { u
"widget_type"_s, u
"rasteroptions"_s } } ) } } ) );
82 addParameter( creationOptsParam.release() );
89 mDataType = QgsRasterAnalysisUtils::rasterTypeChoiceToDataType( parameterAsEnum( parameters, u
"DATA_TYPE"_s, context ) );
90 if ( mDataType ==
Qgis::DataType::Int8 && atoi( GDALVersionInfo(
"VERSION_NUM" ) ) < GDAL_COMPUTE_VERSION( 3, 7, 0 ) )
93 QgsRasterLayer *layer = parameterAsRasterLayer( parameters, u
"INPUT_RASTER"_s, context );
98 mBand = parameterAsInt( parameters, u
"RASTER_BAND"_s, context );
99 if ( mBand < 1 || mBand > layer->
bandCount() )
100 throw QgsProcessingException( QObject::tr(
"Invalid band number for RASTER_BAND (%1): Valid values for input raster are 1 to %2" ).arg( mBand ).arg( layer->
bandCount() ) );
103 mExtent = layer->
extent();
107 mNbCellsXProvider = mInterface->xSize();
108 mNbCellsYProvider = mInterface->ySize();
110 mNoDataValue = parameterAsDouble( parameters, u
"NO_DATA"_s, context );
111 mUseNoDataForMissingValues = parameterAsBoolean( parameters, u
"NODATA_FOR_MISSING"_s, context );
113 const int boundsType = parameterAsEnum( parameters, u
"RANGE_BOUNDARIES"_s, context );
114 switch ( boundsType )
117 mBoundsType = QgsReclassifyUtils::RasterClass::IncludeMax;
121 mBoundsType = QgsReclassifyUtils::RasterClass::IncludeMin;
125 mBoundsType = QgsReclassifyUtils::RasterClass::IncludeMinAndMax;
129 mBoundsType = QgsReclassifyUtils::RasterClass::Exclusive;
133 return _prepareAlgorithm( parameters, context, feedback );
138 const QVector<QgsReclassifyUtils::RasterClass> classes = createClasses( mBoundsType, parameters, context, feedback );
140 QgsReclassifyUtils::reportClasses( classes, feedback );
141 QgsReclassifyUtils::checkForOverlaps( classes, feedback );
143 QString creationOptions = parameterAsString( parameters, u
"CREATION_OPTIONS"_s, context ).trimmed();
145 const QString optionsString = parameterAsString( parameters, u
"CREATE_OPTIONS"_s, context );
146 if ( !optionsString.isEmpty() )
147 creationOptions = optionsString;
149 const QString outputFile = parameterAsOutputLayer( parameters, u
"OUTPUT"_s, context );
150 const QString outputFormat = parameterAsOutputRasterFormat( parameters, u
"OUTPUT"_s, context );
152 auto writer = std::make_unique<QgsRasterFileWriter>( outputFile );
153 writer->setOutputProviderKey( u
"gdal"_s );
154 if ( !creationOptions.isEmpty() )
156 writer->setCreationOptions( creationOptions.split(
'|' ) );
159 writer->setOutputFormat( outputFormat );
160 std::unique_ptr<QgsRasterDataProvider> provider( writer->createOneBandRaster( mDataType, mNbCellsXProvider, mNbCellsYProvider, mExtent, mCrs ) );
163 if ( !provider->isValid() )
166 provider->setNoDataValue( 1, mNoDataValue );
168 QgsReclassifyUtils::reclassify( classes, mInterface.get(), mBand, mExtent, mNbCellsXProvider, mNbCellsYProvider, std::move( provider ), mNoDataValue, mUseNoDataForMissingValues, feedback );
171 outputs.insert( u
"OUTPUT"_s, outputFile );
180QString QgsReclassifyByLayerAlgorithm::name()
const
182 return u
"reclassifybylayer"_s;
185QString QgsReclassifyByLayerAlgorithm::displayName()
const
187 return QObject::tr(
"Reclassify by layer" );
190QStringList QgsReclassifyByLayerAlgorithm::tags()
const
192 return QObject::tr(
"raster,reclassify,classes,calculator" ).split(
',' );
195QString QgsReclassifyByLayerAlgorithm::shortHelpString()
const
197 return QObject::tr(
"This algorithm reclassifies a raster band by assigning new class values based on the ranges specified in a vector table." );
200QString QgsReclassifyByLayerAlgorithm::shortDescription()
const
202 return QObject::tr(
"Reclassifies a raster band by assigning new class values based on the ranges specified in a vector table." );
205QgsReclassifyByLayerAlgorithm *QgsReclassifyByLayerAlgorithm::createInstance()
const
207 return new QgsReclassifyByLayerAlgorithm();
210void QgsReclassifyByLayerAlgorithm::addAlgorithmParams()
220 std::unique_ptr<QgsFeatureSource> tableSource( parameterAsSource( parameters, u
"INPUT_TABLE"_s, context ) );
224 const QString fieldMin = parameterAsString( parameters, u
"MIN_FIELD"_s, context );
225 mMinFieldIdx = tableSource->fields().lookupField( fieldMin );
226 if ( mMinFieldIdx < 0 )
227 throw QgsProcessingException( QObject::tr(
"Invalid field specified for MIN_FIELD: %1" ).arg( fieldMin ) );
228 const QString fieldMax = parameterAsString( parameters, u
"MAX_FIELD"_s, context );
229 mMaxFieldIdx = tableSource->fields().lookupField( fieldMax );
230 if ( mMaxFieldIdx < 0 )
231 throw QgsProcessingException( QObject::tr(
"Invalid field specified for MAX_FIELD: %1" ).arg( fieldMax ) );
232 const QString fieldValue = parameterAsString( parameters, u
"VALUE_FIELD"_s, context );
233 mValueFieldIdx = tableSource->fields().lookupField( fieldValue );
234 if ( mValueFieldIdx < 0 )
235 throw QgsProcessingException( QObject::tr(
"Invalid field specified for VALUE_FIELD: %1" ).arg( fieldValue ) );
240 mTableIterator = tableSource->getFeatures( request );
247 QVector<QgsReclassifyUtils::RasterClass> classes;
249 while ( mTableIterator.nextFeature( f ) )
254 const QVariant minVariant = f.
attribute( mMinFieldIdx );
258 minValue = std::numeric_limits<double>::quiet_NaN();
262 minValue = minVariant.toDouble( &ok );
264 throw QgsProcessingException( QObject::tr(
"Invalid value for minimum: %1" ).arg( minVariant.toString() ) );
266 const QVariant maxVariant = f.
attribute( mMaxFieldIdx );
270 maxValue = std::numeric_limits<double>::quiet_NaN();
275 maxValue = maxVariant.toDouble( &ok );
277 throw QgsProcessingException( QObject::tr(
"Invalid value for maximum: %1" ).arg( maxVariant.toString() ) );
280 const double value = f.
attribute( mValueFieldIdx ).toDouble( &ok );
284 classes << QgsReclassifyUtils::RasterClass( minValue, maxValue, boundsType, value );
294QString QgsReclassifyByTableAlgorithm::name()
const
296 return u
"reclassifybytable"_s;
299QString QgsReclassifyByTableAlgorithm::displayName()
const
301 return QObject::tr(
"Reclassify by table" );
304QStringList QgsReclassifyByTableAlgorithm::tags()
const
306 return QObject::tr(
"raster,reclassify,classes,calculator" ).split(
',' );
309QString QgsReclassifyByTableAlgorithm::shortHelpString()
const
311 return QObject::tr(
"This algorithm reclassifies a raster band by assigning new class values based on the ranges specified in a fixed table." );
314QString QgsReclassifyByTableAlgorithm::shortDescription()
const
316 return QObject::tr(
"Reclassifies a raster band by assigning new class values based on the ranges specified in a fixed table." );
319QgsReclassifyByTableAlgorithm *QgsReclassifyByTableAlgorithm::createInstance()
const
321 return new QgsReclassifyByTableAlgorithm();
324void QgsReclassifyByTableAlgorithm::addAlgorithmParams()
326 addParameter(
new QgsProcessingParameterMatrix( u
"TABLE"_s, QObject::tr(
"Reclassification table" ), 1,
false, QStringList() << QObject::tr(
"Minimum" ) << QObject::tr(
"Maximum" ) << QObject::tr(
"Value" ) ) );
334QVector<QgsReclassifyUtils::RasterClass> QgsReclassifyByTableAlgorithm::createClasses( QgsReclassifyUtils::RasterClass::BoundsType boundsType,
const QVariantMap ¶meters,
QgsProcessingContext &context,
QgsProcessingFeedback * )
336 const QVariantList table = parameterAsMatrix( parameters, u
"TABLE"_s, context );
337 if ( table.count() % 3 != 0 )
338 throw QgsProcessingException( QObject::tr(
"Invalid value for TABLE: list must contain a multiple of 3 elements (found %1)" ).arg( table.count() ) );
340 const int rows = table.count() / 3;
341 QVector<QgsReclassifyUtils::RasterClass> classes;
342 classes.reserve( rows );
343 for (
int row = 0; row < rows; ++row )
348 const QVariant minVariant = table.at( row * 3 );
352 minValue = std::numeric_limits<double>::quiet_NaN();
356 minValue = minVariant.toDouble( &ok );
358 throw QgsProcessingException( QObject::tr(
"Invalid value for minimum: %1" ).arg( table.at( row * 3 ).toString() ) );
360 const QVariant maxVariant = table.at( row * 3 + 1 );
364 maxValue = std::numeric_limits<double>::quiet_NaN();
369 maxValue = maxVariant.toDouble( &ok );
371 throw QgsProcessingException( QObject::tr(
"Invalid value for maximum: %1" ).arg( table.at( row * 3 + 1 ).toString() ) );
374 const double value = table.at( row * 3 + 2 ).toDouble( &ok );
376 throw QgsProcessingException( QObject::tr(
"Invalid output value: %1" ).arg( table.at( row * 3 + 2 ).toString() ) );
378 classes << QgsReclassifyUtils::RasterClass( minValue, maxValue, boundsType, value );
@ Vector
Tables (i.e. vector layers with or without geometry). When used for a sink this indicates the sink ha...
@ NoGeometry
Geometry is not required. It may still be returned if e.g. required for a filter condition.
@ Numeric
Accepts numeric fields.
@ Float32
Thirty two bit floating point (float).
@ Int8
Eight bit signed integer (qint8) (added in QGIS 3.30).
@ 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.
Wraps a request for features to a vector layer (or directly its vector data provider).
QgsFeatureRequest & setFlags(Qgis::FeatureRequestFlags flags)
Sets flags that affect how features will be fetched.
QgsFeatureRequest & setSubsetOfAttributes(const QgsAttributeList &attrs)
Set a subset of attributes that will be fetched.
The feature class encapsulates a single feature including its unique ID, geometry and a list of field...
Q_INVOKABLE QVariant attribute(const QString &name) const
Lookup attribute value by attribute name.
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.
A raster band parameter for Processing algorithms.
An input feature source (such as vector layers) parameter for processing algorithms.
A vector layer or feature source field parameter for processing algorithms.
A table (matrix) 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.
QgsRasterDataProvider * clone() const override=0
Clone itself, create deep copy.
Represents a raster layer.
int bandCount() const
Returns the number of bands in this layer.
double rasterUnitsPerPixelX() const
Returns the number of raster units per each raster pixel in X axis.
QgsRasterDataProvider * dataProvider() override
Returns the source data provider.
double rasterUnitsPerPixelY() const
Returns the number of raster units per each raster pixel in Y axis.
BoundsType
Handling for min and max bounds.
static bool isNull(const QVariant &variant, bool silenceNullWarnings=false)
Returns true if the specified variant should be considered a NULL value.
QList< int > QgsAttributeList