[FEATURE]: AND and OR operator for raster calculator

git-svn-id: http://svn.osgeo.org/qgis/trunk@14892 c8812cc2-4d05-0410-92ff-de0c093fc19c
This commit is contained in:
mhugent 2010-12-11 21:43:46 +00:00
parent 0c5fa88610
commit 8586feb657
9 changed files with 154 additions and 11 deletions

View File

@ -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; }

View File

@ -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<QString, QgsRasterMatrix*>& 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<QString, QgsRasterMatrix*>::iterator it = rasterData.find( mRasterName );
if( it == rasterData.end() )
if ( it == rasterData.end() )
{
return false;
}
@ -48,20 +48,20 @@ bool QgsRasterCalcNode::calculate( QMap<QString, QgsRasterMatrix*>& 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<QString, QgsRasterMatrix*>& 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<QString, QgsRasterMatrix*>& 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;

View File

@ -55,6 +55,8 @@ class ANALYSIS_EXPORT QgsRasterCalcNode
opLT, // <
opGE, // >=
opLE, // <=
opAND,
opOR
};
QgsRasterCalcNode();

View File

@ -55,6 +55,8 @@
%type <node> root
%type <node> 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); }

View File

@ -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;

View File

@ -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 );

View File

@ -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 " );
}

View File

@ -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

View File

@ -7,7 +7,7 @@
<x>0</x>
<y>0</y>
<width>651</width>
<height>512</height>
<height>518</height>
</rect>
</property>
<property name="windowTitle">
@ -323,6 +323,55 @@
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QPushButton" name="mLessButton">
<property name="text">
<string>&lt;</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QPushButton" name="mGreaterButton">
<property name="text">
<string>&gt;</string>
</property>
</widget>
</item>
<item row="2" column="2">
<widget class="QPushButton" name="mEqualButton">
<property name="text">
<string>=</string>
</property>
</widget>
</item>
<item row="2" column="6">
<widget class="QPushButton" name="mOrButton">
<property name="text">
<string>OR</string>
</property>
</widget>
</item>
<item row="2" column="5">
<widget class="QPushButton" name="mAndButton">
<property name="text">
<string>AND</string>
</property>
</widget>
</item>
<item row="2" column="3">
<widget class="QPushButton" name="mLesserEqualButton">
<property name="text">
<string>&lt;=</string>
</property>
</widget>
</item>
<item row="2" column="4">
<widget class="QPushButton" name="mGreaterEqualButton">
<property name="text">
<string>&gt;=</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>