QGIS API Documentation  2.99.0-Master (6a61179)
qgsrastercalcnode.cpp
Go to the documentation of this file.
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 #include <cfloat>
19 
21  : mType( tNumber )
22  , mLeft( nullptr )
23  , mRight( nullptr )
24  , mNumber( 0 )
25  , mMatrix( nullptr )
26  , mOperator( opNONE )
27 {
28 }
29 
31  : mType( tNumber )
32  , mLeft( nullptr )
33  , mRight( nullptr )
34  , mNumber( number )
35  , mMatrix( nullptr )
36  , mOperator( opNONE )
37 {
38 }
39 
41  : mType( tMatrix )
42  , mLeft( nullptr )
43  , mRight( nullptr )
44  , mNumber( 0 )
45  , mMatrix( matrix )
46  , mOperator( opNONE )
47 {
48 
49 }
50 
52  : mType( tOperator )
53  , mLeft( left )
54  , mRight( right )
55  , mNumber( 0 )
56  , mMatrix( nullptr )
57  , mOperator( op )
58 {
59 }
60 
61 QgsRasterCalcNode::QgsRasterCalcNode( const QString& rasterName )
62  : mType( tRasterRef )
63  , mLeft( nullptr )
64  , mRight( nullptr )
65  , mNumber( 0 )
66  , mRasterName( rasterName )
67  , mMatrix( nullptr )
68  , mOperator( opNONE )
69 {
70  if ( mRasterName.startsWith( '"' ) && mRasterName.endsWith( '"' ) )
71  mRasterName = mRasterName.mid( 1, mRasterName.size() - 2 );
72 }
73 
75 {
76  if ( mLeft )
77  {
78  delete mLeft;
79  }
80  if ( mRight )
81  {
82  delete mRight;
83  }
84 }
85 
86 bool QgsRasterCalcNode::calculate( QMap<QString, QgsRasterBlock* >& rasterData, QgsRasterMatrix& result, int row ) const
87 {
88  //if type is raster ref: return a copy of the corresponding matrix
89 
90  //if type is operator, call the proper matrix operations
91  if ( mType == tRasterRef )
92  {
93  QMap<QString, QgsRasterBlock*>::iterator it = rasterData.find( mRasterName );
94  if ( it == rasterData.end() )
95  {
96  return false;
97  }
98 
99  int nRows = ( row >= 0 ? 1 : ( *it )->height() );
100  int startRow = ( row >= 0 ? row : 0 );
101  int endRow = startRow + nRows;
102  int nCols = ( *it )->width();
103  int nEntries = nCols * nRows;
104  double* data = new double[nEntries];
105 
106  //convert input raster values to double, also convert input no data to result no data
107 
108  int outRow = 0;
109  for ( int dataRow = startRow; dataRow < endRow ; ++dataRow, ++outRow )
110  {
111  for ( int dataCol = 0; dataCol < nCols; ++dataCol )
112  {
113  data[ dataCol + nCols * outRow] = ( *it )->isNoData( dataRow , dataCol ) ? result.nodataValue() : ( *it )->value( dataRow, dataCol );
114  }
115  }
116  result.setData( nCols, nRows, data, result.nodataValue() );
117  return true;
118  }
119  else if ( mType == tOperator )
120  {
121  QgsRasterMatrix leftMatrix, rightMatrix;
122  leftMatrix.setNodataValue( result.nodataValue() );
123  rightMatrix.setNodataValue( result.nodataValue() );
124 
125  if ( !mLeft || !mLeft->calculate( rasterData, leftMatrix, row ) )
126  {
127  return false;
128  }
129  if ( mRight && !mRight->calculate( rasterData, rightMatrix, row ) )
130  {
131  return false;
132  }
133 
134  switch ( mOperator )
135  {
136  case opPLUS:
137  leftMatrix.add( rightMatrix );
138  break;
139  case opMINUS:
140  leftMatrix.subtract( rightMatrix );
141  break;
142  case opMUL:
143  leftMatrix.multiply( rightMatrix );
144  break;
145  case opDIV:
146  leftMatrix.divide( rightMatrix );
147  break;
148  case opPOW:
149  leftMatrix.power( rightMatrix );
150  break;
151  case opEQ:
152  leftMatrix.equal( rightMatrix );
153  break;
154  case opNE:
155  leftMatrix.notEqual( rightMatrix );
156  break;
157  case opGT:
158  leftMatrix.greaterThan( rightMatrix );
159  break;
160  case opLT:
161  leftMatrix.lesserThan( rightMatrix );
162  break;
163  case opGE:
164  leftMatrix.greaterEqual( rightMatrix );
165  break;
166  case opLE:
167  leftMatrix.lesserEqual( rightMatrix );
168  break;
169  case opAND:
170  leftMatrix.logicalAnd( rightMatrix );
171  break;
172  case opOR:
173  leftMatrix.logicalOr( rightMatrix );
174  break;
175  case opSQRT:
176  leftMatrix.squareRoot();
177  break;
178  case opSIN:
179  leftMatrix.sinus();
180  break;
181  case opCOS:
182  leftMatrix.cosinus();
183  break;
184  case opTAN:
185  leftMatrix.tangens();
186  break;
187  case opASIN:
188  leftMatrix.asinus();
189  break;
190  case opACOS:
191  leftMatrix.acosinus();
192  break;
193  case opATAN:
194  leftMatrix.atangens();
195  break;
196  case opSIGN:
197  leftMatrix.changeSign();
198  break;
199  case opLOG:
200  leftMatrix.log();
201  break;
202  case opLOG10:
203  leftMatrix.log10();
204  break;
205  default:
206  return false;
207  }
208  int newNColumns = leftMatrix.nColumns();
209  int newNRows = leftMatrix.nRows();
210  result.setData( newNColumns, newNRows, leftMatrix.takeData(), leftMatrix.nodataValue() );
211  return true;
212  }
213  else if ( mType == tNumber )
214  {
215  double* data = new double[1];
216  data[0] = mNumber;
217  result.setData( 1, 1, data, result.nodataValue() );
218  return true;
219  }
220  else if ( mType == tMatrix )
221  {
222  int nEntries = mMatrix->nColumns() * mMatrix->nRows();
223  double* data = new double[nEntries];
224  for ( int i = 0; i < nEntries; ++i )
225  {
226  data[i] = mMatrix->data()[i] == mMatrix->nodataValue() ? result.nodataValue() : mMatrix->data()[i];
227  }
228  result.setData( mMatrix->nColumns(), mMatrix->nRows(), data, result.nodataValue() );
229  return true;
230  }
231  return false;
232 }
233 
234 QgsRasterCalcNode* QgsRasterCalcNode::parseRasterCalcString( const QString& str, QString& parserErrorMsg )
235 {
236  extern QgsRasterCalcNode* localParseRasterCalcString( const QString & str, QString & parserErrorMsg );
237  return localParseRasterCalcString( str, parserErrorMsg );
238 }
239 
double * takeData()
Returns data and ownership.
bool add(const QgsRasterMatrix &other)
Adds another matrix to this one.
void setNodataValue(double d)
double nodataValue() const
bool power(const QgsRasterMatrix &other)
bool greaterThan(const QgsRasterMatrix &other)
bool notEqual(const QgsRasterMatrix &other)
bool equal(const QgsRasterMatrix &other)
int nRows() const
bool calculate(QMap< QString, QgsRasterBlock * > &rasterData, QgsRasterMatrix &result, int row=-1) const
Calculates result of raster calculation (might be real matrix or single number).
bool logicalOr(const QgsRasterMatrix &other)
void setData(int cols, int rows, double *data, double nodataValue)
bool subtract(const QgsRasterMatrix &other)
Subtracts another matrix from this one.
Operator
possible operators
bool multiply(const QgsRasterMatrix &other)
int nColumns() const
bool lesserEqual(const QgsRasterMatrix &other)
bool divide(const QgsRasterMatrix &other)
bool greaterEqual(const QgsRasterMatrix &other)
double * data()
Returns data array (but not ownership)
static QgsRasterCalcNode * parseRasterCalcString(const QString &str, QString &parserErrorMsg)
bool lesserThan(const QgsRasterMatrix &other)
bool logicalAnd(const QgsRasterMatrix &other)