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