QGIS API Documentation 3.37.0-Master (fdefdf9c27f)
qgsmeshdataset.cpp
Go to the documentation of this file.
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 "qgsmeshdataprovider.h"
20#include "qgsrectangle.h"
21#include "qgis.h"
22
24 : mGroupIndex( group ), mDatasetIndex( dataset )
25{}
26
28{
29 return mGroupIndex;
30}
31
33{
34 return mDatasetIndex;
35}
36
38{
39 return ( group() > -1 ) && ( dataset() > -1 );
40}
41
43{
44 if ( isValid() && other.isValid() )
45 return other.group() == group() && other.dataset() == dataset();
46 else
47 return isValid() == other.isValid();
48}
49
51{
52 return !( operator==( other ) );
53}
54
56 : mX( x ), mY( y )
57{}
58
60 : mX( scalar )
61{}
62
64{
65 if ( std::isnan( mY ) )
66 {
67 return mX;
68 }
69 else if ( std::isnan( mX ) )
70 {
71 return std::numeric_limits<double>::quiet_NaN();
72 }
73 else
74 {
75 return std::sqrt( ( mX ) * ( mX ) + ( mY ) * ( mY ) );
76 }
77}
78
79void QgsMeshDatasetValue::set( double scalar )
80{
81 setX( scalar );
82}
83
85{
86 mX = x;
87}
88
90{
91 mY = y;
92}
93
95{
96 return mX;
97}
98
100{
101 return mY;
102}
103
105{
106 bool equal = std::isnan( mX ) == std::isnan( other.x() );
107 equal &= std::isnan( mY ) == std::isnan( other.y() );
108
109 if ( equal )
110 {
111 if ( std::isnan( mY ) )
112 {
113 equal &= qgsDoubleNear( other.x(), mX, 1E-8 );
114 }
115 else
116 {
117 equal &= qgsDoubleNear( other.x(), mX, 1E-8 );
118 equal &= qgsDoubleNear( other.y(), mY, 1E-8 );
119 }
120 }
121 return equal;
122}
123
125 const QString uri,
126 bool isScalar,
127 DataType dataType,
128 double minimum,
129 double maximum,
130 int maximumVerticalLevels,
131 const QDateTime &referenceTime,
132 bool isTemporal,
133 const QMap<QString, QString> &extraOptions )
134 : mName( name )
135 , mUri( uri )
136 , mIsScalar( isScalar )
137 , mDataType( dataType )
138 , mMinimumValue( minimum )
139 , mMaximumValue( maximum )
140 , mExtraOptions( extraOptions )
141 , mMaximumVerticalLevelsCount( maximumVerticalLevels )
142 , mReferenceTime( referenceTime )
143 , mIsTemporal( isTemporal )
144{
145}
146
147QMap<QString, QString> QgsMeshDatasetGroupMetadata::extraOptions() const
148{
149 return mExtraOptions;
150}
151
153{
154 return !mIsScalar;
155}
156
158{
159 return mIsScalar;
160}
161
163{
164 return mIsTemporal;
165}
166
168{
169 return mName;
170}
171
173{
174 return mDataType;
175}
176
178{
179 return mMinimumValue;
180}
181
183{
184 return mMaximumValue;
185}
186
188{
189 return mMaximumVerticalLevelsCount;
190}
191
193{
194 return mReferenceTime;
195}
196
198{
199 return mUri;
200}
201
203 double time,
204 bool isValid,
205 double minimum,
206 double maximum,
207 int maximumVerticalLevels )
208 : mTime( time )
209 , mIsValid( isValid )
210 , mMinimumValue( minimum )
211 , mMaximumValue( maximum )
212 , mMaximumVerticalLevelsCount( maximumVerticalLevels )
213{
214}
215
217{
218 return mTime;
219}
220
222{
223 return mIsValid;
224}
225
227{
228 return mMinimumValue;
229}
230
232{
233 return mMaximumValue;
234}
235
237{
238 return mMaximumVerticalLevelsCount;
239}
240
242 : mType( ActiveFlagInteger )
243{
244}
245
247 : mType( type ),
248 mSize( count )
249{
250}
251
253{
254 return mType;
255}
256
258{
259 return mSize;
260}
261
263{
264 return ( count() > 0 ) && ( mIsValid );
265}
266
268{
269 if ( !isValid() )
270 return QgsMeshDatasetValue();
271
272 Q_ASSERT( mType != ActiveFlagInteger );
273
274 if ( mType == ScalarDouble )
275 return QgsMeshDatasetValue( mDoubleBuffer[index] );
276
277 return QgsMeshDatasetValue(
278 mDoubleBuffer[2 * index],
279 mDoubleBuffer[2 * index + 1]
280 );
281}
282
283bool QgsMeshDataBlock::active( int index ) const
284{
285 if ( !isValid() )
286 return false;
287
288 Q_ASSERT( mType == ActiveFlagInteger );
289
290 if ( mIntegerBuffer.empty() )
291 return true;
292 else
293 return bool( mIntegerBuffer[index] );
294}
295
296void QgsMeshDataBlock::setActive( const QVector<int> &vals )
297{
298 Q_ASSERT( mType == ActiveFlagInteger );
299 Q_ASSERT( vals.size() == count() );
300
301 mIntegerBuffer = vals;
302 setValid( true );
303}
304
305QVector<int> QgsMeshDataBlock::active() const
306{
307 Q_ASSERT( mType == ActiveFlagInteger );
308 return mIntegerBuffer;
309}
310
311QVector<double> QgsMeshDataBlock::values() const
312{
313 Q_ASSERT( mType != ActiveFlagInteger );
314
315 return mDoubleBuffer;
316}
317
318void QgsMeshDataBlock::setValues( const QVector<double> &vals )
319{
320 Q_ASSERT( mType != ActiveFlagInteger );
321 Q_ASSERT( mType == ScalarDouble ? vals.size() == count() : vals.size() == 2 * count() );
322
323 mDoubleBuffer = vals;
324 setValid( true );
325}
326
328{
329 mIsValid = valid;
330}
331
333
335
336QgsMesh3DDataBlock::QgsMesh3DDataBlock( int count, bool isVector )
337 : mSize( count )
338 , mIsVector( isVector )
339{
340}
341
343{
344 return mIsValid;
345}
346
348{
349 return mIsVector;
350}
351
353{
354 return mSize;
355}
356
358{
359 if ( mFaceToVolumeIndex.empty() )
360 return -1;
361 return mFaceToVolumeIndex[0];
362}
363
365{
366 if ( mFaceToVolumeIndex.empty() || mVerticalLevelsCount.empty() )
367 return -1;
368 const int lastVolumeStartIndex = mFaceToVolumeIndex[mFaceToVolumeIndex.size() - 1];
369 const int volumesCountInLastRow = mVerticalLevelsCount[mVerticalLevelsCount.size() - 1];
370 return lastVolumeStartIndex + volumesCountInLastRow;
371}
372
374{
376}
377
379{
380 Q_ASSERT( isValid() );
381 return mVerticalLevelsCount;
382}
383
384void QgsMesh3DDataBlock::setFaceToVolumeIndex( const QVector<int> &faceToVolumeIndex )
385{
386 Q_ASSERT( faceToVolumeIndex.size() == count() );
387 mFaceToVolumeIndex = faceToVolumeIndex;
388}
389
390void QgsMesh3DDataBlock::setVerticalLevelsCount( const QVector<int> &verticalLevelsCount )
391{
392 Q_ASSERT( verticalLevelsCount.size() == count() );
393 mVerticalLevelsCount = verticalLevelsCount;
394}
395
397{
398 Q_ASSERT( isValid() );
399 return mVerticalLevels;
400}
401
402void QgsMesh3DDataBlock::setVerticalLevels( const QVector<double> &verticalLevels )
403{
404 Q_ASSERT( verticalLevels.size() == volumesCount() + count() );
405 mVerticalLevels = verticalLevels;
406}
407
409{
410 Q_ASSERT( isValid() );
411 return mFaceToVolumeIndex;
412}
413
414QVector<double> QgsMesh3DDataBlock::values() const
415{
416 Q_ASSERT( isValid() );
417 return mDoubleBuffer;
418}
419
421{
422 if ( !isValid() )
423 return QgsMeshDatasetValue();
424
425 if ( !mIsVector )
426 return QgsMeshDatasetValue( mDoubleBuffer[volumeIndex] );
427
428 return QgsMeshDatasetValue(
429 mDoubleBuffer[2 * volumeIndex],
430 mDoubleBuffer[2 * volumeIndex + 1]
431 );
432}
433
434void QgsMesh3DDataBlock::setValues( const QVector<double> &doubleBuffer )
435{
436 Q_ASSERT( doubleBuffer.size() == ( isVector() ? 2 * volumesCount() : volumesCount() ) );
437 mDoubleBuffer = doubleBuffer;
438}
439
441{
442 mIsValid = valid;
443}
444
446
447QgsMeshDatasetGroupTreeItem::QgsMeshDatasetGroupTreeItem( const QString &defaultName, const QString &sourceName,
448 bool isVector,
449 int index )
450 : mOriginalName( defaultName )
451 , mSourceName( sourceName )
452 , mIsVector( isVector )
453 , mDatasetGroupIndex( index )
454{
455}
456
458{
459 Q_UNUSED( context );
460 if ( itemElement.hasAttribute( QStringLiteral( "display-name" ) ) )
461 mUserName = itemElement.attribute( QStringLiteral( "display-name" ), mUserName );
462
463 if ( itemElement.hasAttribute( QStringLiteral( "original-name" ) ) )
464 mOriginalName = itemElement.attribute( QStringLiteral( "original-name" ), mOriginalName );
465
466 if ( itemElement.hasAttribute( QStringLiteral( "source-name" ) ) )
467 mSourceName = itemElement.attribute( QStringLiteral( "source-name" ), mSourceName );
468
469 if ( itemElement.hasAttribute( QStringLiteral( "is-vector" ) ) )
470 mIsVector = itemElement.attribute( QStringLiteral( "is-vector" ) ).toInt();
471
472 if ( itemElement.hasAttribute( QStringLiteral( "dataset-index" ) ) )
473 mDatasetGroupIndex = itemElement.attribute( QStringLiteral( "dataset-index" ) ).toInt();
474
475 if ( itemElement.hasAttribute( QStringLiteral( "is-enabled" ) ) )
476 mIsEnabled = itemElement.attribute( QStringLiteral( "is-enabled" ) ).toInt();
477
478 if ( itemElement.hasAttribute( QStringLiteral( "dataset-group-type" ) ) )
479 mDatasetGroupType = static_cast<QgsMeshDatasetGroup::Type>( itemElement.attribute( QStringLiteral( "dataset-group-type" ) ) .toInt() ) ;
480
481 if ( itemElement.hasAttribute( QStringLiteral( "description" ) ) )
482 mDescription = itemElement.attribute( QStringLiteral( "description" ) );
483
484 QDomElement dependOnElement = itemElement.firstChildElement( QStringLiteral( "dependent-on-item" ) );
485 while ( !dependOnElement.isNull() )
486 {
487 if ( dependOnElement.hasAttribute( QStringLiteral( "dataset-index" ) ) )
488 mDatasetGroupDependentOn.append( dependOnElement.attribute( QStringLiteral( "dataset-index" ) ).toInt() );
489 dependOnElement = dependOnElement.nextSiblingElement( QStringLiteral( "dependent-on-item" ) );
490 }
491
492 QDomElement dependencyElement = itemElement.firstChildElement( QStringLiteral( "dependency-item" ) );
493 while ( !dependencyElement.isNull() )
494 {
495 if ( dependencyElement.hasAttribute( QStringLiteral( "dataset-index" ) ) )
496 mDatasetGroupDependencies.append( dependencyElement.attribute( QStringLiteral( "dataset-index" ) ).toInt() );
497 dependencyElement = dependencyElement.nextSiblingElement( QStringLiteral( "dependency-item" ) );
498 }
499
500 QDomElement childElement = itemElement.firstChildElement( QStringLiteral( "mesh-dataset-group-tree-item" ) );
501 while ( !childElement.isNull() )
502 {
503 appendChild( new QgsMeshDatasetGroupTreeItem( childElement, context ) );
504 childElement = childElement.nextSiblingElement( QStringLiteral( "mesh-dataset-group-tree-item" ) );
505 }
506}
507
509{
510 // Remove from where this item is linked
511
512 freeAsDependency();
513 freeFromDependencies();
514 qDeleteAll( mChildren );
515 if ( mParent )
516 {
517 mParent->mDatasetGroupIndexToChild.remove( mDatasetGroupIndex );
518 mParent->mChildren.removeOne( this );
519 }
520}
521
523{
524 QgsMeshDatasetGroupTreeItem *other = new QgsMeshDatasetGroupTreeItem( mOriginalName, mSourceName, mIsVector, mDatasetGroupIndex );
525 *other = *this;
526
527 other->mChildren.clear();
528 other->mDatasetGroupIndexToChild.clear();
529 if ( !mChildren.empty() )
530 for ( int i = 0; i < mChildren.count(); ++i )
531 other->appendChild( mChildren.at( i )->clone() );
532
533 return other;
534}
535
537{
538 mChildren.append( item );
539 item->mParent = this;
540 mDatasetGroupIndexToChild[item->datasetGroupIndex()] = item;
541}
542
544{
545 delete item;
546}
547
549{
550 if ( row < mChildren.count() )
551 return mChildren.at( row );
552 else
553 return nullptr;
554}
555
557{
558 if ( mDatasetGroupIndexToChild.empty() )
559 return nullptr;
560
561 const QMap<int, QgsMeshDatasetGroupTreeItem *>::iterator it = mDatasetGroupIndexToChild.find( index );
562
563 if ( it != mDatasetGroupIndexToChild.end() )
564 return it.value();
565 else
566 {
567 QgsMeshDatasetGroupTreeItem *item = nullptr;
568 for ( int i = 0; i < mChildren.count(); ++i )
569 {
570 item = mChildren.at( i )->childFromDatasetGroupIndex( index );
571 if ( item )
572 break;
573 }
574 return item;
575 }
576}
577
579{
580 return mChildren.count();
581}
582
584{
585 int count = 0;
586 for ( int i = 0; i < mChildren.count(); ++i )
587 {
588 count++;
589 count += mChildren.at( i )->totalChildCount();
590 }
591 return count;
592}
593
595{
596 QList<int> indexesList;
597
598 for ( int i = 0; i < mChildren.count(); ++i )
599 {
600 if ( mChildren.at( i )->isEnabled() )
601 indexesList.append( mChildren.at( i )->datasetGroupIndex() );
602 indexesList.append( mChildren.at( i )->enabledDatasetGroupIndexes() );
603 }
604
605 return indexesList;
606}
607
609{
610 return mParent;
611}
612
614{
615 if ( mParent )
616 return mParent->mChildren.indexOf( const_cast<QgsMeshDatasetGroupTreeItem *>( this ) );
617
618 return 0;
619}
620
622{
623 if ( mUserName.isEmpty() )
624 return mOriginalName;
625 else
626 return mUserName;
627}
628
630{
631 return mIsVector;
632}
633
635{
636 return mDatasetGroupIndex;
637}
638
640{
641 return mIsEnabled;
642}
643
645{
646 mIsEnabled = enabled;
647}
648
650{
651 return mOriginalName;
652}
653
655{
656 return mDatasetGroupType;
657}
658
660{
661 return mDescription;
662}
663
665{
666 if ( datasetGroup )
667 {
668 mDescription = datasetGroup->description();
669 mDatasetGroupType = datasetGroup->type();
670 const QStringList &datasetGroupNames = datasetGroup->datasetGroupNamesDependentOn();
671 for ( const QString &varName : datasetGroupNames )
672 {
673 QgsMeshDatasetGroupTreeItem *varItem = searchItemBySourceName( varName );
674 if ( varItem )
675 {
676 varItem->mDatasetGroupDependencies.append( this->datasetGroupIndex() );
677 mDatasetGroupDependentOn.append( varItem->datasetGroupIndex() );
678 }
679 }
680 }
681}
682
684{
685 mDatasetGroupType = QgsMeshDatasetGroup::Persistent;
686 mDatasetGroupDependentOn.clear();
687 mDescription = uri;
688}
689
690QDomElement QgsMeshDatasetGroupTreeItem::writeXml( QDomDocument &doc, const QgsReadWriteContext &context )
691{
692 Q_UNUSED( context );
693
694 QDomElement itemElement = doc.createElement( QStringLiteral( "mesh-dataset-group-tree-item" ) );
695 itemElement.setAttribute( QStringLiteral( "display-name" ), mUserName );
696 itemElement.setAttribute( QStringLiteral( "source-name" ), mSourceName );
697 itemElement.setAttribute( QStringLiteral( "original-name" ), mOriginalName );
698 itemElement.setAttribute( QStringLiteral( "is-vector" ), mIsVector ? true : false );
699 itemElement.setAttribute( QStringLiteral( "dataset-index" ), mDatasetGroupIndex );
700 itemElement.setAttribute( QStringLiteral( "is-enabled" ), mIsEnabled ? true : false );
701 itemElement.setAttribute( QStringLiteral( "dataset-group-type" ), mDatasetGroupType );
702 itemElement.setAttribute( QStringLiteral( "description" ), mDescription );
703
704 for ( const int index : mDatasetGroupDependentOn )
705 {
706 QDomElement dependOnElement = doc.createElement( QStringLiteral( "dependent-on-item" ) );
707 dependOnElement.setAttribute( QStringLiteral( "dataset-index" ), index );
708 itemElement.appendChild( dependOnElement );
709 }
710
711 for ( const int index : mDatasetGroupDependencies )
712 {
713 QDomElement dependencyElement = doc.createElement( QStringLiteral( "dependency-item" ) );
714 dependencyElement.setAttribute( QStringLiteral( "dataset-index" ), index );
715 itemElement.appendChild( dependencyElement );
716 }
717
718 for ( int i = 0; i < mChildren.count(); ++i )
719 itemElement.appendChild( mChildren.at( i )->writeXml( doc, context ) );
720
721 return itemElement;
722}
723
725{
726 QList<int> dependencies;
727 QgsMeshDatasetGroupTreeItem *root = rootItem();
728 for ( const int index : mDatasetGroupDependencies )
729 {
730 if ( !dependencies.contains( index ) )
731 dependencies.append( index );
733 if ( item )
734 dependencies.append( item->groupIndexDependencies() );
735 }
736
737 for ( int i = 0; i < childCount(); ++i )
738 {
739 dependencies.append( child( i )->groupIndexDependencies() );
740 }
741
742 return dependencies;
743}
744
745QgsMeshDatasetGroupTreeItem *QgsMeshDatasetGroupTreeItem::searchItemBySourceName( const QString &sourceName ) const
746{
747 QgsMeshDatasetGroupTreeItem *baseItem = rootItem();
748
749 QList<QgsMeshDatasetGroupTreeItem *> itemToCheck;
750 itemToCheck.append( baseItem );
751 while ( baseItem && baseItem->providerName() != sourceName && !itemToCheck.isEmpty() )
752 {
753 for ( int i = 0; i < baseItem->childCount(); ++i )
754 itemToCheck.append( baseItem->child( i ) );
755 itemToCheck.removeOne( baseItem );
756 if ( !itemToCheck.empty() )
757 baseItem = itemToCheck.first();
758 else
759 baseItem = nullptr;
760 }
761
762 return baseItem;
763}
764
765QgsMeshDatasetGroupTreeItem *QgsMeshDatasetGroupTreeItem::rootItem() const
766{
767 const QgsMeshDatasetGroupTreeItem *baseItem = this;
768 while ( baseItem->parentItem() != nullptr )
769 baseItem = baseItem->parentItem();
770
771 return const_cast<QgsMeshDatasetGroupTreeItem *>( baseItem );
772}
773
774void QgsMeshDatasetGroupTreeItem::freeAsDependency()
775{
776 QgsMeshDatasetGroupTreeItem *root = rootItem();
777 for ( const int index : mDatasetGroupDependentOn )
778 {
780 if ( item )
781 item->mDatasetGroupDependencies.removeOne( this->datasetGroupIndex() );
782 }
783}
784
785void QgsMeshDatasetGroupTreeItem::freeFromDependencies()
786{
787 QgsMeshDatasetGroupTreeItem *root = rootItem();
788 for ( const int index : mDatasetGroupDependencies )
789 {
791 if ( item )
792 item->mDatasetGroupDependentOn.removeOne( this->datasetGroupIndex() );
793 }
794}
795
797{
798 return mSourceName;
799}
800
801void QgsMeshDatasetGroupTreeItem::setName( const QString &name )
802{
803 mUserName = name;
804}
805
806
808{
809 if ( valueIndex >= 0 && valueIndex < values.count() )
810 return values[valueIndex];
811 else
812 return QgsMeshDatasetValue();
813}
814
815QgsMeshDataBlock QgsMeshMemoryDataset::datasetValues( bool isScalar, int valueIndex, int count ) const
816{
818 QVector<double> buf( isScalar ? count : 2 * count );
819 for ( int i = 0; i < count; ++i )
820 {
821 const int idx = valueIndex + i;
822 if ( ( idx < 0 ) || ( idx >= values.size() ) )
823 return ret;
824
825 const QgsMeshDatasetValue val = values[ valueIndex + i ];
826 if ( isScalar )
827 buf[i] = val.x();
828 else
829 {
830 buf[2 * i] = val.x();
831 buf[2 * i + 1] = val.y();
832 }
833 }
834 ret.setValues( buf );
835 return ret;
836}
837
839{
841 if ( active.isEmpty() ||
842 ( faceIndex < 0 ) ||
843 ( faceIndex + count > active.size() )
844 )
845 ret.setValid( true );
846 else
847 ret.setActive( active );
848 return ret;
849}
850
852{
854}
855
857{
858 double min = std::numeric_limits<double>::max();
859 double max = std::numeric_limits<double>::lowest();
860
861 if ( !valid )
862 return;
863
864
865 bool firstIteration = true;
866 for ( int i = 0; i < values.size(); ++i )
867 {
868 const double v = values[i].scalar();
869
870 if ( std::isnan( v ) )
871 continue;
872 if ( firstIteration )
873 {
874 firstIteration = false;
875 min = v;
876 max = v;
877 }
878 else
879 {
880 if ( v < min )
881 min = v;
882 if ( v > max )
883 max = v;
884 }
885 }
886
887 minimum = min;
888 maximum = max;
889}
890
891bool QgsMeshMemoryDataset::isActive( int faceIndex ) const
892{
893 if ( active.isEmpty() || faceIndex >= active.count() )
894 return true;
895 else
896 return active.at( faceIndex );
897}
898
900{
901 return values.count();
902}
903
905 : QgsMeshDatasetGroup( name, dataType )
906{
907}
908
910 : QgsMeshDatasetGroup( name )
911{
912}
913
915{
917 name(),
918 QString(),
919 isScalar(),
920 dataType(),
921 minimum(),
922 maximum(),
923 0,
924 mReferenceTime,
925 datasetCount() > 1,
927 );
928}
929
931{
932 return memoryDatasets.size();
933}
934
936{
937 if ( datasetIndex >= 0 && datasetIndex < memoryDatasets.count() )
938 return memoryDatasets[datasetIndex]->metadata();
939 else
940 return QgsMeshDatasetMetadata();
941}
942
944{
945 return memoryDatasets[index].get();
946}
947
948void QgsMeshMemoryDatasetGroup::addDataset( std::shared_ptr<QgsMeshMemoryDataset> dataset )
949{
950 dataset->calculateMinMax();
951 memoryDatasets.push_back( dataset );
952}
953
955{
956 memoryDatasets.clear();
957}
958
960{
962}
963
964std::shared_ptr<const QgsMeshMemoryDataset> QgsMeshMemoryDatasetGroup::constDataset( int index ) const
965{
966 return memoryDatasets[index];
967}
968
969QDomElement QgsMeshMemoryDatasetGroup::writeXml( QDomDocument &doc, const QgsReadWriteContext &context ) const
970{
971 Q_UNUSED( doc )
972 Q_UNUSED( context )
973 return QDomElement();
974}
975
977{
978 updateStatistic();
979}
980
982{
983 mIsStatisticObsolete = true;
984}
985
987{
988 return QStringList();
989}
990
992{
993 return QString();
994}
995
996void QgsMeshDatasetGroup::setReferenceTime( const QDateTime &referenceTime )
997{
998 mReferenceTime = referenceTime;
999}
1000
1001void QgsMeshDatasetGroup::updateStatistic() const
1002{
1003 if ( !mIsStatisticObsolete )
1004 return;
1005
1006 double min = std::numeric_limits<double>::max();
1007 double max = std::numeric_limits<double>::lowest();
1008
1009 const int count = datasetCount();
1010 for ( int i = 0; i < count; ++i )
1011 {
1012 const QgsMeshDatasetMetadata &meta = datasetMetadata( i );
1013 min = std::min( min, meta.minimum() );
1014 max = std::max( max, meta.maximum() );
1015 }
1016 mMinimum = min;
1017 mMaximum = max;
1018
1019 mIsStatisticObsolete = false;
1020}
1021
1023{
1024 for ( int i = 0; i < datasetCount(); ++i )
1025 if ( dataset( i )->valuesCount() != count )
1026 return false;
1027 return true;
1028}
1029
1031 : mName( name ), mDataType( dataType ) {}
1032
1034
1035QgsMeshDatasetGroup::QgsMeshDatasetGroup( const QString &name ): mName( name ) {}
1036
1038{
1039 updateStatistic();
1040 return mMinimum;
1041}
1042
1044{
1045 updateStatistic();
1046 return mMaximum;
1047}
1048
1049void QgsMeshDatasetGroup::setMinimumMaximum( double min, double max ) const
1050{
1051 mMinimum = min;
1052 mMaximum = max;
1053}
1054
1056{
1057 return mName;
1058}
1059
1060void QgsMeshDatasetGroup::setName( const QString &name )
1061{
1062 mName = name;
1063}
1064
1066{
1067 return mDataType;
1068}
1069
1071{
1072 mDataType = type;
1073}
1074
1075void QgsMeshDatasetGroup::addExtraMetadata( QString key, QString value )
1076{
1077 mMetadata.insert( key, value );
1078}
1079
1080QMap<QString, QString> QgsMeshDatasetGroup::extraMetadata() const
1081{
1082 return mMetadata;
1083}
1084
1086{
1087 return mIsScalar;
1088}
1089
1091{
1093}
1094
1095
1097 : mMesh( mesh )
1098{}
1099
1101{
1102 if ( mMesh && valueIndex >= 0 && valueIndex < mMesh->vertexCount() )
1103 return mMesh->vertex( valueIndex ).z();
1104
1105 return std::numeric_limits<double>::quiet_NaN();
1106}
1107
1108QgsMeshDataBlock QgsMeshVerticesElevationDataset::datasetValues( bool isScalar, int valueIndex, int count ) const
1109{
1110 if ( !isScalar || !mMesh )
1111 return QgsMeshDataBlock();
1112
1114 int effectiveValueCount = std::min( count, ( mMesh->vertexCount() - valueIndex ) );
1115 QVector<double> values( effectiveValueCount );
1116 for ( int i = valueIndex; i < effectiveValueCount; ++i )
1117 values[i] = mMesh->vertex( i - valueIndex ).z();
1118 block.setValues( values );
1119 block.setValid( true );
1120 return block;
1121}
1122
1124{
1125 QgsMeshDataBlock block( QgsMeshDataBlock::ActiveFlagInteger, std::min( count, ( mMesh->faceCount() - faceIndex ) ) );
1126 block.setValid( true );
1127 return block;
1128}
1129
1131{
1132 double min = std::numeric_limits<double>::max();
1133 double max = -std::numeric_limits<double>::max();
1134 if ( mMesh )
1135 for ( int i = 0; i < mMesh->vertexCount(); ++i )
1136 {
1137 const double z = mMesh->vertex( i ).z();
1138 if ( min > z )
1139 min = z;
1140 if ( max < z )
1141 max = z;
1142 }
1143
1144 return QgsMeshDatasetMetadata( 0, true, min, max, 0 );
1145}
1146
1148{
1149 if ( mMesh )
1150 return mMesh->vertexCount();
1151
1152 return 0;
1153}
1154
1156 : mDataset( new QgsMeshVerticesElevationDataset( mesh ) )
1157{
1158 mName = name ;
1159 initialize();
1160}
1161
1163{
1165}
1166
1168{
1169 if ( datasetIndex != 0 )
1170 return QgsMeshDatasetMetadata();
1171
1172 return mDataset->metadata();
1173}
1174
1176
1178{
1179 if ( index != 0 )
1180 return nullptr;
1181
1182 return mDataset.get();
1183}
1184
1186{
1187 return QgsMeshDatasetGroup::Memory; //maybe create a new type ?
1188}
1189
void setFaceToVolumeIndex(const QVector< int > &faceToVolumeIndex)
Sets the indexing between faces and volumes.
QgsMeshDatasetValue value(int volumeIndex) const
Returns the value at volume centers.
QVector< double > values() const
Returns the values at volume centers.
void setVerticalLevels(const QVector< double > &verticalLevels)
Sets the vertical levels height.
void setValues(const QVector< double > &doubleBuffer)
Sets the values at volume centers.
QgsMesh3DDataBlock()
Constructs an invalid block.
bool isVector() const
Whether we store vector values.
int count() const
Number of 2d faces for which the volume data is stored in the block.
int volumesCount() const
Returns number of volumes stored in the buffer.
int firstVolumeIndex() const
Index of the first volume stored in the buffer (absolute)
int lastVolumeIndex() const
Index of the last volume stored in the buffer (absolute)
QVector< int > verticalLevelsCount() const
Returns number of vertical level above 2d faces.
bool isValid() const
Whether the block is valid.
void setVerticalLevelsCount(const QVector< int > &verticalLevelsCount)
Sets the vertical level counts.
void setValid(bool valid)
Sets block validity.
QVector< int > faceToVolumeIndex() const
Returns the indexing between faces and volumes.
QVector< double > verticalLevels() const
Returns the vertical levels height.
QgsMeshDataBlock is a block of integers/doubles that can be used to retrieve: active flags (e....
QgsMeshDatasetValue value(int index) const
Returns a value represented by the index For active flag the behavior is undefined.
QVector< double > values() const
Returns buffer to the array with values For vector it is pairs (x1, y1, x2, y2, .....
void setActive(const QVector< int > &vals)
Sets active flag values.
QVector< int > active() const
Returns active flag array.
bool isValid() const
Whether the block is valid.
QgsMeshDataBlock()
Constructs an invalid block.
DataType type() const
Type of data stored in the block.
DataType
Type of data stored in the block.
@ ScalarDouble
Scalar double values.
@ Vector2DDouble
Vector double pairs (x1, y1, x2, y2, ... )
@ ActiveFlagInteger
Integer boolean flag whether face is active.
int count() const
Number of items stored in the block.
void setValues(const QVector< double > &vals)
Sets values.
void setValid(bool valid)
Sets block validity.
QgsMeshDatasetGroupMetadata is a collection of dataset group metadata such as whether the data is vec...
bool isTemporal() const
Returns whether the dataset group is temporal (contains time-related dataset)
QMap< QString, QString > extraOptions() const
Returns extra metadata options, for example description.
bool isVector() const
Returns whether dataset group has vector data.
QString name() const
Returns name of the dataset group.
bool isScalar() const
Returns whether dataset group has scalar data.
int maximumVerticalLevelsCount() const
Returns maximum number of vertical levels for 3d stacked meshes.
QgsMeshDatasetGroupMetadata()=default
Constructs an empty metadata object.
DataType dataType() const
Returns whether dataset group data is defined on vertices or faces or volumes.
QDateTime referenceTime() const
Returns the reference time.
double minimum() const
Returns minimum scalar value/vector magnitude present for whole dataset group.
double maximum() const
Returns maximum scalar value/vector magnitude present for whole dataset group.
DataType
Location of where data is specified for datasets in the dataset group.
QString uri() const
Returns the uri of the source.
Tree item for display of the mesh dataset groups.
void setName(const QString &name)
Overrides the default name with the name to display.
QgsMeshDatasetGroupTreeItem * clone() const
Clones the item.
QList< int > groupIndexDependencies() const
Returns a list of group index corresponding to dataset group that depends on the dataset group repres...
QDomElement writeXml(QDomDocument &doc, const QgsReadWriteContext &context)
Writes the item and its children in a DOM document.
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()
Destructor, destructs also the children.
QgsMeshDatasetGroupTreeItem * parentItem() const
Returns the parent item, nullptr if it is root item.
QgsMeshDatasetGroupTreeItem * childFromDatasetGroupIndex(int index)
Returns the child with dataset group index Searches as depper as needed on the child hierarchy.
void removeChild(QgsMeshDatasetGroupTreeItem *item)
Removes and destroy a item child if exists.
void setIsEnabled(bool isEnabled)
Sets whether the item is enabled, that is if it is displayed in view.
int totalChildCount() const
Returns the total count of children, that is included deeper children and disabled items.
void setDatasetGroup(QgsMeshDatasetGroup *datasetGroup)
Set parameters of the item in accordance with the dataset group.
QList< int > enabledDatasetGroupIndexes() const
Returns a list of enabled dataset group indexes, included deeper children.
QgsMeshDatasetGroupTreeItem()
Constructor for an empty dataset group tree item.
QString providerName() const
Returns the name used by the provider to identify the dataset.
void appendChild(QgsMeshDatasetGroupTreeItem *item)
Appends a child item.
QgsMeshDatasetGroupTreeItem * child(int row) const
Returns a child.
QString description() const
Returns description about the dataset group (URI, formula,...)
int row() const
Returns the position of the item in the parent.
QString name() const
Returns the name of the item This name is the default name if the name has not been overridden (.
QgsMeshDatasetGroup::Type datasetGroupType() const
Abstract class that represents a dataset group.
bool isScalar() const
Returns whether the group contain scalar values.
void addExtraMetadata(QString key, QString value)
Adds extra metadata to the group.
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.
void setMinimumMaximum(double min, double max) const
Overrides the minimum and the maximum value of the whole dataset group.
void setStatisticObsolete() const
Sets statistic obsolete, that means statistic will be recalculated when requested.
void setIsScalar(bool isScalar)
Sets whether the group contain scalar values.
QgsMeshDatasetGroup()=default
Default constructor.
void setDataType(const QgsMeshDatasetGroupMetadata::DataType &dataType)
Sets the data type of the dataset group.
QString name() const
Returns the name of the dataset group.
QgsMeshDatasetGroupMetadata::DataType dataType() const
Returns the data type of the dataset group.
virtual ~QgsMeshDatasetGroup()
virtual QStringList datasetGroupNamesDependentOn() const
Returns the dataset group variable name which this dataset group depends on.
virtual QString description() const
Returns some information about the dataset group.
QMap< QString, QString > mMetadata
Type
Type of the dataset group.
@ Memory
Dataset group store in a file.
@ Persistent
Generic type used for non typed dataset group.
void setReferenceTime(const QDateTime &referenceTime)
Sets the reference time of the dataset group.
double maximum() const
Returns the maximum value of the whole dataset group.
virtual QgsMeshDatasetGroup::Type type() const =0
Returns the type of dataset group.
QgsMeshDatasetGroupMetadata groupMetadata() const
Returns the metadata of the dataset group.
double minimum() const
Returns the minimum value of the whole dataset group.
QMap< QString, QString > extraMetadata() const
Returns all the extra metadata of the group.
void setName(const QString &name)
Sets the name of the dataset group.
virtual int datasetCount() const =0
Returns the count of datasets in the group.
void calculateStatistic() const
Calculates the statistics (minimum and maximum)
virtual QgsMeshDataset * dataset(int index) const =0
Returns the dataset with index.
QgsMeshDatasetGroupMetadata::DataType mDataType
QgsMeshDatasetIndex is index that identifies the dataset group (e.g.
QgsMeshDatasetIndex(int group=-1, int dataset=-1)
Creates an index. -1 represents invalid group/dataset.
bool operator==(QgsMeshDatasetIndex other) const
Equality operator.
bool operator!=(QgsMeshDatasetIndex other) const
Inequality operator.
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 maximum() const
Returns maximum scalar value/vector magnitude present for the dataset.
int maximumVerticalLevelsCount() const
Returns maximum number of vertical levels for 3d stacked meshes.
double minimum() const
Returns minimum scalar value/vector magnitude present for the dataset.
double time() const
Returns the time value for this dataset.
bool isValid() const
Returns whether dataset is valid.
QgsMeshDatasetMetadata()=default
Constructs an empty metadata object.
QgsMeshDatasetValue represents single dataset value.
void setY(double y)
Sets Y value.
void set(double scalar)
Sets scalar value.
double y() const
Returns y value.
bool operator==(QgsMeshDatasetValue other) const
QgsMeshDatasetValue()=default
Default Ctor, initialize to NaN.
double scalar() const
Returns magnitude of vector for vector data or scalar value for scalar data.
double x() const
Returns x value.
void setX(double x)
Sets X value.
Abstract class that represents a dataset.
virtual int valuesCount() const =0
Returns the values count.
void addDataset(std::shared_ptr< QgsMeshMemoryDataset > dataset)
Adds a memory dataset to the group.
QgsMeshMemoryDatasetGroup()=default
Constructor.
QgsMeshDatasetMetadata datasetMetadata(int datasetIndex) const override
Returns the metadata of the dataset with index datasetIndex.
void clearDatasets()
Removes all the datasets from the group.
void initialize() override
Initialize the dataset group.
std::shared_ptr< const QgsMeshMemoryDataset > constDataset(int index) const
Returns the dataset with index.
QVector< std::shared_ptr< QgsMeshMemoryDataset > > memoryDatasets
Contains all the memory datasets.
QDomElement writeXml(QDomDocument &doc, const QgsReadWriteContext &context) const override
Returns a invalid DOM element.
QgsMeshDataset * dataset(int index) const override
Returns the dataset with index.
int datasetCount() const override
Returns the count of datasets in the group.
QgsMeshDataBlock areFacesActive(int faceIndex, int count) const override
Returns whether faces are active.
bool isActive(int faceIndex) const override
Returns whether the face is active.
QVector< QgsMeshDatasetValue > values
QgsMeshDatasetValue datasetValue(int valueIndex) const override
Returns the value with index valueIndex.
QgsMeshDatasetMetadata metadata() const override
Returns the metadata of the dataset.
QgsMeshDataBlock datasetValues(bool isScalar, int valueIndex, int count) const override
Returns count values from valueIndex.
int valuesCount() const override
Returns the values count.
QVector< int > active
void calculateMinMax()
Calculates the minimum and the maximum of this group.
int datasetCount() const override
Returns the count of datasets in the group.
QgsMeshVerticesElevationDatasetGroup(QString name, QgsMesh *mesh)
Constructor with a name and linked to mesh.
void initialize() override
Initialize the dataset group.
QgsMeshDatasetGroup::Type type() const override
Returns the type of dataset group.
QgsMeshDataset * dataset(int index) const override
Returns the dataset with index.
QgsMeshDatasetMetadata datasetMetadata(int datasetIndex) const override
Returns the metadata of the dataset with index datasetIndex.
Class that represents a dataset with elevation value of the vertices of a existing mesh that can be e...
QgsMeshDatasetValue datasetValue(int valueIndex) const override
Returns the value with index valueIndex.
int valuesCount() const override
Returns the values count.
QgsMeshDataBlock areFacesActive(int faceIndex, int count) const override
Returns whether faces are active.
QgsMeshDatasetMetadata metadata() const override
Returns the metadata of the dataset.
QgsMeshDataBlock datasetValues(bool isScalar, int valueIndex, int count) const override
Returns count values from valueIndex.
QgsMeshVerticesElevationDataset(QgsMesh *mesh)
Constructor.
double z
Definition: qgspoint.h:54
The class is used as a container of context for various read/write operations on other objects.
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference)
Definition: qgis.h:5207
Mesh - vertices, edges and faces.
int vertexCount() const
Returns number of vertices.
int faceCount() const
Returns number of faces.
QgsMeshVertex vertex(int index) const
Returns a vertex at the index.