31 QString QgsReclassifyAlgorithmBase::group()
const
33 return QObject::tr(
"Raster analysis" );
36 QString QgsReclassifyAlgorithmBase::groupId()
const
38 return QStringLiteral(
"rasteranalysis" );
41 void QgsReclassifyAlgorithmBase::initAlgorithm(
const QVariantMap & )
44 QObject::tr(
"Raster layer" ) ) );
46 QObject::tr(
"Band number" ), 1, QStringLiteral(
"INPUT_RASTER" ) ) );
50 std::unique_ptr< QgsProcessingParameterNumber > noDataValueParam = qgis::make_unique< QgsProcessingParameterNumber >( QStringLiteral(
"NO_DATA" ),
53 addParameter( noDataValueParam.release() );
55 std::unique_ptr< QgsProcessingParameterEnum > boundsHandling = qgis::make_unique< QgsProcessingParameterEnum >( QStringLiteral(
"RANGE_BOUNDARIES" ),
56 QObject::tr(
"Range boundaries" ), QStringList() << QObject::tr(
"min < value <= max" )
57 << QObject::tr(
"min <= value < max" )
58 << QObject::tr(
"min <= value <= max" )
59 << QObject::tr(
"min < value < max" ),
62 addParameter( boundsHandling.release() );
64 std::unique_ptr< QgsProcessingParameterBoolean > missingValuesParam = qgis::make_unique< QgsProcessingParameterBoolean >( QStringLiteral(
"NODATA_FOR_MISSING" ),
65 QObject::tr(
"Use no data when no range matches value" ),
false,
false );
67 addParameter( missingValuesParam.release() );
69 std::unique_ptr< QgsProcessingParameterDefinition > typeChoice = QgsRasterAnalysisUtils::createRasterTypeParameter( QStringLiteral(
"DATA_TYPE" ), QObject::tr(
"Output data type" ),
Qgis::Float32 );
71 addParameter( typeChoice.release() );
78 mDataType = QgsRasterAnalysisUtils::rasterTypeChoiceToDataType( parameterAsEnum( parameters, QStringLiteral(
"DATA_TYPE" ), context ) );
79 QgsRasterLayer *layer = parameterAsRasterLayer( parameters, QStringLiteral(
"INPUT_RASTER" ), context );
84 mBand = parameterAsInt( parameters, QStringLiteral(
"RASTER_BAND" ), context );
85 if ( mBand < 1 || mBand > layer->
bandCount() )
86 throw QgsProcessingException( QObject::tr(
"Invalid band number for RASTER_BAND (%1): Valid values for input raster are 1 to %2" ).arg( mBand )
94 mNbCellsXProvider = mInterface->xSize();
95 mNbCellsYProvider = mInterface->ySize();
97 mNoDataValue = parameterAsDouble( parameters, QStringLiteral(
"NO_DATA" ), context );
98 mUseNoDataForMissingValues = parameterAsBoolean( parameters, QStringLiteral(
"NODATA_FOR_MISSING" ), context );
100 int boundsType = parameterAsEnum( parameters, QStringLiteral(
"RANGE_BOUNDARIES" ), context );
101 switch ( boundsType )
104 mBoundsType = QgsReclassifyUtils::RasterClass::IncludeMax;
108 mBoundsType = QgsReclassifyUtils::RasterClass::IncludeMin;
112 mBoundsType = QgsReclassifyUtils::RasterClass::IncludeMinAndMax;
116 mBoundsType = QgsReclassifyUtils::RasterClass::Exclusive;
120 return _prepareAlgorithm( parameters, context, feedback );
125 QVector< QgsReclassifyUtils::RasterClass > classes = createClasses( mBoundsType, parameters, context, feedback );
127 QgsReclassifyUtils::reportClasses( classes, feedback );
128 QgsReclassifyUtils::checkForOverlaps( classes, feedback );
130 const QString outputFile = parameterAsOutputLayer( parameters, QStringLiteral(
"OUTPUT" ), context );
131 QFileInfo fi( outputFile );
134 std::unique_ptr< QgsRasterFileWriter > writer = qgis::make_unique< QgsRasterFileWriter >( outputFile );
135 writer->setOutputProviderKey( QStringLiteral(
"gdal" ) );
136 writer->setOutputFormat( outputFormat );
137 std::unique_ptr<QgsRasterDataProvider > provider( writer->createOneBandRaster( mDataType, mNbCellsXProvider, mNbCellsYProvider, mExtent, mCrs ) );
140 if ( !provider->isValid() )
143 provider->setNoDataValue( 1, mNoDataValue );
145 QgsReclassifyUtils::reclassify( classes, mInterface.get(), mBand, mExtent, mNbCellsXProvider, mNbCellsYProvider, provider.get(), mNoDataValue, mUseNoDataForMissingValues,
149 outputs.insert( QStringLiteral(
"OUTPUT" ), outputFile );
158 QString QgsReclassifyByLayerAlgorithm::name()
const
160 return QStringLiteral(
"reclassifybylayer" );
163 QString QgsReclassifyByLayerAlgorithm::displayName()
const
165 return QObject::tr(
"Reclassify by layer" );
168 QStringList QgsReclassifyByLayerAlgorithm::tags()
const
170 return QObject::tr(
"raster,reclassify,classes,calculator" ).split(
',' );
173 QString QgsReclassifyByLayerAlgorithm::shortHelpString()
const
175 return QObject::tr(
"This algorithm reclassifies a raster band by assigning new class values based on the ranges specified in a vector table." );
178 QgsReclassifyByLayerAlgorithm *QgsReclassifyByLayerAlgorithm::createInstance()
const
180 return new QgsReclassifyByLayerAlgorithm();
183 void QgsReclassifyByLayerAlgorithm::addAlgorithmParams()
197 std::unique_ptr< QgsFeatureSource >tableSource( parameterAsSource( parameters, QStringLiteral(
"INPUT_TABLE" ), context ) );
201 QString fieldMin = parameterAsString( parameters, QStringLiteral(
"MIN_FIELD" ), context );
202 mMinFieldIdx = tableSource->fields().lookupField( fieldMin );
203 if ( mMinFieldIdx < 0 )
204 throw QgsProcessingException( QObject::tr(
"Invalid field specified for MIN_FIELD: %1" ).arg( fieldMin ) );
205 QString fieldMax = parameterAsString( parameters, QStringLiteral(
"MAX_FIELD" ), context );
206 mMaxFieldIdx = tableSource->fields().lookupField( fieldMax );
207 if ( mMaxFieldIdx < 0 )
208 throw QgsProcessingException( QObject::tr(
"Invalid field specified for MAX_FIELD: %1" ).arg( fieldMax ) );
209 QString fieldValue = parameterAsString( parameters, QStringLiteral(
"VALUE_FIELD" ), context );
210 mValueFieldIdx = tableSource->fields().lookupField( fieldValue );
211 if ( mValueFieldIdx < 0 )
212 throw QgsProcessingException( QObject::tr(
"Invalid field specified for VALUE_FIELD: %1" ).arg( fieldValue ) );
217 mTableIterator = tableSource->getFeatures( request );
224 QVector< QgsReclassifyUtils::RasterClass > classes;
226 while ( mTableIterator.nextFeature( f ) )
231 const QVariant minVariant = f.
attribute( mMinFieldIdx );
233 if ( minVariant.isNull() || minVariant.toString().isEmpty() )
235 minValue = std::numeric_limits<double>::quiet_NaN();
239 minValue = minVariant.toDouble( &ok );
241 throw QgsProcessingException( QObject::tr(
"Invalid value for minimum: %1" ).arg( minVariant.toString() ) );
243 const QVariant maxVariant = f.
attribute( mMaxFieldIdx );
245 if ( maxVariant.isNull() || maxVariant.toString().isEmpty() )
247 maxValue = std::numeric_limits<double>::quiet_NaN();
252 maxValue = maxVariant.toDouble( &ok );
254 throw QgsProcessingException( QObject::tr(
"Invalid value for maximum: %1" ).arg( maxVariant.toString() ) );
257 const double value = f.
attribute( mValueFieldIdx ).toDouble( &ok );
261 classes << QgsReclassifyUtils::RasterClass( minValue, maxValue, boundsType, value );
271 QString QgsReclassifyByTableAlgorithm::name()
const
273 return QStringLiteral(
"reclassifybytable" );
276 QString QgsReclassifyByTableAlgorithm::displayName()
const
278 return QObject::tr(
"Reclassify by table" );
281 QStringList QgsReclassifyByTableAlgorithm::tags()
const
283 return QObject::tr(
"raster,reclassify,classes,calculator" ).split(
',' );
286 QString QgsReclassifyByTableAlgorithm::shortHelpString()
const
288 return QObject::tr(
"This algorithm reclassifies a raster band by assigning new class values based on the ranges specified in a fixed table." );
291 QgsReclassifyByTableAlgorithm *QgsReclassifyByTableAlgorithm::createInstance()
const
293 return new QgsReclassifyByTableAlgorithm();
296 void QgsReclassifyByTableAlgorithm::addAlgorithmParams()
299 QObject::tr(
"Reclassification table" ),
300 1,
false, QStringList() << QObject::tr(
"Minimum" )
301 << QObject::tr(
"Maximum" )
302 << QObject::tr(
"Value" ) ) );
310 QVector<QgsReclassifyUtils::RasterClass> QgsReclassifyByTableAlgorithm::createClasses( QgsReclassifyUtils::RasterClass::BoundsType boundsType,
const QVariantMap ¶meters,
QgsProcessingContext &context,
QgsProcessingFeedback * )
312 const QVariantList table = parameterAsMatrix( parameters, QStringLiteral(
"TABLE" ), context );
313 if ( table.count() % 3 != 0 )
314 throw QgsProcessingException( QObject::tr(
"Invalid value for TABLE: list must contain a multiple of 3 elements (found %1)" ).arg( table.count() ) );
316 const int rows = table.count() / 3;
317 QVector< QgsReclassifyUtils::RasterClass > classes;
318 classes.reserve( rows );
319 for (
int row = 0; row < rows; ++row )
324 const QVariant minVariant = table.at( row * 3 );
326 if ( minVariant.isNull() || minVariant.toString().isEmpty() )
328 minValue = std::numeric_limits<double>::quiet_NaN();
332 minValue = minVariant.toDouble( &ok );
334 throw QgsProcessingException( QObject::tr(
"Invalid value for minimum: %1" ).arg( table.at( row * 3 ).toString() ) );
336 const QVariant maxVariant = table.at( row * 3 + 1 );
338 if ( maxVariant.isNull() || maxVariant.toString().isEmpty() )
340 maxValue = std::numeric_limits<double>::quiet_NaN();
345 maxValue = maxVariant.toDouble( &ok );
347 throw QgsProcessingException( QObject::tr(
"Invalid value for maximum: %1" ).arg( table.at( row * 3 + 1 ).toString() ) );
350 const double value = table.at( row * 3 + 2 ).toDouble( &ok );
352 throw QgsProcessingException( QObject::tr(
"Invalid output value: %1" ).arg( table.at( row * 3 + 2 ).toString() ) );
354 classes << QgsReclassifyUtils::RasterClass( minValue, maxValue, boundsType, value );