QGIS API Documentation  3.16.0-Hannover (43b64b13f3)
qgsmeshvirtualdatasetgroup.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsmeshvirtualdatasetgroup.cpp
3  ---------------------
4  begin : June 2020
5  copyright : (C) 2020 by Vincent Cloarec
6  email : vcloarec 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 
20 
22  const QString &name,
23  const QString &formulaString,
24  QgsMeshLayer *layer,
25  qint64 relativeStartTime,
26  qint64 relativeEndTime ):
27  QgsMeshDatasetGroup( name )
28  , mFormula( formulaString )
29  , mLayer( layer )
30  , mStartTime( relativeStartTime )
31  , mEndTime( relativeEndTime )
32 {
33 }
34 
36 {
37  QString errMessage;
38  mCalcNode.reset( QgsMeshCalcNode::parseMeshCalcString( mFormula, errMessage ) );
39 
40  if ( !mCalcNode || !mLayer )
41  return;
42 
43  mDatasetGroupNameUsed = mCalcNode->usedDatasetGroupNames();
44  setDataType( QgsMeshCalcUtils::determineResultDataType( mLayer, mDatasetGroupNameUsed ) );
45 
46  //populate used group indexes
47  QMap<QString, int> usedDatasetGroupindexes;
48  const QList<int> &indexes = mLayer->datasetGroupsIndexes();
49  for ( int i : indexes )
50  {
51  QString usedName = mLayer->datasetGroupMetadata( i ).name();
52  if ( mDatasetGroupNameUsed.contains( usedName ) )
53  usedDatasetGroupindexes[usedName] = i;
54  }
55 
56  QSet<qint64> times;
57  if ( !mCalcNode->isNonTemporal() )
58  {
59  //populate dataset index with time;
60  const QList<int> &usedIndexes = usedDatasetGroupindexes.values();
61  for ( int groupIndex : usedIndexes )
62  {
63  int dsCount = mLayer->datasetCount( groupIndex );
64  if ( dsCount == 0 )
65  return;
66 
67  if ( dsCount == 1 ) //non temporal dataset group
68  continue;
69  for ( int i = 0; i < dsCount; i++ )
70  {
71  qint64 time = mLayer->datasetRelativeTimeInMilliseconds( QgsMeshDatasetIndex( groupIndex, i ) );
72  if ( time != INVALID_MESHLAYER_TIME )
73  times.insert( time );
74  }
75  }
76  }
77 
78  if ( times.isEmpty() )
79  times.insert( 0 );
80 
81  mDatasetTimes = qgis::setToList( times );
82  std::sort( mDatasetTimes.begin(), mDatasetTimes.end() );
83 
84  mDatasetMetaData = QVector<QgsMeshDatasetMetadata>( mDatasetTimes.count() );
85 
86  //to fill metadata, calculate all the datasets one time
87  int i = 0;
88  while ( i < mDatasetTimes.count() )
89  {
90  mCurrentDatasetIndex = i;
91  if ( calculateDataset() )
92  ++i; //calculation succeeds
93  else
94  mDatasetTimes.removeAt( i ); //calculation fails, remove this time step
95  }
96 
98 }
99 
101 {
102  return mDatasetTimes.count();
103 }
104 
106 {
107  if ( index < 0 || index >= mDatasetTimes.count() )
108  return nullptr;
109 
110  if ( index != mCurrentDatasetIndex )
111  {
112  mCurrentDatasetIndex = index;
113  calculateDataset();
114  }
115 
116  return mCacheDataset.get();
117 }
118 
120 {
121  if ( datasetIndex < 0 && datasetIndex >= mDatasetMetaData.count() )
122  return QgsMeshDatasetMetadata();
123 
124  return mDatasetMetaData.at( datasetIndex );
125 }
126 
128 {
129  return mDatasetGroupNameUsed;
130 }
131 
132 QDomElement QgsMeshVirtualDatasetGroup::writeXml( QDomDocument &doc, const QgsReadWriteContext &context ) const
133 {
134  Q_UNUSED( context )
135  QDomElement elemDataset = doc.createElement( QStringLiteral( "mesh-dataset" ) );
136  elemDataset.setAttribute( QStringLiteral( "source-type" ), QStringLiteral( "virtual" ) );
137  elemDataset.setAttribute( QStringLiteral( "name" ), name() );
138  elemDataset.setAttribute( QStringLiteral( "formula" ), mFormula );
139  elemDataset.setAttribute( QStringLiteral( "start-time" ), mStartTime );
140  elemDataset.setAttribute( QStringLiteral( "end-time" ), mEndTime );
141 
142  return elemDataset;
143 }
144 
146 {
147  return mFormula;
148 }
149 
150 bool QgsMeshVirtualDatasetGroup::calculateDataset() const
151 {
152  if ( !mLayer )
153  return false;
154 
155  QgsMeshCalcUtils dsu( mLayer, mDatasetGroupNameUsed, QgsInterval( mDatasetTimes[mCurrentDatasetIndex] / 1000.0 ) );
156 
157  if ( !dsu.isValid() )
158  return false;
159 
160  //open output dataset
161  std::unique_ptr<QgsMeshMemoryDatasetGroup> outputGroup = qgis::make_unique<QgsMeshMemoryDatasetGroup> ( QString(), dsu.outputType() );
162  mCalcNode->calculate( dsu, *outputGroup );
163 
164  if ( outputGroup->memoryDatasets.isEmpty() )
165  return false;
166 
167  mCacheDataset = outputGroup->memoryDatasets[0];
168  if ( !mDatasetMetaData[mCurrentDatasetIndex].isValid() )
169  {
170  mCacheDataset->calculateMinMax();
171  mCacheDataset->time = mDatasetTimes[mCurrentDatasetIndex] / 3600.0 / 1000.0;
172  mDatasetMetaData[mCurrentDatasetIndex] = mCacheDataset->metadata();
173  }
174 
175  return true;
176 }
QgsMeshLayer::datasetGroupsIndexes
QList< int > datasetGroupsIndexes() const
Returns the list of indexes of dataset groups count handled by the layer.
Definition: qgsmeshlayer.cpp:337
QgsReadWriteContext
The class is used as a container of context for various read/write operations on other objects.
Definition: qgsreadwritecontext.h:35
qgsmeshvirtualdatasetgroup.h
QgsMeshVirtualDatasetGroup::datasetGroupNamesDependentOn
QStringList datasetGroupNamesDependentOn() const override
Returns the dataset group variable name which this dataset group depends on.
Definition: qgsmeshvirtualdatasetgroup.cpp:127
QgsMeshDataset
Abstract class that represents a dataset.
Definition: qgsmeshdataset.h:541
QgsMeshVirtualDatasetGroup::description
QString description() const override
Returns some information about the dataset group.
Definition: qgsmeshvirtualdatasetgroup.cpp:145
QgsMeshVirtualDatasetGroup::writeXml
QDomElement writeXml(QDomDocument &doc, const QgsReadWriteContext &context) const override
Write dataset group information in a DOM element.
Definition: qgsmeshvirtualdatasetgroup.cpp:132
QgsMeshDatasetMetadata
QgsMeshDatasetMetadata is a collection of mesh dataset metadata such as whether the data is valid or ...
Definition: qgsmeshdataset.h:476
QgsMeshVirtualDatasetGroup::datasetMetadata
QgsMeshDatasetMetadata datasetMetadata(int datasetIndex) const override
Returns the metadata of the dataset with index datasetIndex.
Definition: qgsmeshvirtualdatasetgroup.cpp:119
QgsMeshVirtualDatasetGroup::datasetCount
int datasetCount() const override
Returns the count of datasets in the group.
Definition: qgsmeshvirtualdatasetgroup.cpp:100
QgsMeshDatasetIndex
QgsMeshDatasetIndex is index that identifies the dataset group (e.g.
Definition: qgsmeshdataset.h:47
QgsMeshLayer
Represents a mesh layer supporting display of data on structured or unstructured meshes.
Definition: qgsmeshlayer.h:95
QgsMeshLayer::datasetCount
int datasetCount(const QgsMeshDatasetIndex &index) const
Returns the dataset count in the dataset groups.
Definition: qgsmeshlayer.cpp:347
QgsMeshVirtualDatasetGroup::initialize
void initialize() override
Initialize the dataset group.
Definition: qgsmeshvirtualdatasetgroup.cpp:35
QgsMeshLayer::datasetRelativeTimeInMilliseconds
qint64 datasetRelativeTimeInMilliseconds(const QgsMeshDatasetIndex &index)
Returns the relative time (in milliseconds) of the dataset from the reference time of its group.
Definition: qgsmeshlayer.cpp:842
QgsMeshDatasetGroupMetadata::name
QString name() const
Returns name of the dataset group.
Definition: qgsmeshdataset.cpp:166
QgsMeshDatasetGroup
Abstract class that represents a dataset group.
Definition: qgsmeshdataset.h:576
QgsMeshVirtualDatasetGroup::dataset
QgsMeshDataset * dataset(int index) const override
Returns the dataset with index.
Definition: qgsmeshvirtualdatasetgroup.cpp:105
QgsInterval
A representation of the interval between two datetime values.
Definition: qgsinterval.h:41
QgsMeshDatasetGroup::calculateStatistic
void calculateStatistic()
Calculates the statictics (minimum and maximum)
Definition: qgsmeshdataset.cpp:959
QgsMeshLayer::datasetGroupMetadata
QgsMeshDatasetGroupMetadata datasetGroupMetadata(const QgsMeshDatasetIndex &index) const
Returns the dataset groups metadata.
Definition: qgsmeshlayer.cpp:342
QgsMeshDatasetGroup::name
QString name() const
Returns the name of the dataset group.
Definition: qgsmeshdataset.cpp:1019
qgsmeshlayertemporalproperties.h
QgsMeshVirtualDatasetGroup::QgsMeshVirtualDatasetGroup
QgsMeshVirtualDatasetGroup(const QString &name, const QString &formulaString, QgsMeshLayer *layer, qint64 relativeStartTime, qint64 relativeEndTime)
Constructor.
Definition: qgsmeshvirtualdatasetgroup.cpp:21
QgsMeshDatasetGroup::setDataType
void setDataType(const QgsMeshDatasetGroupMetadata::DataType &dataType)
Sets the data type of the dataset group.
Definition: qgsmeshdataset.cpp:1034
INVALID_MESHLAYER_TIME
#define INVALID_MESHLAYER_TIME
Definition: qgsmeshdataprovidertemporalcapabilities.h:25