From 8586feb657c7cb3e9fbac0fc4913b2c803637a34 Mon Sep 17 00:00:00 2001 From: mhugent Date: Sat, 11 Dec 2010 21:43:46 +0000 Subject: [PATCH] [FEATURE]: AND and OR operator for raster calculator git-svn-id: http://svn.osgeo.org/qgis/trunk@14892 c8812cc2-4d05-0410-92ff-de0c093fc19c --- src/analysis/raster/qgsrastercalclexer.ll | 2 + src/analysis/raster/qgsrastercalcnode.cpp | 24 ++++++---- src/analysis/raster/qgsrastercalcnode.h | 2 + src/analysis/raster/qgsrastercalcparser.yy | 4 ++ src/analysis/raster/qgsrastermatrix.cpp | 34 +++++++++++++++ src/analysis/raster/qgsrastermatrix.h | 6 ++- src/app/qgsrastercalcdialog.cpp | 35 +++++++++++++++ src/app/qgsrastercalcdialog.h | 7 +++ src/ui/qgsrastercalcdialogbase.ui | 51 +++++++++++++++++++++- 9 files changed, 154 insertions(+), 11 deletions(-) diff --git a/src/analysis/raster/qgsrastercalclexer.ll b/src/analysis/raster/qgsrastercalclexer.ll index 54d98aff933..edb49d5479b 100644 --- a/src/analysis/raster/qgsrastercalclexer.ll +++ b/src/analysis/raster/qgsrastercalclexer.ll @@ -58,6 +58,8 @@ raster_band_ref ({raster_ref_char}+)@{dig} "acos" { rasterlval.op = QgsRasterCalcNode::opACOS; return FUNCTION;} "atan" { rasterlval.op = QgsRasterCalcNode::opATAN; return FUNCTION;} +"AND" { return AND; } +"OR" { return OR; } "!=" { return NE; } "<=" { return LE; } ">=" { return GE; } diff --git a/src/analysis/raster/qgsrastercalcnode.cpp b/src/analysis/raster/qgsrastercalcnode.cpp index f679ec3020c..b08eae2ce02 100644 --- a/src/analysis/raster/qgsrastercalcnode.cpp +++ b/src/analysis/raster/qgsrastercalcnode.cpp @@ -19,11 +19,11 @@ QgsRasterCalcNode::QgsRasterCalcNode( const QString& rasterName ): mType( tRaste QgsRasterCalcNode::~QgsRasterCalcNode() { - if( mLeft ) + if ( mLeft ) { delete mLeft; } - if( mRight ) + if ( mRight ) { delete mRight; } @@ -34,10 +34,10 @@ bool QgsRasterCalcNode::calculate( QMap& rasterData, //if type is raster ref: return a copy of the corresponding matrix //if type is operator, call the proper matrix operations - if( mType == tRasterRef ) + if ( mType == tRasterRef ) { QMap::iterator it = rasterData.find( mRasterName ); - if( it == rasterData.end() ) + if ( it == rasterData.end() ) { return false; } @@ -48,20 +48,20 @@ bool QgsRasterCalcNode::calculate( QMap& rasterData, result.setData(( *it )->nColumns(), ( *it )->nRows(), data, ( *it )->nodataValue() ); return true; } - else if( mType == tOperator ) + else if ( mType == tOperator ) { QgsRasterMatrix leftMatrix, rightMatrix; QgsRasterMatrix resultMatrix; - if( !mLeft || !mLeft->calculate( rasterData, leftMatrix ) ) + if ( !mLeft || !mLeft->calculate( rasterData, leftMatrix ) ) { return false; } - if( mRight && !mRight->calculate( rasterData, rightMatrix ) ) + if ( mRight && !mRight->calculate( rasterData, rightMatrix ) ) { return false; } - switch( mOperator ) + switch ( mOperator ) { case opPLUS: leftMatrix.add( rightMatrix ); @@ -96,6 +96,12 @@ bool QgsRasterCalcNode::calculate( QMap& rasterData, case opLE: leftMatrix.lesserEqual( rightMatrix ); break; + case opAND: + leftMatrix.logicalAnd( rightMatrix ); + break; + case opOR: + leftMatrix.logicalOr( rightMatrix ); + break; case opSQRT: leftMatrix.squareRoot(); break; @@ -125,7 +131,7 @@ bool QgsRasterCalcNode::calculate( QMap& rasterData, result.setData( newNColumns, newNRows, leftMatrix.takeData(), leftMatrix.nodataValue() ); return true; } - else if( mType == tNumber ) + else if ( mType == tNumber ) { float* data = new float[1]; data[0] = mNumber; diff --git a/src/analysis/raster/qgsrastercalcnode.h b/src/analysis/raster/qgsrastercalcnode.h index 4036bc7e0b0..48bfc18c74a 100644 --- a/src/analysis/raster/qgsrastercalcnode.h +++ b/src/analysis/raster/qgsrastercalcnode.h @@ -55,6 +55,8 @@ class ANALYSIS_EXPORT QgsRasterCalcNode opLT, // < opGE, // >= opLE, // <= + opAND, + opOR }; QgsRasterCalcNode(); diff --git a/src/analysis/raster/qgsrastercalcparser.yy b/src/analysis/raster/qgsrastercalcparser.yy index 98176def311..0743ad46952 100644 --- a/src/analysis/raster/qgsrastercalcparser.yy +++ b/src/analysis/raster/qgsrastercalcparser.yy @@ -55,6 +55,8 @@ %type root %type raster_exp +%left AND +%left OR %left NE %left GE %left LE @@ -71,6 +73,8 @@ root: raster_exp{} raster_exp: FUNCTION '(' raster_exp ')' { $$ = new QgsRasterCalcNode($1, $3, 0); joinTmpNodes($$, $3, 0);} + | raster_exp AND raster_exp { $$ = new QgsRasterCalcNode( QgsRasterCalcNode::opAND, $1, $3 ); joinTmpNodes($$,$1,$3); } + | raster_exp OR raster_exp { $$ = new QgsRasterCalcNode( QgsRasterCalcNode::opOR, $1, $3 ); joinTmpNodes($$,$1,$3); } | raster_exp '=' raster_exp { $$ = new QgsRasterCalcNode( QgsRasterCalcNode::opEQ, $1, $3 ); joinTmpNodes($$,$1,$3); } | raster_exp NE raster_exp { $$ = new QgsRasterCalcNode( QgsRasterCalcNode::opNE, $1, $3 ); joinTmpNodes($$,$1,$3); } | raster_exp '>' raster_exp { $$ = new QgsRasterCalcNode( QgsRasterCalcNode::opGT, $1, $3 ); joinTmpNodes($$, $1, $3); } diff --git a/src/analysis/raster/qgsrastermatrix.cpp b/src/analysis/raster/qgsrastermatrix.cpp index b9f49372195..0cdf86b9ddd 100644 --- a/src/analysis/raster/qgsrastermatrix.cpp +++ b/src/analysis/raster/qgsrastermatrix.cpp @@ -122,6 +122,16 @@ bool QgsRasterMatrix::lesserEqual( const QgsRasterMatrix& other ) return twoArgumentOperation( opLE, other ); } +bool QgsRasterMatrix::logicalAnd( const QgsRasterMatrix& other ) +{ + return twoArgumentOperation( opAND, other ); +} + +bool QgsRasterMatrix::logicalOr( const QgsRasterMatrix& other ) +{ + return twoArgumentOperation( opOR, other ); +} + bool QgsRasterMatrix::squareRoot() { return oneArgumentOperation( opSQRT ); @@ -266,6 +276,12 @@ bool QgsRasterMatrix::twoArgumentOperation( TwoArgOperator op, const QgsRasterMa case opLE: mData[0] = mData[0] <= other.number() ? 1.0f : 0.0f; break; + case opAND: + mData[0] = mData[0] && other.number() ? 1.0f : 0.0f; + break; + case opOR: + mData[0] = mData[0] || other.number() ? 1.0f : 0.0f; + break; } return true; } @@ -335,6 +351,12 @@ bool QgsRasterMatrix::twoArgumentOperation( TwoArgOperator op, const QgsRasterMa case opLE: mData[i] = value1 <= value2 ? 1.0f : 0.0f; break; + case opAND: + mData[i] = value1 && value2 ? 1.0f : 0.0f; + break; + case opOR: + mData[i] = value1 || value2 ? 1.0f : 0.0f; + break; } } } @@ -417,6 +439,12 @@ bool QgsRasterMatrix::twoArgumentOperation( TwoArgOperator op, const QgsRasterMa case opLE: mData[i] = value <= matrix[i] ? 1.0f : 0.0f; break; + case opAND: + mData[i] = value && matrix[i] ? 1.0f : 0.0f; + break; + case opOR: + mData[i] = value || matrix[i] ? 1.0f : 0.0f; + break; } } return true; @@ -491,6 +519,12 @@ bool QgsRasterMatrix::twoArgumentOperation( TwoArgOperator op, const QgsRasterMa case opLE: mData[i] = mData[i] <= value ? 1.0f : 0.0f; break; + case opAND: + mData[i] = mData[i] && value ? 1.0f : 0.0f; + break; + case opOR: + mData[i] = mData[i] || value ? 1.0f : 0.0f; + break; } } return true; diff --git a/src/analysis/raster/qgsrastermatrix.h b/src/analysis/raster/qgsrastermatrix.h index cfc5c4c252d..4c800e9adcc 100644 --- a/src/analysis/raster/qgsrastermatrix.h +++ b/src/analysis/raster/qgsrastermatrix.h @@ -35,6 +35,8 @@ class ANALYSIS_EXPORT QgsRasterMatrix opLT, // < opGE, // >= opLE, // <= + opAND, + opOR }; enum OneArgOperator @@ -85,6 +87,8 @@ class ANALYSIS_EXPORT QgsRasterMatrix bool lesserThan( const QgsRasterMatrix& other ); bool greaterEqual( const QgsRasterMatrix& other ); bool lesserEqual( const QgsRasterMatrix& other ); + bool logicalAnd( const QgsRasterMatrix& other ); + bool logicalOr( const QgsRasterMatrix& other ); bool squareRoot(); bool sinus(); @@ -100,7 +104,7 @@ class ANALYSIS_EXPORT QgsRasterMatrix float* mData; double mNodataValue; - /**+,-,*,/,^,<,>,<=,>=,=,!=*/ + /**+,-,*,/,^,<,>,<=,>=,=,!=, and, or*/ bool twoArgumentOperation( TwoArgOperator op, const QgsRasterMatrix& other ); /*sqrt, sin, cos, tan, asin, acos, atan*/ bool oneArgumentOperation( OneArgOperator op ); diff --git a/src/app/qgsrastercalcdialog.cpp b/src/app/qgsrastercalcdialog.cpp index 0007b4b189d..fb4bcf98dd4 100644 --- a/src/app/qgsrastercalcdialog.cpp +++ b/src/app/qgsrastercalcdialog.cpp @@ -389,3 +389,38 @@ void QgsRasterCalcDialog::on_mCloseBracketPushButton_clicked() { mExpressionTextEdit->insertPlainText( " ) " ); } + +void QgsRasterCalcDialog::on_mLessButton_clicked() +{ + mExpressionTextEdit->insertPlainText( " < " ); +} + +void QgsRasterCalcDialog::on_mGreaterButton_clicked() +{ + mExpressionTextEdit->insertPlainText( " > " ); +} + +void QgsRasterCalcDialog::on_mEqualButton_clicked() +{ + mExpressionTextEdit->insertPlainText( " = " ); +} + +void QgsRasterCalcDialog::on_mLesserEqualButton_clicked() +{ + mExpressionTextEdit->insertPlainText( " <= " ); +} + +void QgsRasterCalcDialog::on_mGreaterEqualButton_clicked() +{ + mExpressionTextEdit->insertPlainText( " >= " ); +} + +void QgsRasterCalcDialog::on_mAndButton_clicked() +{ + mExpressionTextEdit->insertPlainText( " AND " ); +} + +void QgsRasterCalcDialog::on_mOrButton_clicked() +{ + mExpressionTextEdit->insertPlainText( " OR " ); +} diff --git a/src/app/qgsrastercalcdialog.h b/src/app/qgsrastercalcdialog.h index 56fb77be335..852d5b082cd 100644 --- a/src/app/qgsrastercalcdialog.h +++ b/src/app/qgsrastercalcdialog.h @@ -68,6 +68,13 @@ class QgsRasterCalcDialog: public QDialog, private Ui::QgsRasterCalcDialogBase void on_mATanButton_clicked(); void on_mOpenBracketPushButton_clicked(); void on_mCloseBracketPushButton_clicked(); + void on_mLessButton_clicked(); + void on_mGreaterButton_clicked(); + void on_mEqualButton_clicked(); + void on_mLesserEqualButton_clicked(); + void on_mGreaterEqualButton_clicked(); + void on_mAndButton_clicked(); + void on_mOrButton_clicked(); private: //insert available GDAL drivers that support the create() option diff --git a/src/ui/qgsrastercalcdialogbase.ui b/src/ui/qgsrastercalcdialogbase.ui index 75b9193fc05..d29567c4bf9 100644 --- a/src/ui/qgsrastercalcdialogbase.ui +++ b/src/ui/qgsrastercalcdialogbase.ui @@ -7,7 +7,7 @@ 0 0 651 - 512 + 518 @@ -323,6 +323,55 @@ + + + + < + + + + + + + > + + + + + + + = + + + + + + + OR + + + + + + + AND + + + + + + + <= + + + + + + + >= + + +