QGIS API Documentation 3.39.0-Master (47f7b3a4989)
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#include "qgsmeshdataprovider.h"
20#include "qgsrectangle.h"
21#include "qgis.h"
22#include <QRegularExpression>
23#include <QRegularExpressionMatch>
24
26 : mGroupIndex( group ), mDatasetIndex( dataset )
27{}
28
30{
31 return mGroupIndex;
32}
33
35{
36 return mDatasetIndex;
37}
38
40{
41 return ( group() > -1 ) && ( dataset() > -1 );
42}
43
45{
46 if ( isValid() && other.isValid() )
47 return other.group() == group() && other.dataset() == dataset();
48 else
49 return isValid() == other.isValid();
50}
51
53{
54 return !( operator==( other ) );
55}
56
58 : mX( x ), mY( y )
59{}
60
62 : mX( scalar )
63{}
64
66{
67 if ( std::isnan( mY ) )
68 {
69 return mX;
70 }
71 else if ( std::isnan( mX ) )
72 {
73 return std::numeric_limits<double>::quiet_NaN();
74 }
75 else
76 {
77 return std::sqrt( ( mX ) * ( mX ) + ( mY ) * ( mY ) );
78 }
79}
80
81void QgsMeshDatasetValue::set( double scalar )
82{
83 setX( scalar );
84}
85
87{
88 mX = x;
89}
90
92{
93 mY = y;
94}
95
97{
98 return mX;
99}
100
102{
103 return mY;
104}
105
107{
108 bool equal = std::isnan( mX ) == std::isnan( other.x() );
109 equal &= std::isnan( mY ) == std::isnan( other.y() );
110
111 if ( equal )
112 {
113 if ( std::isnan( mY ) )
114 {
115 equal &= qgsDoubleNear( other.x(), mX, 1E-8 );
116 }
117 else
118 {
119 equal &= qgsDoubleNear( other.x(), mX, 1E-8 );
120 equal &= qgsDoubleNear( other.y(), mY, 1E-8 );
121 }
122 }
123 return equal;
124}
125
127 const QString uri,
128 bool isScalar,
129 DataType dataType,
130 double minimum,
131 double maximum,
132 int maximumVerticalLevels,
133 const QDateTime &referenceTime,
134 bool isTemporal,
135 const QMap<QString, QString> &extraOptions )
136 : mName( name )
137 , mUri( uri )
138 , mIsScalar( isScalar )
139 , mDataType( dataType )
140 , mMinimumValue( minimum )
141 , mMaximumValue( maximum )
142 , mExtraOptions( extraOptions )
143 , mMaximumVerticalLevelsCount( maximumVerticalLevels )
144 , mReferenceTime( referenceTime )
145 , mIsTemporal( isTemporal )
146{
147 // this relies on the naming convention used by MDAL's NetCDF driver: <group name>_<dimension_name>:<dimension_value>
148 // If future MDAL releases expose quantities via a standard API then we can safely remove this and port to the new API.
149 const thread_local QRegularExpression parentQuantityRegex( QStringLiteral( "^(.*):.*?$" ) );
150 const QRegularExpressionMatch parentQuantityMatch = parentQuantityRegex.match( mName );
151 if ( parentQuantityMatch.hasMatch() )
152 {
153 mParentQuantityName = parentQuantityMatch.captured( 1 );
154 }
155}
156
157QMap<QString, QString> QgsMeshDatasetGroupMetadata::extraOptions() const
158{
159 return mExtraOptions;
160}
161
163{
164 return !mIsScalar;
165}
166
168{
169 return mIsScalar;
170}
171
173{
174 return mIsTemporal;
175}
176
178{
179 return mName;
180}
181
183{
184 return mParentQuantityName;
185}
186
189{
190 return mDataType;
191}
192
194{
195 return mMinimumValue;
196}
197
199{
200 return mMaximumValue;
201}
202
204{
205 return mMaximumVerticalLevelsCount;
206}
207
209{
210 return mReferenceTime;
211}
212
214{
215 return mUri;
216}
217
219 double time,
220 bool isValid,
221 double minimum,
222 double maximum,
223 int maximumVerticalLevels )
224 : mTime( time )
225 , mIsValid( isValid )
226 , mMinimumValue( minimum )
227 , mMaximumValue( maximum )
228 , mMaximumVerticalLevelsCount( maximumVerticalLevels )
229{
230}
231
233{
234 return mTime;
235}
236
238{
239 return mIsValid;
240}
241
243{
244 return mMinimumValue;
245}
246
248{
249 return mMaximumValue;
250}
251
253{
254 return mMaximumVerticalLevelsCount;
255}
256
258 : mType( ActiveFlagInteger )
259{
260}
261
263 : mType( type ),
264 mSize( count )
265{
266}
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(
294 mDoubleBuffer[2 * index],
295 mDoubleBuffer[2 * index + 1]
296 );
297}
298
299bool QgsMeshDataBlock::active( int index ) const
300{
301 if ( !isValid() )
302 return false;
303
304 Q_ASSERT( mType == ActiveFlagInteger );
305
306 if ( mIntegerBuffer.empty() )
307 return true;
308 else
309 return bool( mIntegerBuffer[index] );
310}
311
312void QgsMeshDataBlock::setActive( const QVector<int> &vals )
313{
314 Q_ASSERT( mType == ActiveFlagInteger );
315 Q_ASSERT( vals.size() == count() );
316
317 mIntegerBuffer = vals;
318 setValid( true );
319}
320
321QVector<int> QgsMeshDataBlock::active() const
322{
323 Q_ASSERT( mType == ActiveFlagInteger );
324 return mIntegerBuffer;
325}
326
327QVector<double> QgsMeshDataBlock::values() const
328{
329 Q_ASSERT( mType != ActiveFlagInteger );
330
331 return mDoubleBuffer;
332}
333
334void QgsMeshDataBlock::setValues( const QVector<double> &vals )
335{
336 Q_ASSERT( mType != ActiveFlagInteger );
337 Q_ASSERT( mType == ScalarDouble ? vals.size() == count() : vals.size() == 2 * count() );
338
339 mDoubleBuffer = vals;
340 setValid( true );
341}
342
344{
345 mIsValid = valid;
346}
347
349
351
352QgsMesh3DDataBlock::QgsMesh3DDataBlock( int count, bool isVector )
353 : mSize( count )
354 , mIsVector( isVector )
355{
356}
357
359{
360 return mIsValid;
361}
362
364{
365 return mIsVector;
366}
367
369{
370 return mSize;
371}
372
374{
375 if ( mFaceToVolumeIndex.empty() )
376 return -1;
377 return mFaceToVolumeIndex[0];
378}
379
381{
382 if ( mFaceToVolumeIndex.empty() || mVerticalLevelsCount.empty() )
383 return -1;
384 const int lastVolumeStartIndex = mFaceToVolumeIndex[mFaceToVolumeIndex.size() - 1];
385 const int volumesCountInLastRow = mVerticalLevelsCount[mVerticalLevelsCount.size() - 1];
386 return lastVolumeStartIndex + volumesCountInLastRow;
387}
388
393
395{
396 Q_ASSERT( isValid() );
397 return mVerticalLevelsCount;
398}
399
400void QgsMesh3DDataBlock::setFaceToVolumeIndex( const QVector<int> &faceToVolumeIndex )
401{
402 Q_ASSERT( faceToVolumeIndex.size() == count() );
403 mFaceToVolumeIndex = faceToVolumeIndex;
404}
405
406void QgsMesh3DDataBlock::setVerticalLevelsCount( const QVector<int> &verticalLevelsCount )
407{
408 Q_ASSERT( verticalLevelsCount.size() == count() );
409 mVerticalLevelsCount = verticalLevelsCount;
410}
411
413{
414 Q_ASSERT( isValid() );
415 return mVerticalLevels;
416}
417
418void QgsMesh3DDataBlock::setVerticalLevels( const QVector<double> &verticalLevels )
419{
420 Q_ASSERT( verticalLevels.size() == volumesCount() + count() );
421 mVerticalLevels = verticalLevels;
422}
423
425{
426 Q_ASSERT( isValid() );
427 return mFaceToVolumeIndex;
428}
429
430QVector<double> QgsMesh3DDataBlock::values() const
431{
432 Q_ASSERT( isValid() );
433 return mDoubleBuffer;
434}
435
437{
438 if ( !isValid() )
439 return QgsMeshDatasetValue();
440
441 if ( !mIsVector )
442 return QgsMeshDatasetValue( mDoubleBuffer[volumeIndex] );
443
444 return QgsMeshDatasetValue(
445 mDoubleBuffer[2 * volumeIndex],
446 mDoubleBuffer[2 * volumeIndex + 1]
447 );
448}
449
450void QgsMesh3DDataBlock::setValues( const QVector<double> &doubleBuffer )
451{
452 Q_ASSERT( doubleBuffer.size() == ( isVector() ? 2 * volumesCount() : volumesCount() ) );
453 mDoubleBuffer = doubleBuffer;
454}
455
457{
458 mIsValid = valid;
459}
460
462
463QgsMeshDatasetGroupTreeItem::QgsMeshDatasetGroupTreeItem( const QString &defaultName, const QString &sourceName,
464 bool isVector,
465 int index )
466 : mOriginalName( defaultName )
467 , mSourceName( sourceName )
468 , mIsVector( isVector )
469 , mDatasetGroupIndex( index )
470{
471}
472
474{
475 Q_UNUSED( context );
476 if ( itemElement.hasAttribute( QStringLiteral( "display-name" ) ) )
477 mUserName = itemElement.attribute( QStringLiteral( "display-name" ), mUserName );
478
479 if ( itemElement.hasAttribute( QStringLiteral( "original-name" ) ) )
480 mOriginalName = itemElement.attribute( QStringLiteral( "original-name" ), mOriginalName );
481
482 if ( itemElement.hasAttribute( QStringLiteral( "source-name" ) ) )
483 mSourceName = itemElement.attribute( QStringLiteral( "source-name" ), mSourceName );
484
485 if ( itemElement.hasAttribute( QStringLiteral( "is-vector" ) ) )
486 mIsVector = itemElement.attribute( QStringLiteral( "is-vector" ) ).toInt();
487
488 if ( itemElement.hasAttribute( QStringLiteral( "dataset-index" ) ) )
489 mDatasetGroupIndex = itemElement.attribute( QStringLiteral( "dataset-index" ) ).toInt();
490
491 if ( itemElement.hasAttribute( QStringLiteral( "is-enabled" ) ) )
492 mIsEnabled = itemElement.attribute( QStringLiteral( "is-enabled" ) ).toInt();
493
494 if ( itemElement.hasAttribute( QStringLiteral( "dataset-group-type" ) ) )
495 mDatasetGroupType = static_cast<QgsMeshDatasetGroup::Type>( itemElement.attribute( QStringLiteral( "dataset-group-type" ) ) .toInt() ) ;
496
497 if ( itemElement.hasAttribute( QStringLiteral( "description" ) ) )
498 mDescription = itemElement.attribute( QStringLiteral( "description" ) );
499
500 QDomElement dependOnElement = itemElement.firstChildElement( QStringLiteral( "dependent-on-item" ) );
501 while ( !dependOnElement.isNull() )
502 {
503 if ( dependOnElement.hasAttribute( QStringLiteral( "dataset-index" ) ) )
504 mDatasetGroupDependentOn.append( dependOnElement.attribute( QStringLiteral( "dataset-index" ) ).toInt() );
505 dependOnElement = dependOnElement.nextSiblingElement( QStringLiteral( "dependent-on-item" ) );
506 }
507
508 QDomElement dependencyElement = itemElement.firstChildElement( QStringLiteral( "dependency-item" ) );
509 while ( !dependencyElement.isNull() )
510 {
511 if ( dependencyElement.hasAttribute( QStringLiteral( "dataset-index" ) ) )
512 mDatasetGroupDependencies.append( dependencyElement.attribute( QStringLiteral( "dataset-index" ) ).toInt() );
513 dependencyElement = dependencyElement.nextSiblingElement( QStringLiteral( "dependency-item" ) );
514 }
515
516 QDomElement childElement = itemElement.firstChildElement( QStringLiteral( "mesh-dataset-group-tree-item" ) );
517 while ( !childElement.isNull() )
518 {
519 appendChild( new QgsMeshDatasetGroupTreeItem( childElement, context ) );
520 childElement = childElement.nextSiblingElement( QStringLiteral( "mesh-dataset-group-tree-item" ) );
521 }
522}
523
525{
526 // Remove from where this item is linked
527
528 freeAsDependency();
529 freeFromDependencies();
530 qDeleteAll( mChildren );
531 if ( mParent )
532 {
533 mParent->mDatasetGroupIndexToChild.remove( mDatasetGroupIndex );
534 mParent->mChildren.removeOne( this );
535 }
536}
537
539{
540 QgsMeshDatasetGroupTreeItem *other = new QgsMeshDatasetGroupTreeItem( mOriginalName, mSourceName, mIsVector, mDatasetGroupIndex );
541 *other = *this;
542
543 other->mChildren.clear();
544 other->mDatasetGroupIndexToChild.clear();
545 if ( !mChildren.empty() )
546 for ( int i = 0; i < mChildren.count(); ++i )
547 other->appendChild( mChildren.at( i )->clone() );
548
549 return other;
550}
551
553{
554 mChildren.append( item );
555 item->mParent = this;
556 mDatasetGroupIndexToChild[item->datasetGroupIndex()] = item;
557}
558
563
565{
566 if ( row < mChildren.count() )
567 return mChildren.at( row );
568 else
569 return nullptr;
570}
571
573{
574 if ( mDatasetGroupIndexToChild.empty() )
575 return nullptr;
576
577 const QMap<int, QgsMeshDatasetGroupTreeItem *>::iterator it = mDatasetGroupIndexToChild.find( index );
578
579 if ( it != mDatasetGroupIndexToChild.end() )
580 return it.value();
581 else
582 {
583 QgsMeshDatasetGroupTreeItem *item = nullptr;
584 for ( int i = 0; i < mChildren.count(); ++i )
585 {
586 item = mChildren.at( i )->childFromDatasetGroupIndex( index );
587 if ( item )
588 break;
589 }
590 return item;
591 }
592}
593
595{
596 return mChildren.count();
597}
598
600{
601 int count = 0;
602 for ( int i = 0; i < mChildren.count(); ++i )
603 {
604 count++;
605 count += mChildren.at( i )->totalChildCount();
606 }
607 return count;
608}
609
611{
612 QList<int> indexesList;
613
614 for ( int i = 0; i < mChildren.count(); ++i )
615 {
616 if ( mChildren.at( i )->isEnabled() )
617 indexesList.append( mChildren.at( i )->datasetGroupIndex() );
618 indexesList.append( mChildren.at( i )->enabledDatasetGroupIndexes() );
619 }
620
621 return indexesList;
622}
623
628
630{
631 if ( mParent )
632 return mParent->mChildren.indexOf( const_cast<QgsMeshDatasetGroupTreeItem *>( this ) );
633
634 return 0;
635}
636
638{
639 if ( mUserName.isEmpty() )
640 return mOriginalName;
641 else
642 return mUserName;
643}
644
646{
647 return mIsVector;
648}
649
651{
652 return mDatasetGroupIndex;
653}
654
656{
657 return mIsEnabled;
658}
659
661{
662 mIsEnabled = enabled;
663}
664
666{
667 return mOriginalName;
668}
669
671{
672 return mDatasetGroupType;
673}
674
676{
677 return mDescription;
678}
679
681{
682 if ( datasetGroup )
683 {
684 mDescription = datasetGroup->description();
685 mDatasetGroupType = datasetGroup->type();
686 const QStringList &datasetGroupNames = datasetGroup->datasetGroupNamesDependentOn();
687 for ( const QString &varName : datasetGroupNames )
688 {
689 QgsMeshDatasetGroupTreeItem *varItem = searchItemBySourceName( varName );
690 if ( varItem )
691 {
692 varItem->mDatasetGroupDependencies.append( this->datasetGroupIndex() );
693 mDatasetGroupDependentOn.append( varItem->datasetGroupIndex() );
694 }
695 }
696 }
697}
698
700{
701 mDatasetGroupType = QgsMeshDatasetGroup::Persistent;
702 mDatasetGroupDependentOn.clear();
703 mDescription = uri;
704}
705
706QDomElement QgsMeshDatasetGroupTreeItem::writeXml( QDomDocument &doc, const QgsReadWriteContext &context )
707{
708 Q_UNUSED( context );
709
710 QDomElement itemElement = doc.createElement( QStringLiteral( "mesh-dataset-group-tree-item" ) );
711 itemElement.setAttribute( QStringLiteral( "display-name" ), mUserName );
712 itemElement.setAttribute( QStringLiteral( "source-name" ), mSourceName );
713 itemElement.setAttribute( QStringLiteral( "original-name" ), mOriginalName );
714 itemElement.setAttribute( QStringLiteral( "is-vector" ), mIsVector ? true : false );
715 itemElement.setAttribute( QStringLiteral( "dataset-index" ), mDatasetGroupIndex );
716 itemElement.setAttribute( QStringLiteral( "is-enabled" ), mIsEnabled ? true : false );
717 itemElement.setAttribute( QStringLiteral( "dataset-group-type" ), mDatasetGroupType );
718 itemElement.setAttribute( QStringLiteral( "description" ), mDescription );
719
720 for ( const int index : mDatasetGroupDependentOn )
721 {
722 QDomElement dependOnElement = doc.createElement( QStringLiteral( "dependent-on-item" ) );
723 dependOnElement.setAttribute( QStringLiteral( "dataset-index" ), index );
724 itemElement.appendChild( dependOnElement );
725 }
726
727 for ( const int index : mDatasetGroupDependencies )
728 {
729 QDomElement dependencyElement = doc.createElement( QStringLiteral( "dependency-item" ) );
730 dependencyElement.setAttribute( QStringLiteral( "dataset-index" ), index );
731 itemElement.appendChild( dependencyElement );
732 }
733
734 for ( int i = 0; i < mChildren.count(); ++i )
735 itemElement.appendChild( mChildren.at( i )->writeXml( doc, context ) );
736
737 return itemElement;
738}
739
741{
742 QList<int> dependencies;
743 QgsMeshDatasetGroupTreeItem *root = rootItem();
744 for ( const int index : mDatasetGroupDependencies )
745 {
746 if ( !dependencies.contains( index ) )
747 dependencies.append( index );
749 if ( item )
750 dependencies.append( item->groupIndexDependencies() );
751 }
752
753 for ( int i = 0; i < childCount(); ++i )
754 {
755 dependencies.append( child( i )->groupIndexDependencies() );
756 }
757
758 return dependencies;
759}
760
761QgsMeshDatasetGroupTreeItem *QgsMeshDatasetGroupTreeItem::searchItemBySourceName( const QString &sourceName ) const
762{
763 QgsMeshDatasetGroupTreeItem *baseItem = rootItem();
764
765 QList<QgsMeshDatasetGroupTreeItem *> itemToCheck;
766 itemToCheck.append( baseItem );
767 while ( baseItem && baseItem->providerName() != sourceName && !itemToCheck.isEmpty() )
768 {
769 for ( int i = 0; i < baseItem->childCount(); ++i )
770 itemToCheck.append( baseItem->child( i ) );
771 itemToCheck.removeOne( baseItem );
772 if ( !itemToCheck.empty() )
773 baseItem = itemToCheck.first();
774 else
775 baseItem = nullptr;
776 }
777
778 return baseItem;
779}
780
781QgsMeshDatasetGroupTreeItem *QgsMeshDatasetGroupTreeItem::rootItem() const
782{
783 const QgsMeshDatasetGroupTreeItem *baseItem = this;
784 while ( baseItem->parentItem() != nullptr )
785 baseItem = baseItem->parentItem();
786
787 return const_cast<QgsMeshDatasetGroupTreeItem *>( baseItem );
788}
789
790void QgsMeshDatasetGroupTreeItem::freeAsDependency()
791{
792 QgsMeshDatasetGroupTreeItem *root = rootItem();
793 for ( const int index : mDatasetGroupDependentOn )
794 {
796 if ( item )
797 item->mDatasetGroupDependencies.removeOne( this->datasetGroupIndex() );
798 }
799}
800
801void QgsMeshDatasetGroupTreeItem::freeFromDependencies()
802{
803 QgsMeshDatasetGroupTreeItem *root = rootItem();
804 for ( const int index : mDatasetGroupDependencies )
805 {
807 if ( item )
808 item->mDatasetGroupDependentOn.removeOne( this->datasetGroupIndex() );
809 }
810}
811
813{
814 return mSourceName;
815}
816
817void QgsMeshDatasetGroupTreeItem::setName( const QString &name )
818{
819 mUserName = name;
820}
821
822
824{
825 if ( valueIndex >= 0 && valueIndex < values.count() )
826 return values[valueIndex];
827 else
828 return QgsMeshDatasetValue();
829}
830
831QgsMeshDataBlock QgsMeshMemoryDataset::datasetValues( bool isScalar, int valueIndex, int count ) const
832{
834 QVector<double> buf( isScalar ? count : 2 * count );
835 for ( int i = 0; i < count; ++i )
836 {
837 const int idx = valueIndex + i;
838 if ( ( idx < 0 ) || ( idx >= values.size() ) )
839 return ret;
840
841 const QgsMeshDatasetValue val = values[ valueIndex + i ];
842 if ( isScalar )
843 buf[i] = val.x();
844 else
845 {
846 buf[2 * i] = val.x();
847 buf[2 * i + 1] = val.y();
848 }
849 }
850 ret.setValues( buf );
851 return ret;
852}
853
855{
857 if ( active.isEmpty() ||
858 ( faceIndex < 0 ) ||
859 ( faceIndex + count > active.size() )
860 )
861 ret.setValid( true );
862 else
863 ret.setActive( active );
864 return ret;
865}
866
871
873{
874 double min = std::numeric_limits<double>::max();
875 double max = std::numeric_limits<double>::lowest();
876
877 if ( !valid )
878 return;
879
880
881 bool firstIteration = true;
882 for ( int i = 0; i < values.size(); ++i )
883 {
884 const double v = values[i].scalar();
885
886 if ( std::isnan( v ) )
887 continue;
888 if ( firstIteration )
889 {
890 firstIteration = false;
891 min = v;
892 max = v;
893 }
894 else
895 {
896 if ( v < min )
897 min = v;
898 if ( v > max )
899 max = v;
900 }
901 }
902
903 minimum = min;
904 maximum = max;
905}
906
907bool QgsMeshMemoryDataset::isActive( int faceIndex ) const
908{
909 if ( active.isEmpty() || faceIndex >= active.count() )
910 return true;
911 else
912 return active.at( faceIndex );
913}
914
916{
917 return values.count();
918}
919
924
929
931{
933 name(),
934 QString(),
935 isScalar(),
936 dataType(),
937 minimum(),
938 maximum(),
939 0,
940 mReferenceTime,
941 datasetCount() > 1,
943 );
944}
945
947{
948 return memoryDatasets.size();
949}
950
952{
953 if ( datasetIndex >= 0 && datasetIndex < memoryDatasets.count() )
954 return memoryDatasets[datasetIndex]->metadata();
955 else
956 return QgsMeshDatasetMetadata();
957}
958
960{
961 return memoryDatasets[index].get();
962}
963
964void QgsMeshMemoryDatasetGroup::addDataset( std::shared_ptr<QgsMeshMemoryDataset> dataset )
965{
966 dataset->calculateMinMax();
967 memoryDatasets.push_back( dataset );
968}
969
974
979
980std::shared_ptr<const QgsMeshMemoryDataset> QgsMeshMemoryDatasetGroup::constDataset( int index ) const
981{
982 return memoryDatasets[index];
983}
984
985QDomElement QgsMeshMemoryDatasetGroup::writeXml( QDomDocument &doc, const QgsReadWriteContext &context ) const
986{
987 Q_UNUSED( doc )
988 Q_UNUSED( context )
989 return QDomElement();
990}
991
993{
994 updateStatistic();
995}
996
998{
999 mIsStatisticObsolete = true;
1000}
1001
1003{
1004 return QStringList();
1005}
1006
1008{
1009 return QString();
1010}
1011
1012void QgsMeshDatasetGroup::setReferenceTime( const QDateTime &referenceTime )
1013{
1014 mReferenceTime = referenceTime;
1015}
1016
1017void QgsMeshDatasetGroup::updateStatistic() const
1018{
1019 if ( !mIsStatisticObsolete )
1020 return;
1021
1022 double min = std::numeric_limits<double>::max();
1023 double max = std::numeric_limits<double>::lowest();
1024
1025 const int count = datasetCount();
1026 for ( int i = 0; i < count; ++i )
1027 {
1028 const QgsMeshDatasetMetadata &meta = datasetMetadata( i );
1029 min = std::min( min, meta.minimum() );
1030 max = std::max( max, meta.maximum() );
1031 }
1032 mMinimum = min;
1033 mMaximum = max;
1034
1035 mIsStatisticObsolete = false;
1036}
1037
1039{
1040 for ( int i = 0; i < datasetCount(); ++i )
1041 if ( dataset( i )->valuesCount() != count )
1042 return false;
1043 return true;
1044}
1045
1047 : mName( name ), mDataType( dataType ) {}
1048
1050
1051QgsMeshDatasetGroup::QgsMeshDatasetGroup( const QString &name ): mName( name ) {}
1052
1054{
1055 updateStatistic();
1056 return mMinimum;
1057}
1058
1060{
1061 updateStatistic();
1062 return mMaximum;
1063}
1064
1065void QgsMeshDatasetGroup::setMinimumMaximum( double min, double max ) const
1066{
1067 mMinimum = min;
1068 mMaximum = max;
1069}
1070
1072{
1073 return mName;
1074}
1075
1076void QgsMeshDatasetGroup::setName( const QString &name )
1077{
1078 mName = name;
1079}
1080
1085
1090
1091void QgsMeshDatasetGroup::addExtraMetadata( QString key, QString value )
1092{
1093 mMetadata.insert( key, value );
1094}
1095
1096QMap<QString, QString> QgsMeshDatasetGroup::extraMetadata() const
1097{
1098 return mMetadata;
1099}
1100
1102{
1103 return mIsScalar;
1104}
1105
1107{
1109}
1110
1111
1115
1117{
1118 if ( mMesh && valueIndex >= 0 && valueIndex < mMesh->vertexCount() )
1119 return mMesh->vertex( valueIndex ).z();
1120
1121 return std::numeric_limits<double>::quiet_NaN();
1122}
1123
1124QgsMeshDataBlock QgsMeshVerticesElevationDataset::datasetValues( bool isScalar, int valueIndex, int count ) const
1125{
1126 if ( !isScalar || !mMesh )
1127 return QgsMeshDataBlock();
1128
1130 int effectiveValueCount = std::min( count, ( mMesh->vertexCount() - valueIndex ) );
1131 QVector<double> values( effectiveValueCount );
1132 for ( int i = valueIndex; i < effectiveValueCount; ++i )
1133 values[i] = mMesh->vertex( i - valueIndex ).z();
1134 block.setValues( values );
1135 block.setValid( true );
1136 return block;
1137}
1138
1140{
1141 QgsMeshDataBlock block( QgsMeshDataBlock::ActiveFlagInteger, std::min( count, ( mMesh->faceCount() - faceIndex ) ) );
1142 block.setValid( true );
1143 return block;
1144}
1145
1147{
1148 double min = std::numeric_limits<double>::max();
1149 double max = -std::numeric_limits<double>::max();
1150 if ( mMesh )
1151 for ( int i = 0; i < mMesh->vertexCount(); ++i )
1152 {
1153 const double z = mMesh->vertex( i ).z();
1154 if ( min > z )
1155 min = z;
1156 if ( max < z )
1157 max = z;
1158 }
1159
1160 return QgsMeshDatasetMetadata( 0, true, min, max, 0 );
1161}
1162
1164{
1165 if ( mMesh )
1166 return mMesh->vertexCount();
1167
1168 return 0;
1169}
1170
1177
1182
1184{
1185 if ( datasetIndex != 0 )
1186 return QgsMeshDatasetMetadata();
1187
1188 return mDataset->metadata();
1189}
1190
1192
1194{
1195 if ( index != 0 )
1196 return nullptr;
1197
1198 return mDataset.get();
1199}
1200
1205
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 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...
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:5465
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.