QGIS API Documentation  3.20.0-Odense (decaadbb31)
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 
51 void QgsMeshDatasetGroupStore::setPersistentProvider( QgsMeshDataProvider *provider, const QStringList &extraDatasetUri )
52 {
53  removePersistentProvider();
54  mPersistentProvider = provider;
55  if ( !mPersistentProvider )
56  return;
57  for ( const QString &uri : extraDatasetUri )
58  mPersistentProvider->addDataset( uri );
59 
60  onPersistentDatasetAdded( mPersistentProvider->datasetGroupCount() );
61 
62  checkDatasetConsistency( mPersistentProvider );
63  removeUnregisteredItemFromTree();
64 
65  //Once everything is in place, initialize the extra dataset groups
66  if ( mExtraDatasets )
67  {
68  const int groupCount = mExtraDatasets->datasetGroupCount();
69  for ( int i = 0; i < groupCount; ++i )
70  if ( mExtraDatasets->datasetGroup( i ) )
71  mExtraDatasets->datasetGroup( i )->initialize();
72  }
73 
74  mExtraDatasets->updateTemporalCapabilities();
75 
76  connect( mPersistentProvider, &QgsMeshDataProvider::datasetGroupsAdded, this, &QgsMeshDatasetGroupStore::onPersistentDatasetAdded );
77 }
78 
79 QgsMeshDatasetGroupStore::DatasetGroup QgsMeshDatasetGroupStore::datasetGroup( int index ) const
80 {
81  if ( mRegistery.contains( index ) )
82  return mRegistery[index];
83  else
84  return DatasetGroup{nullptr, -1};
85 }
86 
88 {
89  if ( !mPersistentProvider )
90  return false;
91  return mPersistentProvider->addDataset( path ) ;
92 }
93 
95 {
96  if ( !mPersistentProvider || !mExtraDatasets )
97  return false;
98 
99  switch ( group->dataType() )
100  {
102  if ( ! group->checkValueCountPerDataset( mPersistentProvider->faceCount() ) )
103  return false;
104  break;
106  if ( ! group->checkValueCountPerDataset( mPersistentProvider->vertexCount() ) )
107  return false;
108  break;
110  return false; // volume not supported for extra dataset
111  break;
113  if ( ! group->checkValueCountPerDataset( mPersistentProvider->edgeCount() ) )
114  return false;
115  break;
116  }
117 
118  int nativeIndex = mExtraDatasets->addDatasetGroup( group );
119  int groupIndex = registerDatasetGroup( DatasetGroup{mExtraDatasets.get(), nativeIndex} );
120  QList<int> groupIndexes;
121  groupIndexes.append( groupIndex );
122  createDatasetGroupTreeItems( groupIndexes );
123  syncItemToDatasetGroup( groupIndex );
124 
125  emit datasetGroupsAdded( groupIndexes );
126 
127  return true;
128 }
129 
131 {
132  mDatasetGroupTreeRootItem.reset( new QgsMeshDatasetGroupTreeItem );
133  createDatasetGroupTreeItems( datasetGroupIndexes() );
134  QList<int> groupIndexes = datasetGroupIndexes();
135  for ( int groupIndex : groupIndexes )
136  syncItemToDatasetGroup( groupIndex );
137 }
138 
140 {
141  return mDatasetGroupTreeRootItem.get();
142 }
143 
145 {
146  if ( rootItem )
147  mDatasetGroupTreeRootItem.reset( rootItem->clone() );
148  else
149  mDatasetGroupTreeRootItem.reset();
150 
151  unregisterGroupNotPresentInTree();
152 }
153 
155 {
156  QgsMeshDatasetGroupStore::DatasetGroup group = datasetGroup( index.group() );
157  if ( group.first )
158  return group.first->datasetGroupMetadata( group.second );
159  else
161 }
162 
163 int QgsMeshDatasetGroupStore::datasetCount( int groupIndex ) const
164 {
165  QgsMeshDatasetGroupStore::DatasetGroup group = datasetGroup( groupIndex );
166  if ( group.first )
167  return group.first->datasetCount( group.second );
168  else
169  return 0;
170 }
171 
173 {
174  QgsMeshDatasetGroupStore::DatasetGroup group = datasetGroup( index.group() );
175  if ( group.first )
176  return group.first->datasetMetadata( QgsMeshDatasetIndex( group.second, index.dataset() ) );
177  else
178  return QgsMeshDatasetMetadata();
179 }
180 
182 {
183  QgsMeshDatasetGroupStore::DatasetGroup group = datasetGroup( index.group() );
184  if ( group.first )
185  return group.first->datasetValue( QgsMeshDatasetIndex( group.second, index.dataset() ), valueIndex );
186  else
187  return QgsMeshDatasetValue();
188 }
189 
190 QgsMeshDataBlock QgsMeshDatasetGroupStore::datasetValues( const QgsMeshDatasetIndex &index, int valueIndex, int count ) const
191 {
192  QgsMeshDatasetGroupStore::DatasetGroup group = datasetGroup( index.group() );
193  if ( group.first )
194  return group.first->datasetValues( QgsMeshDatasetIndex( group.second, index.dataset() ), valueIndex, count );
195  else
196  return QgsMeshDataBlock();
197 }
198 
200 {
201  QgsMeshDatasetGroupStore::DatasetGroup group = datasetGroup( index.group() );
202  if ( group.first )
203  return group.first->dataset3dValues( QgsMeshDatasetIndex( group.second, index.dataset() ), faceIndex, count );
204  else
205  return QgsMesh3dDataBlock();
206 }
207 
209 {
210  QgsMeshDatasetGroupStore::DatasetGroup group = datasetGroup( index.group() );
211  if ( group.first )
212  return group.first->areFacesActive( QgsMeshDatasetIndex( group.second, index.dataset() ), faceIndex, count );
213  else
214  return QgsMeshDataBlock();
215 }
216 
217 bool QgsMeshDatasetGroupStore::isFaceActive( const QgsMeshDatasetIndex &index, int faceIndex ) const
218 {
219  QgsMeshDatasetGroupStore::DatasetGroup group = datasetGroup( index.group() );
220  if ( group.first )
221  return group.first->isFaceActive( QgsMeshDatasetIndex( group.second, index.dataset() ), faceIndex );
222  else
223  return false;
224 }
225 
227  qint64 time,
229 {
230  QgsMeshDatasetGroupStore::DatasetGroup group = datasetGroup( groupIndex );
231  if ( !group.first )
232  return QgsMeshDatasetIndex();
233 
234  const QDateTime &referenceTime = mPersistentProvider->temporalCapabilities()->referenceTime();
235 
236  return QgsMeshDatasetIndex( groupIndex,
237  group.first->datasetIndexAtTime( referenceTime, group.second, time, method ).dataset() );
238 }
239 
241 {
242  QgsMeshDatasetGroupStore::DatasetGroup group = datasetGroup( index.group() );
243  if ( !group.first || group.second < 0 )
244  return INVALID_MESHLAYER_TIME;
245 
246  QgsMeshDatasetIndex nativeIndex( group.second, index.dataset() );
247 
248  if ( group.first == mPersistentProvider )
249  return mPersistentProvider->temporalCapabilities()->datasetTime( nativeIndex );
250  else if ( group.first == mExtraDatasets.get() )
251  return mExtraDatasets->datasetRelativeTime( nativeIndex );
252 
253  return INVALID_MESHLAYER_TIME;
254 
255 }
256 
258 {
259  return ( mPersistentProvider && mPersistentProvider->temporalCapabilities()->hasTemporalCapabilities() ) ||
260  ( mExtraDatasets && mExtraDatasets->hasTemporalCapabilities() );
261 }
262 
263 QDomElement QgsMeshDatasetGroupStore::writeXml( QDomDocument &doc, const QgsReadWriteContext &context )
264 {
265  Q_UNUSED( context );
266  QDomElement storeElement = doc.createElement( QStringLiteral( "mesh-dataset-groups-store" ) );
267  storeElement.appendChild( mDatasetGroupTreeRootItem->writeXml( doc, context ) );
268 
269  QMap < int, DatasetGroup>::const_iterator it = mRegistery.constBegin();
270  while ( it != mRegistery.constEnd() )
271  {
272  QDomElement elemDataset;
273  if ( it.value().first == mPersistentProvider )
274  {
275  elemDataset = doc.createElement( QStringLiteral( "mesh-dataset" ) );
276  elemDataset.setAttribute( QStringLiteral( "global-index" ), it.key() );
277  elemDataset.setAttribute( QStringLiteral( "source-type" ), QStringLiteral( "persitent-provider" ) );
278  elemDataset.setAttribute( QStringLiteral( "source-index" ), it.value().second );
279  }
280  else if ( it.value().first == mExtraDatasets.get() )
281  {
282  QgsMeshDatasetGroupTreeItem *item = mDatasetGroupTreeRootItem->childFromDatasetGroupIndex( it.key() );
283  if ( item )
284  {
285  elemDataset = mExtraDatasets->writeXml( it.value().second, doc, context );
286  if ( !elemDataset.isNull() )
287  elemDataset.setAttribute( QStringLiteral( "global-index" ), it.key() );
288  }
289  }
290 
291  if ( !elemDataset.isNull() )
292  storeElement.appendChild( elemDataset );
293  ++it;
294  }
295 
296  return storeElement;
297 }
298 
299 void QgsMeshDatasetGroupStore::readXml( const QDomElement &storeElem, const QgsReadWriteContext &context )
300 {
301  Q_UNUSED( context );
302  mRegistery.clear();
303  QDomElement datasetElem = storeElem.firstChildElement( "mesh-dataset" );
304  QMap<int, QgsMeshDatasetGroup *> extraDatasetGroups;
305  while ( !datasetElem.isNull() )
306  {
307  int globalIndex = datasetElem.attribute( QStringLiteral( "global-index" ) ).toInt();
308  int sourceIndex = -1;
309  QgsMeshDatasetSourceInterface *source = nullptr;
310  const QString sourceType = datasetElem.attribute( QStringLiteral( "source-type" ) );
311  if ( sourceType == QLatin1String( "persitent-provider" ) )
312  {
313  source = mPersistentProvider;
314  sourceIndex = datasetElem.attribute( QStringLiteral( "source-index" ) ).toInt();
315  mPersistentExtraDatasetGroupIndexes.append( globalIndex );
316  }
317  else if ( sourceType == QLatin1String( "virtual" ) )
318  {
319  source = mExtraDatasets.get();
320  QString name = datasetElem.attribute( QStringLiteral( "name" ) );
321  QString formula = datasetElem.attribute( QStringLiteral( "formula" ) );
322  qint64 startTime = datasetElem.attribute( QStringLiteral( "start-time" ) ).toLongLong();
323  qint64 endTime = datasetElem.attribute( QStringLiteral( "end-time" ) ).toLongLong();
324 
325  QgsMeshDatasetGroup *dsg = new QgsMeshVirtualDatasetGroup( name, formula, mLayer, startTime, endTime );
326  extraDatasetGroups[globalIndex] = dsg;
327  sourceIndex = mExtraDatasets->addDatasetGroup( dsg );
328  }
329  else
330  {
331  QgsDebugMsg( QStringLiteral( "Unhandled source-type: %1." ).arg( sourceType ) );
332  }
333  if ( source )
334  {
335  mRegistery[globalIndex] = DatasetGroup{source, sourceIndex};
336  }
337 
338  datasetElem = datasetElem.nextSiblingElement( QStringLiteral( "mesh-dataset" ) );
339  }
340 
341  QDomElement rootTreeItemElem = storeElem.firstChildElement( QStringLiteral( "mesh-dataset-group-tree-item" ) );
342  if ( !rootTreeItemElem.isNull() )
343  setDatasetGroupTreeItem( new QgsMeshDatasetGroupTreeItem( rootTreeItemElem, context ) );
344 }
345 
346 
347 bool QgsMeshDatasetGroupStore::saveDatasetGroup( QString filePath, int groupIndex, QString driver )
348 {
349  DatasetGroup group = datasetGroup( groupIndex );
350 
351  bool fail = true;
352  if ( group.first && group.second >= 0 )
353  fail = mPersistentProvider->persistDatasetGroup( filePath, driver, group.first, group.second );
354 
355  if ( !fail )
356  {
357  eraseDatasetGroup( group );
358  group.first = mPersistentProvider;
359  group.second = mPersistentProvider->datasetGroupCount() - 1;
360  mRegistery[groupIndex] = group;
361  //update the item type
362  if ( mDatasetGroupTreeRootItem )
363  {
364  QgsMeshDatasetGroupTreeItem *item = mDatasetGroupTreeRootItem->childFromDatasetGroupIndex( groupIndex );
365  if ( item )
366  item->setPersistentDatasetGroup( filePath );
367  }
368  }
369 
370  return fail;
371 }
372 
373 void QgsMeshDatasetGroupStore::onPersistentDatasetAdded( int count )
374 {
375  Q_ASSERT( mPersistentProvider );
376 
377  int providerTotalCount = mPersistentProvider->datasetGroupCount();
378  int providerBeginIndex = mPersistentProvider->datasetGroupCount() - count;
379  QList<int> newGroupIndexes;
380  for ( int i = providerBeginIndex; i < providerTotalCount; ++i )
381  {
382  if ( i < mPersistentExtraDatasetGroupIndexes.count() )
383  mRegistery[mPersistentExtraDatasetGroupIndexes.at( i )] = DatasetGroup( mPersistentProvider, i );
384  else
385  newGroupIndexes.append( registerDatasetGroup( DatasetGroup{mPersistentProvider, i} ) );
386  }
387 
388  if ( !newGroupIndexes.isEmpty() )
389  {
390  createDatasetGroupTreeItems( newGroupIndexes );
391  mPersistentExtraDatasetGroupIndexes.append( newGroupIndexes );
392 
393  for ( int groupIndex : std::as_const( newGroupIndexes ) )
394  syncItemToDatasetGroup( groupIndex );
395 
396  emit datasetGroupsAdded( newGroupIndexes );
397  }
398 }
399 
400 void QgsMeshDatasetGroupStore::removePersistentProvider()
401 {
402  if ( !mPersistentProvider )
403  return;
404 
405  disconnect( mPersistentProvider, &QgsMeshDataProvider::datasetGroupsAdded, this, &QgsMeshDatasetGroupStore::onPersistentDatasetAdded );
406 
407  QMap < int, DatasetGroup>::iterator it = mRegistery.begin();
408  while ( it != mRegistery.end() )
409  {
410  if ( it.value().first == mPersistentProvider )
411  it = mRegistery.erase( it );
412  else
413  ++it;
414  }
415 
416  mPersistentProvider = nullptr;
417 }
418 
419 int QgsMeshDatasetGroupStore::newIndex()
420 {
421  int index = 0;
422  QMap < int, DatasetGroup>::iterator it = mRegistery.begin();
423  while ( it != mRegistery.end() )
424  {
425  if ( index <= it.key() )
426  index = it.key() + 1;
427  ++it;
428  }
429  return index;
430 }
431 
432 int QgsMeshDatasetGroupStore::registerDatasetGroup( const QgsMeshDatasetGroupStore::DatasetGroup &group )
433 {
434  int groupIndex = newIndex();
435  mRegistery[newIndex()] = group;
436  return groupIndex;
437 }
438 
439 void QgsMeshDatasetGroupStore::eraseDatasetGroup( const QgsMeshDatasetGroupStore::DatasetGroup &group )
440 {
441  if ( group.first == mPersistentProvider )
442  return; //removing persistent dataset group from the store is not allowed
443  else if ( group.first == mExtraDatasets.get() )
444  eraseExtraDataset( group.second );
445 }
446 
447 void QgsMeshDatasetGroupStore::eraseExtraDataset( int indexInExtraStore )
448 {
449  mExtraDatasets->removeDatasetGroup( indexInExtraStore );
450 
451  //search dataset with index greater than indexInExtraStore and decrement it
452  QMap < int, DatasetGroup>::iterator it = mRegistery.begin();
453  while ( it != mRegistery.end() )
454  {
455  int localIndex = it.value().second;
456  if ( it.value().first == mExtraDatasets.get() && localIndex > indexInExtraStore )
457  it->second = localIndex - 1;
458  ++it;
459  }
460 }
461 
462 int QgsMeshDatasetGroupStore::nativeIndexToGroupIndex( QgsMeshDatasetSourceInterface *source, int nativeIndex )
463 {
464  QMap < int, DatasetGroup>::const_iterator it = mRegistery.constBegin();
465  while ( it != mRegistery.constEnd() )
466  {
467  if ( it.value() == DatasetGroup{source, nativeIndex} )
468  return it.key();
469  ++it;
470  }
471  return -1;
472 }
473 
474 void QgsMeshDatasetGroupStore::checkDatasetConsistency( QgsMeshDatasetSourceInterface *source )
475 {
476  // check if datasets of source are present, if not, add them
477  QList<int> indexes;
478  for ( int i = 0; i < source->datasetGroupCount(); ++i )
479  if ( nativeIndexToGroupIndex( source, i ) == -1 )
480  indexes.append( registerDatasetGroup( DatasetGroup{source, i} ) );
481 
482  if ( !indexes.isEmpty() )
483  createDatasetGroupTreeItems( indexes );
484 
485  for ( int globalIndex : mRegistery.keys() )
486  {
487  if ( mRegistery.value( globalIndex ).first == source )
488  syncItemToDatasetGroup( globalIndex );
489  }
490 }
491 
492 void QgsMeshDatasetGroupStore::removeUnregisteredItemFromTree()
493 {
494  QList<QgsMeshDatasetGroupTreeItem *> itemsToCheck;
495  QList<int> indexItemToRemove;
496  for ( int i = 0; i < mDatasetGroupTreeRootItem->childCount(); ++i )
497  itemsToCheck.append( mDatasetGroupTreeRootItem->child( i ) );
498 
499  while ( !itemsToCheck.isEmpty() )
500  {
501  QgsMeshDatasetGroupTreeItem *item = itemsToCheck.takeFirst();
502  int globalIndex = item->datasetGroupIndex();
503  if ( !mRegistery.contains( globalIndex ) )
504  indexItemToRemove.append( globalIndex );
505  for ( int i = 0; i < item->childCount(); ++i )
506  itemsToCheck.append( item->child( i ) );
507  }
508 
509  for ( int i : indexItemToRemove )
510  {
511  QgsMeshDatasetGroupTreeItem *item = mDatasetGroupTreeRootItem->childFromDatasetGroupIndex( i );
512  if ( item )
513  item->parentItem()->removeChild( item );
514  }
515 }
516 
517 void QgsMeshDatasetGroupStore::unregisterGroupNotPresentInTree()
518 {
519  if ( !mDatasetGroupTreeRootItem )
520  {
521  mRegistery.clear();
522  return;
523  }
524 
525  QMap < int, DatasetGroup>::iterator it = mRegistery.begin();
526  while ( it != mRegistery.end() )
527  {
528  DatasetGroup datasetGroup = it.value();
529  int globalIndex = it.key();
530  if ( ! mDatasetGroupTreeRootItem->childFromDatasetGroupIndex( globalIndex ) // Not in the tree item
531  && datasetGroup.first != mPersistentProvider ) // and not persistent
532  {
533  it = mRegistery.erase( it ); //remove from registery
534  eraseDatasetGroup( datasetGroup ); //remove from where the dataset group is stored
535  }
536  else
537  ++it;
538  }
539 }
540 
541 void QgsMeshDatasetGroupStore::syncItemToDatasetGroup( int groupIndex )
542 {
543  if ( !mDatasetGroupTreeRootItem )
544  return;
545  DatasetGroup group = datasetGroup( groupIndex );
546  QgsMeshDatasetGroupTreeItem *item = mDatasetGroupTreeRootItem->childFromDatasetGroupIndex( groupIndex );
547  if ( group.first == mPersistentProvider && mPersistentProvider )
548  {
549  QgsMeshDatasetGroupMetadata meta = mPersistentProvider->datasetGroupMetadata( group.second );
550  if ( item )
551  item->setPersistentDatasetGroup( meta.uri() );
552  }
553  else if ( group.first == mExtraDatasets.get() )
554  {
555  if ( item )
556  item->setDatasetGroup( mExtraDatasets->datasetGroup( group.second ) );
557  }
558 }
559 
560 void QgsMeshDatasetGroupStore::createDatasetGroupTreeItems( const QList<int> &indexes )
561 {
562  QMap<QString, QgsMeshDatasetGroupTreeItem *> mNameToItem;
563 
564  for ( int i = 0; i < indexes.count(); ++i )
565  {
566  int groupIndex = indexes.at( i );
567  const QgsMeshDatasetGroupMetadata meta = datasetGroupMetadata( groupIndex );
568  const QString name = meta.name();
569  const QStringList subdatasets = name.split( '/' );
570 
571  QString displayName = name;
572  QgsMeshDatasetGroupTreeItem *parent = mDatasetGroupTreeRootItem.get();
573 
574  if ( subdatasets.size() == 2 )
575  {
576  auto it = mNameToItem.find( subdatasets[0] );
577  if ( it == mNameToItem.end() )
578  QgsDebugMsg( QStringLiteral( "Unable to find parent group for %1." ).arg( name ) );
579  else
580  {
581  displayName = subdatasets[1];
582  parent = it.value();
583  }
584  }
585  else if ( subdatasets.size() != 1 )
586  QgsDebugMsg( QStringLiteral( "Ignoring too deep child group name %1." ).arg( name ) );
587 
588  QgsMeshDatasetGroupTreeItem *item = new QgsMeshDatasetGroupTreeItem( displayName, name, meta.isVector(), groupIndex );
589  parent->appendChild( item );
590  if ( mNameToItem.contains( name ) )
591  QgsDebugMsg( QStringLiteral( "Group %1 is not unique" ).arg( displayName ) );
592  mNameToItem[name] = item;
593  }
594 }
595 
597 {
598  int groupIndex = mGroups.size();
599  mGroups.push_back( std::unique_ptr<QgsMeshDatasetGroup>( datasetGroup ) );
600 
601  if ( datasetGroup->datasetCount() > 1 )
602  {
603  mTemporalCapabilities->setHasTemporalCapabilities( true );
604  for ( int i = 0; i < datasetGroup->datasetCount(); ++i )
605  mTemporalCapabilities->addDatasetTime( groupIndex, datasetGroup->datasetMetadata( i ).time() );
606  }
607 
608  return mGroups.size() - 1;
609 }
610 
612 {
613  if ( index < datasetGroupCount() )
614  mGroups.erase( mGroups.begin() + index );
615 
616 
618 }
619 
621 {
622  return mTemporalCapabilities->hasTemporalCapabilities();
623 }
624 
626 {
627  return mTemporalCapabilities->datasetTime( index );
628 }
629 
630 QString QgsMeshExtraDatasetStore::description( int groupIndex ) const
631 {
632  if ( groupIndex >= 0 && groupIndex < int( mGroups.size() ) )
633  return mGroups.at( groupIndex )->description();
634  else
635  return QString();
636 }
637 
639 {
640  if ( groupIndex >= 0 && groupIndex < int( mGroups.size() ) )
641  return mGroups[groupIndex].get();
642  else
643  return nullptr;
644 }
645 
646 bool QgsMeshExtraDatasetStore::addDataset( const QString &uri )
647 {
648  Q_UNUSED( uri );
649  return false;
650 }
651 
653 {
654  return QStringList();
655 }
656 
658 {
659  return mGroups.size();
660 }
661 
662 int QgsMeshExtraDatasetStore::datasetCount( int groupIndex ) const
663 {
664  if ( groupIndex >= 0 && groupIndex < datasetGroupCount() )
665  return mGroups.at( groupIndex )->datasetCount();
666  else
667  return 0;
668 }
669 
671 {
672  if ( groupIndex >= 0 && groupIndex < datasetGroupCount() )
673  return mGroups.at( groupIndex )->groupMetadata();
674  else
676 }
677 
679 {
680  int groupIndex = index.group();
681  if ( index.isValid() && groupIndex < datasetGroupCount() )
682  {
683  int datasetIndex = index.dataset();
684  const QgsMeshDatasetGroup *group = mGroups.at( groupIndex ).get();
685  if ( datasetIndex < group->datasetCount() )
686  return group->datasetMetadata( datasetIndex );
687  }
688  return QgsMeshDatasetMetadata();
689 }
690 
692 {
693  int groupIndex = index.group();
694  if ( index.isValid() && groupIndex < datasetGroupCount() )
695  {
696  const QgsMeshDatasetGroup *group = mGroups.at( groupIndex ).get();
697  int datasetIndex = index.dataset();
698  if ( datasetIndex < group->datasetCount() )
699  return group->dataset( datasetIndex )->datasetValue( valueIndex );
700  }
701 
702  return QgsMeshDatasetValue();
703 }
704 
706 {
707  int groupIndex = index.group();
708  if ( index.isValid() && groupIndex < datasetGroupCount() )
709  {
710  const QgsMeshDatasetGroup *group = mGroups.at( groupIndex ).get();
711  int datasetIndex = index.dataset();
712  if ( datasetIndex < group->datasetCount() )
713  return group->dataset( datasetIndex )->datasetValues( group->isScalar(), valueIndex, count );
714  }
715 
716  return QgsMeshDataBlock();
717 }
718 
720 {
721  // Not supported for now
722  Q_UNUSED( index )
723  Q_UNUSED( faceIndex )
724  Q_UNUSED( count )
725  return QgsMesh3dDataBlock();
726 }
727 
729 {
730  int groupIndex = index.group();
731  if ( index.isValid() && groupIndex < datasetGroupCount() )
732  {
733  const QgsMeshDatasetGroup *group = mGroups.at( groupIndex ).get();
734  int datasetIndex = index.dataset();
735  if ( datasetIndex < group->datasetCount() )
736  return group->dataset( datasetIndex )->isActive( faceIndex );
737  }
738 
739  return false;
740 }
741 
743 {
744  int groupIndex = index.group();
745  if ( index.isValid() && groupIndex < datasetGroupCount() )
746  {
747  const QgsMeshDatasetGroup *group = mGroups.at( groupIndex ).get();
748  int datasetIndex = index.dataset();
749  if ( datasetIndex < group->datasetCount() )
750  return group->dataset( datasetIndex )->areFacesActive( faceIndex, count );
751  }
752  return QgsMeshDataBlock();
753 }
754 
755 bool QgsMeshExtraDatasetStore::persistDatasetGroup( const QString &outputFilePath,
756  const QString &outputDriver,
757  const QgsMeshDatasetGroupMetadata &meta,
758  const QVector<QgsMeshDataBlock> &datasetValues,
759  const QVector<QgsMeshDataBlock> &datasetActive,
760  const QVector<double> &times )
761 {
762  Q_UNUSED( outputFilePath )
763  Q_UNUSED( outputDriver )
764  Q_UNUSED( meta )
765  Q_UNUSED( datasetValues )
766  Q_UNUSED( datasetActive )
767  Q_UNUSED( times )
768  return true; // not implemented/supported
769 }
770 
771 bool QgsMeshExtraDatasetStore::persistDatasetGroup( const QString &outputFilePath,
772  const QString &outputDriver,
774  int datasetGroupIndex )
775 {
776  Q_UNUSED( outputFilePath )
777  Q_UNUSED( outputDriver )
778  Q_UNUSED( source )
779  Q_UNUSED( datasetGroupIndex )
780  return true; // not implemented/supported
781 }
782 
783 QDomElement QgsMeshExtraDatasetStore::writeXml( int groupIndex, QDomDocument &doc, const QgsReadWriteContext &context )
784 {
785  if ( groupIndex >= 0 && groupIndex < int( mGroups.size() ) && mGroups[groupIndex] )
786  return mGroups[groupIndex]->writeXml( doc, context );
787  else
788  return QDomElement();
789 }
790 
792 {
793  //update temporal capabilitie
794  mTemporalCapabilities->clear();
795  bool hasTemporal = false;
796  for ( size_t g = 0; g < mGroups.size(); ++g )
797  {
798  const QgsMeshDatasetGroup *group = mGroups[g].get();
799  hasTemporal |= group->datasetCount() > 1;
800  for ( int i = 0; i < group->datasetCount(); ++i )
801  mTemporalCapabilities->addDatasetTime( g, group->datasetMetadata( i ).time() );
802  }
803 
804  mTemporalCapabilities->setHasTemporalCapabilities( hasTemporal );
805 }
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.
void setPersistentProvider(QgsMeshDataProvider *provider, const QStringList &extraDatasetUri)
Sets the persistent mesh data provider with the path of its extra dataset.
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 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 child item.
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