QGIS API Documentation  2.8.2-Wien
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
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 <cfloat>
17 
19  : mType( tNumber )
20  , mLeft( 0 )
21  , mRight( 0 )
22  , mNumber( 0 )
23  , mOperator( opNONE )
24 {
25 }
26 
28  : mType( tNumber )
29  , mLeft( 0 )
30  , mRight( 0 )
31  , mNumber( number )
32  , mOperator( opNONE )
33 {
34 }
35 
37  : mType( tOperator )
38  , mLeft( left )
39  , mRight( right )
40  , mNumber( 0 )
41  , mOperator( op )
42 {
43 }
44 
45 QgsRasterCalcNode::QgsRasterCalcNode( const QString& rasterName )
46  : mType( tRasterRef )
47  , mLeft( 0 )
48  , mRight( 0 )
49  , mNumber( 0 )
50  , mRasterName( rasterName )
51  , mOperator( opNONE )
52 {
53  if ( mRasterName.startsWith( '"' ) && mRasterName.endsWith( '"' ) )
54  mRasterName = mRasterName.mid( 1, mRasterName.size() - 2 );
55 }
56 
58 {
59  if ( mLeft )
60  {
61  delete mLeft;
62  }
63  if ( mRight )
64  {
65  delete mRight;
66  }
67 }
68 
69 bool QgsRasterCalcNode::calculate( QMap<QString, QgsRasterMatrix*>& rasterData, QgsRasterMatrix& result ) const
70 {
71  //if type is raster ref: return a copy of the corresponding matrix
72 
73  //if type is operator, call the proper matrix operations
74  if ( mType == tRasterRef )
75  {
76  QMap<QString, QgsRasterMatrix*>::iterator it = rasterData.find( mRasterName );
77  if ( it == rasterData.end() )
78  {
79  return false;
80  }
81 
82  int nEntries = ( *it )->nColumns() * ( *it )->nRows();
83  float* data = new float[nEntries];
84  memcpy( data, ( *it )->data(), nEntries * sizeof( float ) );
85  result.setData(( *it )->nColumns(), ( *it )->nRows(), data, ( *it )->nodataValue() );
86  return true;
87  }
88  else if ( mType == tOperator )
89  {
90  QgsRasterMatrix leftMatrix, rightMatrix;
91  QgsRasterMatrix resultMatrix;
92  if ( !mLeft || !mLeft->calculate( rasterData, leftMatrix ) )
93  {
94  return false;
95  }
96  if ( mRight && !mRight->calculate( rasterData, rightMatrix ) )
97  {
98  return false;
99  }
100 
101  switch ( mOperator )
102  {
103  case opPLUS:
104  leftMatrix.add( rightMatrix );
105  break;
106  case opMINUS:
107  leftMatrix.subtract( rightMatrix );
108  break;
109  case opMUL:
110  leftMatrix.multiply( rightMatrix );
111  break;
112  case opDIV:
113  leftMatrix.divide( rightMatrix );
114  break;
115  case opPOW:
116  leftMatrix.power( rightMatrix );
117  break;
118  case opEQ:
119  leftMatrix.equal( rightMatrix );
120  break;
121  case opNE:
122  leftMatrix.notEqual( rightMatrix );
123  break;
124  case opGT:
125  leftMatrix.greaterThan( rightMatrix );
126  break;
127  case opLT:
128  leftMatrix.lesserThan( rightMatrix );
129  break;
130  case opGE:
131  leftMatrix.greaterEqual( rightMatrix );
132  break;
133  case opLE:
134  leftMatrix.lesserEqual( rightMatrix );
135  break;
136  case opAND:
137  leftMatrix.logicalAnd( rightMatrix );
138  break;
139  case opOR:
140  leftMatrix.logicalOr( rightMatrix );
141  break;
142  case opSQRT:
143  leftMatrix.squareRoot();
144  break;
145  case opSIN:
146  leftMatrix.sinus();
147  break;
148  case opCOS:
149  leftMatrix.cosinus();
150  break;
151  case opTAN:
152  leftMatrix.tangens();
153  break;
154  case opASIN:
155  leftMatrix.asinus();
156  break;
157  case opACOS:
158  leftMatrix.acosinus();
159  break;
160  case opATAN:
161  leftMatrix.atangens();
162  break;
163  case opSIGN:
164  leftMatrix.changeSign();
165  break;
166  default:
167  return false;
168  }
169  int newNColumns = leftMatrix.nColumns();
170  int newNRows = leftMatrix.nRows();
171  result.setData( newNColumns, newNRows, leftMatrix.takeData(), leftMatrix.nodataValue() );
172  return true;
173  }
174  else if ( mType == tNumber )
175  {
176  float* data = new float[1];
177  data[0] = mNumber;
178  result.setData( 1, 1, data, -FLT_MAX );
179  return true;
180  }
181  return false;
182 }
183 
184 QgsRasterCalcNode* QgsRasterCalcNode::parseRasterCalcString( const QString& str, QString& parserErrorMsg )
185 {
186  extern QgsRasterCalcNode* localParseRasterCalcString( const QString & str, QString & parserErrorMsg );
187  return localParseRasterCalcString( str, parserErrorMsg );
188 }
189