Skip to content

Commit

Permalink
Merge pull request #8564 from elpaso/rastercalculator-fast-track
Browse files Browse the repository at this point in the history
Rastercalculator memory efficient track

Cherry-picked from master 0fde410
  • Loading branch information
elpaso committed Dec 5, 2018
1 parent ae03a81 commit 1e5e373
Show file tree
Hide file tree
Showing 8 changed files with 370 additions and 73 deletions.
16 changes: 16 additions & 0 deletions python/analysis/auto_generated/raster/qgsrastercalcnode.sip.in
Expand Up @@ -74,6 +74,22 @@ QgsRasterCalcNode cannot be copied
void setRight( QgsRasterCalcNode *right );


QString toString( bool cStyle = false ) const;
%Docstring
Returns a string representation of the expression

:param cStyle: if true operators will follow C syntax

.. versionadded:: 3.6
%End

QList<const QgsRasterCalcNode *> findNodes( const QgsRasterCalcNode::Type type ) const;
%Docstring
Returns a list of nodes of a specific ``type``

.. versionadded:: 3.6
%End

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

private:
Expand Down
4 changes: 2 additions & 2 deletions python/plugins/processing/algs/qgis/RasterCalculator.py
Expand Up @@ -168,8 +168,8 @@ def _cellsize(layer):

output = self.parameterAsOutputLayer(parameters, self.OUTPUT, context)

width = math.floor((bbox.xMaximum() - bbox.xMinimum()) / cellsize)
height = math.floor((bbox.yMaximum() - bbox.yMinimum()) / cellsize)
width = round((bbox.xMaximum() - bbox.xMinimum()) / cellsize)
height = round((bbox.yMaximum() - bbox.yMinimum()) / cellsize)
driverName = GdalUtils.getFormatShortNameFromFilename(output)

calc = QgsRasterCalculator(expression,
Expand Down
Expand Up @@ -2537,7 +2537,7 @@ tests:
EXPRESSION: dem@1
results:
OUTPUT:
hash: ef97a22ee16e0e28bbdc0341449777b1527e37febc3c4339b2c057c9
hash: 525577c05dd999239d9c6f95fd5e70d96355da3a0ea71bfcf021e729
type: rasterhash

- algorithm: qgis:rastercalculator
Expand All @@ -2552,7 +2552,7 @@ tests:
EXPRESSION: dem@1 * 2
results:
OUTPUT:
hash: fe6e018be13c5a3c17f3f4d0f0dc7686c628cb440b74c4642aa0c939
hash: 98daf025230ec9d031f7502c6a80a3b04dd060808d6b7bcb4328e87c
type: rasterhash

- algorithm: native:orientedminimumboundingbox
Expand Down
122 changes: 122 additions & 0 deletions src/analysis/raster/qgsrastercalcnode.cpp
Expand Up @@ -16,6 +16,7 @@
#include "qgsrasterblock.h"
#include "qgsrastermatrix.h"
#include <cfloat>
#include <QtDebug>

QgsRasterCalcNode::QgsRasterCalcNode( double number )
: mNumber( number )
Expand Down Expand Up @@ -199,6 +200,127 @@ 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;
}

QList<const QgsRasterCalcNode *> QgsRasterCalcNode::findNodes( const QgsRasterCalcNode::Type type ) const
{
QList<const QgsRasterCalcNode *> nodeList;
if ( mType == type )
nodeList.push_back( this );
if ( mLeft )
nodeList.append( mLeft->findNodes( type ) );
if ( mRight )
nodeList.append( mRight->findNodes( type ) );
return 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;

/**
* Returns a list of nodes of a specific \a type
* \since QGIS 3.6
*/
QList<const QgsRasterCalcNode *> findNodes( const QgsRasterCalcNode::Type type ) const;

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

private:
Expand Down

0 comments on commit 1e5e373

Please sign in to comment.