QGIS API Documentation 4.0.0-Norrköping (1ddcee3d0e4)
Loading...
Searching...
No Matches
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
20#include "qgis.h"
21#include "qgsmeshdataprovider.h"
22#include "qgsrectangle.h"
23
24#include <QRegularExpression>
25#include <QRegularExpressionMatch>
26#include <QString>
27
28using namespace Qt::StringLiterals;
29
31 : mGroupIndex( group )
32 , mDatasetIndex( dataset )
33{}
34
36{
37 return mGroupIndex;
38}
39
41{
42 return mDatasetIndex;
43}
44
46{
47 return ( group() > -1 ) && ( dataset() > -1 );
48}
49
51{
52 if ( isValid() && other.isValid() )
53 return other.group() == group() && other.dataset() == dataset();
54 else
55 return isValid() == other.isValid();
56}
57
59{
60 return !( operator==( other ) );
61}
62
64 : mX( x )
65 , mY( y )
66{}
67
71
73{
74 if ( std::isnan( mY ) )
75 {
76 return mX;
77 }
78 else if ( std::isnan( mX ) )
79 {
80 return std::numeric_limits<double>::quiet_NaN();
81 }
82 else
83 {
84 return std::sqrt( ( mX ) * ( mX ) + ( mY ) * ( mY ) );
85 }
86}
87
89{
90 setX( scalar );
91}
92
94{
95 mX = x;
96}
97
99{
100 mY = y;
101}
102
104{
105 return mX;
106}
107
109{
110 return mY;
111}
112
114{
115 bool equal = std::isnan( mX ) == std::isnan( other.x() );
116 equal &= std::isnan( mY ) == std::isnan( other.y() );
117
118 if ( equal )
119 {
120 if ( std::isnan( mY ) )
121 {
122 equal &= qgsDoubleNear( other.x(), mX, 1E-8 );
123 }
124 else
125 {
126 equal &= qgsDoubleNear( other.x(), mX, 1E-8 );
127 equal &= qgsDoubleNear( other.y(), mY, 1E-8 );
128 }
129 }
130 return equal;
131}
132
134 const QString &name,
135 const QString uri,
136 bool isScalar,
138 double minimum,
139 double maximum,
140 int maximumVerticalLevels,
141 const QDateTime &referenceTime,
142 bool isTemporal,
143 const QMap<QString, QString> &extraOptions
144)
145 : mName( name )
146 , mUri( uri )
147 , mIsScalar( isScalar )
148 , mDataType( dataType )
149 , mMinimumValue( minimum )
150 , mMaximumValue( maximum )
151 , mExtraOptions( extraOptions )
152 , mMaximumVerticalLevelsCount( maximumVerticalLevels )
153 , mReferenceTime( referenceTime )
154 , mIsTemporal( isTemporal )
155{
156 // this relies on the naming convention used by MDAL's NetCDF driver: <group name>_<dimension_name>:<dimension_value>
157 // If future MDAL releases expose quantities via a standard API then we can safely remove this and port to the new API.
158 const thread_local QRegularExpression parentQuantityRegex( u"^(.*):.*?$"_s );
159 const QRegularExpressionMatch parentQuantityMatch = parentQuantityRegex.match( mName );
160 if ( parentQuantityMatch.hasMatch() )
161 {
162 mParentQuantityName = parentQuantityMatch.captured( 1 );
163 }
164}
165
166QMap<QString, QString> QgsMeshDatasetGroupMetadata::extraOptions() const
167{
168 return mExtraOptions;
169}
170
172{
173 return !mIsScalar;
174}
175
177{
178 return mIsScalar;
179}
180
182{
183 return mIsTemporal;
184}
185
187{
188 return mName;
189}
190
192{
193 return mParentQuantityName;
194}
195
200
202{
203 return mMinimumValue;
204}
205
207{
208 return mMaximumValue;
209}
210
212{
213 return mMaximumVerticalLevelsCount;
214}
215
217{
218 return mReferenceTime;
219}
220
222{
223 return mUri;
224}
225
226QgsMeshDatasetMetadata::QgsMeshDatasetMetadata( double time, bool isValid, double minimum, double maximum, int maximumVerticalLevels )
227 : mTime( time )
228 , mIsValid( isValid )
229 , mMinimumValue( minimum )
230 , mMaximumValue( maximum )
231 , mMaximumVerticalLevelsCount( maximumVerticalLevels )
232{}
233
235{
236 return mTime;
237}
238
240{
241 return mIsValid;
242}
243
245{
246 return mMinimumValue;
247}
248
250{
251 return mMaximumValue;
252}
253
255{
256 return mMaximumVerticalLevelsCount;
257}
258
262
267
269{
270 return mType;
271}
272
274{
275 return mSize;
276}
277
279{
280 return ( count() > 0 ) && ( mIsValid );
281}
282
284{
285 if ( !isValid() )
286 return QgsMeshDatasetValue();
287
288 Q_ASSERT( mType != ActiveFlagInteger );
289
290 if ( mType == ScalarDouble )
291 return QgsMeshDatasetValue( mDoubleBuffer[index] );
292
293 return QgsMeshDatasetValue( mDoubleBuffer[2 * index], mDoubleBuffer[2 * index + 1] );
294}
295
296bool QgsMeshDataBlock::active( int index ) const
297{
298 if ( !isValid() )
299 return false;
300
301 Q_ASSERT( mType == ActiveFlagInteger );
302
303 if ( mIntegerBuffer.empty() )
304 return true;
305 else
306 return bool( mIntegerBuffer[index] );
307}
308
309void QgsMeshDataBlock::setActive( const QVector<int> &vals )
310{
311 Q_ASSERT( mType == ActiveFlagInteger );
312 Q_ASSERT( vals.size() == count() );
313
314 mIntegerBuffer = vals;
315 setValid( true );
316}
317
318QVector<int> QgsMeshDataBlock::active() const
319{
320 Q_ASSERT( mType == ActiveFlagInteger );
321 return mIntegerBuffer;
322}
323
324QVector<double> QgsMeshDataBlock::values() const
325{
326 Q_ASSERT( mType != ActiveFlagInteger );
327
328 return mDoubleBuffer;
329}
330
331void QgsMeshDataBlock::setValues( const QVector<double> &vals )
332{
333 Q_ASSERT( mType != ActiveFlagInteger );
334 Q_ASSERT( mType == ScalarDouble ? vals.size() == count() : vals.size() == 2 * count() );
335
336 mDoubleBuffer = vals;
337 setValid( true );
338}
339
341{
342 mIsValid = valid;
343}
344
346
349
351 : mSize( other.mSize )
352 , mIsValid( other.mIsValid )
353 , mIsVector( other.mIsVector )
354 , mVerticalLevelsCount( other.mVerticalLevelsCount )
355 , mVerticalLevels( other.mVerticalLevels )
356 , mFaceToVolumeIndex( other.mFaceToVolumeIndex )
357 , mDoubleBuffer( other.mDoubleBuffer )
358{}
359
361 : mSize( other.mSize )
362 , mIsValid( other.mIsValid )
363 , mIsVector( other.mIsVector )
364 , mVerticalLevelsCount( std::move( other.mVerticalLevelsCount ) )
365 , mVerticalLevels( std::move( other.mVerticalLevels ) )
366 , mFaceToVolumeIndex( std::move( other.mFaceToVolumeIndex ) )
367 , mDoubleBuffer( std::move( other.mDoubleBuffer ) )
368{}
369
371{
372 if ( &other == this )
373 return *this;
374
375 mSize = other.mSize;
376 mIsValid = other.mIsValid;
377 mIsVector = other.mIsVector;
378 mVerticalLevelsCount = other.mVerticalLevelsCount;
379 mVerticalLevels = other.mVerticalLevels;
380 mFaceToVolumeIndex = other.mFaceToVolumeIndex;
381 mDoubleBuffer = other.mDoubleBuffer;
382 return *this;
383}
384
386{
387 if ( &other == this )
388 return *this;
389
390 mSize = other.mSize;
391 mIsValid = other.mIsValid;
392 mIsVector = other.mIsVector;
393 mVerticalLevelsCount = std::move( other.mVerticalLevelsCount );
394 mVerticalLevels = std::move( other.mVerticalLevels );
395 mFaceToVolumeIndex = std::move( other.mFaceToVolumeIndex );
396 mDoubleBuffer = std::move( other.mDoubleBuffer );
397 return *this;
398}
399
401 : mSize( count )
402 , mIsVector( isVector )
403{}
404
406{
407 return mIsValid;
408}
409
411{
412 return mIsVector;
413}
414
416{
417 return mSize;
418}
419
421{
422 if ( mFaceToVolumeIndex.empty() )
423 return -1;
424 return mFaceToVolumeIndex[0];
425}
426
428{
429 if ( mFaceToVolumeIndex.empty() || mVerticalLevelsCount.empty() )
430 return -1;
431 const int lastVolumeStartIndex = mFaceToVolumeIndex[mFaceToVolumeIndex.size() - 1];
432 const int volumesCountInLastRow = mVerticalLevelsCount[mVerticalLevelsCount.size() - 1];
433 return lastVolumeStartIndex + volumesCountInLastRow;
434}
435
440
442{
443 Q_ASSERT( isValid() );
444 return mVerticalLevelsCount;
445}
446
448{
449 Q_ASSERT( faceToVolumeIndex.size() == count() );
450 mFaceToVolumeIndex = faceToVolumeIndex;
451}
452
454{
455 Q_ASSERT( verticalLevelsCount.size() == count() );
456 mVerticalLevelsCount = verticalLevelsCount;
457}
458
460{
461 Q_ASSERT( isValid() );
462 return mVerticalLevels;
463}
464
466{
467 Q_ASSERT( verticalLevels.size() == volumesCount() + count() );
468 mVerticalLevels = verticalLevels;
469}
470
472{
473 Q_ASSERT( isValid() );
474 return mFaceToVolumeIndex;
475}
476
477QVector<double> QgsMesh3DDataBlock::values() const
478{
479 Q_ASSERT( isValid() );
480 return mDoubleBuffer;
481}
482
484{
485 if ( !isValid() )
486 return QgsMeshDatasetValue();
487
488 if ( !mIsVector )
489 return QgsMeshDatasetValue( mDoubleBuffer[volumeIndex] );
490
491 return QgsMeshDatasetValue( mDoubleBuffer[2 * volumeIndex], mDoubleBuffer[2 * volumeIndex + 1] );
492}
493
494void QgsMesh3DDataBlock::setValues( const QVector<double> &doubleBuffer )
495{
496 Q_ASSERT( doubleBuffer.size() == ( isVector() ? 2 * volumesCount() : volumesCount() ) );
497 mDoubleBuffer = doubleBuffer;
498}
499
501{
502 mIsValid = valid;
503}
504
506
507QgsMeshDatasetGroupTreeItem::QgsMeshDatasetGroupTreeItem( const QString &defaultName, const QString &sourceName, bool isVector, int index )
508 : mOriginalName( defaultName )
509 , mSourceName( sourceName )
510 , mIsVector( isVector )
511 , mDatasetGroupIndex( index )
512{}
513
515{
516 Q_UNUSED( context );
517 if ( itemElement.hasAttribute( u"display-name"_s ) )
518 mUserName = itemElement.attribute( u"display-name"_s, mUserName );
519
520 if ( itemElement.hasAttribute( u"original-name"_s ) )
521 mOriginalName = itemElement.attribute( u"original-name"_s, mOriginalName );
522
523 if ( itemElement.hasAttribute( u"source-name"_s ) )
524 mSourceName = itemElement.attribute( u"source-name"_s, mSourceName );
525
526 if ( itemElement.hasAttribute( u"is-vector"_s ) )
527 mIsVector = itemElement.attribute( u"is-vector"_s ).toInt();
528
529 if ( itemElement.hasAttribute( u"dataset-index"_s ) )
530 mDatasetGroupIndex = itemElement.attribute( u"dataset-index"_s ).toInt();
531
532 if ( itemElement.hasAttribute( u"is-enabled"_s ) )
533 mIsEnabled = itemElement.attribute( u"is-enabled"_s ).toInt();
534
535 if ( itemElement.hasAttribute( u"dataset-group-type"_s ) )
536 mDatasetGroupType = static_cast<QgsMeshDatasetGroup::Type>( itemElement.attribute( u"dataset-group-type"_s ).toInt() );
537
538 if ( itemElement.hasAttribute( u"description"_s ) )
539 mDescription = itemElement.attribute( u"description"_s );
540
541 QDomElement dependOnElement = itemElement.firstChildElement( u"dependent-on-item"_s );
542 while ( !dependOnElement.isNull() )
543 {
544 if ( dependOnElement.hasAttribute( u"dataset-index"_s ) )
545 mDatasetGroupDependentOn.append( dependOnElement.attribute( u"dataset-index"_s ).toInt() );
546 dependOnElement = dependOnElement.nextSiblingElement( u"dependent-on-item"_s );
547 }
548
549 QDomElement dependencyElement = itemElement.firstChildElement( u"dependency-item"_s );
550 while ( !dependencyElement.isNull() )
551 {
552 if ( dependencyElement.hasAttribute( u"dataset-index"_s ) )
553 mDatasetGroupDependencies.append( dependencyElement.attribute( u"dataset-index"_s ).toInt() );
554 dependencyElement = dependencyElement.nextSiblingElement( u"dependency-item"_s );
555 }
556
557 QDomElement childElement = itemElement.firstChildElement( u"mesh-dataset-group-tree-item"_s );
558 while ( !childElement.isNull() )
559 {
560 appendChild( new QgsMeshDatasetGroupTreeItem( childElement, context ) );
561 childElement = childElement.nextSiblingElement( u"mesh-dataset-group-tree-item"_s );
562 }
563}
564
566{
567 // Remove from where this item is linked
568
569 freeAsDependency();
570 freeFromDependencies();
571 qDeleteAll( mChildren );
572 if ( mParent )
573 {
574 mParent->mDatasetGroupIndexToChild.remove( mDatasetGroupIndex );
575 mParent->mChildren.removeOne( this );
576 }
577}
578
580{
581 QgsMeshDatasetGroupTreeItem *other = new QgsMeshDatasetGroupTreeItem( mOriginalName, mSourceName, mIsVector, mDatasetGroupIndex );
582 *other = *this;
583
584 other->mChildren.clear();
585 other->mDatasetGroupIndexToChild.clear();
586 if ( !mChildren.empty() )
587 for ( int i = 0; i < mChildren.count(); ++i )
588 other->appendChild( mChildren.at( i )->clone() );
589
590 return other;
591}
592
594{
595 mChildren.append( item );
596 item->mParent = this;
597 mDatasetGroupIndexToChild[item->datasetGroupIndex()] = item;
598}
599
604
606{
607 if ( row < mChildren.count() )
608 return mChildren.at( row );
609 else
610 return nullptr;
611}
612
614{
615 if ( mDatasetGroupIndexToChild.empty() )
616 return nullptr;
617
618 const QMap<int, QgsMeshDatasetGroupTreeItem *>::iterator it = mDatasetGroupIndexToChild.find( index );
619
620 if ( it != mDatasetGroupIndexToChild.end() )
621 return it.value();
622 else
623 {
624 QgsMeshDatasetGroupTreeItem *item = nullptr;
625 for ( int i = 0; i < mChildren.count(); ++i )
626 {
627 item = mChildren.at( i )->childFromDatasetGroupIndex( index );
628 if ( item )
629 break;
630 }
631 return item;
632 }
633}
634
636{
637 return mChildren.count();
638}
639
641{
642 int count = 0;
643 for ( int i = 0; i < mChildren.count(); ++i )
644 {
645 count++;
646 count += mChildren.at( i )->totalChildCount();
647 }
648 return count;
649}
650
652{
653 QList<int> indexesList;
654
655 for ( int i = 0; i < mChildren.count(); ++i )
656 {
657 if ( mChildren.at( i )->isEnabled() )
658 indexesList.append( mChildren.at( i )->datasetGroupIndex() );
659 indexesList.append( mChildren.at( i )->enabledDatasetGroupIndexes() );
660 }
661
662 return indexesList;
663}
664
669
671{
672 if ( mParent )
673 return mParent->mChildren.indexOf( const_cast<QgsMeshDatasetGroupTreeItem *>( this ) );
674
675 return 0;
676}
677
679{
680 if ( mUserName.isEmpty() )
681 return mOriginalName;
682 else
683 return mUserName;
684}
685
687{
688 return mIsVector;
689}
690
692{
693 return mDatasetGroupIndex;
694}
695
697{
698 return mIsEnabled;
699}
700
702{
703 mIsEnabled = enabled;
704}
705
707{
708 return mOriginalName;
709}
710
712{
713 return mDatasetGroupType;
714}
715
717{
718 return mDescription;
719}
720
722{
723 if ( datasetGroup )
724 {
725 mDescription = datasetGroup->description();
726 mDatasetGroupType = datasetGroup->type();
727 const QStringList &datasetGroupNames = datasetGroup->datasetGroupNamesDependentOn();
728 for ( const QString &varName : datasetGroupNames )
729 {
730 QgsMeshDatasetGroupTreeItem *varItem = searchItemBySourceName( varName );
731 if ( varItem )
732 {
733 varItem->mDatasetGroupDependencies.append( this->datasetGroupIndex() );
734 mDatasetGroupDependentOn.append( varItem->datasetGroupIndex() );
735 }
736 }
737 }
738}
739
741{
742 mDatasetGroupType = QgsMeshDatasetGroup::Persistent;
743 mDatasetGroupDependentOn.clear();
744 mDescription = uri;
745}
746
747QDomElement QgsMeshDatasetGroupTreeItem::writeXml( QDomDocument &doc, const QgsReadWriteContext &context )
748{
749 Q_UNUSED( context );
750
751 QDomElement itemElement = doc.createElement( u"mesh-dataset-group-tree-item"_s );
752 itemElement.setAttribute( u"display-name"_s, mUserName );
753 itemElement.setAttribute( u"source-name"_s, mSourceName );
754 itemElement.setAttribute( u"original-name"_s, mOriginalName );
755 itemElement.setAttribute( u"is-vector"_s, mIsVector ? true : false );
756 itemElement.setAttribute( u"dataset-index"_s, mDatasetGroupIndex );
757 itemElement.setAttribute( u"is-enabled"_s, mIsEnabled ? true : false );
758 itemElement.setAttribute( u"dataset-group-type"_s, mDatasetGroupType );
759 itemElement.setAttribute( u"description"_s, mDescription );
760
761 for ( const int index : mDatasetGroupDependentOn )
762 {
763 QDomElement dependOnElement = doc.createElement( u"dependent-on-item"_s );
764 dependOnElement.setAttribute( u"dataset-index"_s, index );
765 itemElement.appendChild( dependOnElement );
766 }
767
768 for ( const int index : mDatasetGroupDependencies )
769 {
770 QDomElement dependencyElement = doc.createElement( u"dependency-item"_s );
771 dependencyElement.setAttribute( u"dataset-index"_s, index );
772 itemElement.appendChild( dependencyElement );
773 }
774
775 for ( int i = 0; i < mChildren.count(); ++i )
776 itemElement.appendChild( mChildren.at( i )->writeXml( doc, context ) );
777
778 return itemElement;
779}
780
782{
783 QList<int> dependencies;
784 QgsMeshDatasetGroupTreeItem *root = rootItem();
785 for ( const int index : mDatasetGroupDependencies )
786 {
787 if ( !dependencies.contains( index ) )
788 dependencies.append( index );
790 if ( item )
791 dependencies.append( item->groupIndexDependencies() );
792 }
793
794 for ( int i = 0; i < childCount(); ++i )
795 {
796 dependencies.append( child( i )->groupIndexDependencies() );
797 }
798
799 return dependencies;
800}
801
802QgsMeshDatasetGroupTreeItem *QgsMeshDatasetGroupTreeItem::searchItemBySourceName( const QString &sourceName ) const
803{
804 QgsMeshDatasetGroupTreeItem *baseItem = rootItem();
805
806 QList<QgsMeshDatasetGroupTreeItem *> itemToCheck;
807 itemToCheck.append( baseItem );
808 while ( baseItem && baseItem->providerName() != sourceName && !itemToCheck.isEmpty() )
809 {
810 for ( int i = 0; i < baseItem->childCount(); ++i )
811 itemToCheck.append( baseItem->child( i ) );
812 itemToCheck.removeOne( baseItem );
813 if ( !itemToCheck.empty() )
814 baseItem = itemToCheck.first();
815 else
816 baseItem = nullptr;
817 }
818
819 return baseItem;
820}
821
822QgsMeshDatasetGroupTreeItem *QgsMeshDatasetGroupTreeItem::rootItem() const
823{
824 const QgsMeshDatasetGroupTreeItem *baseItem = this;
825 while ( baseItem->parentItem() )
826 baseItem = baseItem->parentItem();
827
828 return const_cast<QgsMeshDatasetGroupTreeItem *>( baseItem );
829}
830
831void QgsMeshDatasetGroupTreeItem::freeAsDependency()
832{
833 QgsMeshDatasetGroupTreeItem *root = rootItem();
834 if ( !root )
835 return;
836
837 for ( const int index : mDatasetGroupDependentOn )
838 {
840 if ( item )
841 item->mDatasetGroupDependencies.removeOne( this->datasetGroupIndex() );
842 }
843}
844
845void QgsMeshDatasetGroupTreeItem::freeFromDependencies()
846{
847 QgsMeshDatasetGroupTreeItem *root = rootItem();
848 for ( const int index : mDatasetGroupDependencies )
849 {
851 if ( item )
852 item->mDatasetGroupDependentOn.removeOne( this->datasetGroupIndex() );
853 }
854}
855
857{
858 return mSourceName;
859}
860
862{
863 mUserName = name;
864}
865
866
868{
869 if ( valueIndex >= 0 && valueIndex < values.count() )
870 return values[valueIndex];
871 else
872 return QgsMeshDatasetValue();
873}
874
875QgsMeshDataBlock QgsMeshMemoryDataset::datasetValues( bool isScalar, int valueIndex, int count ) const
876{
878 QVector<double> buf( isScalar ? count : 2 * count );
879 for ( int i = 0; i < count; ++i )
880 {
881 const int idx = valueIndex + i;
882 if ( ( idx < 0 ) || ( idx >= values.size() ) )
883 return ret;
884
885 const QgsMeshDatasetValue val = values[valueIndex + i];
886 if ( isScalar )
887 buf[i] = val.x();
888 else
889 {
890 buf[2 * i] = val.x();
891 buf[2 * i + 1] = val.y();
892 }
893 }
894 ret.setValues( buf );
895 return ret;
896}
897
899{
901 if ( active.isEmpty() || ( faceIndex < 0 ) || ( faceIndex + count > active.size() ) )
902 ret.setValid( true );
903 else
904 ret.setActive( active );
905 return ret;
906}
907
912
914{
915 double min = std::numeric_limits<double>::max();
916 double max = std::numeric_limits<double>::lowest();
917
918 if ( !valid )
919 return;
920
921
922 bool firstIteration = true;
923 for ( int i = 0; i < values.size(); ++i )
924 {
925 const double v = values[i].scalar();
926
927 if ( std::isnan( v ) )
928 continue;
929 if ( firstIteration )
930 {
931 firstIteration = false;
932 min = v;
933 max = v;
934 }
935 else
936 {
937 if ( v < min )
938 min = v;
939 if ( v > max )
940 max = v;
941 }
942 }
943
944 minimum = min;
945 maximum = max;
946}
947
948bool QgsMeshMemoryDataset::isActive( int faceIndex ) const
949{
950 if ( active.isEmpty() || faceIndex >= active.count() )
951 return true;
952 else
953 return active.at( faceIndex );
954}
955
957{
958 return values.count();
959}
960
964
968
973
975{
976 return memoryDatasets.size();
977}
978
980{
981 if ( datasetIndex >= 0 && datasetIndex < memoryDatasets.count() )
982 return memoryDatasets[datasetIndex]->metadata();
983 else
984 return QgsMeshDatasetMetadata();
985}
986
988{
989 return memoryDatasets[index].get();
990}
991
992void QgsMeshMemoryDatasetGroup::addDataset( std::shared_ptr<QgsMeshMemoryDataset> dataset )
993{
994 dataset->calculateMinMax();
995 memoryDatasets.push_back( dataset );
996}
997
1002
1007
1008std::shared_ptr<const QgsMeshMemoryDataset> QgsMeshMemoryDatasetGroup::constDataset( int index ) const
1009{
1010 return memoryDatasets[index];
1011}
1012
1013QDomElement QgsMeshMemoryDatasetGroup::writeXml( QDomDocument &doc, const QgsReadWriteContext &context ) const
1014{
1015 Q_UNUSED( doc )
1016 Q_UNUSED( context )
1017 return QDomElement();
1018}
1019
1021{
1022 updateStatistic();
1023}
1024
1026{
1027 mIsStatisticObsolete = true;
1028}
1029
1031{
1032 return QStringList();
1033}
1034
1036{
1037 return QString();
1038}
1039
1040void QgsMeshDatasetGroup::setReferenceTime( const QDateTime &referenceTime )
1041{
1042 mReferenceTime = referenceTime;
1043}
1044
1045void QgsMeshDatasetGroup::updateStatistic() const
1046{
1047 if ( !mIsStatisticObsolete )
1048 return;
1049
1050 double min = std::numeric_limits<double>::max();
1051 double max = std::numeric_limits<double>::lowest();
1052
1053 const int count = datasetCount();
1054 for ( int i = 0; i < count; ++i )
1055 {
1056 const QgsMeshDatasetMetadata &meta = datasetMetadata( i );
1057 min = std::min( min, meta.minimum() );
1058 max = std::max( max, meta.maximum() );
1059 }
1060 mMinimum = min;
1061 mMaximum = max;
1062
1063 mIsStatisticObsolete = false;
1064}
1065
1067{
1068 for ( int i = 0; i < datasetCount(); ++i )
1069 if ( dataset( i )->valuesCount() != count )
1070 return false;
1071 return true;
1072}
1073
1078
1080
1082 : mName( name )
1083{}
1084
1086{
1087 updateStatistic();
1088 return mMinimum;
1089}
1090
1092{
1093 updateStatistic();
1094 return mMaximum;
1095}
1096
1097void QgsMeshDatasetGroup::setMinimumMaximum( double min, double max ) const
1098{
1099 mMinimum = min;
1100 mMaximum = max;
1101}
1102
1104{
1105 return mName;
1106}
1107
1109{
1110 mName = name;
1111}
1112
1117
1122
1123void QgsMeshDatasetGroup::addExtraMetadata( QString key, QString value )
1124{
1125 mMetadata.insert( key, value );
1126}
1127
1128QMap<QString, QString> QgsMeshDatasetGroup::extraMetadata() const
1129{
1130 return mMetadata;
1131}
1132
1134{
1135 return mIsScalar;
1136}
1137
1142
1143
1147
1149{
1150 if ( mMesh && valueIndex >= 0 && valueIndex < mMesh->vertexCount() )
1151 return mMesh->vertex( valueIndex ).z();
1152
1153 return std::numeric_limits<double>::quiet_NaN();
1154}
1155
1156QgsMeshDataBlock QgsMeshVerticesElevationDataset::datasetValues( bool isScalar, int valueIndex, int count ) const
1157{
1158 if ( !isScalar || !mMesh )
1159 return QgsMeshDataBlock();
1160
1162 int effectiveValueCount = std::min( count, ( mMesh->vertexCount() - valueIndex ) );
1163 QVector<double> values( effectiveValueCount );
1164 for ( int i = valueIndex; i < effectiveValueCount; ++i )
1165 values[i] = mMesh->vertex( i - valueIndex ).z();
1166 block.setValues( values );
1167 block.setValid( true );
1168 return block;
1169}
1170
1172{
1173 QgsMeshDataBlock block( QgsMeshDataBlock::ActiveFlagInteger, std::min( count, ( mMesh->faceCount() - faceIndex ) ) );
1174 block.setValid( true );
1175 return block;
1176}
1177
1179{
1180 double min = std::numeric_limits<double>::max();
1181 double max = -std::numeric_limits<double>::max();
1182 if ( mMesh )
1183 for ( int i = 0; i < mMesh->vertexCount(); ++i )
1184 {
1185 const double z = mMesh->vertex( i ).z();
1186 if ( min > z )
1187 min = z;
1188 if ( max < z )
1189 max = z;
1190 }
1191
1192 return QgsMeshDatasetMetadata( 0, true, min, max, 0 );
1193}
1194
1196{
1197 if ( mMesh )
1198 return mMesh->vertexCount();
1199
1200 return 0;
1201}
1202
1209
1214
1216{
1217 if ( datasetIndex != 0 )
1218 return QgsMeshDatasetMetadata();
1219
1220 return mDataset->metadata();
1221}
1222
1224{
1225 return 1;
1226}
1227
1229{
1230 if ( index != 0 )
1231 return nullptr;
1232
1233 return mDataset.get();
1234}
1235
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.
QgsMesh3DDataBlock & operator=(const QgsMesh3DDataBlock &other)
QVector< int > faceToVolumeIndex() const
Returns the indexing between faces and volumes.
QVector< double > verticalLevels() const
Returns the vertical levels height.
A block of integers/doubles from a mesh dataset.
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.
A collection of dataset group metadata such as whether the data is vector or scalar,...
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 parentQuantityName() const
Returns the name of the dataset's parent quantity, if available.
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...
bool isVector() const
Return true if the dataset group is vector.
QString defaultName() const
Returns the default name.
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.
int datasetGroupIndex() const
Returns the dataset group index.
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.
bool isEnabled() const
Returns true if the item is enabled, i.e.
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
Returns the dataset group type.
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
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
Temporary dataset group in memory.
@ Persistent
Dataset group store in a file.
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(int group=-1, int dataset=-1)
Creates an index. -1 represents invalid group/dataset.
bool operator==(QgsMeshDatasetIndex other) const
bool operator!=(QgsMeshDatasetIndex other) const
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().
Represents mesh dataset metadata, such as whether the data is valid or the associated time.
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.
Represents a single mesh 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.
QgsMeshDatasetValue(double x, double y)
Constructor for vector value.
double x() const
Returns x value.
void setX(double x)
Sets X value.
Abstract class that represents a mesh dataset.
void addDataset(std::shared_ptr< QgsMeshMemoryDataset > dataset)
Adds a memory dataset to the group.
QgsMeshMemoryDatasetGroup()=default
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.
Represents a dataset with elevation value of the vertices of an existing mesh that can be edited.
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.
A container for the context for various read/write operations on 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:6975
Mesh - vertices, edges and faces.