41   , mFunctionName( functionName )
 
   42   , mFunctionArgs( functionArgs )
 
   48   , mRasterName( rasterName )
 
   50   if ( mRasterName.startsWith( 
'"' ) && mRasterName.endsWith( 
'"' ) )
 
   51     mRasterName = mRasterName.mid( 1, mRasterName.size() - 2 );
 
   67     const QMap<QString, QgsRasterBlock *>::iterator it = rasterData.find( mRasterName );
 
   68     if ( it == rasterData.end() )
 
   70       QgsDebugMsg( QStringLiteral( 
"Error: could not find raster data for \"%1\"" ).arg( mRasterName ) );
 
   74     const int nRows = ( row >= 0 ? 1 : ( *it )->height() );
 
   75     const int startRow = ( row >= 0 ? row : 0 );
 
   76     const int endRow = startRow + nRows;
 
   77     const int nCols = ( *it )->width();
 
   78     const int nEntries = nCols * nRows;
 
   79     double *data = 
new double[nEntries];
 
   84     bool isNoData = 
false;
 
   85     for ( 
int dataRow = startRow; dataRow < endRow ; ++dataRow, ++outRow )
 
   87       for ( 
int dataCol = 0; dataCol < nCols; ++dataCol )
 
   89         const double value = ( *it )->valueAndNoData( dataRow, dataCol, isNoData );
 
   90         data[ dataCol + nCols * outRow] = isNoData ? result.
nodataValue() : value;
 
  101     if ( !mLeft || !mLeft->
calculate( rasterData, leftMatrix, row ) )
 
  105     if ( mRight && !mRight->
calculate( rasterData, rightMatrix, row ) )
 
  113         leftMatrix.
add( rightMatrix );
 
  122         leftMatrix.
divide( rightMatrix );
 
  125         leftMatrix.
power( rightMatrix );
 
  128         leftMatrix.
equal( rightMatrix );
 
  152         leftMatrix.
min( rightMatrix );
 
  155         leftMatrix.
max( rightMatrix );
 
  193     const int newNColumns = leftMatrix.
nColumns();
 
  194     const int newNRows = leftMatrix.
nRows();
 
  200     const size_t nEntries = 
static_cast<size_t>( result.
nColumns() * result.
nRows() );
 
  201     double *data = 
new double[ nEntries ];
 
  202     std::fill( data, data + nEntries, mNumber );
 
  210     double *data = 
