23#include "qgsmeshmemorydataprovider.h" 
   30const double D_TRUE = 1.0;
 
   31const double D_FALSE = 0.0;
 
   32const double D_NODATA = std::numeric_limits<double>::quiet_NaN();
 
   34std::shared_ptr<QgsMeshMemoryDatasetGroup> QgsMeshCalcUtils::createMemoryDatasetGroup( 
const QString &datasetGroupName, 
const QgsInterval &relativeTime, 
const QgsInterval &startTime, 
const QgsInterval &endTime )
 const 
   36  std::shared_ptr<QgsMeshMemoryDatasetGroup> grp;
 
   37  const QList<int> &indexes = mMeshLayer->datasetGroupsIndexes();
 
   38  for ( 
const int groupIndex : indexes )
 
   41    const QString name = meta.
name();
 
   42    if ( name == datasetGroupName )
 
   49      grp = std::make_shared<QgsMeshMemoryDatasetGroup>();
 
   51      grp->setDataType( mOutputType );
 
   53      grp->setName( meta.
name() );
 
   57        for ( 
int index = 0; index < mMeshLayer->datasetCount( groupIndex ); ++index )
 
   60      else if ( relativeTime.
isValid() )
 
   62        const QgsMeshDatasetIndex datasetIndex = mMeshLayer->datasetIndexAtRelativeTime( relativeTime, groupIndex );
 
   64          grp->addDataset( createMemoryDataset( datasetIndex ) );
 
   68        QList<QgsMeshDatasetIndex> datasetIndexes = mMeshLayer->datasetIndexInRelativeTimeInterval( startTime, endTime, groupIndex );
 
   70        if ( datasetIndexes.isEmpty() ) 
 
   71          datasetIndexes.append( mMeshLayer->datasetIndexAtRelativeTime( startTime, groupIndex ) );
 
   74          grp->addDataset( createMemoryDataset( index ) );
 
   86  return createMemoryDataset( grp.
dataType() );
 
   89std::shared_ptr<QgsMeshMemoryDataset> QgsMeshCalcUtils::createMemoryDataset( 
const QgsMeshDatasetIndex &datasetIndex )
 const 
   92  const int groupIndex = datasetIndex.
group();
 
   93  const auto meta = mMeshLayer->datasetGroupMetadata( groupIndex );
 
   99  std::shared_ptr<QgsMeshMemoryDataset> ds = createMemoryDataset( mOutputType );
 
  100  ds->maximum = dsMeta.
maximum();
 
  101  ds->minimum = dsMeta.
minimum();
 
  102  ds->time = dsMeta.
