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