00001 #include "qgsrastercalcnode.h"
00002 #include <cfloat>
00003
00004 QgsRasterCalcNode::QgsRasterCalcNode(): mLeft( 0 ), mRight( 0 ), mRasterMatrix( 0 ), mNumber( 0 )
00005 {
00006 }
00007
00008 QgsRasterCalcNode::QgsRasterCalcNode( double number ): mType( tNumber ), mLeft( 0 ), mRight( 0 ), mRasterMatrix( 0 ), mNumber( number )
00009 {
00010 }
00011
00012 QgsRasterCalcNode::QgsRasterCalcNode( Operator op, QgsRasterCalcNode* left, QgsRasterCalcNode* right ): mType( tOperator ), mLeft( left ), mRight( right ), mRasterMatrix( 0 ), mNumber( 0 ), mOperator( op )
00013 {
00014 }
00015
00016 QgsRasterCalcNode::QgsRasterCalcNode( const QString& rasterName ): mType( tRasterRef ), mLeft( 0 ), mRight( 0 ), mRasterMatrix( 0 ), mNumber( 0 ), mRasterName( rasterName )
00017 {
00018 }
00019
00020 QgsRasterCalcNode::~QgsRasterCalcNode()
00021 {
00022 if( mLeft )
00023 {
00024 delete mLeft;
00025 }
00026 if( mRight )
00027 {
00028 delete mRight;
00029 }
00030 }
00031
00032 bool QgsRasterCalcNode::calculate( QMap<QString, QgsRasterMatrix*>& rasterData, QgsRasterMatrix& result ) const
00033 {
00034
00035
00036
00037 if( mType == tRasterRef )
00038 {
00039 QMap<QString, QgsRasterMatrix*>::iterator it = rasterData.find( mRasterName );
00040 if( it == rasterData.end() )
00041 {
00042 return false;
00043 }
00044
00045 int nEntries = ( *it )->nColumns() * ( *it )->nRows();
00046 float* data = new float[nEntries];
00047 memcpy( data, ( *it )->data(), nEntries * sizeof( float ) );
00048 result.setData(( *it )->nColumns(), ( *it )->nRows(), data, ( *it )->nodataValue() );
00049 return true;
00050 }
00051 else if( mType == tOperator )
00052 {
00053 QgsRasterMatrix leftMatrix, rightMatrix;
00054 QgsRasterMatrix resultMatrix;
00055 if( !mLeft || !mLeft->calculate( rasterData, leftMatrix ) )
00056 {
00057 return false;
00058 }
00059 if( mRight && !mRight->calculate( rasterData, rightMatrix ) )
00060 {
00061 return false;
00062 }
00063
00064 switch( mOperator )
00065 {
00066 case opPLUS:
00067 leftMatrix.add( rightMatrix );
00068 break;
00069 case opMINUS:
00070 leftMatrix.subtract( rightMatrix );
00071 break;
00072 case opMUL:
00073 leftMatrix.multiply( rightMatrix );
00074 break;
00075 case opDIV:
00076 leftMatrix.divide( rightMatrix );
00077 break;
00078 case opPOW:
00079 leftMatrix.power( rightMatrix );
00080 break;
00081 case opEQ:
00082 leftMatrix.equal( rightMatrix );
00083 break;
00084 case opNE:
00085 leftMatrix.notEqual( rightMatrix );
00086 break;
00087 case opGT:
00088 leftMatrix.greaterThan( rightMatrix );
00089 break;
00090 case opLT:
00091 leftMatrix.lesserThan( rightMatrix );
00092 break;
00093 case opGE:
00094 leftMatrix.greaterEqual( rightMatrix );
00095 break;
00096 case opLE:
00097 leftMatrix.lesserEqual( rightMatrix );
00098 break;
00099 case opSQRT:
00100 leftMatrix.squareRoot();
00101 break;
00102 case opSIN:
00103 leftMatrix.sinus();
00104 break;
00105 case opCOS:
00106 leftMatrix.cosinus();
00107 break;
00108 case opTAN:
00109 leftMatrix.tangens();
00110 break;
00111 case opASIN:
00112 leftMatrix.asinus();
00113 break;
00114 case opACOS:
00115 leftMatrix.acosinus();
00116 break;
00117 case opATAN:
00118 leftMatrix.atangens();
00119 break;
00120 default:
00121 return false;
00122 }
00123 int newNColumns = leftMatrix.nColumns();
00124 int newNRows = leftMatrix.nRows();
00125 result.setData( newNColumns, newNRows, leftMatrix.takeData(), leftMatrix.nodataValue() );
00126 return true;
00127 }
00128 else if( mType == tNumber )
00129 {
00130 float* data = new float[1];
00131 data[0] = mNumber;
00132 result.setData( 1, 1, data, -FLT_MAX );
00133 return true;
00134 }
00135 return false;
00136 }
00137
00138 QgsRasterCalcNode* QgsRasterCalcNode::parseRasterCalcString( const QString& str, QString& parserErrorMsg )
00139 {
00140 extern QgsRasterCalcNode* localParseRasterCalcString( const QString & str, QString & parserErrorMsg );
00141 return localParseRasterCalcString( str, parserErrorMsg );
00142 }
00143