LCOV - code coverage report
Current view: top level - analysis/raster - qgsrastercalcnode.cpp (source / functions) Hit Total Coverage
Test: coverage.info.cleaned Lines: 0 241 0.0 %
Date: 2021-04-10 08:29:14 Functions: 0 0 -
Branches: 0 0 -

           Branch data     Line data    Source code
       1                 :            : /***************************************************************************
       2                 :            :     qgsrastercalcnode.cpp
       3                 :            :     ---------------------
       4                 :            :     begin                : October 2010
       5                 :            :     copyright            : (C) 2010 by Marco Hugentobler
       6                 :            :     email                : marco dot hugentobler at sourcepole dot ch
       7                 :            :  ***************************************************************************
       8                 :            :  *                                                                         *
       9                 :            :  *   This program is free software; you can redistribute it and/or modify  *
      10                 :            :  *   it under the terms of the GNU General Public License as published by  *
      11                 :            :  *   the Free Software Foundation; either version 2 of the License, or     *
      12                 :            :  *   (at your option) any later version.                                   *
      13                 :            :  *                                                                         *
      14                 :            :  ***************************************************************************/
      15                 :            : #include "qgsrastercalcnode.h"
      16                 :            : #include "qgsrasterblock.h"
      17                 :            : #include "qgsrastermatrix.h"
      18                 :            : 
      19                 :          0 : QgsRasterCalcNode::QgsRasterCalcNode( double number )
      20                 :          0 :   : mNumber( number )
      21                 :            : {
      22                 :          0 : }
      23                 :            : 
      24                 :          0 : QgsRasterCalcNode::QgsRasterCalcNode( QgsRasterMatrix *matrix )
      25                 :          0 :   : mType( tMatrix )
      26                 :          0 :   , mMatrix( matrix )
      27                 :            : {
      28                 :            : 
      29                 :          0 : }
      30                 :            : 
      31                 :          0 : QgsRasterCalcNode::QgsRasterCalcNode( Operator op, QgsRasterCalcNode *left, QgsRasterCalcNode *right )
      32                 :          0 :   : mType( tOperator )
      33                 :          0 :   , mLeft( left )
      34                 :          0 :   , mRight( right )
      35                 :          0 :   , mOperator( op )
      36                 :            : {
      37                 :          0 : }
      38                 :            : 
      39                 :          0 : QgsRasterCalcNode::QgsRasterCalcNode( const QString &rasterName )
      40                 :          0 :   : mType( tRasterRef )
      41                 :          0 :   , mRasterName( rasterName )
      42                 :            : {
      43                 :          0 :   if ( mRasterName.startsWith( '"' ) && mRasterName.endsWith( '"' ) )
      44                 :          0 :     mRasterName = mRasterName.mid( 1, mRasterName.size() - 2 );
      45                 :          0 : }
      46                 :            : 
      47                 :          0 : QgsRasterCalcNode::~QgsRasterCalcNode()
      48                 :            : {
      49                 :          0 :   delete mLeft;
      50                 :          0 :   delete mRight;
      51                 :          0 : }
      52                 :            : 
      53                 :          0 : bool QgsRasterCalcNode::calculate( QMap<QString, QgsRasterBlock * > &rasterData, QgsRasterMatrix &result, int row ) const
      54                 :            : {
      55                 :            :   //if type is raster ref: return a copy of the corresponding matrix
      56                 :            : 
      57                 :            :   //if type is operator, call the proper matrix operations
      58                 :          0 :   if ( mType == tRasterRef )
      59                 :            :   {
      60                 :          0 :     QMap<QString, QgsRasterBlock *>::iterator it = rasterData.find( mRasterName );
      61                 :          0 :     if ( it == rasterData.end() )
      62                 :            :     {
      63                 :          0 :       QgsDebugMsg( QStringLiteral( "Error: could not find raster data for \"%1\"" ).arg( mRasterName ) );
      64                 :          0 :       return false;
      65                 :            :     }
      66                 :            : 
      67                 :          0 :     int nRows = ( row >= 0 ? 1 : ( *it )->height() );
      68                 :          0 :     int startRow = ( row >= 0 ? row : 0 );
      69                 :          0 :     int endRow = startRow + nRows;
      70                 :          0 :     int nCols = ( *it )->width();
      71                 :          0 :     int nEntries = nCols * nRows;
      72                 :          0 :     double *data = new double[nEntries];
      73                 :            : 
      74                 :            :     //convert input raster values to double, also convert input no data to result no data
      75                 :            : 
      76                 :          0 :     int outRow = 0;
      77                 :          0 :     bool isNoData = false;
      78                 :          0 :     for ( int dataRow = startRow; dataRow < endRow ; ++dataRow, ++outRow )
      79                 :            :     {
      80                 :          0 :       for ( int dataCol = 0; dataCol < nCols; ++dataCol )
      81                 :            :       {
      82                 :          0 :         const double value = ( *it )->valueAndNoData( dataRow, dataCol, isNoData );
      83                 :          0 :         data[ dataCol + nCols * outRow] = isNoData ? result.nodataValue() : value;
      84                 :          0 :       }
      85                 :          0 :     }
      86                 :          0 :     result.setData( nCols, nRows, data, result.nodataValue() );
      87                 :          0 :     return true;
      88                 :            :   }
      89                 :          0 :   else if ( mType == tOperator )
      90                 :            :   {
      91                 :          0 :     QgsRasterMatrix leftMatrix( result.nColumns(), result.nRows(), nullptr, result.nodataValue() );
      92                 :          0 :     QgsRasterMatrix rightMatrix( result.nColumns(), result.nRows(), nullptr, result.nodataValue() );
      93                 :            : 
      94                 :          0 :     if ( !mLeft || !mLeft->calculate( rasterData, leftMatrix, row ) )
      95                 :            :     {
      96                 :          0 :       return false;
      97                 :            :     }
      98                 :          0 :     if ( mRight && !mRight->calculate( rasterData, rightMatrix, row ) )
      99                 :            :     {
     100                 :          0 :       return false;
     101                 :            :     }
     102                 :            : 
     103                 :          0 :     switch ( mOperator )
     104                 :            :     {
     105                 :            :       case opPLUS:
     106                 :          0 :         leftMatrix.add( rightMatrix );
     107                 :          0 :         break;
     108                 :            :       case opMINUS:
     109                 :          0 :         leftMatrix.subtract( rightMatrix );
     110                 :          0 :         break;
     111                 :            :       case opMUL:
     112                 :          0 :         leftMatrix.multiply( rightMatrix );
     113                 :          0 :         break;
     114                 :            :       case opDIV:
     115                 :          0 :         leftMatrix.divide( rightMatrix );
     116                 :          0 :         break;
     117                 :            :       case opPOW:
     118                 :          0 :         leftMatrix.power( rightMatrix );
     119                 :          0 :         break;
     120                 :            :       case opEQ:
     121                 :          0 :         leftMatrix.equal( rightMatrix );
     122                 :          0 :         break;
     123                 :            :       case opNE:
     124                 :          0 :         leftMatrix.notEqual( rightMatrix );
     125                 :          0 :         break;
     126                 :            :       case opGT:
     127                 :          0 :         leftMatrix.greaterThan( rightMatrix );
     128                 :          0 :         break;
     129                 :            :       case opLT:
     130                 :          0 :         leftMatrix.lesserThan( rightMatrix );
     131                 :          0 :         break;
     132                 :            :       case opGE:
     133                 :          0 :         leftMatrix.greaterEqual( rightMatrix );
     134                 :          0 :         break;
     135                 :          0 :       case opLE:
     136                 :          0 :         leftMatrix.lesserEqual( rightMatrix );
     137                 :          0 :         break;
     138                 :          0 :       case opAND:
     139                 :          0 :         leftMatrix.logicalAnd( rightMatrix );
     140                 :          0 :         break;
     141                 :            :       case opOR:
     142                 :          0 :         leftMatrix.logicalOr( rightMatrix );
     143                 :          0 :         break;
     144                 :            :       case opMIN:
     145                 :          0 :         leftMatrix.min( rightMatrix );
     146                 :          0 :         break;
     147                 :            :       case opMAX:
     148                 :          0 :         leftMatrix.max( rightMatrix );
     149                 :          0 :         break;
     150                 :            :       case opSQRT:
     151                 :          0 :         leftMatrix.squareRoot();
     152                 :          0 :         break;
     153                 :            :       case opSIN:
     154                 :          0 :         leftMatrix.sinus();
     155                 :          0 :         break;
     156                 :            :       case opCOS:
     157                 :          0 :         leftMatrix.cosinus();
     158                 :          0 :         break;
     159                 :            :       case opTAN:
     160                 :          0 :         leftMatrix.tangens();
     161                 :          0 :         break;
     162                 :            :       case opASIN:
     163                 :          0 :         leftMatrix.asinus();
     164                 :          0 :         break;
     165                 :            :       case opACOS:
     166                 :          0 :         leftMatrix.acosinus();
     167                 :          0 :         break;
     168                 :            :       case opATAN:
     169                 :          0 :         leftMatrix.atangens();
     170                 :          0 :         break;
     171                 :            :       case opSIGN:
     172                 :          0 :         leftMatrix.changeSign();
     173                 :          0 :         break;
     174                 :            :       case opLOG:
     175                 :          0 :         leftMatrix.log();
     176                 :          0 :         break;
     177                 :            :       case opLOG10:
     178                 :          0 :         leftMatrix.log10();
     179                 :          0 :         break;
     180                 :            :       case opABS:
     181                 :          0 :         leftMatrix.absoluteValue();
     182                 :          0 :         break;
     183                 :            :       default:
     184                 :          0 :         return false;
     185                 :            :     }
     186                 :          0 :     int newNColumns = leftMatrix.nColumns();
     187                 :          0 :     int newNRows = leftMatrix.nRows();
     188                 :          0 :     result.setData( newNColumns, newNRows, leftMatrix.takeData(), leftMatrix.nodataValue() );
     189                 :          0 :     return true;
     190                 :          0 :   }
     191                 :          0 :   else if ( mType == tNumber )
     192                 :            :   {
     193                 :          0 :     size_t nEntries = static_cast<size_t>( result.nColumns() * result.nRows() );
     194                 :          0 :     double *data = new double[ nEntries ];
     195                 :          0 :     std::fill( data, data + nEntries, mNumber );
     196                 :          0 :     result.setData( result.nColumns(), 1, data, result.nodataValue() );
     197                 :            : 
     198                 :          0 :     return true;
     199                 :            :   }
     200                 :          0 :   else if ( mType == tMatrix )
     201                 :            :   {
     202                 :          0 :     int nEntries = mMatrix->nColumns() * mMatrix->nRows();
     203                 :          0 :     double *data = new double[nEntries];
     204                 :          0 :     for ( int i = 0; i < nEntries; ++i )
     205                 :            :     {
     206                 :          0 :       data[i] = mMatrix->data()[i] == mMatrix->nodataValue() ? result.nodataValue() : mMatrix->data()[i];
     207                 :          0 :     }
     208                 :          0 :     result.setData( mMatrix->nColumns(), mMatrix->nRows(), data, result.nodataValue() );
     209                 :          0 :     return true;
     210                 :            :   }
     211                 :          0 :   return false;
     212                 :          0 : }
     213                 :            : 
     214                 :          0 : QString QgsRasterCalcNode::toString( bool cStyle ) const
     215                 :            : {
     216                 :          0 :   QString result;
     217                 :          0 :   QString left;
     218                 :          0 :   QString right;
     219                 :          0 :   if ( mLeft )
     220                 :          0 :     left = mLeft->toString( cStyle );
     221                 :          0 :   if ( mRight )
     222                 :          0 :     right = mRight->toString( cStyle );
     223                 :            : 
     224                 :          0 :   switch ( mType )
     225                 :            :   {
     226                 :            :     case tOperator:
     227                 :          0 :       switch ( mOperator )
     228                 :            :       {
     229                 :            :         case opPLUS:
     230                 :          0 :           result = QStringLiteral( "( %1 + %2 )" ).arg( left ).arg( right );
     231                 :          0 :           break;
     232                 :            :         case opMINUS:
     233                 :          0 :           result = QStringLiteral( "( %1 - %2 )" ).arg( left ).arg( right );
     234                 :          0 :           break;
     235                 :            :         case opSIGN:
     236                 :          0 :           result = QStringLiteral( "-%1" ).arg( left );
     237                 :          0 :           break;
     238                 :            :         case opMUL:
     239                 :          0 :           result = QStringLiteral( "%1 * %2" ).arg( left ).arg( right );
     240                 :          0 :           break;
     241                 :            :         case opDIV:
     242                 :          0 :           result = QStringLiteral( "%1 / %2" ).arg( left ).arg( right );
     243                 :          0 :           break;
     244                 :            :         case opPOW:
     245                 :          0 :           if ( cStyle )
     246                 :          0 :             result = QStringLiteral( "pow( %1, %2 )" ).arg( left ).arg( right );
     247                 :            :           else
     248                 :          0 :             result = QStringLiteral( "%1^%2" ).arg( left ).arg( right );
     249                 :          0 :           break;
     250                 :            :         case opEQ:
     251                 :          0 :           if ( cStyle )
     252                 :          0 :             result = QStringLiteral( "( float ) ( %1 == %2 )" ).arg( left ).arg( right );
     253                 :            :           else
     254                 :          0 :             result = QStringLiteral( "%1 = %2" ).arg( left ).arg( right );
     255                 :          0 :           break;
     256                 :            :         case opNE:
     257                 :          0 :           if ( cStyle )
     258                 :          0 :             result = QStringLiteral( "( float ) ( %1 != %2 )" ).arg( left ).arg( right );
     259                 :            :           else
     260                 :          0 :             result = QStringLiteral( "%1 != %2" ).arg( left ).arg( right );
     261                 :          0 :           break;
     262                 :            :         case opGT:
     263                 :          0 :           if ( cStyle )
     264                 :          0 :             result = QStringLiteral( "( float ) ( %1 > %2 )" ).arg( left ).arg( right );
     265                 :            :           else
     266                 :          0 :             result = QStringLiteral( "%1 > %2" ).arg( left ).arg( right );
     267                 :          0 :           break;
     268                 :            :         case opLT:
     269                 :          0 :           if ( cStyle )
     270                 :          0 :             result = QStringLiteral( "( float ) ( %1 < %2 )" ).arg( left ).arg( right );
     271                 :            :           else
     272                 :          0 :             result = QStringLiteral( "%1 < %2" ).arg( left ).arg( right );
     273                 :          0 :           break;
     274                 :            :         case opGE:
     275                 :          0 :           if ( cStyle )
     276                 :          0 :             result = QStringLiteral( "( float ) ( %1 >= %2 )" ).arg( left ).arg( right );
     277                 :            :           else
     278                 :          0 :             result = QStringLiteral( "%1 >= %2" ).arg( left ).arg( right );
     279                 :          0 :           break;
     280                 :            :         case opLE:
     281                 :          0 :           if ( cStyle )
     282                 :          0 :             result = QStringLiteral( "( float ) ( %1 <= %2 )" ).arg( left ).arg( right );
     283                 :            :           else
     284                 :          0 :             result = QStringLiteral( "%1 <= %2" ).arg( left ).arg( right );
     285                 :          0 :           break;
     286                 :            :         case opAND:
     287                 :          0 :           if ( cStyle )
     288                 :          0 :             result = QStringLiteral( "( float ) ( %1 && %2 )" ).arg( left ).arg( right );
     289                 :            :           else
     290                 :          0 :             result = QStringLiteral( "%1 AND %2" ).arg( left ).arg( right );
     291                 :          0 :           break;
     292                 :            :         case opOR:
     293                 :          0 :           if ( cStyle )
     294                 :          0 :             result = QStringLiteral( "( float ) ( %1 || %2 )" ).arg( left ).arg( right );
     295                 :            :           else
     296                 :          0 :             result = QStringLiteral( "%1 OR %2" ).arg( left ).arg( right );
     297                 :          0 :           break;
     298                 :            :         case opSQRT:
     299                 :          0 :           result = QStringLiteral( "sqrt( %1 )" ).arg( left );
     300                 :          0 :           break;
     301                 :            :         case opSIN:
     302                 :          0 :           result = QStringLiteral( "sin( %1 )" ).arg( left );
     303                 :          0 :           break;
     304                 :            :         case opCOS:
     305                 :          0 :           result = QStringLiteral( "cos( %1 )" ).arg( left );
     306                 :          0 :           break;
     307                 :            :         case opTAN:
     308                 :          0 :           result = QStringLiteral( "tan( %1 )" ).arg( left );
     309                 :          0 :           break;
     310                 :            :         case opASIN:
     311                 :          0 :           result = QStringLiteral( "asin( %1 )" ).arg( left );
     312                 :          0 :           break;
     313                 :            :         case opACOS:
     314                 :          0 :           result = QStringLiteral( "acos( %1 )" ).arg( left );
     315                 :          0 :           break;
     316                 :            :         case opATAN:
     317                 :          0 :           result = QStringLiteral( "atan( %1 )" ).arg( left );
     318                 :          0 :           break;
     319                 :            :         case opLOG:
     320                 :          0 :           result = QStringLiteral( "log( %1 )" ).arg( left );
     321                 :          0 :           break;
     322                 :            :         case opLOG10:
     323                 :          0 :           result = QStringLiteral( "log10( %1 )" ).arg( left );
     324                 :          0 :           break;
     325                 :            :         case opABS:
     326                 :          0 :           if ( cStyle )
     327                 :          0 :             result = QStringLiteral( "fabs( %1 )" ).arg( left );
     328                 :            :           else
     329                 :            :             // Call the floating point version
     330                 :          0 :             result = QStringLiteral( "abs( %1 )" ).arg( left );
     331                 :          0 :           break;
     332                 :            :         case opMIN:
     333                 :          0 :           if ( cStyle )
     334                 :          0 :             result = QStringLiteral( "min( ( float ) ( %1 ), ( float ) ( %2 ) )" ).arg( left ).arg( right );
     335                 :            :           else
     336                 :          0 :             result = QStringLiteral( "min( %1, %2 )" ).arg( left ).arg( right );
     337                 :          0 :           break;
     338                 :            :         case opMAX:
     339                 :          0 :           if ( cStyle )
     340                 :          0 :             result = QStringLiteral( "max( ( float ) ( %1 ), ( float ) ( %2 ) )" ).arg( left ).arg( right );
     341                 :            :           else
     342                 :          0 :             result = QStringLiteral( "max( %1, %2 )" ).arg( left ).arg( right );
     343                 :          0 :           break;
     344                 :            :         case opNONE:
     345                 :          0 :           break;
     346                 :            :       }
     347                 :          0 :       break;
     348                 :            :     case tRasterRef:
     349                 :          0 :       if ( cStyle )
     350                 :          0 :         result = QStringLiteral( "( float ) \"%1\"" ).arg( mRasterName );
     351                 :            :       else
     352                 :          0 :         result = QStringLiteral( "\"%1\"" ).arg( mRasterName );
     353                 :          0 :       break;
     354                 :            :     case tNumber:
     355                 :          0 :       result = QString::number( mNumber );
     356                 :          0 :       if ( cStyle )
     357                 :            :       {
     358                 :          0 :         result = QStringLiteral( "( float ) %1" ).arg( result );
     359                 :          0 :       }
     360                 :          0 :       break;
     361                 :            :     case tMatrix:
     362                 :          0 :       break;
     363                 :            :   }
     364                 :          0 :   return result;
     365                 :          0 : }
     366                 :            : 
     367                 :          0 : QList<const QgsRasterCalcNode *> QgsRasterCalcNode::findNodes( const QgsRasterCalcNode::Type type ) const
     368                 :            : {
     369                 :          0 :   QList<const QgsRasterCalcNode *> nodeList;
     370                 :          0 :   if ( mType == type )
     371                 :          0 :     nodeList.push_back( this );
     372                 :          0 :   if ( mLeft )
     373                 :          0 :     nodeList.append( mLeft->findNodes( type ) );
     374                 :          0 :   if ( mRight )
     375                 :          0 :     nodeList.append( mRight->findNodes( type ) );
     376                 :          0 :   return nodeList;
     377                 :          0 : }
     378                 :            : 
     379                 :          0 : QgsRasterCalcNode *QgsRasterCalcNode::parseRasterCalcString( const QString &str, QString &parserErrorMsg )
     380                 :            : {
     381                 :            :   extern QgsRasterCalcNode *localParseRasterCalcString( const QString & str, QString & parserErrorMsg );
     382                 :          0 :   return localParseRasterCalcString( str, parserErrorMsg );
     383                 :            : }
     384                 :            : 

Generated by: LCOV version 1.14