19#include "moc_qgsmeshdatasetgroupstore.cpp"
28 return mRegistry.keys();
33 return mDatasetGroupTreeRootItem->enabledDatasetGroupIndexes();
38 return mRegistry.count();
53 removePersistentProvider();
54 mPersistentProvider = provider;
55 if ( !mPersistentProvider )
57 for (
const QString &uri : extraDatasetUri )
62 checkDatasetConsistency( mPersistentProvider );
63 removeUnregisteredItemFromTree();
67 for (
int i = 0; i < groupCount; ++i )
76QgsMeshDatasetGroupStore::DatasetGroup QgsMeshDatasetGroupStore::datasetGroup(
int index )
const
78 return mRegistry.value( index, DatasetGroup{
nullptr, -1} );
83 if ( !mPersistentProvider )
85 return mPersistentProvider->
addDataset( path ) ;
113 int groupIndex = registerDatasetGroup( DatasetGroup{&mExtraDatasets, nativeIndex} );
115 if ( groupIndex == -1 )
118 QList<int> groupIndexes;
119 groupIndexes.append( groupIndex );
120 createDatasetGroupTreeItems( groupIndexes );
121 syncItemToDatasetGroup( groupIndex );
133 for (
int groupIndex : groupIndexes )
134 syncItemToDatasetGroup( groupIndex );
139 return mDatasetGroupTreeRootItem.get();
145 mDatasetGroupTreeRootItem.reset( rootItem->
clone() );
147 mDatasetGroupTreeRootItem.reset();
149 unregisterGroupNotPresentInTree();
154 QgsMeshDatasetGroupStore::DatasetGroup group = datasetGroup( index.
group() );
156 return group.first->datasetGroupMetadata( group.second );
163 QgsMeshDatasetGroupStore::DatasetGroup group = datasetGroup( groupIndex );
165 return group.first->datasetCount( group.second );
172 QgsMeshDatasetGroupStore::DatasetGroup group = datasetGroup( index.
group() );
181 QgsMeshDatasetGroupStore::DatasetGroup group = datasetGroup( index.
group() );
190 QgsMeshDatasetGroupStore::DatasetGroup group = datasetGroup( index.
group() );
199 QgsMeshDatasetGroupStore::DatasetGroup group = datasetGroup( index.
group() );
208 QgsMeshDatasetGroupStore::DatasetGroup group = datasetGroup( index.
group() );
217 QgsMeshDatasetGroupStore::DatasetGroup group = datasetGroup( index.
group() );
228 QgsMeshDatasetGroupStore::DatasetGroup group = datasetGroup( groupIndex );
235 group.first->datasetIndexAtTime( referenceTime, group.second, time, method ).dataset() );
241 int groupIndex )
const
243 const QgsMeshDatasetGroupStore::DatasetGroup group = datasetGroup( groupIndex );
245 return QList<QgsMeshDatasetIndex>();
249 const QList<QgsMeshDatasetIndex> datasetIndexes = group.first->datasetIndexInTimeInterval( referenceTime, group.second, time1, time2 );
251 QList<QgsMeshDatasetIndex> ret;
252 ret.reserve( datasetIndexes.count() );
262 QgsMeshDatasetGroupStore::DatasetGroup group = datasetGroup( index.
group() );
263 if ( !group.first || group.second < 0 )
268 if ( group.first == mPersistentProvider )
270 else if ( group.first == &mExtraDatasets )
286 QDomElement storeElement = doc.createElement( QStringLiteral(
"mesh-dataset-groups-store" ) );
287 storeElement.appendChild( mDatasetGroupTreeRootItem->writeXml( doc, context ) );
289 QMap < int, DatasetGroup>::const_iterator it = mRegistry.constBegin();
290 while ( it != mRegistry.constEnd() )
292 QDomElement elemDataset;
293 if ( it.value().first == mPersistentProvider )
295 elemDataset = doc.createElement( QStringLiteral(
"mesh-dataset" ) );
296 elemDataset.setAttribute( QStringLiteral(
"global-index" ), it.key() );
297 elemDataset.setAttribute( QStringLiteral(
"source-type" ), QStringLiteral(
"persitent-provider" ) );
298 elemDataset.setAttribute( QStringLiteral(
"source-index" ), it.value().second );
300 else if ( it.value().first == &mExtraDatasets )
305 elemDataset = mExtraDatasets.
writeXml( it.value().second, doc, context );
306 if ( !elemDataset.isNull() )
307 elemDataset.setAttribute( QStringLiteral(
"global-index" ), it.key() );
311 if ( !elemDataset.isNull() )
312 storeElement.appendChild( elemDataset );
316 for (
auto it = mGroupNameToGlobalIndex.constBegin(); it != mGroupNameToGlobalIndex.constEnd(); ++it )
318 QDomElement elemNameToIndex = doc.createElement( QStringLiteral(
"name-to-global-index" ) );
319 elemNameToIndex.setAttribute( QStringLiteral(
"name" ), it.key() );
320 elemNameToIndex.setAttribute( QStringLiteral(
"global-index" ), it.value() );
322 storeElement.appendChild( elemNameToIndex );
332 QDomElement datasetElem = storeElem.firstChildElement(
"mesh-dataset" );
333 QMap<int, QgsMeshDatasetGroup *> extraDatasetGroups;
334 while ( !datasetElem.isNull() )
336 int globalIndex = datasetElem.attribute( QStringLiteral(
"global-index" ) ).toInt();
338 const QString sourceType = datasetElem.attribute( QStringLiteral(
"source-type" ) );
339 if ( sourceType == QLatin1String(
"persitent-provider" ) )
341 mPersistentExtraDatasetGroupIndexes.append( globalIndex );
343 else if ( sourceType == QLatin1String(
"virtual" ) )
346 QString name = datasetElem.attribute( QStringLiteral(
"name" ) );
347 QString formula = datasetElem.attribute( QStringLiteral(
"formula" ) );
348 qint64 startTime = datasetElem.attribute( QStringLiteral(
"start-time" ) ).toLongLong();
349 qint64 endTime = datasetElem.attribute( QStringLiteral(
"end-time" ) ).toLongLong();
352 extraDatasetGroups[globalIndex] = dsg;
355 mRegistry[globalIndex] = DatasetGroup{source, sourceIndex};
359 QgsDebugError( QStringLiteral(
"Unhandled source-type: %1." ).arg( sourceType ) );
362 datasetElem = datasetElem.nextSiblingElement( QStringLiteral(
"mesh-dataset" ) );
365 QDomElement nameToIndexElem = storeElem.firstChildElement(
"name-to-global-index" );
366 mGroupNameToGlobalIndex.clear();
367 while ( !nameToIndexElem.isNull() )
369 QString name = nameToIndexElem.attribute( QStringLiteral(
"name" ) );
370 int globalIndex = nameToIndexElem.attribute( QStringLiteral(
"global-index" ) ).toInt();
372 mGroupNameToGlobalIndex.insert( name, globalIndex );
374 nameToIndexElem = nameToIndexElem.nextSiblingElement( QStringLiteral(
"name-to-global-index" ) );
377 QDomElement rootTreeItemElem = storeElem.firstChildElement( QStringLiteral(
"mesh-dataset-group-tree-item" ) );
378 if ( !rootTreeItemElem.isNull() )
387 for ( QMap<int, DatasetGroup>::const_iterator it = mRegistry.cbegin(); it != mRegistry.cend(); ++it )
389 if ( it.value().first == source && it.value().second == nativeGroupIndex )
398 return mGroupNameToGlobalIndex.value(
groupName, -1 );
408 DatasetGroup group = datasetGroup( groupIndex );
411 if ( group.first && group.second >= 0 )
412 fail = mPersistentProvider->
persistDatasetGroup( filePath, driver, group.first, group.second );
416 eraseDatasetGroup( group );
417 group.first = mPersistentProvider;
419 mRegistry[groupIndex] = group;
421 if ( mDatasetGroupTreeRootItem )
432void QgsMeshDatasetGroupStore::onPersistentDatasetAdded(
int count )
434 Q_ASSERT( mPersistentProvider );
438 QList<int> newGroupIndexes;
439 for (
int i = providerBeginIndex; i < providerTotalCount; ++i )
442 if ( mGroupNameToGlobalIndex.empty() && i < mPersistentExtraDatasetGroupIndexes.count() )
445 mRegistry[mPersistentExtraDatasetGroupIndexes.at( i )] = DatasetGroup( mPersistentProvider, i );
447 else if ( mGroupNameToGlobalIndex.contains(
groupName ) )
450 registerDatasetGroup( DatasetGroup{mPersistentProvider, i} );
454 int newGroupIndex = registerDatasetGroup( DatasetGroup{mPersistentProvider, i} );
455 if ( newGroupIndex != -1 )
456 newGroupIndexes.append( newGroupIndex );
460 if ( !newGroupIndexes.isEmpty() )
462 createDatasetGroupTreeItems( newGroupIndexes );
463 mPersistentExtraDatasetGroupIndexes.append( newGroupIndexes );
465 for (
int groupIndex : std::as_const( newGroupIndexes ) )
466 syncItemToDatasetGroup( groupIndex );
472void QgsMeshDatasetGroupStore::removePersistentProvider()
474 if ( !mPersistentProvider )
479 QMap < int, DatasetGroup>::iterator it = mRegistry.begin();
480 while ( it != mRegistry.end() )
482 if ( it.value().first == mPersistentProvider )
483 it = mRegistry.erase( it );
488 mPersistentProvider =
nullptr;
491int QgsMeshDatasetGroupStore::newIndex()
493 QSet usedIndex = qgis::listToSet( mRegistry.keys() );
494 usedIndex.unite( qgis::listToSet( mGroupNameToGlobalIndex.values() ) );
497 while ( usedIndex.contains( index ) )
503int QgsMeshDatasetGroupStore::registerDatasetGroup(
const QgsMeshDatasetGroupStore::DatasetGroup &group )
505 const QString &name = group.first->datasetGroupMetadata( group.second ).name();
506 auto it = mGroupNameToGlobalIndex.find( name );
509 if ( it != mGroupNameToGlobalIndex.end() )
511 groupIndex = it.value();
513 if ( mRegistry.contains( groupIndex ) )
515 QgsDebugError( QStringLiteral(
"Duplicate group name for %1." ).arg( name ) );
521 groupIndex = newIndex();
522 mGroupNameToGlobalIndex.insert( name, groupIndex );
525 mRegistry[groupIndex] = group;
529void QgsMeshDatasetGroupStore::eraseDatasetGroup(
const QgsMeshDatasetGroupStore::DatasetGroup &group )
531 if ( group.first == mPersistentProvider )
533 else if ( group.first == &mExtraDatasets )
534 eraseExtraDataset( group.second );
537void QgsMeshDatasetGroupStore::eraseExtraDataset(
int indexInExtraStore )
542 QMap < int, DatasetGroup>::iterator it = mRegistry.begin();
543 while ( it != mRegistry.end() )
545 int localIndex = it.value().second;
546 if ( it.value().first == &mExtraDatasets && localIndex > indexInExtraStore )
547 it->second = localIndex - 1;
559 if ( globalIndex == -1 )
560 globalIndex = registerDatasetGroup( DatasetGroup{source, i} );
562 if ( globalIndex != - 1 )
563 indexes.append( globalIndex );
566 if ( !indexes.isEmpty() )
567 createDatasetGroupTreeItems( indexes );
569 const QList<int> globalIndexes = mRegistry.keys();
570 for (
int globalIndex : globalIndexes )
572 if ( mRegistry.value( globalIndex ).first == source )
573 syncItemToDatasetGroup( globalIndex );
577void QgsMeshDatasetGroupStore::removeUnregisteredItemFromTree()
579 QList<QgsMeshDatasetGroupTreeItem *> itemsToCheck;
580 QList<int> indexItemToRemove;
581 for (
int i = 0; i < mDatasetGroupTreeRootItem->childCount(); ++i )
582 itemsToCheck.append( mDatasetGroupTreeRootItem->child( i ) );
584 while ( !itemsToCheck.isEmpty() )
588 if ( !mRegistry.contains( globalIndex ) )
589 indexItemToRemove.append( globalIndex );
590 for (
int i = 0; i < item->
childCount(); ++i )
591 itemsToCheck.append( item->
child( i ) );
594 for (
int i : indexItemToRemove )
602void QgsMeshDatasetGroupStore::unregisterGroupNotPresentInTree()
604 if ( !mDatasetGroupTreeRootItem )
610 QMap < int, DatasetGroup>::iterator it = mRegistry.begin();
611 while ( it != mRegistry.end() )
613 DatasetGroup datasetGroup = it.value();
614 int globalIndex = it.key();
615 if ( ! mDatasetGroupTreeRootItem->childFromDatasetGroupIndex( globalIndex )
616 && datasetGroup.first != mPersistentProvider )
618 it = mRegistry.erase( it );
619 eraseDatasetGroup( datasetGroup );
626void QgsMeshDatasetGroupStore::syncItemToDatasetGroup(
int groupIndex )
628 if ( !mDatasetGroupTreeRootItem )
630 const DatasetGroup group = datasetGroup( groupIndex );
632 if ( group.first == mPersistentProvider && mPersistentProvider )
638 else if ( group.first == &mExtraDatasets )
645void QgsMeshDatasetGroupStore::createDatasetGroupTreeItems(
const QList<int> &indexes )
647 QMap<QString, QgsMeshDatasetGroupTreeItem *> mNameToItem;
649 for (
int i = 0; i < indexes.count(); ++i )
651 int groupIndex = indexes.at( i );
652 if ( mDatasetGroupTreeRootItem->childFromDatasetGroupIndex( groupIndex ) )
655 const QString name = meta.
name();
656 const QStringList subdatasets = name.split(
'/' );
658 QString displayName = name;
661 if ( subdatasets.size() == 2 )
663 auto it = mNameToItem.find( subdatasets[0] );
664 if ( it == mNameToItem.end() )
665 QgsDebugError( QStringLiteral(
"Unable to find parent group for %1." ).arg( name ) );
668 displayName = subdatasets[1];
672 else if ( subdatasets.size() != 1 )
673 QgsDebugError( QStringLiteral(
"Ignoring too deep child group name %1." ).arg( name ) );
677 if ( mNameToItem.contains( name ) )
678 QgsDebugError( QStringLiteral(
"Group %1 is not unique" ).arg( displayName ) );
679 mNameToItem[name] = item;
685 int groupIndex = mGroups.size();
686 mGroups.push_back( std::unique_ptr<QgsMeshDatasetGroup>(
datasetGroup ) );
695 return mGroups.size() - 1;
701 mGroups.erase( mGroups.begin() + index );
719 if ( groupIndex >= 0 && groupIndex <
int( mGroups.size() ) )
720 return mGroups.at( groupIndex )->description();
727 if ( groupIndex >= 0 && groupIndex <
int( mGroups.size() ) )
728 return mGroups[groupIndex].get();
741 return QStringList();
746 return mGroups.size();
752 return mGroups.at( groupIndex )->datasetCount();
760 return mGroups.at( groupIndex )->groupMetadata();
767 int groupIndex = index.
group();
770 int datasetIndex = index.
dataset();
780 int groupIndex = index.
group();
784 int datasetIndex = index.
dataset();
794 int groupIndex = index.
group();
798 int datasetIndex = index.
dataset();
810 Q_UNUSED( faceIndex )
817 int groupIndex = index.
group();
821 int datasetIndex = index.
dataset();
831 int groupIndex = index.
group();
835 int datasetIndex = index.
dataset();
843 const QString &outputDriver,
845 const QVector<QgsMeshDataBlock> &datasetValues,
846 const QVector<QgsMeshDataBlock> &datasetActive,
847 const QVector<double> × )
849 Q_UNUSED( outputFilePath )
850 Q_UNUSED( outputDriver )
853 Q_UNUSED( datasetActive )
859 const QString &outputDriver,
861 int datasetGroupIndex )
863 Q_UNUSED( outputFilePath )
864 Q_UNUSED( outputDriver )
866 Q_UNUSED( datasetGroupIndex )
872 if ( groupIndex >= 0 && groupIndex <
int( mGroups.size() ) && mGroups[groupIndex] )
873 return mGroups[groupIndex]->writeXml( doc, context );
875 return QDomElement();
882 bool hasTemporal =
false;
883 for (
size_t g = 0; g < mGroups.size(); ++g )
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.
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.
void setDatasetGroupTreeItem(const QgsMeshDatasetGroupTreeItem *rootItem)
Sets the root of the dataset groups tree item.
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.
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.
QList< QgsMeshDatasetIndex > datasetIndexInTimeInterval(qint64 time1, qint64 time2, int groupIndex) const
Returns the global dataset index of the dataset int the dataset group with groupIndex,...
bool addDatasetGroup(QgsMeshDatasetGroup *group)
Adds a extra dataset group, take ownership, returns True if the group is effectivly added.
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.
QString groupName(int groupIndex) const
Returns the name of the dataset group with global index groupIndex.
void setPersistentProvider(QgsMeshDataProvider *provider, const QStringList &extraDatasetUri)
Sets the persistent mesh data provider with the path of its extra dataset to be loaded by the provide...
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.
int globalDatasetGroupIndexInSource(QgsMeshDatasetSourceInterface *source, int nativeGroupIndex) const
Returns the global dataset group index of the dataset group with native index nativeGroupIndex in the...
int indexFromGroupName(const QString &groupName) const
Returns the global dataset group index of the dataset with name groupName.
void datasetGroupsAdded(QList< int > indexes)
Emitted after dataset groups are added.
QgsMesh3DDataBlock dataset3dValues(const QgsMeshDatasetIndex &index, int faceIndex, int count) const
Returns count 3D values of the dataset with global index and from valueIndex.
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.
int datasetGroupIndex() const
QgsMeshDatasetGroupTreeItem * parentItem() const
Returns the parent item, nullptr if it is root item.
void removeChild(QgsMeshDatasetGroupTreeItem *item)
Removes and destroy 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.
QgsMeshDatasetGroupMetadata::DataType dataType() const
Returns the data type of the dataset group.
virtual void initialize()=0
Initialize the dataset group.
virtual int datasetCount() const =0
Returns the count of datasets in the group.
virtual QgsMeshDataset * dataset(int index) const =0
Returns the dataset with index.
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()
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 > ×)
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.
Represents a mesh layer supporting display of data on structured or unstructured meshes.
int meshFaceCount() const
Returns the faces count of the mesh frame.
int meshEdgeCount() const
Returns the edges count of the mesh frame.
int meshVertexCount() const
Returns the vertices count of the mesh frame.
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 QgsDebugError(str)
#define INVALID_MESHLAYER_TIME