Skip to content

Commit

Permalink
Added findNodes method and tests
Browse files Browse the repository at this point in the history
  • Loading branch information
elpaso committed Nov 28, 2018
1 parent e2a2aec commit 3801e9e
Show file tree
Hide file tree
Showing 3 changed files with 165 additions and 1 deletion.
119 changes: 119 additions & 0 deletions src/analysis/raster/qgsrastercalcnode.cpp
Expand Up @@ -199,6 +199,125 @@ bool QgsRasterCalcNode::calculate( QMap<QString, QgsRasterBlock * > &rasterData,
return false;
}

QString QgsRasterCalcNode::toString( bool cStyle ) const
{
QString result;
QString left;
QString right;
if ( mLeft )
left = mLeft->toString( cStyle );
if ( mRight )
right = mRight->toString( cStyle );
switch ( mType )
{
case tOperator:
switch ( mOperator )
{
case opPLUS:
result = QStringLiteral( "%1 + %2" ).arg( left ).arg( right );
break;
case opMINUS:
case opSIGN:
result = QStringLiteral( "%1 - %2" ).arg( left ).arg( right );
break;
case opMUL:
result = QStringLiteral( "%1 * %2" ).arg( left ).arg( right );
break;
case opDIV:
result = QStringLiteral( "%1 / %2" ).arg( left ).arg( right );
break;
case opPOW:
if ( cStyle )
result = QStringLiteral( "pow( %1, %2 )" ).arg( left ).arg( right );
else
result = QStringLiteral( "%1^%2" ).arg( left ).arg( right );
break;
case opEQ:
if ( cStyle )
result = QStringLiteral( "%1 == %2" ).arg( left ).arg( right );
else
result = QStringLiteral( "%1 = %2" ).arg( left ).arg( right );
break;
case opNE:
result = QStringLiteral( "%1 != %2" ).arg( left ).arg( right );
break;
case opGT:
result = QStringLiteral( "%1 > %2" ).arg( left ).arg( right );
break;
case opLT:
result = QStringLiteral( "%1 < %2" ).arg( left ).arg( right );
break;
case opGE:
result = QStringLiteral( "%1 >= %2" ).arg( left ).arg( right );
break;
case opLE:
result = QStringLiteral( "%1 <= %2" ).arg( left ).arg( right );
break;
case opAND:
if ( cStyle )
result = QStringLiteral( "%1 && %2" ).arg( left ).arg( right );
else
result = QStringLiteral( "%1 AND %2" ).arg( left ).arg( right );
break;
case opOR:
if ( cStyle )
result = QStringLiteral( "%1 || %2" ).arg( left ).arg( right );
else
result = QStringLiteral( "%1 OR%2" ).arg( left ).arg( right );
break;
case opSQRT:
result = QStringLiteral( "sqrt( %1 )" ).arg( left );
break;
case opSIN:
result = QStringLiteral( "sin( %1 )" ).arg( left );
break;
case opCOS:
result = QStringLiteral( "cos( %1 )" ).arg( left );
break;
case opTAN:
result = QStringLiteral( "tan( %1 )" ).arg( left );
break;
case opASIN:
result = QStringLiteral( "asin( %1 )" ).arg( left );
break;
case opACOS:
result = QStringLiteral( "acos( %1 )" ).arg( left );
break;
case opATAN:
result = QStringLiteral( "atan( %1 )" ).arg( left );
break;
case opLOG:
result = QStringLiteral( "log( %1 )" ).arg( left );
break;
case opLOG10:
result = QStringLiteral( "log10( %1 )" ).arg( left );
break;
case opNONE:
break;
}
break;
case tRasterRef:
result = QStringLiteral( "\"%1\"" ).arg( mRasterName );
break;
case tNumber:
result = QString::number( mNumber );
break;
case tMatrix:
break;
}
return result;
}

void QgsRasterCalcNode::findNodes( const QgsRasterCalcNode::Type type, QList<const QgsRasterCalcNode *> &nodeList ) const
{
if ( mType == type )
nodeList.push_back( this );
if ( mLeft )
mLeft->findNodes( type, nodeList );
if ( mRight )
mRight->findNodes( type, nodeList );
}

QgsRasterCalcNode *QgsRasterCalcNode::parseRasterCalcString( const QString &str, QString &parserErrorMsg )
{
extern QgsRasterCalcNode *localParseRasterCalcString( const QString & str, QString & parserErrorMsg );
Expand Down
13 changes: 13 additions & 0 deletions src/analysis/raster/qgsrastercalcnode.h
Expand Up @@ -106,6 +106,19 @@ class ANALYSIS_EXPORT QgsRasterCalcNode
*/
bool calculate( QMap<QString, QgsRasterBlock * > &rasterData, QgsRasterMatrix &result, int row = -1 ) const SIP_SKIP;

/**
* Returns a string representation of the expression
* \param cStyle if true operators will follow C syntax
* \since QGIS 3.6
*/
QString toString( bool cStyle = false ) const;

/**
* Populates a list of nodes of a specific type.
* \since QGIS 3.6
*/
void findNodes( const QgsRasterCalcNode::Type type, QList<const QgsRasterCalcNode *> &nodeList ) const;

static QgsRasterCalcNode *parseRasterCalcString( const QString &str, QString &parserErrorMsg ) SIP_FACTORY;

private:
Expand Down
34 changes: 33 additions & 1 deletion tests/src/analysis/testqgsrastercalculator.cpp
Expand Up @@ -55,6 +55,8 @@ class TestQgsRasterCalculator : public QObject
void calcWithReprojectedLayers();

void errors();
void toString();
void findNodes();

private:

Expand Down Expand Up @@ -530,7 +532,37 @@ void TestQgsRasterCalculator::calcWithReprojectedLayers()
delete block;
}

void TestQgsRasterCalculator::errors()
void TestQgsRasterCalculator::findNodes()
{

std::unique_ptr< QgsRasterCalcNode > calcNode;

auto _test =
[ & ]( QString exp, const QgsRasterCalcNode::Type type ) -> QStringList
{
QList<const QgsRasterCalcNode *> nodeList;
QString error;
calcNode.reset( QgsRasterCalcNode::parseRasterCalcString( exp, error ) );
if ( error.isEmpty() )
calcNode->findNodes( type, nodeList );
QStringList result;
for ( const auto &n : nodeList )
{
result.push_back( n->toString( true ) );
}
return result;
};

QCOMPARE( _test( QStringLiteral( "atan(\"raster@1\") * cos( 3 + 2 )" ), QgsRasterCalcNode::Type::tOperator ).length(), 4 );
QCOMPARE( _test( QStringLiteral( "\"raster@1\"" ), QgsRasterCalcNode::Type::tOperator ).length(), 0 );
QCOMPARE( _test( QStringLiteral( "\"raster@1\"" ), QgsRasterCalcNode::Type::tRasterRef ).length(), 1 );
QCOMPARE( _test( QStringLiteral( "\"raster@1\"" ), QgsRasterCalcNode::Type::tMatrix ).length(), 0 );
QCOMPARE( _test( QStringLiteral( "2 + 3" ), QgsRasterCalcNode::Type::tNumber ).length(), 2 );
QCOMPARE( _test( QStringLiteral( "2 + 3" ), QgsRasterCalcNode::Type::tOperator ).length(), 1 );

}

void TestQgsRasterCalculator::errors( )
{
QgsRasterCalculatorEntry entry1;
entry1.bandNumber = 0; // bad band
Expand Down

0 comments on commit 3801e9e

Please sign in to comment.