new double[nEntries];
 
  211     for ( 
int i = 0; i < nEntries; ++i )
 
  220     QVector <QgsRasterMatrix *> matrixContainer;
 
  221     for ( 
int i = 0; i < mFunctionArgs.size(); ++i )
 
  224       if ( !mFunctionArgs.at( i ) || !mFunctionArgs.at( i )->calculate( rasterData, *singleMatrix, row ) )
 
  228       matrixContainer.append( singleMatrix.release() );
 
  230     evaluateFunction( matrixContainer, result );
 
  252           result = QStringLiteral( 
"( %1 + %2 )" ).arg( left ).arg( right );
 
  255           result = QStringLiteral( 
"( %1 - %2 )" ).arg( left ).arg( right );
 
  258           result = QStringLiteral( 
"-%1" ).arg( left );
 
  261           result = QStringLiteral( 
"%1 * %2" ).arg( left ).arg( right );
 
  264           result = QStringLiteral( 
"%1 / %2" ).arg( left ).arg( right );
 
  268             result = QStringLiteral( 
"pow( %1, %2 )" ).arg( left ).arg( right );
 
  270             result = QStringLiteral( 
"%1^%2" ).arg( left ).arg( right );
 
  274             result = QStringLiteral( 
"( float ) ( %1 == %2 )" ).arg( left ).arg( right );
 
  276             result = QStringLiteral( 
"%1 = %2" ).arg( left ).arg( right );
 
  280             result = QStringLiteral( 
"( float ) ( %1 != %2 )" ).arg( left ).arg( right );
 
  282             result = QStringLiteral( 
"%1 != %2" ).arg( left ).arg( right );
 
  286             result = QStringLiteral( 
"( float ) ( %1 > %2 )" ).arg( left ).arg( right );
 
  288             result = QStringLiteral( 
"%1 > %2" ).arg( left ).arg( right );
 
  292             result = QStringLiteral( 
"( float ) ( %1 < %2 )" ).arg( left ).arg( right );
 
  294             result = QStringLiteral( 
"%1 < %2" ).arg( left ).arg( right );
 
  298             result = QStringLiteral( 
"( float ) ( %1 >= %2 )" ).arg( left ).arg( right );
 
  300             result = QStringLiteral( 
"%1 >= %2" ).arg( left ).arg( right );
 
  304             result = QStringLiteral( 
"( float ) ( %1 <= %2 )" ).arg( left ).arg( right );
 
  306             result = QStringLiteral( 
"%1 <= %2" ).arg( left ).arg( right );
 
  310             result = QStringLiteral( 
"( float ) ( %1 && %2 )" ).arg( left ).arg( right );
 
  312             result = QStringLiteral( 
"%1 AND %2" ).arg( left ).arg( right );
 
  316             result = QStringLiteral( 
"( float ) ( %1 || %2 )" ).arg( left ).arg( right );
 
  318             result = QStringLiteral( 
"%1 OR %2" ).arg( left ).arg( right );
 
  321           result = QStringLiteral( 
"sqrt( %1 )" ).arg( left );
 
  324           result = QStringLiteral( 
"sin( %1 )" ).arg( left );
 
  327           result = QStringLiteral( 
"cos( %1 )" ).arg( left );
 
  330           result = QStringLiteral( 
"tan( %1 )" ).arg( left );
 
  333           result = QStringLiteral( 
"asin( %1 )" ).arg( left );
 
  336           result = QStringLiteral( 
"acos( %1 )" ).arg( left );
 
  339           result = QStringLiteral( 
"atan( %1 )" ).arg( left );
 
  342           result = QStringLiteral( 
"log( %1 )" ).arg( left );
 
  345           result = QStringLiteral( 
"log10( %1 )" ).arg( left );
 
  349             result = QStringLiteral( 
"fabs( %1 )" ).arg( left );
 
  352             result = QStringLiteral( 
"abs( %1 )" ).arg( left );
 
  356             result = QStringLiteral( 
"min( ( float ) ( %1 ), ( float ) ( %2 ) )" ).arg( left ).arg( right );
 
  358             result = QStringLiteral( 
"min( %1, %2 )" ).arg( left ).arg( right );
 
  362             result = QStringLiteral( 
"max( ( float ) ( %1 ), ( float ) ( %2 ) )" ).arg( left ).arg( right );
 
  364             result = QStringLiteral( 
"max( %1, %2 )" ).arg( left ).arg( right );
 
  372         result = QStringLiteral( 
"( float ) \"%1\"" ).arg( mRasterName );
 
  374         result = QStringLiteral( 
"\"%1\"" ).arg( mRasterName );
 
  377       result = QString::number( mNumber );
 
  380         result = QStringLiteral( 
"( float ) %1" ).arg( result );
 
  386       if ( mFunctionName == 
"if" )
 
  388         const QString argOne = mFunctionArgs.at( 0 )->toString( cStyle );
 
  389         const QString argTwo = mFunctionArgs.at( 1 )->toString( cStyle );
 
  390         const QString argThree = mFunctionArgs.at( 2 )->toString( cStyle );
 
  392           result =  QStringLiteral( 
" ( %1 ) ? ( %2 ) : ( %3 ) " ).arg( argOne, argTwo, argThree );
 
  394           result = QStringLiteral( 
"if( %1 , %2 , %3 )" ).arg( argOne, argTwo, argThree );
 
  403   QList<const QgsRasterCalcNode *> nodeList;
 
  405     nodeList.push_back( 
this );
 
  412     nodeList.append( node->findNodes( 
type ) );
 
  419   extern QgsRasterCalcNode *localParseRasterCalcString( 
const QString & 
str, QString & parserErrorMsg );
 
  420   return localParseRasterCalcString( 
str, parserErrorMsg );
 
  425   QStringList referencedRasters;
 
  428   for ( 
const auto &i : rasterRef )
 
  430     if ( referencedRasters.contains( i.mid( 0, i.lastIndexOf( 
"@" ) ) ) ) 
continue;
 
  431     referencedRasters << i.mid( 0, i.lastIndexOf( 
"@" ) );
 
  434   return referencedRasters;
 
  439   QStringList rasterReferences;
 
  440   const QList<const QgsRasterCalcNode *> rasterRefNodes =  this->
findNodes( QgsRasterCalcNode::Type::tRasterRef );
 
  445     QString layerRef( r->toString() );
 
  446     if ( layerRef.at( 0 ) == QLatin1String( 
"\"" ) && layerRef.at( layerRef.size() - 1 ) == QLatin1String( 
"\"" ) )
 
  448       layerRef.remove( 0, 1 );
 
  452     layerRef.remove( QChar( 
'\\' ), Qt::CaseInsensitive );
 
  453     rasterReferences << layerRef;
 
  456   return rasterReferences;
 
  462   if ( mFunctionName == 
"if" )
 
  465     if ( matrixVector.at( 0 )->isNumber() )
 
  467       result = ( matrixVector.at( 0 )->data() ? * matrixVector.at( 1 ) : * matrixVector.at( 2 ) );
 
  470     int nCols = matrixVector.at( 0 )->
nColumns();
 
  471     int nRows = matrixVector.at( 0 )->nRows();
 
  472     int nEntries = nCols * nRows;
 
  473     std::unique_ptr< double > dataResult( 
new double[nEntries] );
 
  474     double *dataResultRawPtr =  dataResult.get();
 
  476     double *condition = matrixVector.at( 0 )->data();
 
  477     double *firstOption = matrixVector.at( 1 )->data();
 
  478     double *secondOption = matrixVector.at( 2 )->data();
 
  480     bool isFirstOptionNumber = matrixVector.at( 1 )->isNumber();
 
  481     bool isSecondCOptionNumber = matrixVector.at( 2 )->isNumber();
 
  482     double noDataValueCondition = matrixVector.at( 0 )->nodataValue();
 
  484     for ( 
int i = 0; i < nEntries; ++i )
 
  486       if ( condition[i] == noDataValueCondition )
 
  491       else if ( condition[i] != 0 )
 
  493         dataResultRawPtr[i] = isFirstOptionNumber ? firstOption[0] : firstOption[i];
 
  496       dataResultRawPtr[i] = isSecondCOptionNumber ? secondOption[0] : secondOption[i];