QGIS API Documentation  3.18.1-Zürich (202f1bf7e5)
qgsmeshdatasetgroupstore.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsmeshdatasetgroupstore.cpp
3  ---------------------
4  begin : June 2020
5  copyright : (C) 2020 by Vincent Cloarec
6  email : vcloarec at gmail dot com
7  ***************************************************************************/
8 
9 /***************************************************************************
10  * *
11  * This program is free software; you can redistribute it and/or modify *
12  * it under the terms of the GNU General Public License as published by *
13  * the Free Software Foundation; either version 2 of the License, or *
14  * (at your option) any later version. *
15  * *
16  ***************************************************************************/
17 
19 #include "qgsmeshlayer.h"
20 #include "qgsmeshlayerutils.h"
21 #include "qgsapplication.h"
23 #include "qgslogger.h"
24 
26 {
27  return mRegistery.keys();
28 }
29 
31 {
32  return mDatasetGroupTreeRootItem->enabledDatasetGroupIndexes();
33 }
34 
36 {
37  return mRegistery.count();
38 }
39 
41 {
42  return mExtraDatasets->datasetGroupCount();
43 }
44 
46  mLayer( layer ),
47  mExtraDatasets( new QgsMeshExtraDatasetStore ),
48  mDatasetGroupTreeRootItem( new QgsMeshDatasetGroupTreeItem )
49 {}
50 
52 {
53  removePersistentProvider();
54  mPersistentProvider = provider;
55  if ( !mPersistentProvider )
56  return;
57  connect( mPersistentProvider, &QgsMeshDataProvider::datasetGroupsAdded, this, &QgsMeshDatasetGroupStore::onPersistentDatasetAdded );
58  onPersistentDatasetAdded( mPersistentProvider->datasetGroupCount() );
59 }
60 
61 QgsMeshDatasetGroupStore::DatasetGroup QgsMeshDatasetGroupStore::datasetGroup( int index ) const
62 {
63  if ( mRegistery.contains( index ) )
64  return mRegistery[index];
65  else
66  return DatasetGroup{nullptr, -1};
67 }
68 
70 {
71  if ( !mPersistentProvider )
72  return false;
73  return mPersistentProvider->addDataset( path ) ;
74 }
75 
77 {
78  if ( !mPersistentProvider || !mExtraDatasets )
79  return false;
80 
81  switch ( group->dataType() )
82  {
84  if ( ! group->checkValueCountPerDataset( mPersistentProvider->faceCount() ) )
85  return false;
86  break;
88  if ( ! group->checkValueCountPerDataset( mPersistentProvider->vertexCount() ) )
89  return false;
90  break;
92  return false; // volume not supported for extra dataset
93  break;
95  if ( ! group->checkValueCountPerDataset( mPersistentProvider->edgeCount() ) )
96  return false;
97  break;
98  }
99 
100  int nativeIndex = mExtraDatasets->addDatasetGroup( group );
101  int groupIndex = registerDatasetGroup( DatasetGroup{mExtraDatasets.get(), nativeIndex} );
102  QList<int> groupIndexes;
103  groupIndexes.append( groupIndex );
104  createDatasetGroupTreeItems( groupIndexes );
105  syncItemToDatasetGroup( groupIndex );
106 
107  emit datasetGroupsAdded( groupIndexes );
108 
109  return true;
110 }
111 
113 {
114  mDatasetGroupTreeRootItem.reset( new QgsMeshDatasetGroupTreeItem );
115  createDatasetGroupTreeItems( datasetGroupIndexes() );
116  QList<int> groupIndexes = datasetGroupIndexes();
117  for ( int groupIndex : groupIndexes )
118  syncItemToDatasetGroup( groupIndex );
119 }
120 
122 {
123  return mDatasetGroupTreeRootItem.get();
124 }
125 
127 {
128  if ( rootItem )
129  mDatasetGroupTreeRootItem.reset( rootItem->clone() );
130  else
131  mDatasetGroupTreeRootItem.reset();
132 
133  unregisterGroupNotPresentInTree();
134 }
135 
137 {
138  QgsMeshDatasetGroupStore::DatasetGroup group = datasetGroup( index.group() );
139  if ( group.first )
140  return group.first->datasetGroupMetadata( group.second );
141  else
143 }
144 
145 int QgsMeshDatasetGroupStore::datasetCount( int groupIndex ) const
146 {
147  QgsMeshDatasetGroupStore::DatasetGroup group = datasetGroup( groupIndex );
148  if ( group.first )
149  return group.first->datasetCount( group.second );
150  else
151  return 0;
152 }
153 
155 {
156  QgsMeshDatasetGroupStore::DatasetGroup group = datasetGroup( index.group() );
157  if ( group.first )
158  return group.first->datasetMetadata( QgsMeshDatasetIndex( group.second, index.dataset() ) );
159  else
160  return QgsMeshDatasetMetadata();
161 }
162 
164 {
165  QgsMeshDatasetGroupStore::DatasetGroup group = datasetGroup( index.group() );
166  if ( group.first )
167  return group.first->datasetValue( QgsMeshDatasetIndex( group.second, index.dataset() ), valueIndex );
168  else
169  return QgsMeshDatasetValue();
170 }
171 
172 QgsMeshDataBlock QgsMeshDatasetGroupStore::datasetValues( const QgsMeshDatasetIndex &index, int valueIndex, int count ) const
173 {
174  QgsMeshDatasetGroupStore::DatasetGroup group = datasetGroup( index.group() );
175  if ( group.first )
176  return group.first->datasetValues( QgsMeshDatasetIndex( group.second, index.dataset() ), valueIndex, count );
177  else
178  return QgsMeshDataBlock();
179 }
180 
182 {
183  QgsMeshDatasetGroupStore::DatasetGroup group = datasetGroup( index.group() );
184  if ( group.first )
185  return group.first->dataset3dValues( QgsMeshDatasetIndex( group.second, index.dataset() ), faceIndex, count );
186  else
187  return QgsMesh3dDataBlock();
188 }
189 
191 {
192  QgsMeshDatasetGroupStore::DatasetGroup group = datasetGroup( index.group() );
193  if ( group.first )
194  return group.first->areFacesActive( QgsMeshDatasetIndex( group.second, index.dataset() ), faceIndex, count );
195  else
196  return QgsMeshDataBlock();
197 }
198 
199 bool QgsMeshDatasetGroupStore::isFaceActive( const QgsMeshDatasetIndex &index, int faceIndex ) const
200 {
201  QgsMeshDatasetGroupStore::DatasetGroup group = datasetGroup( index.group() );
202  if ( group.first )
203  return group.first->isFaceActive( QgsMeshDatasetIndex( group.second, index.dataset() ), faceIndex );
204  else
205  return false;
206 }
207 
209  qint64 time,
211 {
212  QgsMeshDatasetGroupStore::DatasetGroup group = datasetGroup( groupIndex );
213  if ( !group.first )
214  return QgsMeshDatasetIndex();
215 
216  const QDateTime &referenceTime = mPersistentProvider->temporalCapabilities()->referenceTime();
217 
218  return QgsMeshDatasetIndex( groupIndex,
219  group.first->datasetIndexAtTime( referenceTime, group.second, time, method ).dataset() );
220 }
221 
223 {
224  QgsMeshDatasetGroupStore::DatasetGroup group = datasetGroup( index.group() );
225  if ( !group.first || group.second < 0 )
226  return INVALID_MESHLAYER_TIME;
227 
228  QgsMeshDatasetIndex nativeIndex( group.second, index.dataset() );
229 
230  if ( group.first == mPersistentProvider )
231  return mPersistentProvider->temporalCapabilities()->datasetTime( nativeIndex );
232  else if ( group.first == mExtraDatasets.get() )
233  return mExtraDatasets->datasetRelativeTime( nativeIndex );
234 
235  return INVALID_MESHLAYER_TIME;
236 
237 }
238 
240 {
241  return ( mPersistentProvider && mPersistentProvider->temporalCapabilities()->hasTemporalCapabilities() ) ||
242  ( mExtraDatasets && mExtraDatasets->hasTemporalCapabilities() );
243 }
244 
245 QDomElement QgsMeshDatasetGroupStore::writeXml( QDomDocument &doc, const QgsReadWriteContext &context )
246 {
247  Q_UNUSED( context );
248  QDomElement storeElement = doc.createElement( QStringLiteral( "mesh-dataset-groups-store" ) );
249  storeElement.appendChild( mDatasetGroupTreeRootItem->writeXml( doc, context ) );
250 
251  QMap < int, DatasetGroup>::const_iterator it = mRegistery.begin();
252  while ( it != mRegistery.end() )
253  {
254  QDomElement elemDataset;
255  if ( it.value().first == mPersistentProvider )
256  {
257  elemDataset = doc.createElement( QStringLiteral( "mesh-dataset" ) );
258  elemDataset.setAttribute( QStringLiteral( "global-index" ), it.key() );
259  elemDataset.setAttribute( QStringLiteral( "source-type" ), QStringLiteral( "persitent-provider" ) );
260  elemDataset.setAttribute( QStringLiteral( "source-index" ), it.value().second );
261 
262  }
263  else if ( it.value().first == mExtraDatasets.get() )
264  {
265  QgsMeshDatasetGroupTreeItem *item = mDatasetGroupTreeRootItem->childFromDatasetGroupIndex( it.key() );
266  if ( item )
267  {
268  elemDataset = mExtraDatasets->writeXml( it.value().second, doc, context );
269  if ( !elemDataset.isNull() )
270  elemDataset.setAttribute( QStringLiteral( "global-index" ), it.key() );
271  }
272  }
273 
274  if ( !elemDataset.isNull() )
275  storeElement.appendChild( elemDataset );
276  ++it;
277  }
278 
279  return storeElement;
280 }
281 
282 void QgsMeshDatasetGroupStore::readXml( const QDomElement &storeElem, const QgsReadWriteContext &context )
283 {
284  Q_UNUSED( context );
285  mRegistery.clear();
286  QDomElement datasetElem = storeElem.firstChildElement( "mesh-dataset" );
287  QMap<int, QgsMeshDatasetGroup *> extraDatasetGroups;
288  while ( !datasetElem.isNull() )
289  {
290  int globalIndex = datasetElem.attribute( QStringLiteral( "global-index" ) ).toInt();
291  int sourceIndex;
292  QgsMeshDatasetSourceInterface *source = nullptr;
293  if ( datasetElem.attribute( QStringLiteral( "source-type" ) ) == QLatin1String( "persitent-provider" ) )
294  {
295  source = mPersistentProvider;
296  sourceIndex = datasetElem.attribute( QStringLiteral( "source-index" ) ).toInt();
297  }
298  else if ( datasetElem.attribute( QStringLiteral( "source-type" ) ) == QLatin1String( "virtual" ) )
299  {
300  source = mExtraDatasets.get();
301  QString name = datasetElem.attribute( QStringLiteral( "name" ) );
302  QString formula = datasetElem.attribute( QStringLiteral( "formula" ) );
303  qint64 startTime = datasetElem.attribute( QStringLiteral( "start-time" ) ).toLongLong();
304  qint64 endTime = datasetElem.attribute( QStringLiteral( "end-time" ) ).toLongLong();
305 
306  QgsMeshDatasetGroup *dsg = new QgsMeshVirtualDatasetGroup( name, formula, mLayer, startTime, endTime );
307  extraDatasetGroups[globalIndex] = dsg;
308  sourceIndex = mExtraDatasets->addDatasetGroup( dsg );
309  }
310 
311  if ( source )
312  mRegistery[globalIndex] = DatasetGroup{source, sourceIndex};
313 
314  datasetElem = datasetElem.nextSiblingElement( QStringLiteral( "mesh-dataset" ) );
315  }
316 
317  QDomElement rootTreeItemElem = storeElem.firstChildElement( QStringLiteral( "mesh-dataset-group-tree-item" ) );
318  if ( !rootTreeItemElem.isNull() )
319  setDatasetGroupTreeItem( new QgsMeshDatasetGroupTreeItem( rootTreeItemElem, context ) );
320 
321  checkDatasetConsistency( mPersistentProvider );
322  removeUnregisteredItemFromTree();
323 
324  //Once everything is created, initialize the extra dataset groups
325  for ( int groupIndex : extraDatasetGroups.keys() )
326  extraDatasetGroups.value( groupIndex )->initialize();
327 
328 
329  mExtraDatasets->updateTemporalCapabilities();
330 }
331 
332 bool QgsMeshDatasetGroupStore::saveDatasetGroup( QString filePath, int groupIndex, QString driver )
333 {
334  DatasetGroup group = datasetGroup( groupIndex );
335 
336  bool fail = true;
337  if ( group.first && group.second >= 0 )
338  fail = mPersistentProvider->persistDatasetGroup( filePath, driver, group.first, group.second );
339 
340  if ( !fail )
341  {
342  eraseDatasetGroup( group );
343  group.first = mPersistentProvider;
344  group.second = mPersistentProvider->datasetGroupCount() - 1;
345  mRegistery[groupIndex] = group;
346  //update the item type
347  if ( mDatasetGroupTreeRootItem )
348  {
349  QgsMeshDatasetGroupTreeItem *item = mDatasetGroupTreeRootItem->childFromDatasetGroupIndex( groupIndex );
350  if ( item )
351  item->setPersistentDatasetGroup( filePath );
352  }
353  }
354 
355  return fail;
356 }
357 
358 void QgsMeshDatasetGroupStore::onPersistentDatasetAdded( int count )
359 {
360  Q_ASSERT( mPersistentProvider );
361 
362  int providerTotalCount = mPersistentProvider->datasetGroupCount();
363  int providerBeginIndex = mPersistentProvider->datasetGroupCount() - count;
364  QList<int> groupIndexes;
365  for ( int i = providerBeginIndex; i < providerTotalCount; ++i )
366  groupIndexes.append( registerDatasetGroup( DatasetGroup{mPersistentProvider, i} ) );
367 
368  createDatasetGroupTreeItems( groupIndexes );
369  for ( int groupIndex : groupIndexes )
370  syncItemToDatasetGroup( groupIndex );
371 
372  emit datasetGroupsAdded( groupIndexes );
373 }
374 
375 void QgsMeshDatasetGroupStore::removePersistentProvider()
376 {
377  if ( !mPersistentProvider )
378  return;
379 
380  disconnect( mPersistentProvider, &QgsMeshDataProvider::datasetGroupsAdded, this, &QgsMeshDatasetGroupStore::onPersistentDatasetAdded );
381 
382  QMap < int, DatasetGroup>::iterator it = mRegistery.begin();
383  while ( it != mRegistery.end() )
384  {
385  if ( it.value().first == mPersistentProvider )
386  it = mRegistery.erase( it );
387  else
388  ++it;
389  }
390 
391  mPersistentProvider = nullptr;
392 }
393 
394 int QgsMeshDatasetGroupStore::newIndex()
395 {
396  int index = 0;
397  QMap < int, DatasetGroup>::iterator it = mRegistery.begin();
398  while ( it != mRegistery.end() )
399  {
400  if ( index <= it.key() )
401  index = it.key() + 1;
402  ++it;
403  }
404  return index;
405 }
406 
407 int QgsMeshDatasetGroupStore::registerDatasetGroup( const QgsMeshDatasetGroupStore::DatasetGroup &group )
408 {
409  int groupIndex = newIndex();
410  mRegistery[newIndex()] = group;
411  return groupIndex;
412 }
413 
414 void QgsMeshDatasetGroupStore::eraseDatasetGroup( const QgsMeshDatasetGroupStore::DatasetGroup &group )
415 {
416  if ( group.first == mPersistentProvider )
417  return; //removing persistent dataset group from the store is not allowed
418  else if ( group.first == mExtraDatasets.get() )
419  eraseExtraDataset( group.second );
420 }
421 
422 void QgsMeshDatasetGroupStore::eraseExtraDataset( int indexInExtraStore )
423 {
424  mExtraDatasets->removeDatasetGroup( indexInExtraStore );
425 
426  //search dataset with index greater than indexInExtraStore and decrement it
427  QMap < int, DatasetGroup>::iterator it = mRegistery.begin();
428  while ( it != mRegistery.end() )
429  {
430  int localIndex = it.value().second;
431  if ( it.value().first == mExtraDatasets.get() && localIndex > indexInExtraStore )
432  it->second = localIndex - 1;
433  ++it;
434  }
435 }
436 
437 int QgsMeshDatasetGroupStore::nativeIndexToGroupIndex( QgsMeshDatasetSourceInterface *source, int nativeIndex )
438 {
439  QMap < int, DatasetGroup>::const_iterator it = mRegistery.begin();
440  while ( it != mRegistery.end() )
441  {
442  if ( it.value() == DatasetGroup{source, nativeIndex} )
443  return it.key();
444  ++it;
445  }
446  return -1;
447 }
448 
449 void QgsMeshDatasetGroupStore::checkDatasetConsistency( QgsMeshDatasetSourceInterface *source )
450 {
451  // check if datasets of source are present, if not, add them
452  QList<int> indexes;
453  for ( int i = 0; i < source->datasetGroupCount(); ++i )
454  if ( nativeIndexToGroupIndex( source, i ) == -1 )
455  indexes.append( registerDatasetGroup( DatasetGroup{source, i} ) );
456 
457  if ( !indexes.isEmpty() )
458  createDatasetGroupTreeItems( indexes );
459  for ( int index : indexes )
460  syncItemToDatasetGroup( index );
461 }
462 
463 void QgsMeshDatasetGroupStore::removeUnregisteredItemFromTree()
464 {
465  QList<QgsMeshDatasetGroupTreeItem *> itemsToCheck;
466  QList<int> indexItemToRemove;
467  for ( int i = 0; i < mDatasetGroupTreeRootItem->childCount(); ++i )
468  itemsToCheck.append( mDatasetGroupTreeRootItem->child( i ) );
469 
470  while ( !itemsToCheck.isEmpty() )
471  {
472  QgsMeshDatasetGroupTreeItem *item = itemsToCheck.takeFirst();
473  int globalIndex = item->datasetGroupIndex();
474  if ( !mRegistery.contains( globalIndex ) )
475  indexItemToRemove.append( globalIndex );
476  for ( int i = 0; i < item->childCount(); ++i )
477  itemsToCheck.append( item->child( i ) );
478  }
479 
480  for ( int i : indexItemToRemove )
481  {
482  QgsMeshDatasetGroupTreeItem *item = mDatasetGroupTreeRootItem->childFromDatasetGroupIndex( i );
483  if ( item )
484  item->parentItem()->removeChild( item );
485  }
486 }
487 
488 void QgsMeshDatasetGroupStore::unregisterGroupNotPresentInTree()
489 {
490  if ( !mDatasetGroupTreeRootItem )
491  {
492  mRegistery.clear();
493  return;
494  }
495 
496  QMap < int, DatasetGroup>::iterator it = mRegistery.begin();
497  while ( it != mRegistery.end() )
498  {
499  DatasetGroup datasetGroup = it.value();
500  int globalIndex = it.key();
501  if ( ! mDatasetGroupTreeRootItem->childFromDatasetGroupIndex( globalIndex ) // Not in the tree item
502  && datasetGroup.first != mPersistentProvider ) // and not persistent
503  {
504  it = mRegistery.erase( it ); //remove from registery
505  eraseDatasetGroup( datasetGroup ); //remove from where the dataset group is stored
506  }
507  else
508  ++it;
509  }
510 }
511 
512 void QgsMeshDatasetGroupStore::syncItemToDatasetGroup( int groupIndex )
513 {
514  if ( !mDatasetGroupTreeRootItem )
515  return;
516  DatasetGroup group = datasetGroup( groupIndex );
517  QgsMeshDatasetGroupTreeItem *item = mDatasetGroupTreeRootItem->childFromDatasetGroupIndex( groupIndex );
518  if ( group.first == mPersistentProvider && mPersistentProvider )
519  {
520  QgsMeshDatasetGroupMetadata meta = mPersistentProvider->datasetGroupMetadata( group.second );
521  if ( item )
522  item->setPersistentDatasetGroup( meta.uri() );
523  }
524  else if ( group.first == mExtraDatasets.get() )
525  {
526  if ( item )
527  item->setDatasetGroup( mExtraDatasets->datasetGroup( group.second ) );
528  }
529 }
530 
531 void QgsMeshDatasetGroupStore::createDatasetGroupTreeItems( const QList<int> &indexes )
532 {
533  QMap<QString, QgsMeshDatasetGroupTreeItem *> mNameToItem;
534 
535  for ( int i = 0; i < indexes.count(); ++i )
536  {
537  int groupIndex = indexes.at( i );
538  const QgsMeshDatasetGroupMetadata meta = datasetGroupMetadata( groupIndex );
539  const QString name = meta.name();
540  const QStringList subdatasets = name.split( '/' );
541 
542  QString displayName = name;
543  QgsMeshDatasetGroupTreeItem *parent = mDatasetGroupTreeRootItem.get();
544 
545  if ( subdatasets.size() == 2 )
546  {
547  auto it = mNameToItem.find( subdatasets[0] );
548  if ( it == mNameToItem.end() )
549  QgsDebugMsg( QStringLiteral( "Unable to find parent group for %1." ).arg( name ) );
550  else
551  {
552  displayName = subdatasets[1];
553  parent = it.value();
554  }
555  }
556  else if ( subdatasets.size() != 1 )
557  QgsDebugMsg( QStringLiteral( "Ignoring too deep child group name %1." ).arg( name ) );
558 
559  QgsMeshDatasetGroupTreeItem *item = new QgsMeshDatasetGroupTreeItem( displayName, name, meta.isVector(), groupIndex );
560  parent->appendChild( item );
561  if ( mNameToItem.contains( name ) )
562  QgsDebugMsg( QStringLiteral( "Group %1 is not unique" ).arg( displayName ) );
563  mNameToItem[name] = item;
564  }
565 }
566 
568 {
569  int groupIndex = mGroups.size();
570  mGroups.push_back( std::unique_ptr<QgsMeshDatasetGroup>( datasetGroup ) );
571 
572  if ( datasetGroup->datasetCount() > 1 )
573  {
574  mTemporalCapabilities->setHasTemporalCapabilities( true );
575  for ( int i = 0; i < datasetGroup->datasetCount(); ++i )
576  mTemporalCapabilities->addDatasetTime( groupIndex, datasetGroup->datasetMetadata( i ).time() );
577  }
578 
579  return mGroups.size() - 1;
580 }
581 
583 {
584  if ( index < datasetGroupCount() )
585  mGroups.erase( mGroups.begin() + index );
586 
587 
589 }
590 
592 {
593  return mTemporalCapabilities->hasTemporalCapabilities();
594 }
595 
597 {
598  return mTemporalCapabilities->datasetTime( index );
599 }
600 
601 QString QgsMeshExtraDatasetStore::description( int groupIndex ) const
602 {
603  if ( groupIndex >= 0 && groupIndex < int( mGroups.size() ) )
604  return mGroups.at( groupIndex )->description();
605  else
606  return QString();
607 }
608 
610 {
611  if ( groupIndex >= 0 && groupIndex < int( mGroups.size() ) )
612  return mGroups[groupIndex].get();
613  else
614  return nullptr;
615 }
616 
617 bool QgsMeshExtraDatasetStore::addDataset( const QString &uri )
618 {
619  Q_UNUSED( uri );
620  return false;
621 }
622 
624 {
625  return QStringList();
626 }
627 
629 {
630  return mGroups.size();
631 }
632 
633 int QgsMeshExtraDatasetStore::datasetCount( int groupIndex ) const
634 {
635  if ( groupIndex >= 0 && groupIndex < datasetGroupCount() )
636  return mGroups.at( groupIndex )->datasetCount();
637  else
638  return 0;
639 }
640 
642 {
643  if ( groupIndex >= 0 && groupIndex < datasetGroupCount() )
644  return mGroups.at( groupIndex )->groupMetadata();
645  else
647 }
648 
650 {
651  int groupIndex = index.group();
652  if ( index.isValid() && groupIndex < datasetGroupCount() )
653  {
654  int datasetIndex = index.dataset();
655  const QgsMeshDatasetGroup *group = mGroups.at( groupIndex ).get();
656  if ( datasetIndex < group->datasetCount() )
657  return group->datasetMetadata( datasetIndex );
658  }
659  return QgsMeshDatasetMetadata();
660 }
661 
663 {
664  int groupIndex = index.group();
665  if ( index.isValid() && groupIndex < datasetGroupCount() )
666  {
667  const QgsMeshDatasetGroup *group = mGroups.at( groupIndex ).get();
668  int datasetIndex = index.dataset();
669  if ( datasetIndex < group->datasetCount() )
670  return group->dataset( datasetIndex )->datasetValue( valueIndex );
671  }
672 
673  return QgsMeshDatasetValue();
674 }
675 
677 {
678  int groupIndex = index.group();
679  if ( index.isValid() && groupIndex < datasetGroupCount() )
680  {
681  const QgsMeshDatasetGroup *group = mGroups.at( groupIndex ).get();
682  int datasetIndex = index.dataset();
683  if ( datasetIndex < group->datasetCount() )
684  return group->dataset( datasetIndex )->datasetValues( group->isScalar(), valueIndex, count );
685  }
686 
687  return QgsMeshDataBlock();
688 }
689 
691 {
692  // Not supported for now
693  Q_UNUSED( index )
694  Q_UNUSED( faceIndex )
695  Q_UNUSED( count )
696  return QgsMesh3dDataBlock();
697 }
698 
700 {
701  int groupIndex = index.group();
702  if ( index.isValid() && groupIndex < datasetGroupCount() )
703  {
704  const QgsMeshDatasetGroup *group = mGroups.at( groupIndex ).get();
705  int datasetIndex = index.dataset();
706  if ( datasetIndex < group->datasetCount() )
707  return group->dataset( datasetIndex )->isActive( faceIndex );
708  }
709 
710  return false;
711 }
712 
714 {
715  int groupIndex = index.group();
716  if ( index.isValid() && groupIndex < datasetGroupCount() )
717  {
718  const QgsMeshDatasetGroup *group = mGroups.at( groupIndex ).get();
719  int datasetIndex = index.dataset();
720  if ( datasetIndex < group->datasetCount() )
721  return group->dataset( datasetIndex )->areFacesActive( faceIndex, count );
722  }
723  return QgsMeshDataBlock();
724 }
725 
726 bool QgsMeshExtraDatasetStore::persistDatasetGroup( const QString &outputFilePath,
727  const QString &outputDriver,
728  const QgsMeshDatasetGroupMetadata &meta,
729  const QVector<QgsMeshDataBlock> &datasetValues,
730  const QVector<QgsMeshDataBlock> &datasetActive,
731  const QVector<double> &times )
732 {
733  Q_UNUSED( outputFilePath )
734  Q_UNUSED( outputDriver )
735  Q_UNUSED( meta )
736  Q_UNUSED( datasetValues )
737  Q_UNUSED( datasetActive )
738  Q_UNUSED( times )
739  return true; // not implemented/supported
740 }
741 
742 bool QgsMeshExtraDatasetStore::persistDatasetGroup( const QString &outputFilePath,
743  const QString &outputDriver,
745  int datasetGroupIndex )
746 {
747  Q_UNUSED( outputFilePath )
748  Q_UNUSED( outputDriver )
749  Q_UNUSED( source )
750  Q_UNUSED( datasetGroupIndex )
751  return true; // not implemented/supported
752 }
753 
754 QDomElement QgsMeshExtraDatasetStore::writeXml( int groupIndex, QDomDocument &doc, const QgsReadWriteContext &context )
755 {
756  if ( groupIndex >= 0 && groupIndex < int( mGroups.size() ) && mGroups[groupIndex] )
757  return mGroups[groupIndex]->writeXml( doc, context );
758  else
759  return QDomElement();
760 }
761 
763 {
764  //update temporal capabilitie
765  mTemporalCapabilities->clear();
766  bool hasTemporal = false;
767  for ( size_t g = 0; g < mGroups.size(); ++g )
768  {
769  const QgsMeshDatasetGroup *group = mGroups[g].get();
770  hasTemporal |= group->datasetCount() > 1;
771  for ( int i = 0; i < group->datasetCount(); ++i )
772  mTemporalCapabilities->addDatasetTime( g, group->datasetMetadata( i ).time() );
773  }
774 
775  mTemporalCapabilities->setHasTemporalCapabilities( hasTemporal );
776 }
bool hasTemporalCapabilities() const
Returns true if the provider has temporal capabilities available.
QgsMesh3dDataBlock is a block of 3d stacked mesh data related N faces defined on base mesh frame.
QgsMeshDataBlock is a block of integers/doubles that can be used to retrieve: active flags (e....
QDateTime referenceTime() const
Returns the reference time.
MatchingTemporalDatasetMethod
Method for selection of temporal mesh dataset from a range time.
qint64 datasetTime(const QgsMeshDatasetIndex &index) const
Returns the relative time in milliseconds of the dataset.
Base class for providing data for QgsMeshLayer.
void datasetGroupsAdded(int count)
Emitted when some new dataset groups have been added.
QgsMeshDataProviderTemporalCapabilities * temporalCapabilities() override
Returns the provider's temporal capabilities.
virtual int vertexCount() const =0
Returns number of vertices in the native mesh.
virtual int edgeCount() const =0
Returns number of edges in the native mesh.
virtual int faceCount() const =0
Returns number of faces in the native mesh.
QgsMeshDatasetGroupMetadata is a collection of dataset group metadata such as whether the data is vec...
bool isVector() const
Returns whether dataset group has vector data.
QString name() const
Returns name of the dataset group.
@ DataOnEdges
Data is defined on edges.
@ DataOnFaces
Data is defined on faces.
@ DataOnVertices
Data is defined on vertices.
@ DataOnVolumes
Data is defined on volumes.
QString uri() const
Returns the uri of the source.
QgsMeshDatasetGroupTreeItem * datasetGroupTreeItem() const
Returns a pointer to the root of the dataset groups tree item.
QgsMeshDatasetMetadata datasetMetadata(const QgsMeshDatasetIndex &index) const
Returns the metadata of the dataset with global index.
QList< int > enabledDatasetGroupIndexes() const
Returns a list of all group indexes that are enabled.
bool addPersistentDatasets(const QString &path)
Adds persistent datasets from a file with path.
QgsMeshDatasetGroupMetadata datasetGroupMetadata(const QgsMeshDatasetIndex &index) const
Returns the metadata of the dataset group with global index.
bool isFaceActive(const QgsMeshDatasetIndex &index, int faceIndex) const
Returns whether face is active for particular dataset.
QList< int > datasetGroupIndexes() const
Returns a list of all group indexes.
bool hasTemporalCapabilities() const
Returns whether at lea&st one of stored dataset group is temporal.
void resetDatasetGroupTreeItem()
Resets to default state the dataset groups tree item.
QgsMeshDataBlock datasetValues(const QgsMeshDatasetIndex &index, int valueIndex, int count) const
Returns count values of the dataset with global index and from valueIndex.
QgsMesh3dDataBlock dataset3dValues(const QgsMeshDatasetIndex &index, int faceIndex, int count) const
Returns count 3D values of the dataset with global index and from valueIndex.
QgsMeshDatasetIndex datasetIndexAtTime(qint64 time, int groupIndex, QgsMeshDataProviderTemporalCapabilities::MatchingTemporalDatasetMethod method) const
Returns the global dataset index of the dataset int the dataset group with groupIndex,...
bool saveDatasetGroup(QString filePath, int groupIndex, QString driver)
Saves on a file with filePath the dataset groups index with groupIndex with the specified driver.
bool addDatasetGroup(QgsMeshDatasetGroup *group)
Adds a extra dataset group, take ownership.
QgsMeshDatasetValue datasetValue(const QgsMeshDatasetIndex &index, int valueIndex) const
Returns the value of the dataset with global index and valueIndex.
QDomElement writeXml(QDomDocument &doc, const QgsReadWriteContext &context)
Writes the store's information in a DOM document.
int extraDatasetGroupCount() const
Returns the count of extra dataset groups.
int datasetGroupCount() const
Returns the count of dataset groups.
QgsMeshDatasetGroupStore(QgsMeshLayer *layer)
Constructor.
QgsMeshDataBlock areFacesActive(const QgsMeshDatasetIndex &index, int faceIndex, int count) const
Returns whether faces are active for particular dataset.
void setDatasetGroupTreeItem(QgsMeshDatasetGroupTreeItem *rootItem)
Sets the root of the dataset groups tree item, doesn't take onwnershib but clone the root item.
qint64 datasetRelativeTime(const QgsMeshDatasetIndex &index) const
Returns the relative time of the dataset from the persistent provider reference time.
int datasetCount(int groupIndex) const
Returns the total count of dataset group in the store.
void readXml(const QDomElement &storeElem, const QgsReadWriteContext &context)
Reads the store's information from a DOM document.
void setPersistentProvider(QgsMeshDataProvider *provider)
Sets the persistent mesh data provider.
void datasetGroupsAdded(QList< int > indexes)
Emitted after dataset groups are added.
Tree item for display of the mesh dataset groups.
QgsMeshDatasetGroupTreeItem * clone() const
Clones the item.
void setPersistentDatasetGroup(const QString &uri)
Set parameters of the item in accordance with the persistent dataset group with uri.
int childCount() const
Returns the count of children.
QgsMeshDatasetGroupTreeItem * parentItem() const
Returns the parent item, nullptr if it is root item.
void removeChild(QgsMeshDatasetGroupTreeItem *item)
Removes a item child if exists.
void setDatasetGroup(QgsMeshDatasetGroup *datasetGroup)
Set parameters of the item in accordance with the dataset group.
void appendChild(QgsMeshDatasetGroupTreeItem *item)
Appends a item child.
QgsMeshDatasetGroupTreeItem * child(int row) const
Returns a child.
Abstract class that represents a dataset group.
bool isScalar() const
Returns whether the group contain scalar values.
bool checkValueCountPerDataset(int count) const
Returns whether all the datasets contain count values.
virtual QgsMeshDatasetMetadata datasetMetadata(int datasetIndex) const =0
Returns the metadata of the dataset with index datasetIndex.
virtual QgsMeshDataset * dataset(int index) const =0
Returns the dataset with index.
QgsMeshDatasetGroupMetadata::DataType dataType() const
Returns the data type of the dataset group.
virtual int datasetCount() const =0
Returns the count of datasets in the group.
QgsMeshDatasetIndex is 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.
int dataset() const
Returns a dataset index within group()
QgsMeshDatasetMetadata is a collection of mesh dataset metadata such as whether the data is valid or ...
double time() const
Returns the time value for this dataset.
Interface for mesh datasets and dataset groups.
virtual Q_DECL_DEPRECATED bool persistDatasetGroup(const QString &path, const QgsMeshDatasetGroupMetadata &meta, const QVector< QgsMeshDataBlock > &datasetValues, const QVector< QgsMeshDataBlock > &datasetActive, const QVector< double > &times)
Creates a new dataset group from a data and persists it into a destination path.
virtual QgsMeshDatasetGroupMetadata datasetGroupMetadata(int groupIndex) const =0
Returns dataset group metadata.
virtual int datasetGroupCount() const =0
Returns number of datasets groups loaded.
std::unique_ptr< QgsMeshDataProviderTemporalCapabilities > mTemporalCapabilities
virtual bool addDataset(const QString &uri)=0
Associate dataset with the mesh.
QgsMeshDatasetValue represents single dataset value.
virtual QgsMeshDataBlock datasetValues(bool isScalar, int valueIndex, int count) const =0
Returns count values from valueIndex.
virtual bool isActive(int faceIndex) const =0
Returns whether the face is active.
virtual QgsMeshDataBlock areFacesActive(int faceIndex, int count) const =0
Returns whether faces are active.
virtual QgsMeshDatasetValue datasetValue(int valueIndex) const =0
Returns the value with index valueIndex.
Class that can be used to store and access extra dataset group, like memory dataset (temporary) Deriv...
int datasetCount(int groupIndex) const override
Returns number of datasets loaded in the group.
QString description(int groupIndex) const
Returns information related to the dataset group with groupIndex.
void updateTemporalCapabilities()
Updates the temporal capabilities.
QStringList extraDatasets() const override
Not implemented, always returns empty list.
QgsMeshDatasetGroup * datasetGroup(int groupIndex) const
Returns a pointer to the dataset group.
bool persistDatasetGroup(const QString &outputFilePath, const QString &outputDriver, const QgsMeshDatasetGroupMetadata &meta, const QVector< QgsMeshDataBlock > &datasetValues, const QVector< QgsMeshDataBlock > &datasetActive, const QVector< double > &times) override
Not implemented, always returns true.
quint64 datasetRelativeTime(QgsMeshDatasetIndex index)
Returns the relative times of the dataset index with index, returned value in milliseconds.
QgsMeshDataBlock datasetValues(QgsMeshDatasetIndex index, int valueIndex, int count) const override
Returns N vector/scalar values from the index from the dataset.
int addDatasetGroup(QgsMeshDatasetGroup *datasetGroup)
Adds a dataset group, returns the index of the added dataset group.
QgsMeshDataBlock areFacesActive(QgsMeshDatasetIndex index, int faceIndex, int count) const override
Returns whether the faces are active for particular dataset.
int datasetGroupCount() const override
Returns number of datasets groups loaded.
bool hasTemporalCapabilities() const
Returns whether if the dataset groups have temporal capabilities (a least one dataset group with more...
bool isFaceActive(QgsMeshDatasetIndex index, int faceIndex) const override
Returns whether the face is active for particular dataset.
QDomElement writeXml(int groupIndex, QDomDocument &doc, const QgsReadWriteContext &context)
Writes the store's information in a DOM document.
QgsMeshDatasetMetadata datasetMetadata(QgsMeshDatasetIndex index) const override
Returns dataset metadata.
void removeDatasetGroup(int index)
Removes the dataset group with the local index.
QgsMesh3dDataBlock dataset3dValues(QgsMeshDatasetIndex index, int faceIndex, int count) const override
Returns N vector/scalar values from the face index from the dataset for 3d stacked meshes.
QgsMeshDatasetGroupMetadata datasetGroupMetadata(int groupIndex) const override
Returns dataset group metadata.
QgsMeshDatasetValue datasetValue(QgsMeshDatasetIndex index, int valueIndex) const override
Returns vector/scalar value associated with the index from the dataset To read multiple continuous va...
bool addDataset(const QString &uri) override
Not implemented, always returns false.
Represents a mesh layer supporting display of data on structured or unstructured meshes.
Definition: qgsmeshlayer.h:95
Represents a dataset group calculated from a formula string.
The class is used as a container of context for various read/write operations on other objects.
#define QgsDebugMsg(str)
Definition: qgslogger.h:38