Quantum GIS API Documentation
1.8
|
00001 /*************************************************************************** 00002 qgsrastercalcnode.cpp 00003 --------------------- 00004 begin : October 2010 00005 copyright : (C) 2010 by Marco Hugentobler 00006 email : marco dot hugentobler at sourcepole dot ch 00007 *************************************************************************** 00008 * * 00009 * This program is free software; you can redistribute it and/or modify * 00010 * it under the terms of the GNU General Public License as published by * 00011 * the Free Software Foundation; either version 2 of the License, or * 00012 * (at your option) any later version. * 00013 * * 00014 ***************************************************************************/ 00015 #include "qgsrastercalcnode.h" 00016 #include <cfloat> 00017 00018 QgsRasterCalcNode::QgsRasterCalcNode(): mLeft( 0 ), mRight( 0 ), mRasterMatrix( 0 ), mNumber( 0 ) 00019 { 00020 } 00021 00022 QgsRasterCalcNode::QgsRasterCalcNode( double number ): mType( tNumber ), mLeft( 0 ), mRight( 0 ), mRasterMatrix( 0 ), mNumber( number ) 00023 { 00024 } 00025 00026 QgsRasterCalcNode::QgsRasterCalcNode( Operator op, QgsRasterCalcNode* left, QgsRasterCalcNode* right ): mType( tOperator ), mLeft( left ), mRight( right ), mRasterMatrix( 0 ), mNumber( 0 ), mOperator( op ) 00027 { 00028 } 00029 00030 QgsRasterCalcNode::QgsRasterCalcNode( const QString& rasterName ): mType( tRasterRef ), mLeft( 0 ), mRight( 0 ), mRasterMatrix( 0 ), mNumber( 0 ), mRasterName( rasterName ) 00031 { 00032 } 00033 00034 QgsRasterCalcNode::~QgsRasterCalcNode() 00035 { 00036 if ( mLeft ) 00037 { 00038 delete mLeft; 00039 } 00040 if ( mRight ) 00041 { 00042 delete mRight; 00043 } 00044 } 00045 00046 bool QgsRasterCalcNode::calculate( QMap<QString, QgsRasterMatrix*>& rasterData, QgsRasterMatrix& result ) const 00047 { 00048 //if type is raster ref: return a copy of the corresponding matrix 00049 00050 //if type is operator, call the proper matrix operations 00051 if ( mType == tRasterRef ) 00052 { 00053 QMap<QString, QgsRasterMatrix*>::iterator it = rasterData.find( mRasterName ); 00054 if ( it == rasterData.end() ) 00055 { 00056 return false; 00057 } 00058 00059 int nEntries = ( *it )->nColumns() * ( *it )->nRows(); 00060 float* data = new float[nEntries]; 00061 memcpy( data, ( *it )->data(), nEntries * sizeof( float ) ); 00062 result.setData(( *it )->nColumns(), ( *it )->nRows(), data, ( *it )->nodataValue() ); 00063 return true; 00064 } 00065 else if ( mType == tOperator ) 00066 { 00067 QgsRasterMatrix leftMatrix, rightMatrix; 00068 QgsRasterMatrix resultMatrix; 00069 if ( !mLeft || !mLeft->calculate( rasterData, leftMatrix ) ) 00070 { 00071 return false; 00072 } 00073 if ( mRight && !mRight->calculate( rasterData, rightMatrix ) ) 00074 { 00075 return false; 00076 } 00077 00078 switch ( mOperator ) 00079 { 00080 case opPLUS: 00081 leftMatrix.add( rightMatrix ); 00082 break; 00083 case opMINUS: 00084 leftMatrix.subtract( rightMatrix ); 00085 break; 00086 case opMUL: 00087 leftMatrix.multiply( rightMatrix ); 00088 break; 00089 case opDIV: 00090 leftMatrix.divide( rightMatrix ); 00091 break; 00092 case opPOW: 00093 leftMatrix.power( rightMatrix ); 00094 break; 00095 case opEQ: 00096 leftMatrix.equal( rightMatrix ); 00097 break; 00098 case opNE: 00099 leftMatrix.notEqual( rightMatrix ); 00100 break; 00101 case opGT: 00102 leftMatrix.greaterThan( rightMatrix ); 00103 break; 00104 case opLT: 00105 leftMatrix.lesserThan( rightMatrix ); 00106 break; 00107 case opGE: 00108 leftMatrix.greaterEqual( rightMatrix ); 00109 break; 00110 case opLE: 00111 leftMatrix.lesserEqual( rightMatrix ); 00112 break; 00113 case opAND: 00114 leftMatrix.logicalAnd( rightMatrix ); 00115 break; 00116 case opOR: 00117 leftMatrix.logicalOr( rightMatrix ); 00118 break; 00119 case opSQRT: 00120 leftMatrix.squareRoot(); 00121 break; 00122 case opSIN: 00123 leftMatrix.sinus(); 00124 break; 00125 case opCOS: 00126 leftMatrix.cosinus(); 00127 break; 00128 case opTAN: 00129 leftMatrix.tangens(); 00130 break; 00131 case opASIN: 00132 leftMatrix.asinus(); 00133 break; 00134 case opACOS: 00135 leftMatrix.acosinus(); 00136 break; 00137 case opATAN: 00138 leftMatrix.atangens(); 00139 case opSIGN: 00140 leftMatrix.changeSign(); 00141 break; 00142 default: 00143 return false; 00144 } 00145 int newNColumns = leftMatrix.nColumns(); 00146 int newNRows = leftMatrix.nRows(); 00147 result.setData( newNColumns, newNRows, leftMatrix.takeData(), leftMatrix.nodataValue() ); 00148 return true; 00149 } 00150 else if ( mType == tNumber ) 00151 { 00152 float* data = new float[1]; 00153 data[0] = mNumber; 00154 result.setData( 1, 1, data, -FLT_MAX ); 00155 return true; 00156 } 00157 return false; 00158 } 00159 00160 QgsRasterCalcNode* QgsRasterCalcNode::parseRasterCalcString( const QString& str, QString& parserErrorMsg ) 00161 { 00162 extern QgsRasterCalcNode* localParseRasterCalcString( const QString & str, QString & parserErrorMsg ); 00163 return localParseRasterCalcString( str, parserErrorMsg ); 00164 } 00165