time();
 
  106  const QgsMeshDataBlock block = QgsMeshLayerUtils::datasetValues( mMeshLayer, datasetIndex, 0, nativeCount );
 
  109  Q_ASSERT( block.
count() == nativeCount );
 
  116      QVector<double> data =
 
  117        QgsMeshLayerUtils::interpolateFromFacesData(
 
  124      Q_ASSERT( data.size() == resultCount );
 
  125      for ( 
int valueIndex = 0; valueIndex < resultCount; ++valueIndex )
 
  130      QVector<double> buf = block.
values();
 
  131      QVector<double> x( nativeCount );
 
  132      QVector<double> y( nativeCount );
 
  133      for ( 
int value_i = 0; value_i < nativeCount; ++value_i )
 
  135        x[value_i] = buf[2 * value_i];
 
  136        y[value_i] = buf[2 * value_i + 1];
 
  139      QVector<double> dataX =
 
  140        QgsMeshLayerUtils::interpolateFromFacesData(
 
  142          mMeshLayer->nativeMesh(),
 
  143          mMeshLayer->triangularMesh(),
 
  145          mMeshLayer->rendererSettings().scalarSettings( groupIndex ).dataResamplingMethod()
 
  147      Q_ASSERT( dataX.size() == resultCount );
 
  148      QVector<double> dataY =
 
  149        QgsMeshLayerUtils::interpolateFromFacesData(
 
  151          mMeshLayer->nativeMesh(),
 
  152          mMeshLayer->triangularMesh(),
 
  154          mMeshLayer->rendererSettings().scalarSettings( groupIndex ).dataResamplingMethod()
 
  157      Q_ASSERT( dataY.size() == resultCount );
 
  159      for ( 
int value_i = 0; value_i < resultCount; ++value_i )
 
  167    for ( 
int value_i = 0; value_i < resultCount; ++value_i )
 
  168      ds->values[value_i] = block.
value( value_i );
 
  175    for ( 
int value_i = 0; value_i < dp->
faceCount(); ++value_i )
 
  176      ds->active[value_i] = active.
active( value_i );
 
  186  auto ds = std::make_shared<QgsMeshMemoryDataset>();
 
  189    ds->values.resize( mMeshLayer->dataProvider()->vertexCount() );
 
  190    ds->active.resize( mMeshLayer->dataProvider()->faceCount() );
 
  191    memset( ds->active.data(), 1, 
static_cast<size_t>( ds->active.size() ) * 
sizeof( 
int ) );
 
  195    ds->values.resize( mMeshLayer->dataProvider()->faceCount() );
 
  201QgsMeshCalcUtils:: QgsMeshCalcUtils( 
QgsMeshLayer *layer,
 
  202                                     const QStringList &usedGroupNames,
 
  205  : mMeshLayer( layer )
 
  209  if ( !mMeshLayer || !mMeshLayer->dataProvider() )
 
  213  mOutputType = determineResultDataType( layer, usedGroupNames );
 
  225  for ( 
const QString &groupName : usedGroupNames )
 
  227    const std::shared_ptr<QgsMeshMemoryDatasetGroup> ds = createMemoryDatasetGroup( groupName );
 
  231    mDatasetGroupMap.insert( groupName, ds );
 
  235  mDatasetGroupMapForAggregate = mDatasetGroupMap;
 
  239  bool timesPopulated = 
false;
 
  240  const QList<std::shared_ptr<QgsMeshMemoryDatasetGroup>> vals = mDatasetGroupMap.values();
 
  241  for ( 
const std::shared_ptr<QgsMeshMemoryDatasetGroup> &ds : vals )
 
  243    if ( ds->datasetCount() == 0 )
 
  249    if ( ds->datasetCount() > 1 )
 
  251      if ( timesPopulated )
 
  253        if ( ds->datasetCount() != mTimes.size() )
 
  260      for ( 
int datasetIndex = 0; datasetIndex < ds->datasetCount(); ++datasetIndex )
 
  262        const std::shared_ptr<const QgsMeshMemoryDataset> o = ds->constDataset( datasetIndex );
 
  263        if ( timesPopulated )
 
  273          mTimes.append( o->time );
 
  277      timesPopulated = 
true;
 
  282  if ( mTimes.isEmpty() )
 
  284    mTimes.push_back( 0.0 );
 
  289    for ( QVector<double>::iterator it = mTimes.begin(); it != mTimes.end(); )
 
  293           ( ( *it >= startTime ) && ( *it <= endTime ) ) )
 
  296        it = mTimes.erase( it );
 
  301  for ( 
const std::shared_ptr<QgsMeshMemoryDatasetGroup> &ds : vals )
 
  303    if ( ds->dataType() != mOutputType )
 
  311QgsMeshCalcUtils::QgsMeshCalcUtils( 
QgsMeshLayer *layer, 
const QStringList &usedGroupNames, 
const QgsInterval &relativeTime )
 
  312  : mMeshLayer( layer )
 
  316  if ( !mMeshLayer || !mMeshLayer->dataProvider() )
 
  320  mOutputType = determineResultDataType( layer, usedGroupNames );
 
  334  for ( 
const QString &groupName : usedGroupNames )
 
  336    const std::shared_ptr<QgsMeshMemoryDatasetGroup> ds = createMemoryDatasetGroup( groupName, relativeTime );
 
  337    if ( !ds || ds->memoryDatasets.isEmpty() )
 
  340    mDatasetGroupMap.insert( groupName, ds );
 
  343  mTimes.push_back( usedInterval.
hours() );
 
  349                                    const QStringList &usedGroupNames,
 
  350                                    const QStringList &usedGroupNamesForAggregate,
 
  354  : mMeshLayer( layer )
 
  358  if ( !mMeshLayer || !mMeshLayer->dataProvider() )
 
  363  mOutputType = determineResultDataType( layer, usedGroupNames + usedGroupNamesForAggregate );
 
  373  for ( 
const QString &groupName : usedGroupNamesForAggregate )
 
  375    const std::shared_ptr<QgsMeshMemoryDatasetGroup> dsg = createMemoryDatasetGroup( groupName, 
QgsInterval(), startTime, endTime );
 
  379    mDatasetGroupMapForAggregate.insert( groupName, dsg );
 
  382  for ( 
const QString &groupName : usedGroupNames )
 
  384    const std::shared_ptr<QgsMeshMemoryDatasetGroup> ds = createMemoryDatasetGroup( groupName, relativeTime );
 
  385    if ( ( !ds || ds->memoryDatasets.isEmpty() ) )
 
  387      if ( mDatasetGroupMapForAggregate.contains( groupName ) )
 
  392    mDatasetGroupMap.insert( groupName, ds );
 
  398  mTimes.append( usedInterval.
hours() );
 
  404bool  QgsMeshCalcUtils::isValid()
 const 
  414std::shared_ptr<const QgsMeshMemoryDatasetGroup> QgsMeshCalcUtils::group( 
const QString &datasetName, 
bool isAggregate )
 const 
  417    return mDatasetGroupMapForAggregate.value( datasetName );
 
  419    return mDatasetGroupMap.value( datasetName );
 
  422std::shared_ptr<const QgsMeshMemoryDatasetGroup> QgsMeshCalcUtils::group( 
const QString &datasetName )
 const 
  424  return mDatasetGroupMap[datasetName];
 
  433  const std::shared_ptr<QgsMeshMemoryDataset> output = createMemoryDataset( filter );
 
  434  output->time = mTimes[0];
 
  436  const QList<int> faceIndexesForRectangle = triangularMesh()->faceIndexesForRectangle( extent );
 
  437  const QVector<int> trianglesToNativeFaces = triangularMesh()->trianglesToNativeFaces();
 
  441    for ( 
const int faceIndex : faceIndexesForRectangle )
 
  443      const int nativeIndex = trianglesToNativeFaces[faceIndex];
 
  444      const QgsMeshFace face = nativeMesh()->face( nativeIndex );
 
  445      for ( 
const int vertexIndex : face )
 
  447        output->values[vertexIndex].set( D_TRUE );
 
  453    for ( 
const int faceIndex : faceIndexesForRectangle )
 
  455      const int nativeIndex = trianglesToNativeFaces[faceIndex];
 
  456      output->values[nativeIndex].set( D_TRUE );
 
  468  const std::shared_ptr<QgsMeshMemoryDataset> output = createMemoryDataset( filter );
 
  469  output->time = mTimes[0];
 
  471  const QVector<QgsMeshVertex> &vertices = triangularMesh()->vertices();
 
  475    const int nativeVertexCount = mMeshLayer->dataProvider()->vertexCount();
 
  477    for ( 
int i = 0; i < nativeVertexCount; ++i )
 
  482        output->values[i].set( D_TRUE );
 
  486        output->values[i].set( D_FALSE );
 
  492    const QVector<QgsMeshFace> &triangles = triangularMesh()->triangles();
 
  493    for ( 
int i = 0; i < triangles.size(); ++i )
 
  500        output->values[i].
set( D_TRUE );
 
  504        output->values[i].set( D_FALSE );
 
  511std::shared_ptr<QgsMeshMemoryDataset>  QgsMeshCalcUtils::number( 
double val, 
double time )
 const 
  513  Q_ASSERT( isValid() );
 
  515  std::shared_ptr<QgsMeshMemoryDataset> output = createMemoryDataset( mOutputType );
 
  519  if ( std::isnan( val ) )
 
  522      memset( output->active.data(), 0, 
static_cast<size_t>( output->active.size() ) * 
sizeof( 
int ) );
 
  526    for ( 
int i = 0; i < output->values.size(); ++i ) 
 
  528      output->values[i].set( val );
 
  537  Q_ASSERT( isValid() );
 
  540  const std::shared_ptr<QgsMeshMemoryDataset> output = number( val, mTimes[0] );
 
  547  Q_ASSERT( isValid() );
 
  548  number( group1, 1.0 );
 
  553  Q_ASSERT( isValid() );
 
  554  number( group1, D_NODATA );
 
  558std::shared_ptr<QgsMeshMemoryDataset>  QgsMeshCalcUtils::copy(
 
  559  std::shared_ptr<const QgsMeshMemoryDataset> dataset0
 
  562  Q_ASSERT( isValid() );
 
  563  Q_ASSERT( dataset0 );
 
  565  auto output = std::make_shared<QgsMeshMemoryDataset>();
 
  566  output->values = dataset0->values; 
 
  567  output->active = dataset0->active; 
 
  568  output->time = dataset0->time;
 
  569  output->valid = dataset0->valid;
 
  575  Q_ASSERT( isValid() );
 
  577  const std::shared_ptr<const QgsMeshMemoryDatasetGroup> group2 = group( groupName, isAggregate );
 
  580  if ( group2->datasetCount() == 1 )
 
  583    const std::shared_ptr<const QgsMeshMemoryDataset> o0 = group2->constDataset( 0 );
 
  584    const std::shared_ptr<QgsMeshMemoryDataset> output = copy( o0 );
 
  589    for ( 
int output_index = 0; output_index < group2->datasetCount(); ++output_index )
 
  591      const std::shared_ptr<const QgsMeshMemoryDataset> o0 = group2->constDataset( output_index );
 
  595           ( ( o0->time >= mTimes.first() ) && ( o0->time <= mTimes.last() ) )
 
  598        const std::shared_ptr<QgsMeshMemoryDataset> output = copy( o0 );
 
  607  Q_ASSERT( isValid() );
 
  612    const std::shared_ptr<QgsMeshMemoryDataset> o = group2.
memoryDatasets[i];
 
  621  Q_ASSERT( isValid() );
 
  627      const std::shared_ptr<QgsMeshMemoryDataset> o0 = group1.
memoryDatasets[0];
 
  631        const std::shared_ptr<QgsMeshMemoryDataset> o = copy( o0 );
 
  645std::shared_ptr<QgsMeshMemoryDataset>  QgsMeshCalcUtils::canditateDataset(
 
  647  int datasetIndex )
 const 
  649  Q_ASSERT( isValid() );
 
  663std::shared_ptr<const QgsMeshMemoryDataset>  QgsMeshCalcUtils::constCandidateDataset(
 
  665  int datasetIndex )
 const 
  667  Q_ASSERT( isValid() );
 
  681int  QgsMeshCalcUtils::datasetCount(
 
  685  Q_ASSERT( isValid() );
 
  692      return mTimes.size();
 
  701                              std::function<
double( 
double )> func )
 const 
  703  Q_ASSERT( isValid() );
 
  705  for ( 
int time_index = 0; time_index < group.
datasetCount(); ++time_index )
 
  707    const std::shared_ptr<QgsMeshMemoryDataset> output = canditateDataset( group, time_index );
 
  709    for ( 
int n = 0; n < output->values.size(); ++n )
 
  711      const double val1 = output->values[n].scalar();
 
  712      double res_val = D_NODATA;
 
  713      if ( !std::isnan( val1 ) )
 
  714        res_val = func( val1 );
 
  715      output->values[n] = res_val;
 
  726                              std::function<
double( 
double, 
double )> func )
 const 
  728  Q_ASSERT( isValid() );
 
  731  expand( group1, group2 );
 
  733  for ( 
int time_index = 0; time_index < datasetCount( group1, group2 ); ++time_index )
 
  735    const std::shared_ptr<QgsMeshMemoryDataset> o1 = canditateDataset( group1, time_index );
 
  736    const std::shared_ptr<const QgsMeshMemoryDataset> o2 = constCandidateDataset( group2, time_index );
 
  738    for ( 
int n = 0; n < o2->values.size(); ++n )
 
  740      const double val1 = o1->values[n].scalar();
 
  741      const double val2 = o2->values[n].scalar();
 
  742      double res_val = D_NODATA;
 
  743      if ( !std::isnan( val1 ) && !std::isnan( val2 ) )
 
  744        res_val = func( val1, val2 );
 
  745      o1->values[n] = res_val;
 
  756void QgsMeshCalcUtils::funcAggr(
 
  758  std::function<
double( QVector<double>& )> func
 
  761  Q_ASSERT( isValid() );
 
  766    output->time = mTimes[0];
 
  767    for ( 
int n = 0; n < mMeshLayer->dataProvider()->vertexCount(); ++n )
 
  769      QVector < double > vals;
 
  770      for ( 
int datasetIndex = 0; datasetIndex < group1.
datasetCount(); ++datasetIndex )
 
  772        const std::shared_ptr<QgsMeshMemoryDataset> o1 = canditateDataset( group1, datasetIndex );
 
  774        const double val1 = o1->values[n].scalar();
 
  778        if ( !std::isnan( val1 ) )
 
  780          vals.push_back( val1 );
 
  784      double res_val = D_NODATA;
 
  785      if ( !vals.isEmpty() )
 
  787        res_val = func( vals );
 
  790      output->values[n] = res_val;
 
  803    output->time = mTimes[0];
 
  805    const int facesCount = mMeshLayer->dataProvider()->faceCount();
 
  806    output->values.resize( facesCount );
 
  808    for ( 
int n = 0; n < mMeshLayer->dataProvider()->faceCount(); ++n )
 
  810      QVector < double > vals;
 
  811      for ( 
int datasetIndex = 0; datasetIndex < group1.
datasetCount(); ++datasetIndex )
 
  813        const std::shared_ptr<QgsMeshMemoryDataset> o1 = canditateDataset( group1, datasetIndex );
 
  814        const double val1 = o1->values[n].scalar();
 
  815        if ( !std::isnan( val1 ) )
 
  817          vals.push_back( val1 );
 
  821      double res_val = D_NODATA;
 
  822      if ( !vals.isEmpty() )
 
  824        res_val = func( vals );
 
  827      output->values[n] = res_val;
 
  838  Q_ASSERT( mMeshLayer->triangularMesh() );
 
  839  return mMeshLayer->triangularMesh();
 
  842const QgsMesh *QgsMeshCalcUtils::nativeMesh()
 const 
  845  const QgsMesh *res = mMeshLayer->nativeMesh();
 
  850void QgsMeshCalcUtils::updateMesh()
 const 
  852  if ( ! mMeshLayer->nativeMesh() )
 
  855    mMeshLayer->updateTriangularMesh();
 
  868  Q_ASSERT( isValid() );
 
  871  expand( trueGroup, condition );
 
  872  expand( trueGroup, falseGroup );
 
  877  for ( 
int time_index = 0; time_index < trueGroup.
datasetCount(); ++time_index )
 
  879    const std::shared_ptr<QgsMeshMemoryDataset> true_o = canditateDataset( trueGroup, time_index );
 
  880    const std::shared_ptr<const QgsMeshMemoryDataset> false_o = constCandidateDataset( falseGroup, time_index );
 
  881    const std::shared_ptr<const QgsMeshMemoryDataset> condition_o = constCandidateDataset( condition, time_index );
 
  882    for ( 
int n = 0; n < true_o->values.size(); ++n )
 
  884      const double conditionValue =  condition_o->values[n].scalar();
 
  885      double resultValue = D_NODATA;
 
  886      if ( !std::isnan( conditionValue ) )
 
  889          resultValue = true_o->values[n].scalar();
 
  891          resultValue = false_o->values[n].scalar();
 
  893      true_o->values[n] = resultValue;
 
  900      activate( true_o, condition_o );
 
  908  Q_ASSERT( isValid() );
 
  912    for ( 
int datasetIndex = 0; datasetIndex < group.
datasetCount(); ++datasetIndex )
 
  914      const std::shared_ptr<QgsMeshMemoryDataset> o1 = canditateDataset( group, datasetIndex );
 
  922void QgsMeshCalcUtils::activate(
 
  923  std::shared_ptr<QgsMeshMemoryDataset> dataset,
 
  924  std::shared_ptr<const QgsMeshMemoryDataset> refDataset 
 
  928  Q_ASSERT( isValid() );
 
  932  for ( 
int idx = 0; idx < mMeshLayer->dataProvider()->faceCount(); ++idx )
 
  934    if ( refDataset && !refDataset->active.isEmpty() && ( !refDataset->active[idx] ) )
 
  936      dataset->active[idx] = 
false;
 
  940    if ( !dataset->active[idx] )
 
  947    bool isActive = 
true; 
 
  948    for ( 
int j = 0; j < face.size(); ++j )
 
  950      if ( std::isnan( dataset->values[face[j]].scalar() ) )
 
  956    dataset->active[idx] = isActive;
 
  960double QgsMeshCalcUtils::ffilter( 
double val1, 
double filter )
 const 
  962  Q_ASSERT( !std::isnan( val1 ) );
 
  970double QgsMeshCalcUtils::fadd( 
double val1, 
double val2 )
 const 
  972  Q_ASSERT( !std::isnan( val1 ) );
 
  973  Q_ASSERT( !std::isnan( val2 ) );
 
  978double QgsMeshCalcUtils::fsubtract( 
double val1, 
double val2 )
 const 
  980  Q_ASSERT( !std::isnan( val1 ) );
 
  981  Q_ASSERT( !std::isnan( val2 ) );
 
  986double QgsMeshCalcUtils::fmultiply( 
double val1, 
double val2 )
 const 
  988  Q_ASSERT( !std::isnan( val1 ) );
 
  989  Q_ASSERT( !std::isnan( val2 ) );
 
  994double QgsMeshCalcUtils::fdivide( 
double val1, 
double val2 )
 const 
  996  Q_ASSERT( !std::isnan( val1 ) );
 
  997  Q_ASSERT( !std::isnan( val2 ) );
 
 1005double QgsMeshCalcUtils::fpower( 
double val1, 
double val2 )
 const 
 1007  Q_ASSERT( !std::isnan( val1 ) );
 
 1008  Q_ASSERT( !std::isnan( val2 ) );
 
 1009  return pow( val1, val2 );
 
 1013double QgsMeshCalcUtils::fequal( 
double val1, 
double val2 )
 const 
 1015  Q_ASSERT( !std::isnan( val1 ) );
 
 1016  Q_ASSERT( !std::isnan( val2 ) );
 
 1028double QgsMeshCalcUtils::fnotEqual( 
double val1, 
double val2 )
 const 
 1030  Q_ASSERT( !std::isnan( val1 ) );
 
 1031  Q_ASSERT( !std::isnan( val2 ) );
 
 1043double QgsMeshCalcUtils::fgreaterThan( 
double val1, 
double val2 )
 const 
 1045  Q_ASSERT( !std::isnan( val1 ) );
 
 1046  Q_ASSERT( !std::isnan( val2 ) );
 
 1058double QgsMeshCalcUtils::flesserThan( 
double val1, 
double val2 )
 const 
 1060  Q_ASSERT( !std::isnan( val1 ) );
 
 1061  Q_ASSERT( !std::isnan( val2 ) );
 
 1073double QgsMeshCalcUtils::flesserEqual( 
double val1, 
double val2 )
 const 
 1075  Q_ASSERT( !std::isnan( val1 ) );
 
 1076  Q_ASSERT( !std::isnan( val2 ) );
 
 1088double QgsMeshCalcUtils::fgreaterEqual( 
double val1, 
double val2 )
 const 
 1090  Q_ASSERT( !std::isnan( val1 ) );
 
 1091  Q_ASSERT( !std::isnan( val2 ) );
 
 1104double QgsMeshCalcUtils::flogicalAnd( 
double val1, 
double val2 )
 const 
 1106  Q_ASSERT( !std::isnan( val1 ) );
 
 1107  Q_ASSERT( !std::isnan( val2 ) );
 
 1110  if ( bval1 && bval2 )
 
 1117double QgsMeshCalcUtils::flogicalOr( 
double val1, 
double val2 )
 const 
 1119  Q_ASSERT( !std::isnan( val1 ) );
 
 1120  Q_ASSERT( !std::isnan( val2 ) );
 
 1123  if ( bval1 || bval2 )
 
 1130double QgsMeshCalcUtils::flogicalNot( 
double val1 )
 const 
 1132  Q_ASSERT( !std::isnan( val1 ) );
 
 1141double QgsMeshCalcUtils::fchangeSign( 
double val1 )
 const 
 1143  Q_ASSERT( !std::isnan( val1 ) );
 
 1147double QgsMeshCalcUtils::fmin( 
double val1, 
double val2 )
 const 
 1149  Q_ASSERT( !std::isnan( val1 ) );
 
 1161double QgsMeshCalcUtils::fmax( 
double val1, 
double val2 )
 const 
 1163  Q_ASSERT( !std::isnan( val1 ) );
 
 1164  Q_ASSERT( !std::isnan( val2 ) );
 
 1176double QgsMeshCalcUtils::fabs( 
double val1 )
 const 
 1178  Q_ASSERT( !std::isnan( val1 ) );
 
 1190double QgsMeshCalcUtils::fsumAggregated( QVector<double> &vals )
 const 
 1192  Q_ASSERT( !vals.contains( D_NODATA ) );
 
 1193  Q_ASSERT( !vals.isEmpty() );
 
 1194  return std::accumulate( vals.begin(), vals.end(), 0.0 );
 
 1197double QgsMeshCalcUtils::fminimumAggregated( QVector<double> &vals )
 const 
 1199  Q_ASSERT( !vals.contains( D_NODATA ) );
 
 1200  Q_ASSERT( !vals.isEmpty() );
 
 1201  return *std::min_element( vals.begin(), vals.end() );
 
 1204double QgsMeshCalcUtils::fmaximumAggregated( QVector<double> &vals )
 const 
 1206  Q_ASSERT( !vals.contains( D_NODATA ) );
 
 1207  Q_ASSERT( !vals.isEmpty() );
 
 1208  return *std::max_element( vals.begin(), vals.end() );
 
 1211double QgsMeshCalcUtils::faverageAggregated( QVector<double> &vals )
 const 
 1213  Q_ASSERT( !vals.contains( D_NODATA ) );
 
 1214  Q_ASSERT( !vals.isEmpty() );
 
 1215  return fsumAggregated( vals ) / vals.size();
 
 1220  return func1( group1, std::bind( & QgsMeshCalcUtils::flogicalNot, 
this, std::placeholders::_1 ) );
 
 1225  return func1( group1, std::bind( & QgsMeshCalcUtils::fchangeSign, 
this, std::placeholders::_1 ) );
 
 1230  return func1( group1, std::bind( & QgsMeshCalcUtils::fabs, 
this, std::placeholders::_1 ) );
 
 1235  return func2( group1, group2, std::bind( & QgsMeshCalcUtils::fadd, 
this, std::placeholders::_1, std::placeholders::_2 ) );
 
 1240  return func2( group1, group2, std::bind( & QgsMeshCalcUtils::fsubtract, 
this, std::placeholders::_1, std::placeholders::_2 ) );
 
 1245  return func2( group1, group2, std::bind( & QgsMeshCalcUtils::fmultiply, 
this, std::placeholders::_1, std::placeholders::_2 ) );
 
 1250  return func2( group1, group2, std::bind( & QgsMeshCalcUtils::fdivide, 
this, std::placeholders::_1, std::placeholders::_2 ) );
 
 1255  return func2( group1, group2, std::bind( & QgsMeshCalcUtils::fpower, 
this, std::placeholders::_1, std::placeholders::_2 ) );
 
 1260  return func2( group1, group2, std::bind( & QgsMeshCalcUtils::fequal, 
this, std::placeholders::_1, std::placeholders::_2 ) );
 
 1265  return func2( group1, group2, std::bind( & QgsMeshCalcUtils::fnotEqual, 
this, std::placeholders::_1, std::placeholders::_2 ) );
 
 1270  return func2( group1, group2, std::bind( & QgsMeshCalcUtils::fgreaterThan, 
this, std::placeholders::_1, std::placeholders::_2 ) );
 
 1275  return func2( group1, group2, std::bind( & QgsMeshCalcUtils::flesserThan, 
this, std::placeholders::_1, std::placeholders::_2 ) );
 
 1280  return func2( group1, group2, std::bind( & QgsMeshCalcUtils::flesserEqual, 
this, std::placeholders::_1, std::placeholders::_2 ) );
 
 1285  return func2( group1, group2, std::bind( & QgsMeshCalcUtils::fgreaterEqual, 
this, std::placeholders::_1, std::placeholders::_2 ) );
 
 1290  return func2( group1, group2, std::bind( & QgsMeshCalcUtils::flogicalAnd, 
this, std::placeholders::_1, std::placeholders::_2 ) );
 
 1295  return func2( group1, group2, std::bind( & QgsMeshCalcUtils::flogicalOr, 
this, std::placeholders::_1, std::placeholders::_2 ) );
 
 1300  return func2( group1, group2, std::bind( & QgsMeshCalcUtils::fmin, 
this, std::placeholders::_1, std::placeholders::_2 ) );
 
 1305  return func2( group1, group2, std::bind( & QgsMeshCalcUtils::fmax, 
this, std::placeholders::_1, std::placeholders::_2 ) );
 
 1310  QHash<QString, int> names;
 
 1312  for ( 
const int groupId : groupIndexes )
 
 1315    const QString name = meta.
name();
 
 1316    names[ name ] = groupId;
 
 1318  for ( 
const QString &datasetGroupName : usedGroupNames )
 
 1320    if ( names.contains( datasetGroupName ) )
 
 1322      const int groupId = names.value( datasetGroupName );
 
 1340  populateSpatialFilter( filter, extent );
 
 1341  return func2( group1, filter, std::bind( & QgsMeshCalcUtils::ffilter, 
this, std::placeholders::_1, std::placeholders::_2 ) );
 
 1347  populateMaskFilter( filter, mask );
 
 1348  return func2( group1, filter, std::bind( & QgsMeshCalcUtils::ffilter, 
this, std::placeholders::_1, std::placeholders::_2 ) );
 
 1353  return funcAggr( group1, std::bind( & QgsMeshCalcUtils::fsumAggregated, 
this, std::placeholders::_1 ) );
 
 1358  return funcAggr( group1, std::bind( & QgsMeshCalcUtils::fminimumAggregated, 
this, std::placeholders::_1 ) );
 
 1363  return funcAggr( group1, std::bind( & QgsMeshCalcUtils::fmaximumAggregated, 
this, std::placeholders::_1 ) );
 
 1368  return funcAggr( group1, std::bind( & QgsMeshCalcUtils::faverageAggregated, 
this, std::placeholders::_1 ) );
 
A geometry is the spatial representation of a feature.
 
bool contains(const QgsPointXY *p) const
Returns true if the geometry contains the point p.
 
QgsRectangle boundingBox() const
Returns the bounding box of the geometry.
 
bool intersects(const QgsRectangle &rectangle) const
Returns true if this geometry exactly intersects with a rectangle.
 
A representation of the interval between two datetime values.
 
bool isValid() const
Returns true if the interval is valid.
 
double hours() const
Returns the interval duration in hours.
 
A block of integers/doubles from a mesh dataset.
 
QgsMeshDatasetValue value(int index) const
Returns a value represented by the index For active flag the behavior is undefined.
 
QVector< double > values() const
Returns buffer to the array with values For vector it is pairs (x1, y1, x2, y2, .....
 
bool isValid() const
Whether the block is valid.
 
bool active(int index) const
Returns a value for active flag by the index For scalar and vector 2d the behavior is undefined.
 
int count() const
Number of items stored in the block.
 
Base class for providing data for QgsMeshLayer.
 
virtual int vertexCount() const =0
Returns number of vertices in the native mesh.
 
virtual int faceCount() const =0
Returns number of faces in the native mesh.
 
QgsMeshDatasetGroupMetadata::DataType dataType() const
Returns the data type of the dataset group.
 
An index that identifies the dataset group (e.g.
 
bool isValid() const
Returns whether index is valid, ie at least groups is set.
 
int group() const
Returns a group index.
 
Represents a single mesh dataset value.
 
Represents a mesh layer supporting display of data on structured or unstructured meshes.
 
QList< int > datasetGroupsIndexes() const
Returns the list of indexes of dataset groups handled by the layer.
 
QgsMeshDatasetGroupMetadata datasetGroupMetadata(const QgsMeshDatasetIndex &index) const
Returns the dataset groups metadata.
 
Represents a mesh dataset group stored in memory.
 
void addDataset(std::shared_ptr< QgsMeshMemoryDataset > dataset)
Adds a memory dataset to the group.
 
void clearDatasets()
Removes all the datasets from the group.
 
std::shared_ptr< const QgsMeshMemoryDataset > constDataset(int index) const
Returns the dataset with index.
 
QVector< std::shared_ptr< QgsMeshMemoryDataset > > memoryDatasets
Contains all the memory datasets.
 
int datasetCount() const override
Returns the count of datasets in the group.
 
@ NeighbourAverage
Does a simple average of values defined for all surrounding faces/vertices.
 
static QgsGeometry toGeometry(const QgsMeshFace &face, const QVector< QgsMeshVertex > &vertices)
Returns face as polygon geometry.
 
A rectangle specified with double values.
 
void set(const QgsPointXY &p1, const QgsPointXY &p2, bool normalize=true)
Sets the rectangle from two QgsPoints.
 
A triangular/derived mesh with vertices in map coordinates.
 
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference)
 
QVector< int > QgsMeshFace
List of vertex indexes.
 
Mesh - vertices, edges and faces.