Branch data Line data Source code
1 : : /***************************************************************************
2 : : qgsmeshdataset.cpp
3 : : -----------------------
4 : : begin : April 2018
5 : : copyright : (C) 2018 by Peter Petrik
6 : : email : zilolv 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 "qgsmeshdataset.h"
19 : : #include "qgsrectangle.h"
20 : : #include "qgis.h"
21 : :
22 : 0 : QgsMeshDatasetIndex::QgsMeshDatasetIndex( int group, int dataset )
23 : 0 : : mGroupIndex( group ), mDatasetIndex( dataset )
24 : 0 : {}
25 : :
26 : 0 : int QgsMeshDatasetIndex::group() const
27 : : {
28 : 0 : return mGroupIndex;
29 : : }
30 : :
31 : 0 : int QgsMeshDatasetIndex::dataset() const
32 : : {
33 : 0 : return mDatasetIndex;
34 : : }
35 : :
36 : 0 : bool QgsMeshDatasetIndex::isValid() const
37 : : {
38 : 0 : return ( group() > -1 ) && ( dataset() > -1 );
39 : : }
40 : :
41 : 0 : bool QgsMeshDatasetIndex::operator ==( QgsMeshDatasetIndex other ) const
42 : : {
43 : 0 : if ( isValid() && other.isValid() )
44 : 0 : return other.group() == group() && other.dataset() == dataset();
45 : : else
46 : 0 : return isValid() == other.isValid();
47 : 0 : }
48 : :
49 : 0 : bool QgsMeshDatasetIndex::operator !=( QgsMeshDatasetIndex other ) const
50 : : {
51 : 0 : return !( operator==( other ) );
52 : : }
53 : :
54 : 0 : QgsMeshDatasetValue::QgsMeshDatasetValue( double x, double y )
55 : 0 : : mX( x ), mY( y )
56 : 0 : {}
57 : :
58 : 0 : QgsMeshDatasetValue::QgsMeshDatasetValue( double scalar )
59 : 0 : : mX( scalar )
60 : 0 : {}
61 : :
62 : 0 : double QgsMeshDatasetValue::scalar() const
63 : : {
64 : 0 : if ( std::isnan( mY ) )
65 : : {
66 : 0 : return mX;
67 : : }
68 : 0 : else if ( std::isnan( mX ) )
69 : : {
70 : 0 : return std::numeric_limits<double>::quiet_NaN();
71 : : }
72 : : else
73 : : {
74 : 0 : return std::sqrt( ( mX ) * ( mX ) + ( mY ) * ( mY ) );
75 : : }
76 : 0 : }
77 : :
78 : 0 : void QgsMeshDatasetValue::set( double scalar )
79 : : {
80 : 0 : setX( scalar );
81 : 0 : }
82 : :
83 : 0 : void QgsMeshDatasetValue::setX( double x )
84 : : {
85 : 0 : mX = x;
86 : 0 : }
87 : :
88 : 0 : void QgsMeshDatasetValue::setY( double y )
89 : : {
90 : 0 : mY = y;
91 : 0 : }
92 : :
93 : 0 : double QgsMeshDatasetValue::x() const
94 : : {
95 : 0 : return mX;
96 : : }
97 : :
98 : 0 : double QgsMeshDatasetValue::y() const
99 : : {
100 : 0 : return mY;
101 : : }
102 : :
103 : 0 : bool QgsMeshDatasetValue::operator==( const QgsMeshDatasetValue other ) const
104 : : {
105 : 0 : bool equal = std::isnan( mX ) == std::isnan( other.x() );
106 : 0 : equal &= std::isnan( mY ) == std::isnan( other.y() );
107 : :
108 : 0 : if ( equal )
109 : : {
110 : 0 : if ( std::isnan( mY ) )
111 : : {
112 : 0 : equal &= qgsDoubleNear( other.x(), mX, 1E-8 );
113 : 0 : }
114 : : else
115 : 0 : {
116 : 0 : equal &= qgsDoubleNear( other.x(), mX, 1E-8 );
117 : 0 : equal &= qgsDoubleNear( other.y(), mY, 1E-8 );
118 : : }
119 : 0 : }
120 : 0 : return equal;
121 : : }
122 : :
123 : 0 : QgsMeshDatasetGroupMetadata::QgsMeshDatasetGroupMetadata( const QString &name,
124 : : const QString uri,
125 : : bool isScalar,
126 : : DataType dataType,
127 : : double minimum,
128 : : double maximum,
129 : : int maximumVerticalLevels,
130 : : const QDateTime &referenceTime,
131 : : bool isTemporal,
132 : : const QMap<QString, QString> &extraOptions )
133 : 0 : : mName( name )
134 : 0 : , mUri( uri )
135 : 0 : , mIsScalar( isScalar )
136 : 0 : , mDataType( dataType )
137 : 0 : , mMinimumValue( minimum )
138 : 0 : , mMaximumValue( maximum )
139 : 0 : , mExtraOptions( extraOptions )
140 : 0 : , mMaximumVerticalLevelsCount( maximumVerticalLevels )
141 : 0 : , mReferenceTime( referenceTime )
142 : 0 : , mIsTemporal( isTemporal )
143 : : {
144 : 0 : }
145 : :
146 : 0 : QMap<QString, QString> QgsMeshDatasetGroupMetadata::extraOptions() const
147 : : {
148 : 0 : return mExtraOptions;
149 : : }
150 : :
151 : 0 : bool QgsMeshDatasetGroupMetadata::isVector() const
152 : : {
153 : 0 : return !mIsScalar;
154 : : }
155 : :
156 : 0 : bool QgsMeshDatasetGroupMetadata::isScalar() const
157 : : {
158 : 0 : return mIsScalar;
159 : : }
160 : :
161 : 0 : bool QgsMeshDatasetGroupMetadata::isTemporal() const
162 : : {
163 : 0 : return mIsTemporal;
164 : : }
165 : :
166 : 0 : QString QgsMeshDatasetGroupMetadata::name() const
167 : : {
168 : 0 : return mName;
169 : : }
170 : :
171 : 0 : QgsMeshDatasetGroupMetadata::DataType QgsMeshDatasetGroupMetadata::dataType() const
172 : : {
173 : 0 : return mDataType;
174 : : }
175 : :
176 : 0 : double QgsMeshDatasetGroupMetadata::minimum() const
177 : : {
178 : 0 : return mMinimumValue;
179 : : }
180 : :
181 : 0 : double QgsMeshDatasetGroupMetadata::maximum() const
182 : : {
183 : 0 : return mMaximumValue;
184 : : }
185 : :
186 : 0 : int QgsMeshDatasetGroupMetadata::maximumVerticalLevelsCount() const
187 : : {
188 : 0 : return mMaximumVerticalLevelsCount;
189 : : }
190 : :
191 : 0 : QDateTime QgsMeshDatasetGroupMetadata::referenceTime() const
192 : : {
193 : 0 : return mReferenceTime;
194 : : }
195 : :
196 : 0 : QString QgsMeshDatasetGroupMetadata::uri() const
197 : : {
198 : 0 : return mUri;
199 : : }
200 : :
201 : 0 : QgsMeshDatasetMetadata::QgsMeshDatasetMetadata(
202 : : double time,
203 : : bool isValid,
204 : : double minimum,
205 : : double maximum,
206 : : int maximumVerticalLevels )
207 : 0 : : mTime( time )
208 : 0 : , mIsValid( isValid )
209 : 0 : , mMinimumValue( minimum )
210 : 0 : , mMaximumValue( maximum )
211 : 0 : , mMaximumVerticalLevelsCount( maximumVerticalLevels )
212 : : {
213 : 0 : }
214 : :
215 : 0 : double QgsMeshDatasetMetadata::time() const
216 : : {
217 : 0 : return mTime;
218 : : }
219 : :
220 : 0 : bool QgsMeshDatasetMetadata::isValid() const
221 : : {
222 : 0 : return mIsValid;
223 : : }
224 : :
225 : 0 : double QgsMeshDatasetMetadata::minimum() const
226 : : {
227 : 0 : return mMinimumValue;
228 : 0 : }
229 : :
230 : 0 : double QgsMeshDatasetMetadata::maximum() const
231 : : {
232 : 0 : return mMaximumValue;
233 : : }
234 : :
235 : 0 : int QgsMeshDatasetMetadata::maximumVerticalLevelsCount() const
236 : : {
237 : 0 : return mMaximumVerticalLevelsCount;
238 : : }
239 : :
240 : 0 : QgsMeshDataBlock::QgsMeshDataBlock()
241 : 0 : : mType( ActiveFlagInteger )
242 : : {
243 : 0 : }
244 : :
245 : 0 : QgsMeshDataBlock::QgsMeshDataBlock( QgsMeshDataBlock::DataType type, int count )
246 : 0 : : mType( type ),
247 : 0 : mSize( count )
248 : : {
249 : 0 : }
250 : :
251 : 0 : QgsMeshDataBlock::DataType QgsMeshDataBlock::type() const
252 : : {
253 : 0 : return mType;
254 : : }
255 : :
256 : 0 : int QgsMeshDataBlock::count() const
257 : : {
258 : 0 : return mSize;
259 : : }
260 : :
261 : 0 : bool QgsMeshDataBlock::isValid() const
262 : : {
263 : 0 : return ( count() > 0 ) && ( mIsValid );
264 : : }
265 : :
266 : 0 : QgsMeshDatasetValue QgsMeshDataBlock::value( int index ) const
267 : : {
268 : 0 : if ( !isValid() )
269 : 0 : return QgsMeshDatasetValue();
270 : :
271 : : Q_ASSERT( mType != ActiveFlagInteger );
272 : :
273 : 0 : if ( mType == ScalarDouble )
274 : 0 : return QgsMeshDatasetValue( mDoubleBuffer[index] );
275 : :
276 : 0 : return QgsMeshDatasetValue(
277 : 0 : mDoubleBuffer[2 * index],
278 : 0 : mDoubleBuffer[2 * index + 1]
279 : : );
280 : 0 : }
281 : :
282 : 0 : bool QgsMeshDataBlock::active( int index ) const
283 : : {
284 : 0 : if ( !isValid() )
285 : 0 : return false;
286 : :
287 : : Q_ASSERT( mType == ActiveFlagInteger );
288 : :
289 : 0 : if ( mIntegerBuffer.empty() )
290 : 0 : return true;
291 : : else
292 : 0 : return bool( mIntegerBuffer[index] );
293 : 0 : }
294 : :
295 : 0 : void QgsMeshDataBlock::setActive( const QVector<int> &vals )
296 : : {
297 : : Q_ASSERT( mType == ActiveFlagInteger );
298 : : Q_ASSERT( vals.size() == count() );
299 : :
300 : 0 : mIntegerBuffer = vals;
301 : 0 : setValid( true );
302 : 0 : }
303 : :
304 : 0 : QVector<int> QgsMeshDataBlock::active() const
305 : : {
306 : : Q_ASSERT( mType == ActiveFlagInteger );
307 : 0 : return mIntegerBuffer;
308 : : }
309 : :
310 : 0 : QVector<double> QgsMeshDataBlock::values() const
311 : : {
312 : : Q_ASSERT( mType != ActiveFlagInteger );
313 : :
314 : 0 : return mDoubleBuffer;
315 : : }
316 : :
317 : 0 : void QgsMeshDataBlock::setValues( const QVector<double> &vals )
318 : : {
319 : : Q_ASSERT( mType != ActiveFlagInteger );
320 : : Q_ASSERT( mType == ScalarDouble ? vals.size() == count() : vals.size() == 2 * count() );
321 : :
322 : 0 : mDoubleBuffer = vals;
323 : 0 : setValid( true );
324 : 0 : }
325 : :
326 : 0 : void QgsMeshDataBlock::setValid( bool valid )
327 : : {
328 : 0 : mIsValid = valid;
329 : 0 : }
330 : 0 :
331 : 0 : QgsMesh3dDataBlock::QgsMesh3dDataBlock() = default;
332 : 0 :
333 : 0 : QgsMesh3dDataBlock::~QgsMesh3dDataBlock() {};
334 : :
335 : 0 : QgsMesh3dDataBlock::QgsMesh3dDataBlock( int count, bool isVector )
336 : 0 : : mSize( count )
337 : 0 : , mIsVector( isVector )
338 : : {
339 : 0 : }
340 : :
341 : 0 : bool QgsMesh3dDataBlock::isValid() const
342 : : {
343 : 0 : return mIsValid;
344 : : }
345 : :
346 : 0 : bool QgsMesh3dDataBlock::isVector() const
347 : : {
348 : 0 : return mIsVector;
349 : : }
350 : :
351 : 0 : int QgsMesh3dDataBlock::count() const
352 : : {
353 : 0 : return mSize;
354 : : }
355 : :
356 : 0 : int QgsMesh3dDataBlock::firstVolumeIndex() const
357 : : {
358 : 0 : if ( mFaceToVolumeIndex.empty() )
359 : 0 : return -1;
360 : 0 : return mFaceToVolumeIndex[0];
361 : 0 : }
362 : :
363 : 0 : int QgsMesh3dDataBlock::lastVolumeIndex() const
364 : : {
365 : 0 : if ( mFaceToVolumeIndex.empty() || mVerticalLevelsCount.empty() )
366 : 0 : return -1;
367 : 0 : const int lastVolumeStartIndex = mFaceToVolumeIndex[mFaceToVolumeIndex.size() - 1];
368 : 0 : const int volumesCountInLastRow = mVerticalLevelsCount[mVerticalLevelsCount.size() - 1];
369 : 0 : return lastVolumeStartIndex + volumesCountInLastRow;
370 : 0 : }
371 : :
372 : 0 : int QgsMesh3dDataBlock::volumesCount() const
373 : : {
374 : 0 : return lastVolumeIndex() - firstVolumeIndex();
375 : : }
376 : :
377 : 0 : QVector<int> QgsMesh3dDataBlock::verticalLevelsCount() const
378 : : {
379 : : Q_ASSERT( isValid() );
380 : 0 : return mVerticalLevelsCount;
381 : : }
382 : :
383 : 0 : void QgsMesh3dDataBlock::setFaceToVolumeIndex( const QVector<int> &faceToVolumeIndex )
384 : : {
385 : : Q_ASSERT( faceToVolumeIndex.size() == count() );
386 : 0 : mFaceToVolumeIndex = faceToVolumeIndex;
387 : 0 : }
388 : :
389 : 0 : void QgsMesh3dDataBlock::setVerticalLevelsCount( const QVector<int> &verticalLevelsCount )
390 : : {
391 : : Q_ASSERT( verticalLevelsCount.size() == count() );
392 : 0 : mVerticalLevelsCount = verticalLevelsCount;
393 : 0 : }
394 : :
395 : 0 : QVector<double> QgsMesh3dDataBlock::verticalLevels() const
396 : : {
397 : : Q_ASSERT( isValid() );
398 : 0 : return mVerticalLevels;
399 : : }
400 : :
401 : 0 : void QgsMesh3dDataBlock::setVerticalLevels( const QVector<double> &verticalLevels )
402 : : {
403 : : Q_ASSERT( verticalLevels.size() == volumesCount() + count() );
404 : 0 : mVerticalLevels = verticalLevels;
405 : 0 : }
406 : :
407 : 0 : QVector<int> QgsMesh3dDataBlock::faceToVolumeIndex() const
408 : : {
409 : : Q_ASSERT( isValid() );
410 : 0 : return mFaceToVolumeIndex;
411 : : }
412 : :
413 : 0 : QVector<double> QgsMesh3dDataBlock::values() const
414 : : {
415 : : Q_ASSERT( isValid() );
416 : 0 : return mDoubleBuffer;
417 : : }
418 : :
419 : 0 : QgsMeshDatasetValue QgsMesh3dDataBlock::value( int volumeIndex ) const
420 : : {
421 : 0 : if ( !isValid() )
422 : 0 : return QgsMeshDatasetValue();
423 : :
424 : 0 : if ( !mIsVector )
425 : 0 : return QgsMeshDatasetValue( mDoubleBuffer[volumeIndex] );
426 : :
427 : 0 : return QgsMeshDatasetValue(
428 : 0 : mDoubleBuffer[2 * volumeIndex],
429 : 0 : mDoubleBuffer[2 * volumeIndex + 1]
430 : : );
431 : 0 : }
432 : :
433 : 0 : void QgsMesh3dDataBlock::setValues( const QVector<double> &doubleBuffer )
434 : : {
435 : : Q_ASSERT( doubleBuffer.size() == ( isVector() ? 2 * volumesCount() : volumesCount() ) );
436 : 0 : mDoubleBuffer = doubleBuffer;
437 : 0 : }
438 : :
439 : 0 : void QgsMesh3dDataBlock::setValid( bool valid )
440 : : {
441 : 0 : mIsValid = valid;
442 : 0 : }
443 : :
444 : 0 : QgsMeshDatasetGroupTreeItem::QgsMeshDatasetGroupTreeItem() = default;
445 : :
446 : 0 : QgsMeshDatasetGroupTreeItem::QgsMeshDatasetGroupTreeItem( const QString &defaultName, const QString &sourceName,
447 : : bool isVector,
448 : : int index )
449 : 0 : : mOriginalName( defaultName )
450 : 0 : , mSourceName( sourceName )
451 : 0 : , mIsVector( isVector )
452 : 0 : , mDatasetGroupIndex( index )
453 : : {
454 : 0 : }
455 : :
456 : 0 : QgsMeshDatasetGroupTreeItem::QgsMeshDatasetGroupTreeItem( const QDomElement &itemElement, const QgsReadWriteContext &context )
457 : : {
458 : 0 : Q_UNUSED( context );
459 : 0 : if ( itemElement.hasAttribute( QStringLiteral( "display-name" ) ) )
460 : 0 : mUserName = itemElement.attribute( QStringLiteral( "display-name" ), mUserName );
461 : :
462 : 0 : if ( itemElement.hasAttribute( QStringLiteral( "original-name" ) ) )
463 : 0 : mOriginalName = itemElement.attribute( QStringLiteral( "original-name" ), mOriginalName );
464 : :
465 : 0 : if ( itemElement.hasAttribute( QStringLiteral( "source-name" ) ) )
466 : 0 : mSourceName = itemElement.attribute( QStringLiteral( "source-name" ), mSourceName );
467 : :
468 : 0 : if ( itemElement.hasAttribute( QStringLiteral( "is-vector" ) ) )
469 : 0 : mIsVector = itemElement.attribute( QStringLiteral( "is-vector" ) ).toInt();
470 : :
471 : 0 : if ( itemElement.hasAttribute( QStringLiteral( "dataset-index" ) ) )
472 : 0 : mDatasetGroupIndex = itemElement.attribute( QStringLiteral( "dataset-index" ) ).toInt();
473 : :
474 : 0 : if ( itemElement.hasAttribute( QStringLiteral( "is-enabled" ) ) )
475 : 0 : mIsEnabled = itemElement.attribute( QStringLiteral( "is-enabled" ) ).toInt();
476 : :
477 : 0 : if ( itemElement.hasAttribute( QStringLiteral( "dataset-group-type" ) ) )
478 : 0 : mDatasetGroupType = static_cast<QgsMeshDatasetGroup::Type>( itemElement.attribute( QStringLiteral( "dataset-group-type" ) ) .toInt() ) ;
479 : :
480 : 0 : if ( itemElement.hasAttribute( QStringLiteral( "description" ) ) )
481 : 0 : mDescription = itemElement.attribute( QStringLiteral( "description" ) );
482 : :
483 : 0 : QDomElement dependOnElement = itemElement.firstChildElement( QStringLiteral( "dependent-on-item" ) );
484 : 0 : while ( !dependOnElement.isNull() )
485 : : {
486 : 0 : if ( dependOnElement.hasAttribute( QStringLiteral( "dataset-index" ) ) )
487 : 0 : mDatasetGroupDependentOn.append( dependOnElement.attribute( QStringLiteral( "dataset-index" ) ).toInt() );
488 : 0 : dependOnElement = dependOnElement.nextSiblingElement( QStringLiteral( "dependent-on-item" ) );
489 : : }
490 : :
491 : 0 : QDomElement dependencieElement = itemElement.firstChildElement( QStringLiteral( "dependency-item" ) );
492 : 0 : while ( !dependencieElement.isNull() )
493 : : {
494 : 0 : if ( dependencieElement.hasAttribute( QStringLiteral( "dataset-index" ) ) )
495 : 0 : mDatasetGroupDependencies.append( dependencieElement.attribute( QStringLiteral( "dataset-index" ) ).toInt() );
496 : 0 : dependencieElement = dependencieElement.nextSiblingElement( QStringLiteral( "dependency-item" ) );
497 : : }
498 : :
499 : 0 : QDomElement childElement = itemElement.firstChildElement( QStringLiteral( "mesh-dataset-group-tree-item" ) );
500 : 0 : while ( !childElement.isNull() )
501 : : {
502 : 0 : appendChild( new QgsMeshDatasetGroupTreeItem( childElement, context ) );
503 : 0 : childElement = childElement.nextSiblingElement( QStringLiteral( "mesh-dataset-group-tree-item" ) );
504 : : }
505 : 0 : }
506 : :
507 : 0 : QgsMeshDatasetGroupTreeItem::~QgsMeshDatasetGroupTreeItem()
508 : : {
509 : : // Remove from where this item is linked
510 : :
511 : 0 : freeAsDependency();
512 : 0 : freeFromDependencies();
513 : 0 : qDeleteAll( mChildren );
514 : 0 : if ( mParent )
515 : : {
516 : 0 : mParent->mDatasetGroupIndexToChild.remove( mDatasetGroupIndex );
517 : 0 : mParent->mChildren.removeOne( this );
518 : 0 : }
519 : 0 : }
520 : :
521 : 0 : QgsMeshDatasetGroupTreeItem *QgsMeshDatasetGroupTreeItem::clone() const
522 : : {
523 : 0 : QgsMeshDatasetGroupTreeItem *other = new QgsMeshDatasetGroupTreeItem( mOriginalName, mSourceName, mIsVector, mDatasetGroupIndex );
524 : 0 : *other = *this;
525 : :
526 : 0 : other->mChildren.clear();
527 : 0 : other->mDatasetGroupIndexToChild.clear();
528 : 0 : if ( !mChildren.empty() )
529 : 0 : for ( int i = 0; i < mChildren.count(); ++i )
530 : 0 : other->appendChild( mChildren.at( i )->clone() );
531 : :
532 : 0 : return other;
533 : 0 : }
534 : :
535 : 0 : void QgsMeshDatasetGroupTreeItem::appendChild( QgsMeshDatasetGroupTreeItem *item )
536 : : {
537 : 0 : mChildren.append( item );
538 : 0 : item->mParent = this;
539 : 0 : mDatasetGroupIndexToChild[item->datasetGroupIndex()] = item;
540 : 0 : }
541 : :
542 : 0 : void QgsMeshDatasetGroupTreeItem::removeChild( QgsMeshDatasetGroupTreeItem *item )
543 : : {
544 : 0 : delete item;
545 : 0 : }
546 : :
547 : 0 : QgsMeshDatasetGroupTreeItem *QgsMeshDatasetGroupTreeItem::child( int row ) const
548 : : {
549 : 0 : if ( row < mChildren.count() )
550 : 0 : return mChildren.at( row );
551 : : else
552 : 0 : return nullptr;
553 : 0 : }
554 : :
555 : 0 : QgsMeshDatasetGroupTreeItem *QgsMeshDatasetGroupTreeItem::childFromDatasetGroupIndex( int index )
556 : : {
557 : 0 : if ( mDatasetGroupIndexToChild.empty() )
558 : 0 : return nullptr;
559 : :
560 : 0 : QMap<int, QgsMeshDatasetGroupTreeItem *>::iterator it = mDatasetGroupIndexToChild.find( index );
561 : :
562 : 0 : if ( it != mDatasetGroupIndexToChild.end() )
563 : 0 : return it.value();
564 : : else
565 : : {
566 : 0 : QgsMeshDatasetGroupTreeItem *item = nullptr;
567 : 0 : for ( int i = 0; i < mChildren.count(); ++i )
568 : : {
569 : 0 : item = mChildren.at( i )->childFromDatasetGroupIndex( index );
570 : 0 : if ( item )
571 : 0 : break;
572 : 0 : }
573 : 0 : return item;
574 : : }
575 : 0 : }
576 : :
577 : 0 : int QgsMeshDatasetGroupTreeItem::childCount() const
578 : : {
579 : 0 : return mChildren.count();
580 : : }
581 : :
582 : 0 : int QgsMeshDatasetGroupTreeItem::totalChildCount() const
583 : : {
584 : 0 : int count = 0;
585 : 0 : for ( int i = 0; i < mChildren.count(); ++i )
586 : : {
587 : 0 : count++;
588 : 0 : count += mChildren.at( i )->totalChildCount();
589 : 0 : }
590 : 0 : return count;
591 : : }
592 : :
593 : 0 : QList<int> QgsMeshDatasetGroupTreeItem::enabledDatasetGroupIndexes() const
594 : : {
595 : 0 : QList<int> indexesList;
596 : :
597 : 0 : for ( int i = 0; i < mChildren.count(); ++i )
598 : : {
599 : 0 : if ( mChildren.at( i )->isEnabled() )
600 : 0 : indexesList.append( mChildren.at( i )->datasetGroupIndex() );
601 : 0 : indexesList.append( mChildren.at( i )->enabledDatasetGroupIndexes() );
602 : 0 : }
603 : :
604 : 0 : return indexesList;
605 : 0 : }
606 : :
607 : 0 : QgsMeshDatasetGroupTreeItem *QgsMeshDatasetGroupTreeItem::parentItem() const
608 : : {
609 : 0 : return mParent;
610 : : }
611 : :
612 : 0 : int QgsMeshDatasetGroupTreeItem::row() const
613 : : {
614 : 0 : if ( mParent )
615 : 0 : return mParent->mChildren.indexOf( const_cast<QgsMeshDatasetGroupTreeItem *>( this ) );
616 : :
617 : 0 : return 0;
618 : 0 : }
619 : :
620 : 0 : QString QgsMeshDatasetGroupTreeItem::name() const
621 : : {
622 : 0 : if ( mUserName.isEmpty() )
623 : 0 : return mOriginalName;
624 : : else
625 : 0 : return mUserName;
626 : 0 : }
627 : :
628 : 0 : bool QgsMeshDatasetGroupTreeItem::isVector() const
629 : : {
630 : 0 : return mIsVector;
631 : : }
632 : :
633 : 0 : int QgsMeshDatasetGroupTreeItem::datasetGroupIndex() const
634 : : {
635 : 0 : return mDatasetGroupIndex;
636 : : }
637 : :
638 : 0 : bool QgsMeshDatasetGroupTreeItem::isEnabled() const
639 : : {
640 : 0 : return mIsEnabled;
641 : : }
642 : :
643 : 0 : void QgsMeshDatasetGroupTreeItem::setIsEnabled( bool enabled )
644 : : {
645 : 0 : mIsEnabled = enabled;
646 : 0 : }
647 : :
648 : 0 : QString QgsMeshDatasetGroupTreeItem::defaultName() const
649 : : {
650 : 0 : return mOriginalName;
651 : : }
652 : :
653 : 0 : QgsMeshDatasetGroup::Type QgsMeshDatasetGroupTreeItem::datasetGroupType() const
654 : : {
655 : 0 : return mDatasetGroupType;
656 : : }
657 : :
658 : 0 : QString QgsMeshDatasetGroupTreeItem::description() const
659 : : {
660 : 0 : return mDescription;
661 : : }
662 : :
663 : 0 : void QgsMeshDatasetGroupTreeItem::setDatasetGroup( QgsMeshDatasetGroup *datasetGroup )
664 : : {
665 : 0 : if ( datasetGroup )
666 : : {
667 : 0 : mDescription = datasetGroup->description();
668 : 0 : mDatasetGroupType = datasetGroup->type();
669 : 0 : const QStringList &datasetGroupNames = datasetGroup->datasetGroupNamesDependentOn();
670 : 0 : for ( const QString &varName : datasetGroupNames )
671 : : {
672 : 0 : QgsMeshDatasetGroupTreeItem *varItem = searchItemBySourceName( varName );
673 : 0 : if ( varItem )
674 : 0 : {
675 : 0 : varItem->mDatasetGroupDependencies.append( this->datasetGroupIndex() );
676 : 0 : mDatasetGroupDependentOn.append( varItem->datasetGroupIndex() );
677 : 0 : }
678 : : }
679 : 0 : }
680 : 0 : }
681 : :
682 : 0 : void QgsMeshDatasetGroupTreeItem::setPersistentDatasetGroup( const QString &uri )
683 : : {
684 : 0 : mDatasetGroupType = QgsMeshDatasetGroup::Persistent;
685 : 0 : mDatasetGroupDependentOn.clear();
686 : 0 : mDescription = uri;
687 : 0 : }
688 : :
689 : 0 : QDomElement QgsMeshDatasetGroupTreeItem::writeXml( QDomDocument &doc, const QgsReadWriteContext &context )
690 : : {
691 : 0 : Q_UNUSED( context );
692 : :
693 : 0 : QDomElement itemElement = doc.createElement( QStringLiteral( "mesh-dataset-group-tree-item" ) );
694 : 0 : itemElement.setAttribute( QStringLiteral( "display-name" ), mUserName );
695 : 0 : itemElement.setAttribute( QStringLiteral( "source-name" ), mSourceName );
696 : 0 : itemElement.setAttribute( QStringLiteral( "original-name" ), mOriginalName );
697 : 0 : itemElement.setAttribute( QStringLiteral( "is-vector" ), mIsVector ? true : false );
698 : 0 : itemElement.setAttribute( QStringLiteral( "dataset-index" ), mDatasetGroupIndex );
699 : 0 : itemElement.setAttribute( QStringLiteral( "is-enabled" ), mIsEnabled ? true : false );
700 : 0 : itemElement.setAttribute( QStringLiteral( "dataset-group-type" ), mDatasetGroupType );
701 : 0 : itemElement.setAttribute( QStringLiteral( "description" ), mDescription );
702 : :
703 : 0 : for ( int index : mDatasetGroupDependentOn )
704 : : {
705 : 0 : QDomElement dependOnElement = doc.createElement( QStringLiteral( "dependent-on-item" ) );
706 : 0 : dependOnElement.setAttribute( QStringLiteral( "dataset-index" ), index );
707 : 0 : itemElement.appendChild( dependOnElement );
708 : 0 : }
709 : :
710 : 0 : for ( int index : mDatasetGroupDependencies )
711 : : {
712 : 0 : QDomElement dependencieElement = doc.createElement( QStringLiteral( "dependency-item" ) );
713 : 0 : dependencieElement.setAttribute( QStringLiteral( "dataset-index" ), index );
714 : 0 : itemElement.appendChild( dependencieElement );
715 : 0 : }
716 : :
717 : 0 : for ( int i = 0; i < mChildren.count(); ++i )
718 : 0 : itemElement.appendChild( mChildren.at( i )->writeXml( doc, context ) );
719 : :
720 : 0 : return itemElement;
721 : 0 : }
722 : :
723 : 0 : QList<int> QgsMeshDatasetGroupTreeItem::groupIndexDependencies() const
724 : : {
725 : 0 : QList<int> dependencies;
726 : 0 : QgsMeshDatasetGroupTreeItem *root = rootItem();
727 : 0 : for ( int index : mDatasetGroupDependencies )
728 : : {
729 : 0 : if ( !dependencies.contains( index ) )
730 : 0 : dependencies.append( index );
731 : 0 : QgsMeshDatasetGroupTreeItem *item = root->childFromDatasetGroupIndex( index );
732 : 0 : if ( item )
733 : 0 : dependencies.append( item->groupIndexDependencies() );
734 : : }
735 : :
736 : 0 : for ( int i = 0; i < childCount(); ++i )
737 : : {
738 : 0 : dependencies.append( child( i )->groupIndexDependencies() );
739 : 0 : }
740 : :
741 : 0 : return dependencies;
742 : 0 : }
743 : :
744 : 0 : QgsMeshDatasetGroupTreeItem *QgsMeshDatasetGroupTreeItem::searchItemBySourceName( const QString &sourceName ) const
745 : : {
746 : 0 : QgsMeshDatasetGroupTreeItem *baseItem = rootItem();
747 : :
748 : 0 : QList<QgsMeshDatasetGroupTreeItem *> itemToCheck;
749 : 0 : itemToCheck.append( baseItem );
750 : 0 : while ( baseItem && baseItem->providerName() != sourceName && !itemToCheck.isEmpty() )
751 : : {
752 : 0 : for ( int i = 0; i < baseItem->childCount(); ++i )
753 : 0 : itemToCheck.append( baseItem->child( i ) );
754 : 0 : itemToCheck.removeOne( baseItem );
755 : 0 : if ( !itemToCheck.empty() )
756 : 0 : baseItem = itemToCheck.first();
757 : : else
758 : 0 : baseItem = nullptr;
759 : : }
760 : :
761 : 0 : return baseItem;
762 : 0 : }
763 : :
764 : 0 : QgsMeshDatasetGroupTreeItem *QgsMeshDatasetGroupTreeItem::rootItem() const
765 : : {
766 : 0 : const QgsMeshDatasetGroupTreeItem *baseItem = this;
767 : 0 : while ( baseItem->parentItem() != nullptr )
768 : 0 : baseItem = baseItem->parentItem();
769 : :
770 : 0 : return const_cast<QgsMeshDatasetGroupTreeItem *>( baseItem );
771 : : }
772 : :
773 : 0 : void QgsMeshDatasetGroupTreeItem::freeAsDependency()
774 : : {
775 : 0 : QgsMeshDatasetGroupTreeItem *root = rootItem();
776 : 0 : for ( int index : mDatasetGroupDependentOn )
777 : : {
778 : 0 : QgsMeshDatasetGroupTreeItem *item = root->childFromDatasetGroupIndex( index );
779 : 0 : if ( item )
780 : 0 : item->mDatasetGroupDependencies.removeOne( this->datasetGroupIndex() );
781 : : }
782 : 0 : }
783 : :
784 : 0 : void QgsMeshDatasetGroupTreeItem::freeFromDependencies()
785 : : {
786 : 0 : QgsMeshDatasetGroupTreeItem *root = rootItem();
787 : 0 : for ( int index : mDatasetGroupDependencies )
788 : : {
789 : 0 : QgsMeshDatasetGroupTreeItem *item = root->childFromDatasetGroupIndex( index );
790 : 0 : if ( item )
791 : 0 : item->mDatasetGroupDependentOn.removeOne( this->datasetGroupIndex() );
792 : : }
793 : 0 : }
794 : :
795 : 0 : QString QgsMeshDatasetGroupTreeItem::providerName() const
796 : : {
797 : 0 : return mSourceName;
798 : : }
799 : :
800 : 0 : void QgsMeshDatasetGroupTreeItem::setName( const QString &name )
801 : : {
802 : 0 : mUserName = name;
803 : 0 : }
804 : :
805 : :
806 : 0 : QgsMeshDatasetValue QgsMeshMemoryDataset::datasetValue( int valueIndex ) const
807 : : {
808 : 0 : if ( valueIndex >= 0 && valueIndex < values.count() )
809 : 0 : return values[valueIndex];
810 : : else
811 : 0 : return QgsMeshDatasetValue();
812 : 0 : }
813 : :
814 : 0 : QgsMeshDataBlock QgsMeshMemoryDataset::datasetValues( bool isScalar, int valueIndex, int count ) const
815 : : {
816 : 0 : QgsMeshDataBlock ret( isScalar ? QgsMeshDataBlock::ScalarDouble : QgsMeshDataBlock::Vector2DDouble, count );
817 : 0 : QVector<double> buf( isScalar ? count : 2 * count );
818 : 0 : for ( int i = 0; i < count; ++i )
819 : : {
820 : 0 : int idx = valueIndex + i;
821 : 0 : if ( ( idx < 0 ) || ( idx >= values.size() ) )
822 : 0 : return ret;
823 : :
824 : 0 : QgsMeshDatasetValue val = values[ valueIndex + i ];
825 : 0 : if ( isScalar )
826 : 0 : buf[i] = val.x();
827 : : else
828 : : {
829 : 0 : buf[2 * i] = val.x();
830 : 0 : buf[2 * i + 1] = val.y();
831 : : }
832 : 0 : }
833 : 0 : ret.setValues( buf );
834 : 0 : return ret;
835 : 0 : }
836 : :
837 : 0 : QgsMeshDataBlock QgsMeshMemoryDataset::areFacesActive( int faceIndex, int count ) const
838 : : {
839 : 0 : QgsMeshDataBlock ret( QgsMeshDataBlock::ActiveFlagInteger, count );
840 : 0 : if ( active.isEmpty() ||
841 : 0 : ( faceIndex < 0 ) ||
842 : 0 : ( faceIndex + count > active.size() )
843 : : )
844 : 0 : ret.setValid( true );
845 : : else
846 : 0 : ret.setActive( active );
847 : 0 : return ret;
848 : 0 : }
849 : :
850 : 0 : QgsMeshDatasetMetadata QgsMeshMemoryDataset::metadata() const
851 : : {
852 : 0 : return QgsMeshDatasetMetadata( time, valid, minimum, maximum, 0 );
853 : : }
854 : :
855 : 0 : void QgsMeshMemoryDataset::calculateMinMax()
856 : : {
857 : 0 : double min = std::numeric_limits<double>::max();
858 : 0 : double max = std::numeric_limits<double>::min();
859 : :
860 : 0 : if ( !valid )
861 : 0 : return;
862 : :
863 : :
864 : 0 : bool firstIteration = true;
865 : 0 : for ( int i = 0; i < values.size(); ++i )
866 : : {
867 : 0 : double v = values[i].scalar();
868 : :
869 : 0 : if ( std::isnan( v ) )
870 : 0 : continue;
871 : 0 : if ( firstIteration )
872 : : {
873 : 0 : firstIteration = false;
874 : 0 : min = v;
875 : 0 : max = v;
876 : 0 : }
877 : : else
878 : : {
879 : 0 : if ( v < min )
880 : 0 : min = v;
881 : 0 : if ( v > max )
882 : 0 : max = v;
883 : : }
884 : 0 : }
885 : :
886 : 0 : minimum = min;
887 : 0 : maximum = max;
888 : 0 : }
889 : :
890 : 0 : bool QgsMeshMemoryDataset::isActive( int faceIndex ) const
891 : : {
892 : 0 : if ( active.isEmpty() || faceIndex >= active.count() )
893 : 0 : return true;
894 : : else
895 : 0 : return active.at( faceIndex );
896 : 0 : }
897 : :
898 : 0 : int QgsMeshMemoryDataset::valuesCount() const
899 : : {
900 : 0 : return values.count();
901 : : }
902 : :
903 : 0 : QgsMeshMemoryDatasetGroup::QgsMeshMemoryDatasetGroup( const QString &name, QgsMeshDatasetGroupMetadata::DataType dataType ):
904 : 0 : QgsMeshDatasetGroup( name, dataType )
905 : 0 : {
906 : 0 : }
907 : :
908 : 0 : QgsMeshMemoryDatasetGroup::QgsMeshMemoryDatasetGroup( const QString &name ):
909 : 0 : QgsMeshDatasetGroup( name )
910 : 0 : {
911 : 0 : }
912 : :
913 : 0 : QgsMeshDatasetGroupMetadata QgsMeshDatasetGroup::groupMetadata() const
914 : : {
915 : 0 : return QgsMeshDatasetGroupMetadata(
916 : 0 : name(),
917 : 0 : QString(),
918 : 0 : isScalar(),
919 : 0 : dataType(),
920 : 0 : minimum(),
921 : 0 : maximum(),
922 : : 0,
923 : 0 : mReferenceTime,
924 : 0 : datasetCount() > 1,
925 : 0 : extraMetadata()
926 : : );
927 : 0 : }
928 : :
929 : 0 : int QgsMeshMemoryDatasetGroup::datasetCount() const
930 : : {
931 : 0 : return memoryDatasets.size();
932 : : }
933 : :
934 : 0 : QgsMeshDatasetMetadata QgsMeshMemoryDatasetGroup::datasetMetadata( int datasetIndex ) const
935 : : {
936 : 0 : if ( datasetIndex >= 0 && datasetIndex < memoryDatasets.count() )
937 : 0 : return memoryDatasets[datasetIndex]->metadata();
938 : : else
939 : 0 : return QgsMeshDatasetMetadata();
940 : 0 : }
941 : :
942 : 0 : QgsMeshDataset *QgsMeshMemoryDatasetGroup::dataset( int index ) const
943 : : {
944 : 0 : return memoryDatasets[index].get();
945 : : }
946 : :
947 : 0 : void QgsMeshMemoryDatasetGroup::addDataset( std::shared_ptr<QgsMeshMemoryDataset> dataset )
948 : : {
949 : 0 : dataset->calculateMinMax();
950 : 0 : memoryDatasets.push_back( dataset );
951 : 0 : }
952 : :
953 : 0 : void QgsMeshMemoryDatasetGroup::clearDatasets()
954 : : {
955 : 0 : memoryDatasets.clear();
956 : 0 : }
957 : :
958 : 0 : void QgsMeshMemoryDatasetGroup::initialize()
959 : : {
960 : 0 : calculateStatistic();
961 : 0 : }
962 : :
963 : 0 : std::shared_ptr<const QgsMeshMemoryDataset> QgsMeshMemoryDatasetGroup::constDataset( int index ) const
964 : : {
965 : 0 : return memoryDatasets[index];
966 : : }
967 : :
968 : 0 : QDomElement QgsMeshMemoryDatasetGroup::writeXml( QDomDocument &doc, const QgsReadWriteContext &context ) const
969 : : {
970 : 0 : Q_UNUSED( doc )
971 : 0 : Q_UNUSED( context )
972 : 0 : return QDomElement();
973 : : }
974 : :
975 : 0 : void QgsMeshDatasetGroup::calculateStatistic()
976 : : {
977 : 0 : double min = std::numeric_limits<double>::max();
978 : 0 : double max = std::numeric_limits<double>::min();
979 : :
980 : 0 : int count = datasetCount();
981 : 0 : for ( int i = 0; i < count; ++i )
982 : : {
983 : 0 : min = std::min( min, datasetMetadata( i ).minimum() );
984 : 0 : max = std::max( max, datasetMetadata( i ).maximum() );
985 : 0 : }
986 : 0 : mMinimum = min;
987 : 0 : mMaximum = max;
988 : 0 : }
989 : :
990 : 0 : QStringList QgsMeshDatasetGroup::datasetGroupNamesDependentOn() const
991 : : {
992 : 0 : return QStringList();
993 : : }
994 : :
995 : 0 : QString QgsMeshDatasetGroup::description() const
996 : : {
997 : 0 : return QString();
998 : : }
999 : :
1000 : 0 : void QgsMeshDatasetGroup::setReferenceTime( const QDateTime &referenceTime )
1001 : : {
1002 : 0 : mReferenceTime = referenceTime;
1003 : 0 : }
1004 : :
1005 : 0 : bool QgsMeshDatasetGroup::checkValueCountPerDataset( int count ) const
1006 : 0 : {
1007 : 0 : for ( int i = 0; i < datasetCount(); ++i )
1008 : 0 : if ( dataset( i )->valuesCount() != count )
1009 : 0 : return false;
1010 : 0 : return true;
1011 : 0 : }
1012 : :
1013 : 0 : QgsMeshDatasetGroup::QgsMeshDatasetGroup( const QString &name, QgsMeshDatasetGroupMetadata::DataType dataType ): mName( name ), mDataType( dataType ) {}
1014 : :
1015 : 0 : QgsMeshDatasetGroup::~QgsMeshDatasetGroup() = default;
1016 : :
1017 : 0 : QgsMeshDatasetGroup::QgsMeshDatasetGroup( const QString &name ): mName( name ) {}
1018 : :
1019 : 0 : double QgsMeshDatasetGroup::minimum() const
1020 : : {
1021 : 0 : return mMinimum;
1022 : : }
1023 : :
1024 : 0 : double QgsMeshDatasetGroup::maximum() const
1025 : : {
1026 : 0 : return mMaximum;
1027 : : }
1028 : :
1029 : 0 : void QgsMeshDatasetGroup::setMinimumMaximum( double min, double max )
1030 : : {
1031 : 0 : mMinimum = min;
1032 : 0 : mMaximum = max;
1033 : 0 : }
1034 : :
1035 : 0 : QString QgsMeshDatasetGroup::name() const
1036 : : {
1037 : 0 : return mName;
1038 : : }
1039 : :
1040 : 0 : void QgsMeshDatasetGroup::setName( const QString &name )
1041 : : {
1042 : 0 : mName = name;
1043 : 0 : }
1044 : :
1045 : 0 : QgsMeshDatasetGroupMetadata::DataType QgsMeshDatasetGroup::dataType() const
1046 : : {
1047 : 0 : return mDataType;
1048 : : }
1049 : :
1050 : 0 : void QgsMeshDatasetGroup::setDataType( const QgsMeshDatasetGroupMetadata::DataType &type )
1051 : : {
1052 : 0 : mDataType = type;
1053 : 0 : }
1054 : :
1055 : 0 : void QgsMeshDatasetGroup::addExtraMetadata( QString key, QString value )
1056 : : {
1057 : 0 : mMetadata.insert( key, value );
1058 : 0 : }
1059 : :
1060 : 0 : QMap<QString, QString> QgsMeshDatasetGroup::extraMetadata() const
1061 : : {
1062 : 0 : return mMetadata;
1063 : : }
1064 : :
1065 : 0 : bool QgsMeshDatasetGroup::isScalar() const
1066 : : {
1067 : 0 : return mIsScalar;
1068 : : }
1069 : :
1070 : 0 : void QgsMeshDatasetGroup::setIsScalar( bool isScalar )
1071 : : {
1072 : 0 : mIsScalar = isScalar;
1073 : 0 : }
|