From 3c1f510115101f16c412524808e556f405499c2c Mon Sep 17 00:00:00 2001 From: Alexander Bruy Date: Fri, 15 Sep 2023 13:44:42 +0300 Subject: [PATCH] add modeler support and deprecate Python implementation --- .../processing/algs/qgis/RasterCalculator.py | 4 + .../tests/testdata/qgis_algorithm_tests2.yaml | 9 +- .../qgsalgorithmrastercalculator.cpp | 166 +++++++++++++++++- .../processing/qgsalgorithmrastercalculator.h | 30 +++- .../qgsalgorithmvirtualrastercalculator.cpp | 163 ++++++++++++++++- .../qgsalgorithmvirtualrastercalculator.h | 28 ++- .../processing/qgsnativealgorithms.cpp | 2 + ...singrastercalculatorexpressionlineedit.cpp | 2 +- .../qgsprocessingwidgetwrapperimpl.cpp | 4 + 9 files changed, 394 insertions(+), 14 deletions(-) diff --git a/python/plugins/processing/algs/qgis/RasterCalculator.py b/python/plugins/processing/algs/qgis/RasterCalculator.py index 9367b263fa9c..2ea965b5c8fc 100644 --- a/python/plugins/processing/algs/qgis/RasterCalculator.py +++ b/python/plugins/processing/algs/qgis/RasterCalculator.py @@ -24,6 +24,7 @@ from processing.algs.qgis.QgisAlgorithm import QgisAlgorithm from processing.algs.gdal.GdalUtils import GdalUtils from qgis.core import (QgsProcessing, + QgsProcessingAlgorithm, QgsProcessingException, QgsProcessingUtils, QgsProcessingParameterCrs, @@ -88,6 +89,9 @@ def clone(self): self.addParameter(QgsProcessingParameterCrs(self.CRS, 'Output CRS', optional=True)) self.addParameter(QgsProcessingParameterRasterDestination(self.OUTPUT, self.tr('Output'))) + def flags(self): + return super().flags() | QgsProcessingAlgorithm.FlagDeprecated | QgsProcessingAlgorithm.FlagNotAvailableInStandaloneTool + def name(self): return 'rastercalculator' diff --git a/python/plugins/processing/tests/testdata/qgis_algorithm_tests2.yaml b/python/plugins/processing/tests/testdata/qgis_algorithm_tests2.yaml index 9a1040ed9b95..f43816b277bc 100644 --- a/python/plugins/processing/tests/testdata/qgis_algorithm_tests2.yaml +++ b/python/plugins/processing/tests/testdata/qgis_algorithm_tests2.yaml @@ -1190,7 +1190,7 @@ tests: - 'Maximum value: 15:29:22' - 'NULL \(missing\) values: 1' - - algorithm: qgis:rastercalculator + - algorithm: native:rastercalc name: Raster Calculator with cellsize params: LAYERS: @@ -1199,13 +1199,14 @@ tests: type: raster type: multi CELLSIZE: 0.001 - EXPRESSION: dem@1 + EXPRESSION: '"dem.tif@1"' results: OUTPUT: hash: 525577c05dd999239d9c6f95fd5e70d96355da3a0ea71bfcf021e729 + hash: 6ced822cc490c7a3d9346b6c8cd4b282eb4e2a9fdd6e7371f6174117 type: rasterhash - - algorithm: qgis:rastercalculator + - algorithm: native:rastercalc name: Raster Calculator params: LAYERS: @@ -1214,7 +1215,7 @@ tests: type: raster type: multi CELLSIZE: 0.0 - EXPRESSION: dem@1 * 2 + EXPRESSION: '"dem.tif@1" * 2' results: OUTPUT: hash: 98daf025230ec9d031f7502c6a80a3b04dd060808d6b7bcb4328e87c diff --git a/src/analysis/processing/qgsalgorithmrastercalculator.cpp b/src/analysis/processing/qgsalgorithmrastercalculator.cpp index d3729fac4681..217fd650c728 100644 --- a/src/analysis/processing/qgsalgorithmrastercalculator.cpp +++ b/src/analysis/processing/qgsalgorithmrastercalculator.cpp @@ -21,6 +21,11 @@ ///@cond PRIVATE +QgsProcessingAlgorithm::Flags QgsRasterCalculatorAlgorithm::flags() const +{ + return QgsProcessingAlgorithm::flags() | QgsProcessingAlgorithm::FlagHideFromModeler; +} + QString QgsRasterCalculatorAlgorithm::name() const { return QStringLiteral( "rastercalc" ); @@ -59,8 +64,8 @@ QgsRasterCalculatorAlgorithm *QgsRasterCalculatorAlgorithm::createInstance() con void QgsRasterCalculatorAlgorithm::initAlgorithm( const QVariantMap & ) { - addParameter( new QgsProcessingParameterMultipleLayers( QStringLiteral( "INPUT" ), QObject::tr( "Input layers" ), QgsProcessing::SourceType::TypeRaster ) ); - addParameter( new QgsProcessingParameterExpression( QStringLiteral( "EXPRESSION" ), QObject::tr( "Expression" ), QVariant(), QStringLiteral( "INPUT" ), false, Qgis::ExpressionType::RasterCalculator ) ); + addParameter( new QgsProcessingParameterMultipleLayers( QStringLiteral( "LAYERS" ), QObject::tr( "Input layers" ), QgsProcessing::SourceType::TypeRaster ) ); + addParameter( new QgsProcessingParameterExpression( QStringLiteral( "EXPRESSION" ), QObject::tr( "Expression" ), QVariant(), QStringLiteral( "LAYERS" ), false, Qgis::ExpressionType::RasterCalculator ) ); std::unique_ptr extentParam = std::make_unique( QStringLiteral( "EXTENT" ), QObject::tr( "Output extent" ), QVariant(), true ); extentParam->setHelp( QObject::tr( "Extent of the output layer. If not specified, the extent will be the overall extent of all input layers" ) ); addParameter( extentParam.release() ); @@ -75,7 +80,7 @@ void QgsRasterCalculatorAlgorithm::initAlgorithm( const QVariantMap & ) bool QgsRasterCalculatorAlgorithm::prepareAlgorithm( const QVariantMap ¶meters, QgsProcessingContext &context, QgsProcessingFeedback *feedback ) { - const QList< QgsMapLayer * > layers = parameterAsLayerList( parameters, QStringLiteral( "INPUT" ), context ); + const QList< QgsMapLayer * > layers = parameterAsLayerList( parameters, QStringLiteral( "LAYERS" ), context ); for ( const QgsMapLayer *layer : std::as_const( layers ) ) { @@ -198,5 +203,160 @@ QVariantMap QgsRasterCalculatorAlgorithm::processAlgorithm( const QVariantMap &p return outputs; } +QgsProcessingAlgorithm::Flags QgsRasterCalculatorModelerAlgorithm::flags() const +{ + return QgsProcessingAlgorithm::flags() | QgsProcessingAlgorithm::FlagHideFromToolbox; +} + +QString QgsRasterCalculatorModelerAlgorithm::name() const +{ + return QStringLiteral( "modelerrastercalc" ); +} + +QString QgsRasterCalculatorModelerAlgorithm::displayName() const +{ + return QObject::tr( "Raster calculator" ); +} + +QStringList QgsRasterCalculatorModelerAlgorithm::tags() const +{ + return QObject::tr( "raster,calculator" ).split( ',' ); +} + +QString QgsRasterCalculatorModelerAlgorithm::group() const +{ + return QObject::tr( "Raster analysis" ); +} + +QString QgsRasterCalculatorModelerAlgorithm::groupId() const +{ + return QStringLiteral( "rasteranalysis" ); +} + +QgsRasterCalculatorModelerAlgorithm *QgsRasterCalculatorModelerAlgorithm::createInstance() const +{ + return new QgsRasterCalculatorModelerAlgorithm(); +} + +QVariantMap QgsRasterCalculatorModelerAlgorithm::processAlgorithm( const QVariantMap ¶meters, QgsProcessingContext &context, QgsProcessingFeedback *feedback ) +{ + for ( QgsMapLayer *layer : std::as_const( mLayers ) ) + { + layer->moveToThread( QThread::currentThread() ); + } + + QgsCoordinateReferenceSystem crs; + if ( parameters.value( QStringLiteral( "CRS" ) ).isValid() ) + { + crs = parameterAsCrs( parameters, QStringLiteral( "CRS" ), context ); + } + else + { + crs = mLayers.at( 0 )->crs(); + } + + QgsRectangle bbox; + if ( parameters.value( QStringLiteral( "EXTENT" ) ).isValid() ) + { + bbox = parameterAsExtent( parameters, QStringLiteral( "EXTENT" ), context, crs ); + } + else + { + bbox = QgsProcessingUtils::combineLayerExtents( mLayers, crs, context ); + } + + double minCellSize = 1e9; + + QVector< QgsRasterCalculatorEntry > entries; + int n = 0; + for ( QgsMapLayer *layer : mLayers ) + { + QgsRasterLayer *rLayer = static_cast( layer ); + if ( !rLayer ) + { + continue; + } + + n++; + const int nBands = rLayer->dataProvider()->bandCount(); + for ( int i = 0; i < nBands; ++i ) + { + QgsRasterCalculatorEntry entry; + entry.ref = QStringLiteral( "%1@%2" ).arg( indexToName( n ) ).arg( i + 1 ); + entry.raster = rLayer; + entry.bandNumber = i + 1; + entries << entry; + } + + QgsRectangle ext = rLayer->extent(); + if ( rLayer->crs() != crs ) + { + QgsCoordinateTransform ct( rLayer->crs(), crs, context.transformContext() ); + ext = ct.transformBoundingBox( ext ); + } + + double cellSize = ( ext.xMaximum() - ext.xMinimum() ) / rLayer->width(); + if ( cellSize < minCellSize ) + { + minCellSize = cellSize; + } + } + + double cellSize = parameterAsDouble( parameters, QStringLiteral( "CELL_SIZE" ), context ); + if ( cellSize == 0 ) + { + cellSize = minCellSize; + } + + const QString expression = parameterAsExpression( parameters, QStringLiteral( "EXPRESSION" ), context ); + const QString outputFile = parameterAsOutputLayer( parameters, QStringLiteral( "OUTPUT" ), context ); + const QFileInfo fi( outputFile ); + const QString outputFormat = QgsRasterFileWriter::driverForExtension( fi.suffix() ); + + double width = std::round( ( bbox.xMaximum() - bbox.xMinimum() ) / cellSize ); + double height = std::round( ( bbox.yMaximum() - bbox.yMinimum() ) / cellSize ); + + QgsRasterCalculator calc( expression, outputFile, outputFormat, bbox, crs, width, height, entries, context.transformContext() ); + QgsRasterCalculator::Result result = calc.processCalculation( feedback ); + qDeleteAll( mLayers ); + mLayers.clear(); + switch ( result ) + { + case QgsRasterCalculator::CreateOutputError: + throw QgsProcessingException( QObject::tr( "Error creating output file." ) ); + case QgsRasterCalculator::InputLayerError: + throw QgsProcessingException( QObject::tr( "Error reading input layer." ) ); + case QgsRasterCalculator::ParserError: + throw QgsProcessingException( QObject::tr( "Error parsing formula." ) ); + case QgsRasterCalculator::MemoryError: + throw QgsProcessingException( QObject::tr( "Error allocating memory for result." ) ); + case QgsRasterCalculator::BandError: + throw QgsProcessingException( QObject::tr( "Invalid band number for input." ) ); + case QgsRasterCalculator::CalculationError: + throw QgsProcessingException( QObject::tr( "Error occurred while performing calculation." ) ); + default: + break; + } + + QVariantMap outputs; + outputs.insert( QStringLiteral( "OUTPUT" ), outputFile ); + return outputs; +} + +QString QgsRasterCalculatorModelerAlgorithm::indexToName( int index ) const +{ + QString name; + int div = index; + int mod = 0; + + while ( div > 0 ) + { + mod = ( div - 1 ) % 26; + name = static_cast( 65 + mod ) + name; + div = ( int )( ( div - mod ) / 26 ); + } + return name; +} + ///@endcond diff --git a/src/analysis/processing/qgsalgorithmrastercalculator.h b/src/analysis/processing/qgsalgorithmrastercalculator.h index 469c36101b81..1521e17cba42 100644 --- a/src/analysis/processing/qgsalgorithmrastercalculator.h +++ b/src/analysis/processing/qgsalgorithmrastercalculator.h @@ -38,6 +38,7 @@ class QgsRasterCalculatorAlgorithm : public QgsProcessingAlgorithm void initAlgorithm( const QVariantMap &configuration = QVariantMap() ) override; QIcon icon() const override { return QgsApplication::getThemeIcon( QStringLiteral( "/algorithms/mAlgorithmRasterCalculator.svg" ) ); } QString svgIconPath() const override { return QgsApplication::iconPath( QStringLiteral( "/algorithms/mAlgorithmRasterCalculator.svg" ) ); } + Flags flags() const override; QString name() const override; QString displayName() const override; QStringList tags() const override; @@ -53,10 +54,37 @@ class QgsRasterCalculatorAlgorithm : public QgsProcessingAlgorithm QVariantMap processAlgorithm( const QVariantMap ¶meters, QgsProcessingContext &context, QgsProcessingFeedback *feedback ) override; - private: QList< QgsMapLayer * > mLayers; }; +class QgsRasterCalculatorModelerAlgorithm : public QgsRasterCalculatorAlgorithm +{ + + public: + + QgsRasterCalculatorModelerAlgorithm() = default; + Flags flags() const override; + QString name() const override; + QString displayName() const override; + QStringList tags() const override; + QString group() const override; + QString groupId() const override; + QgsRasterCalculatorModelerAlgorithm *createInstance() const override SIP_FACTORY; + + protected: + + QVariantMap processAlgorithm( const QVariantMap ¶meters, + QgsProcessingContext &context, QgsProcessingFeedback *feedback ) override; + + private: + + /** + * Generates Excel-like names from the number + * A, B, C, …, Y, Z, AA, AB, AC, …, AZ, BA, BB, BC… + */ + QString indexToName( int index ) const; +}; + ///@endcond PRIVATE #endif // QGSALGORITHMRASTERCALCULATOR_H diff --git a/src/analysis/processing/qgsalgorithmvirtualrastercalculator.cpp b/src/analysis/processing/qgsalgorithmvirtualrastercalculator.cpp index 06e6439663e4..2a773507e926 100644 --- a/src/analysis/processing/qgsalgorithmvirtualrastercalculator.cpp +++ b/src/analysis/processing/qgsalgorithmvirtualrastercalculator.cpp @@ -22,7 +22,7 @@ QgsProcessingAlgorithm::Flags QgsVirtualRasterCalculatorAlgorithm::flags() const { - return QgsProcessingAlgorithm::flags() | QgsProcessingAlgorithm::FlagNoThreading; + return QgsProcessingAlgorithm::flags() | QgsProcessingAlgorithm::FlagNoThreading | FlagHideFromModeler; } QString QgsVirtualRasterCalculatorAlgorithm::name() const @@ -62,8 +62,8 @@ QgsVirtualRasterCalculatorAlgorithm *QgsVirtualRasterCalculatorAlgorithm::create void QgsVirtualRasterCalculatorAlgorithm::initAlgorithm( const QVariantMap & ) { - addParameter( new QgsProcessingParameterMultipleLayers( QStringLiteral( "INPUT" ), QObject::tr( "Input layers" ), QgsProcessing::SourceType::TypeRaster ) ); - addParameter( new QgsProcessingParameterExpression( QStringLiteral( "EXPRESSION" ), QObject::tr( "Expression" ), QVariant(), QStringLiteral( "INPUT" ), false, Qgis::ExpressionType::RasterCalculator ) ); + addParameter( new QgsProcessingParameterMultipleLayers( QStringLiteral( "LAYERS" ), QObject::tr( "Input layers" ), QgsProcessing::SourceType::TypeRaster ) ); + addParameter( new QgsProcessingParameterExpression( QStringLiteral( "EXPRESSION" ), QObject::tr( "Expression" ), QVariant(), QStringLiteral( "LAYERS" ), false, Qgis::ExpressionType::RasterCalculator ) ); std::unique_ptr extentParam = std::make_unique( QStringLiteral( "EXTENT" ), QObject::tr( "Output extent" ), QVariant(), true ); extentParam->setHelp( QObject::tr( "Extent of the output layer. If not specified, the extent will be the overall extent of all input layers" ) ); addParameter( extentParam.release() ); @@ -81,7 +81,7 @@ QVariantMap QgsVirtualRasterCalculatorAlgorithm::processAlgorithm( const QVarian { Q_UNUSED( feedback ); - const QList< QgsMapLayer * > layers = parameterAsLayerList( parameters, QStringLiteral( "INPUT" ), context ); + const QList< QgsMapLayer * > layers = parameterAsLayerList( parameters, QStringLiteral( "LAYERS" ), context ); if ( layers.isEmpty() ) { throw QgsProcessingException( QObject::tr( "No input layers selected" ) ); @@ -180,4 +180,159 @@ QVariantMap QgsVirtualRasterCalculatorAlgorithm::processAlgorithm( const QVarian return outputs; } +QgsProcessingAlgorithm::Flags QgsVirtualRasterCalculatorModelerAlgorithm::flags() const +{ + return QgsProcessingAlgorithm::flags() | QgsProcessingAlgorithm::FlagNoThreading | FlagHideFromToolbox; +} + +QString QgsVirtualRasterCalculatorModelerAlgorithm::name() const +{ + return QStringLiteral( "modelervirtualrastercalc" ); +} + +QString QgsVirtualRasterCalculatorModelerAlgorithm::displayName() const +{ + return QObject::tr( "Raster calculator (virtual)" ); +} + +QStringList QgsVirtualRasterCalculatorModelerAlgorithm::tags() const +{ + return QObject::tr( "raster,calculator,virtual" ).split( ',' ); +} + +QString QgsVirtualRasterCalculatorModelerAlgorithm::group() const +{ + return QObject::tr( "Raster analysis" ); +} + +QString QgsVirtualRasterCalculatorModelerAlgorithm::groupId() const +{ + return QStringLiteral( "rasteranalysis" ); +} + +QgsVirtualRasterCalculatorModelerAlgorithm *QgsVirtualRasterCalculatorModelerAlgorithm::createInstance() const +{ + return new QgsVirtualRasterCalculatorModelerAlgorithm(); +} + +QVariantMap QgsVirtualRasterCalculatorModelerAlgorithm::processAlgorithm( const QVariantMap ¶meters, QgsProcessingContext &context, QgsProcessingFeedback *feedback ) +{ + Q_UNUSED( feedback ); + + const QList< QgsMapLayer * > layers = parameterAsLayerList( parameters, QStringLiteral( "INPUT" ), context ); + if ( layers.isEmpty() ) + { + throw QgsProcessingException( QObject::tr( "No input layers selected" ) ); + } + + QgsCoordinateReferenceSystem crs; + if ( parameters.value( QStringLiteral( "CRS" ) ).isValid() ) + { + crs = parameterAsCrs( parameters, QStringLiteral( "CRS" ), context ); + } + else + { + crs = layers.at( 0 )->crs(); + } + + QgsRectangle bbox; + if ( parameters.value( QStringLiteral( "EXTENT" ) ).isValid() ) + { + bbox = parameterAsExtent( parameters, QStringLiteral( "EXTENT" ), context, crs ); + } + else + { + bbox = QgsProcessingUtils::combineLayerExtents( layers, crs, context ); + } + + double minCellSize = 1e9; + QgsRasterDataProvider::VirtualRasterParameters rasterParameters; + + int n = 0; + for ( const QgsMapLayer *layer : layers ) + { + const QgsRasterLayer *rLayer = static_cast( layer ); + if ( !rLayer ) + { + continue; + } + + n++; + QgsRasterDataProvider::VirtualRasterInputLayers rasterLayer; + rasterLayer.name = indexToName( n ); + rasterLayer.provider = rLayer->dataProvider()->name(); + rasterLayer.uri = rLayer->source(); + rasterParameters.rInputLayers.append( rasterLayer ); + + QgsRectangle ext = rLayer->extent(); + if ( rLayer->crs() != crs ) + { + QgsCoordinateTransform ct( rLayer->crs(), crs, context.transformContext() ); + ext = ct.transformBoundingBox( ext ); + } + + double cellSize = ( ext.xMaximum() - ext.xMinimum() ) / rLayer->width(); + if ( cellSize < minCellSize ) + { + minCellSize = cellSize; + } + } + + double cellSize = parameterAsDouble( parameters, QStringLiteral( "CELL_SIZE" ), context ); + if ( cellSize == 0 ) + { + cellSize = minCellSize; + } + + const QString expression = parameterAsExpression( parameters, QStringLiteral( "EXPRESSION" ), context ); + QString layerName = parameterAsString( parameters, QStringLiteral( "LAYER_NAME" ), context ); + if ( layerName.isEmpty() ) + { + layerName = expression; + } + + double width = std::round( ( bbox.xMaximum() - bbox.xMinimum() ) / cellSize ); + double height = std::round( ( bbox.yMaximum() - bbox.yMinimum() ) / cellSize ); + + rasterParameters.crs = crs; + rasterParameters.extent = bbox; + rasterParameters.width = width; + rasterParameters.height = height; + rasterParameters.formula = expression; + + std::unique_ptr< QgsRasterLayer > layer; + layer = std::make_unique< QgsRasterLayer >( QgsRasterDataProvider::encodeVirtualRasterProviderUri( rasterParameters ), + layerName, QStringLiteral( "virtualraster" ) ); + if ( !layer->isValid() ) + { + feedback->reportError( QObject::tr( "Failed to create virtual raster layer" ) ); + } + else + { + } + const QString layerId = layer->id(); + const QgsProcessingContext::LayerDetails details( layer->name(), context.project(), QStringLiteral( "OUTPUT" ), QgsProcessingUtils::LayerHint::Raster ); + context.addLayerToLoadOnCompletion( layerId, details ); + context.temporaryLayerStore()->addMapLayer( layer.release() ); + + QVariantMap outputs; + outputs.insert( QStringLiteral( "OUTPUT" ), layerId ); + return outputs; +} + +QString QgsVirtualRasterCalculatorModelerAlgorithm::indexToName( int index ) const +{ + QString name; + int div = index; + int mod = 0; + + while ( div > 0 ) + { + mod = ( div - 1 ) % 26; + name = static_cast( 65 + mod ) + name; + div = ( int )( ( div - mod ) / 26 ); + } + return name; +} + ///@endcond diff --git a/src/analysis/processing/qgsalgorithmvirtualrastercalculator.h b/src/analysis/processing/qgsalgorithmvirtualrastercalculator.h index 84448d5c1e7a..a73b5347e0d8 100644 --- a/src/analysis/processing/qgsalgorithmvirtualrastercalculator.h +++ b/src/analysis/processing/qgsalgorithmvirtualrastercalculator.h @@ -52,10 +52,36 @@ class QgsVirtualRasterCalculatorAlgorithm : public QgsProcessingAlgorithm QVariantMap processAlgorithm( const QVariantMap ¶meters, QgsProcessingContext &context, QgsProcessingFeedback *feedback ) override; - private: QList< QgsMapLayer * > mLayers; }; +class QgsVirtualRasterCalculatorModelerAlgorithm : public QgsVirtualRasterCalculatorAlgorithm +{ + + public: + + QgsVirtualRasterCalculatorModelerAlgorithm() = default; + Flags flags() const override; + QString name() const override; + QString displayName() const override; + QStringList tags() const override; + QString group() const override; + QString groupId() const override; + QgsVirtualRasterCalculatorModelerAlgorithm *createInstance() const override SIP_FACTORY; + + protected: + + QVariantMap processAlgorithm( const QVariantMap ¶meters, + QgsProcessingContext &context, QgsProcessingFeedback *feedback ) override; + private: + + /** + * Generates Excel-like names from the number + * A, B, C, …, Y, Z, AA, AB, AC, …, AZ, BA, BB, BC… + */ + QString indexToName( int index ) const; +}; + ///@endcond PRIVATE #endif // QGSALGORITHMVIRTUALRASTERCALCULATOR_H diff --git a/src/analysis/processing/qgsnativealgorithms.cpp b/src/analysis/processing/qgsnativealgorithms.cpp index a47107062d09..3b3697653701 100644 --- a/src/analysis/processing/qgsnativealgorithms.cpp +++ b/src/analysis/processing/qgsnativealgorithms.cpp @@ -443,6 +443,7 @@ void QgsNativeAlgorithms::loadAlgorithms() addAlgorithm( new QgsRandomPoissonRasterAlgorithm() ); addAlgorithm( new QgsRandomUniformRasterAlgorithm() ); addAlgorithm( new QgsRasterCalculatorAlgorithm() ); + addAlgorithm( new QgsRasterCalculatorModelerAlgorithm() ); addAlgorithm( new QgsRasterDtmSlopeBasedFilterAlgorithm() ); addAlgorithm( new QgsRasterFrequencyByEqualOperatorAlgorithm() ); addAlgorithm( new QgsRasterFrequencyByGreaterThanOperatorAlgorithm() ); @@ -525,6 +526,7 @@ void QgsNativeAlgorithms::loadAlgorithms() addAlgorithm( new QgsUnionAlgorithm() ); addAlgorithm( new QgsVariableWidthBufferByMAlgorithm() ); addAlgorithm( new QgsVirtualRasterCalculatorAlgorithm() ); + addAlgorithm( new QgsVirtualRasterCalculatorModelerAlgorithm() ); addAlgorithm( new QgsWedgeBuffersAlgorithm() ); addAlgorithm( new QgsWriteVectorTilesXyzAlgorithm() ); addAlgorithm( new QgsWriteVectorTilesMbtilesAlgorithm() ); diff --git a/src/gui/processing/qgsprocessingrastercalculatorexpressionlineedit.cpp b/src/gui/processing/qgsprocessingrastercalculatorexpressionlineedit.cpp index 52d9d12d69b6..b4ae5f88f642 100644 --- a/src/gui/processing/qgsprocessingrastercalculatorexpressionlineedit.cpp +++ b/src/gui/processing/qgsprocessingrastercalculatorexpressionlineedit.cpp @@ -176,7 +176,7 @@ QString QgsProcessingRasterCalculatorExpressionDialog::quoteBandEntry( const QSt void QgsProcessingRasterCalculatorExpressionDialog::mLayersList_itemDoubleClicked( QListWidgetItem *item ) { - mExpressionTextEdit->insertPlainText( quoteBandEntry( item->text() ) ); + mExpressionTextEdit->insertPlainText( quoteBandEntry( QStringLiteral( "%1@1" ).arg( item->text() ) ) ); } void QgsProcessingRasterCalculatorExpressionDialog::mBtnPlus_clicked() diff --git a/src/gui/processing/qgsprocessingwidgetwrapperimpl.cpp b/src/gui/processing/qgsprocessingwidgetwrapperimpl.cpp index 020f75226eef..395fa9a8a16f 100644 --- a/src/gui/processing/qgsprocessingwidgetwrapperimpl.cpp +++ b/src/gui/processing/qgsprocessingwidgetwrapperimpl.cpp @@ -2303,6 +2303,10 @@ QWidget *QgsProcessingExpressionWidgetWrapper::createWidget() { mRasterCalculatorExpLineEdit = new QgsProcessingRasterCalculatorExpressionLineEdit(); mRasterCalculatorExpLineEdit->setToolTip( parameterDefinition()->toolTip() ); + if ( type() == QgsProcessingGui::Modeler ) + { + mRasterCalculatorExpLineEdit->setLayers( QVariantList() << "A" << "B" << "C" << "D" << "E" << "F" << "G" ); + } connect( mRasterCalculatorExpLineEdit, &QgsProcessingRasterCalculatorExpressionLineEdit::expressionChanged, this, [ = ]( const QString & ) { emit widgetValueHasChanged( this );