Skip to content

Commit

Permalink
fix aggregate functions with mesh virtual dataset group (#45446)
Browse files Browse the repository at this point in the history
  • Loading branch information
vcloarec committed Oct 11, 2021
1 parent 18a782f commit a840cbf
Show file tree
Hide file tree
Showing 18 changed files with 514 additions and 28 deletions.
1 change: 1 addition & 0 deletions python/core/auto_generated/mesh/qgsmeshcalculator.sip.in
Expand Up @@ -10,6 +10,7 @@




class QgsMeshCalculator
{
%Docstring(signature="appended")
Expand Down
18 changes: 18 additions & 0 deletions python/core/auto_generated/mesh/qgsmeshdataprovider.sip.in
Expand Up @@ -390,6 +390,24 @@ Returns the dataset index of the dataset in a specific dataset group at ``time``
:param method: the method used to check the time

:return: the dataset index
%End

QList<QgsMeshDatasetIndex> datasetIndexInTimeInterval( const QDateTime &referenceTime,
int groupIndex,
qint64 time1,
qint64 time2 ) const;
%Docstring
Returns a list of dataset indexes of the dataset in a specific dataset group that are between ``time1`` and ``time2`` from the ``reference`` time

:param referenceTime: the reference time from where to find the dataset
:param groupIndex: the index of the dataset group
:param time1: the first relative time of the time intervale from reference time
:param time2: the second relative time of the time intervale from reference time

:return: the dataset index


.. versionadded:: 3.22
%End

protected:
Expand Down
20 changes: 20 additions & 0 deletions python/core/auto_generated/mesh/qgsmeshlayer.sip.in
Expand Up @@ -566,6 +566,26 @@ Dataset index is valid even the temporal properties is inactive. This method is


.. versionadded:: 3.16
%End

QList<QgsMeshDatasetIndex> datasetIndexInRelativeTimeInterval( const QgsInterval &startRelativeTime, const QgsInterval &endRelativeTime, int datasetGroupIndex ) const;
%Docstring
Returns a list of dataset indexes from datasets group that are in a interval time from the layer reference time.
Dataset index is valid even the temporal properties is inactive. This method is used for calculation on mesh layer.

:param startRelativeTime: the start time of the relative interval from the reference time.
:param endRelativeTime: the end time of the relative interval from the reference time.
:param datasetGroupIndex: the index of the dataset group

:return: dataset index

.. note::

indexes are used to distinguish all the dataset groups handled by the layer (from dataprovider, extra dataset group,...)
In the layer scope, those indexes are different from the data provider indexes.


.. versionadded:: 3.22
%End

QgsMeshDatasetIndex activeScalarDatasetAtTime( const QgsDateTimeRange &timeRange ) const;
Expand Down
134 changes: 130 additions & 4 deletions src/core/mesh/qgsmeshcalcnode.cpp
Expand Up @@ -104,23 +104,149 @@ QStringList QgsMeshCalcNode::usedDatasetGroupNames() const
return res;
}

bool QgsMeshCalcNode::calculate( const QgsMeshCalcUtils &dsu, QgsMeshMemoryDatasetGroup &result ) const
QStringList QgsMeshCalcNode::aggregatedUsedDatasetGroupNames() const
{
QStringList res;

switch ( mOperator )
{
case QgsMeshCalcNode::opPLUS:
case QgsMeshCalcNode::opMINUS:
case QgsMeshCalcNode::opMUL:
case QgsMeshCalcNode::opDIV:
case QgsMeshCalcNode::opPOW:
case QgsMeshCalcNode::opEQ:
case QgsMeshCalcNode::opNE:
case QgsMeshCalcNode::opGT:
case QgsMeshCalcNode::opLT:
case QgsMeshCalcNode::opGE:
case QgsMeshCalcNode::opLE:
case QgsMeshCalcNode::opAND:
case QgsMeshCalcNode::opOR:
case QgsMeshCalcNode::opNOT:
case QgsMeshCalcNode::opIF:
case QgsMeshCalcNode::opSIGN:
case QgsMeshCalcNode::opMIN:
case QgsMeshCalcNode::opMAX:
case QgsMeshCalcNode::opABS:
case QgsMeshCalcNode::opNONE:
if ( mLeft )
{
res += mLeft->aggregatedUsedDatasetGroupNames();
}

if ( mRight )
{
res += mRight->aggregatedUsedDatasetGroupNames();
}

if ( mCondition )
{
res += mCondition->aggregatedUsedDatasetGroupNames();
}
break;
case QgsMeshCalcNode::opSUM_AGGR:
case QgsMeshCalcNode::opMAX_AGGR:
case QgsMeshCalcNode::opMIN_AGGR:
case QgsMeshCalcNode::opAVG_AGGR:
if ( mLeft )
{
res += mLeft->usedDatasetGroupNames();
}

if ( mRight )
{
res += mRight->usedDatasetGroupNames();
}

if ( mCondition )
{
res += mCondition->usedDatasetGroupNames();
}
break;
}

return res;
}

QStringList QgsMeshCalcNode::notAggregatedUsedDatasetGroupNames() const
{
QStringList res;

if ( mType == tDatasetGroupRef )
{
dsu.copy( result, mDatasetGroupName );
res.append( mDatasetGroupName );
}

switch ( mOperator )
{
case QgsMeshCalcNode::opPLUS:
case QgsMeshCalcNode::opMINUS:
case QgsMeshCalcNode::opMUL:
case QgsMeshCalcNode::opDIV:
case QgsMeshCalcNode::opPOW:
case QgsMeshCalcNode::opEQ:
case QgsMeshCalcNode::opNE:
case QgsMeshCalcNode::opGT:
case QgsMeshCalcNode::opLT:
case QgsMeshCalcNode::opGE:
case QgsMeshCalcNode::opLE:
case QgsMeshCalcNode::opAND:
case QgsMeshCalcNode::opOR:
case QgsMeshCalcNode::opNOT:
case QgsMeshCalcNode::opIF:
case QgsMeshCalcNode::opSIGN:
case QgsMeshCalcNode::opMIN:
case QgsMeshCalcNode::opMAX:
case QgsMeshCalcNode::opABS:
if ( mLeft )
{
res += mLeft->notAggregatedUsedDatasetGroupNames();
}

if ( mRight )
{
res += mRight->notAggregatedUsedDatasetGroupNames();
}

if ( mCondition )
{
res += mCondition->notAggregatedUsedDatasetGroupNames();
}
break;
case QgsMeshCalcNode::opSUM_AGGR:
case QgsMeshCalcNode::opMAX_AGGR:
case QgsMeshCalcNode::opMIN_AGGR:
case QgsMeshCalcNode::opAVG_AGGR:
case QgsMeshCalcNode::opNONE:
break;
}

return res;
}

bool QgsMeshCalcNode::calculate( const QgsMeshCalcUtils &dsu, QgsMeshMemoryDatasetGroup &result, bool isAggregate ) const
{
if ( mType == tDatasetGroupRef )
{
dsu.copy( result, mDatasetGroupName, isAggregate );
return true;
}
else if ( mType == tOperator )
{
QgsMeshMemoryDatasetGroup leftDatasetGroup( "left", dsu.outputType() );
QgsMeshMemoryDatasetGroup rightDatasetGroup( "right", dsu.outputType() );

if ( !mLeft || !mLeft->calculate( dsu, leftDatasetGroup ) )
bool currentOperatorIsAggregate = mOperator == opSUM_AGGR ||
mOperator == opMAX_AGGR ||
mOperator == opMIN_AGGR ||
mOperator == opAVG_AGGR;

if ( !mLeft || !mLeft->calculate( dsu, leftDatasetGroup, isAggregate || currentOperatorIsAggregate ) )
{
return false;
}
if ( mRight && !mRight->calculate( dsu, rightDatasetGroup ) )
if ( mRight && !mRight->calculate( dsu, rightDatasetGroup, isAggregate || currentOperatorIsAggregate ) )
{
return false;
}
Expand Down
8 changes: 7 additions & 1 deletion src/core/mesh/qgsmeshcalcnode.h
Expand Up @@ -132,11 +132,17 @@ class CORE_EXPORT QgsMeshCalcNode
* \param result destination dataset group for calculation results
* \returns TRUE on success, FALSE on failure
*/
bool calculate( const QgsMeshCalcUtils &dsu, QgsMeshMemoryDatasetGroup &result ) const;
bool calculate( const QgsMeshCalcUtils &dsu, QgsMeshMemoryDatasetGroup &result, bool isAggregate = false ) const;

//! Returns all dataset group names used in formula
QStringList usedDatasetGroupNames() const;

//! Returns dataset group names used in formula involved in aggregate function
QStringList aggregatedUsedDatasetGroupNames() const;

//! Returns dataset group names used in formula not involved in aggregate function
QStringList notAggregatedUsedDatasetGroupNames() const;

/**
* Parses string to calculation node. Caller takes responsibility to delete the node
* \param str string with formula definition
Expand Down
2 changes: 2 additions & 0 deletions src/core/mesh/qgsmeshcalculator.cpp
Expand Up @@ -19,9 +19,11 @@
#include <limits>
#include <memory>

#include "qgsfeedback.h"
#include "qgsmeshcalcnode.h"
#include "qgsmeshcalculator.h"
#include "qgsmeshcalcutils.h"
#include "qgsmeshlayer.h"
#include "qgsmeshmemorydataprovider.h"
#include "qgsmeshvirtualdatasetgroup.h"
#include "qgis.h"
Expand Down
8 changes: 5 additions & 3 deletions src/core/mesh/qgsmeshcalculator.h
Expand Up @@ -25,10 +25,12 @@
#include "qgis_core.h"
#include "qgis_sip.h"
#include "qgsrectangle.h"
#include "qgsmeshlayer.h"
#include "qgsmeshdataprovider.h"
#include "qgsgeometry.h"
#include "qgsmeshdataset.h"
#include "qgsprovidermetadata.h"
#include "qgsfeedback.h"

class QgsMeshLayer;
class QgsFeedback;

/**
* \ingroup core
Expand Down

0 comments on commit a840cbf

Please sign in to comment.