diff --git a/images/images.qrc b/images/images.qrc
index cf0cd27e2c3..dd58e4420a7 100644
--- a/images/images.qrc
+++ b/images/images.qrc
@@ -127,6 +127,7 @@
themes/default/algorithms/mAlgorithmRandomPointsWithinExtent.svg
themes/default/algorithms/mAlgorithmRandomPoissonRaster.svg
themes/default/algorithms/mAlgorithmRandomRaster.svg
+ themes/default/algorithms/mAlgorithmRasterCalculator.svg
themes/default/algorithms/mAlgorithmRegularPoints.svg
themes/default/algorithms/mAlgorithmRoundRastervalues.svg
themes/default/algorithms/mAlgorithmSelectLocation.svg
diff --git a/images/themes/default/algorithms/mAlgorithmRasterCalculator.svg b/images/themes/default/algorithms/mAlgorithmRasterCalculator.svg
new file mode 100644
index 00000000000..13d02247e75
--- /dev/null
+++ b/images/themes/default/algorithms/mAlgorithmRasterCalculator.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src/analysis/CMakeLists.txt b/src/analysis/CMakeLists.txt
index cf0d76e3969..54cb6ccd4fd 100644
--- a/src/analysis/CMakeLists.txt
+++ b/src/analysis/CMakeLists.txt
@@ -168,6 +168,7 @@ set(QGIS_ANALYSIS_SRCS
processing/qgsalgorithmrandompointsinpolygons.cpp
processing/qgsalgorithmrandompointsonlines.cpp
processing/qgsalgorithmrandomraster.cpp
+ processing/qgsalgorithmrastercalculator.cpp
processing/qgsalgorithmrasterdtmslopebasedfilter.cpp
processing/qgsalgorithmrasterfrequencybycomparisonoperator.cpp
processing/qgsalgorithmrasterlayerproperties.cpp
diff --git a/src/analysis/processing/qgsalgorithmrastercalculator.cpp b/src/analysis/processing/qgsalgorithmrastercalculator.cpp
new file mode 100644
index 00000000000..a33b9040177
--- /dev/null
+++ b/src/analysis/processing/qgsalgorithmrastercalculator.cpp
@@ -0,0 +1,80 @@
+/***************************************************************************
+ qgsalgorithmrastercalculator.cpp
+ ---------------------
+ begin : July 2023
+ copyright : (C) 2023 by Alexander Bruy
+ email : alexander dot bruy at gmail dot com
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#include "qgsalgorithmrastercalculator.h"
+#include "qgsrasterfilewriter.h"
+
+///@cond PRIVATE
+
+QString QgsRasterCalculatorAlgorithm::name() const
+{
+ return QStringLiteral( "rastercalc" );
+}
+
+QString QgsRasterCalculatorAlgorithm::displayName() const
+{
+ return QObject::tr( "Raster calculator" );
+}
+
+QStringList QgsRasterCalculatorAlgorithm::tags() const
+{
+ return QObject::tr( "raster,calculator" ).split( ',' );
+}
+
+QString QgsRasterCalculatorAlgorithm::group() const
+{
+ return QObject::tr( "Raster analysis" );
+}
+
+QString QgsRasterCalculatorAlgorithm::groupId() const
+{
+ return QStringLiteral( "rasteranalysis" );
+}
+
+QString QgsRasterCalculatorAlgorithm::shortHelpString() const
+{
+ return QObject::tr( "Performing algebraic operations using raster layers." );
+}
+
+QgsRasterCalculatorAlgorithm *QgsRasterCalculatorAlgorithm::createInstance() const
+{
+ return new QgsRasterCalculatorAlgorithm();
+}
+
+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 QgsProcessingParameterExtent( QStringLiteral( "EXTENT" ), QObject::tr( "Output extent" ), QVariant(), true ) );
+ addParameter( new QgsProcessingParameterNumber( QStringLiteral( "CELL_SIZE" ), QObject::tr( "Output cell size (leave empty to set automatically)" ), QgsProcessingParameterNumber::Double, QVariant(), true, 0.0 ) );
+ addParameter( new QgsProcessingParameterCrs( QStringLiteral( "CRS" ), QObject::tr( "Output CRS" ), QVariant(), true ) );
+ addParameter( new QgsProcessingParameterRasterDestination( QStringLiteral( "OUTPUT" ), QObject::tr( "Calculated" ) ) );
+}
+
+QVariantMap QgsRasterCalculatorAlgorithm::processAlgorithm( const QVariantMap ¶meters, QgsProcessingContext &context, QgsProcessingFeedback *feedback )
+{
+ const QString outputFile = parameterAsOutputLayer( parameters, QStringLiteral( "OUTPUT" ), context );
+ const QFileInfo fi( outputFile );
+ const QString outputFormat = QgsRasterFileWriter::driverForExtension( fi.suffix() );
+
+ QVariantMap outputs;
+ outputs.insert( QStringLiteral( "OUTPUT" ), outputFile );
+ return outputs;
+}
+
+///@endcond
+
diff --git a/src/analysis/processing/qgsalgorithmrastercalculator.h b/src/analysis/processing/qgsalgorithmrastercalculator.h
new file mode 100644
index 00000000000..3c088e4478e
--- /dev/null
+++ b/src/analysis/processing/qgsalgorithmrastercalculator.h
@@ -0,0 +1,57 @@
+/***************************************************************************
+ qgsalgorithmrastercalculator.h
+ ---------------------
+ begin : July 2023
+ copyright : (C) 2023 by Alexander Bruy
+ email : alexander dot bruy at gmail dot com
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#ifndef QGSALGORITHMRASTERCALCULATOR_H
+#define QGSALGORITHMRASTERCALCULATOR_H
+
+#define SIP_NO_FILE
+
+#include "qgis_sip.h"
+#include "qgsprocessingalgorithm.h"
+#include "qgsapplication.h"
+
+///@cond PRIVATE
+
+/**
+ * Native raster calculator algorithm.
+ */
+class QgsRasterCalculatorAlgorithm : public QgsProcessingAlgorithm
+{
+
+ public:
+
+ QgsRasterCalculatorAlgorithm() = default;
+ 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" ) ); }
+ QString name() const override;
+ QString displayName() const override;
+ QStringList tags() const override;
+ QString group() const override;
+ QString groupId() const override;
+ QString shortHelpString() const override;
+ QgsRasterCalculatorAlgorithm *createInstance() const override SIP_FACTORY;
+
+ protected:
+
+ QVariantMap processAlgorithm( const QVariantMap ¶meters,
+ QgsProcessingContext &context, QgsProcessingFeedback *feedback ) override;
+};
+
+///@endcond PRIVATE
+
+#endif // QGSALGORITHMRASTERCALCULATOR_H
diff --git a/src/analysis/processing/qgsnativealgorithms.cpp b/src/analysis/processing/qgsnativealgorithms.cpp
index 6e64d82366b..97b78498f1e 100644
--- a/src/analysis/processing/qgsnativealgorithms.cpp
+++ b/src/analysis/processing/qgsnativealgorithms.cpp
@@ -152,6 +152,7 @@
#include "qgsalgorithmrandompointsinpolygons.h"
#include "qgsalgorithmrandompointsonlines.h"
#include "qgsalgorithmrandomraster.h"
+#include "qgsalgorithmrastercalculator.h"
#include "qgsalgorithmrasterdtmslopebasedfilter.h"
#include "qgsalgorithmrasterfrequencybycomparisonoperator.h"
#include "qgsalgorithmrasterlayerproperties.h"
@@ -440,6 +441,7 @@ void QgsNativeAlgorithms::loadAlgorithms()
addAlgorithm( new QgsRandomPointsOnLinesAlgorithm() );
addAlgorithm( new QgsRandomPoissonRasterAlgorithm() );
addAlgorithm( new QgsRandomUniformRasterAlgorithm() );
+ addAlgorithm( new QgsRasterCalculatorAlgorithm() );
addAlgorithm( new QgsRasterDtmSlopeBasedFilterAlgorithm() );
addAlgorithm( new QgsRasterFrequencyByEqualOperatorAlgorithm() );
addAlgorithm( new QgsRasterFrequencyByGreaterThanOperatorAlgorithm() );