QGIS API Documentation  3.22.4-Białowieża (ce8e65e95e)
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 
79 void QgsMeshDatasetValue::set( double scalar )
80 {
81  setX( scalar );
82 }
83 
84 void QgsMeshDatasetValue::setX( double x )
85 {
86  mX = x;
87 }
88 
89 void QgsMeshDatasetValue::setY( double y )
90 {
91  mY = y;
92 }
93 
94 double QgsMeshDatasetValue::x() const
95 {
96  return mX;
97 }
98 
99 double QgsMeshDatasetValue::y() const
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 
147 QMap<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 
283 bool 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 
296 void 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 
305 QVector<int> QgsMeshDataBlock::active() const
306 {
307  Q_ASSERT( mType == ActiveFlagInteger );
308  return mIntegerBuffer;
309 }
310 
311 QVector<double> QgsMeshDataBlock::values() const
312 {
313  Q_ASSERT( mType != ActiveFlagInteger );
314 
315  return mDoubleBuffer;
316 }
317 
318 void 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 
327 void QgsMeshDataBlock::setValid( bool valid )
328 {
329  mIsValid = valid;
330 }
331 
333 
335 
336 QgsMesh3dDataBlock::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 {
375  return lastVolumeIndex() - firstVolumeIndex();
376 }
377 
379 {
380  Q_ASSERT( isValid() );
381  return mVerticalLevelsCount;
382 }
383 
384 void QgsMesh3dDataBlock::setFaceToVolumeIndex( const QVector<int> &faceToVolumeIndex )
385 {
386  Q_ASSERT( faceToVolumeIndex.size() == count() );
387  mFaceToVolumeIndex = faceToVolumeIndex;
388 }
389 
390 void QgsMesh3dDataBlock::setVerticalLevelsCount( const QVector<int> &verticalLevelsCount )
391 {
392  Q_ASSERT( verticalLevelsCount.size() == count() );
393  mVerticalLevelsCount = verticalLevelsCount;
394 }
395 
396 QVector<double> QgsMesh3dDataBlock::verticalLevels() const
397 {
398  Q_ASSERT( isValid() );
399  return mVerticalLevels;
400 }
401 
402 void 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 
414 QVector<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 
434 void 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 
447 QgsMeshDatasetGroupTreeItem::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 
457 QgsMeshDatasetGroupTreeItem::QgsMeshDatasetGroupTreeItem( const QDomElement &itemElement, const QgsReadWriteContext &context )
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 dependencieElement = itemElement.firstChildElement( QStringLiteral( "dependency-item" ) );
493  while ( !dependencieElement.isNull() )
494  {
495  if ( dependencieElement.hasAttribute( QStringLiteral( "dataset-index" ) ) )
496  mDatasetGroupDependencies.append( dependencieElement.attribute( QStringLiteral( "dataset-index" ) ).toInt() );
497  dependencieElement = dependencieElement.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 
690 QDomElement 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 dependencieElement = doc.createElement( QStringLiteral( "dependency-item" ) );
714  dependencieElement.setAttribute( QStringLiteral( "dataset-index" ), index );
715  itemElement.appendChild( dependencieElement );
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 
745 QgsMeshDatasetGroupTreeItem *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 
765 QgsMeshDatasetGroupTreeItem *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 
774 void 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 
785 void 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 
801 void 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 
815 QgsMeshDataBlock 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>::min();
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 
891 bool 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,
926  extraMetadata()
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 
948 void 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 
964 std::shared_ptr<const QgsMeshMemoryDataset> QgsMeshMemoryDatasetGroup::constDataset( int index ) const
965 {
966  return memoryDatasets[index];
967 }
968 
969 QDomElement QgsMeshMemoryDatasetGroup::writeXml( QDomDocument &doc, const QgsReadWriteContext &context ) const
970 {
971  Q_UNUSED( doc )
972  Q_UNUSED( context )
973  return QDomElement();
974 }
975 
977 {
978  updateStatictic();
979 }
980 
982 {
983  mIsStatisticObsolete = true;
984 }
985 
987 {
988  return QStringList();
989 }
990 
992 {
993  return QString();
994 }
995 
996 void QgsMeshDatasetGroup::setReferenceTime( const QDateTime &referenceTime )
997 {
998  mReferenceTime = referenceTime;
999 }
1000 
1001 void QgsMeshDatasetGroup::updateStatictic() const
1002 {
1003  if ( !mIsStatisticObsolete )
1004  return;
1005 
1006  double min = std::numeric_limits<double>::max();
1007  double max = std::numeric_limits<double>::min();
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 
1035 QgsMeshDatasetGroup::QgsMeshDatasetGroup( const QString &name ): mName( name ) {}
1036 
1038 {
1039  updateStatictic();
1040  return mMinimum;
1041 }
1042 
1044 {
1045  updateStatictic();
1046  return mMaximum;
1047 }
1048 
1049 void QgsMeshDatasetGroup::setMinimumMaximum( double min, double max )
1050 {
1051  mMinimum = min;
1052  mMaximum = max;
1053 }
1054 
1056 {
1057  return mName;
1058 }
1059 
1060 void QgsMeshDatasetGroup::setName( const QString &name )
1061 {
1062  mName = name;
1063 }
1064 
1066 {
1067  return mDataType;
1068 }
1069 
1071 {
1072  mDataType = type;
1073 }
1074 
1075 void QgsMeshDatasetGroup::addExtraMetadata( QString key, QString value )
1076 {
1077  mMetadata.insert( key, value );
1078 }
1079 
1080 QMap<QString, QString> QgsMeshDatasetGroup::extraMetadata() const
1081 {
1082  return mMetadata;
1083 }
1084 
1086 {
1087  return mIsScalar;
1088 }
1089 
1091 {
1092  mIsScalar = isScalar;
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 
1108 QgsMeshDataBlock 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 setVerticalLevelsCount(const QVector< int > &verticalLevelsCount)
Sets the vertical level counts.
void setValid(bool valid)
Sets block validity.
QgsMesh3dDataBlock()
Constructs an invalid block.
int lastVolumeIndex() const
Index of the last volume stored in the buffer (absolute)
QVector< int > faceToVolumeIndex() const
Returns the indexing between faces and volumes.
bool isValid() const
Whether the block is valid.
int firstVolumeIndex() const
Index of the first volume stored in the buffer (absolute)
int volumesCount() const
Returns number of volumes stored in the buffer.
bool isVector() const
Whether we store vector values.
QVector< int > verticalLevelsCount() const
Returns number of vertical level above 2d faces.
int count() const
Number of 2d faces for which the volume data is stored in the block.
QVector< double > verticalLevels() const
Returns the vertical levels height.
void setFaceToVolumeIndex(const QVector< int > &faceToVolumeIndex)
Sets the indexing between faces and volumes.
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.
QgsMeshDatasetValue value(int volumeIndex) const
Returns the value at volume centers.
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 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 setStatisticObsolete()
Sets statistic obsolete, that means statistic will be recalculated when requested.
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 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.
virtual QgsMeshDataset * dataset(int index) const =0
Returns the dataset with index.
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
void calculateStatistic()
Calculates the statistics (minimum and maximum)
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.
void setMinimumMaximum(double min, double max)
Overrides the minimum and the maximum value of the whole 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.
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:1246
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.