Skip to content
Permalink
Browse files
[FEATURE]: AND and OR operator for raster calculator
git-svn-id: http://svn.osgeo.org/qgis/trunk/qgis@14892 c8812cc2-4d05-0410-92ff-de0c093fc19c
  • Loading branch information
mhugent committed Dec 11, 2010
1 parent 6a6e41b commit 8d7db4fe79c7ea61a617bcfce70be197286874de
@@ -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; }
@@ -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;
@@ -55,6 +55,8 @@ class ANALYSIS_EXPORT QgsRasterCalcNode
opLT, // <
opGE, // >=
opLE, // <=
opAND,
opOR
};

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

0 comments on commit 8d7db4f

Please sign in to comment.