QGIS API Documentation  3.26.3-Buenos Aires (65e4edfdad)
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->notAggregatedUsedDatasetGroupNames();
44  mDatasetGroupNameUsedForAggregate = mCalcNode->aggregatedUsedDatasetGroupNames();
45  setDataType( QgsMeshCalcUtils::determineResultDataType( mLayer,
46  mDatasetGroupNameUsed + mDatasetGroupNameUsedForAggregate ) );
47 
48  //populate used group indexes
49  QMap<QString, int> usedDatasetGroupindexes;
50  const QList<int> &indexes = mLayer->datasetGroupsIndexes();
51  for ( const int i : indexes )
52  {
53  const QString usedName = mLayer->datasetGroupMetadata( i ).name();
54  if ( mDatasetGroupNameUsed.contains( usedName ) )
55  usedDatasetGroupindexes[usedName] = i;
56  }
57 
58  QSet<qint64> times;
59  if ( !mCalcNode->isNonTemporal() )
60  {
61  //populate dataset index with time;
62  const QList<int> &usedIndexes = usedDatasetGroupindexes.values();
63  for ( const int groupIndex : usedIndexes )
64  {
65  const int dsCount = mLayer->datasetCount( groupIndex );
66  if ( dsCount == 0 )
67  return;
68 
69  if ( dsCount == 1 ) //non temporal dataset group
70  continue;
71  for ( int i = 0; i < dsCount; i++ )
72  {
73  const qint64 time = mLayer->datasetRelativeTimeInMilliseconds( QgsMeshDatasetIndex( groupIndex, i ) );
74  if ( time != INVALID_MESHLAYER_TIME )
75  times.insert( time );
76  }
77  }
78  }
79 
80  if ( times.isEmpty() )
81  times.insert( 0 );
82 
83  mDatasetTimes = qgis::setToList( times );
84  std::sort( mDatasetTimes.begin(), mDatasetTimes.end() );
85 
86  mDatasetMetaData = QVector<QgsMeshDatasetMetadata>( mDatasetTimes.count() );
87 
88  //to fill metadata, calculate all the datasets one time
89  int i = 0;
90  while ( i < mDatasetTimes.count() )
91  {
92  mCurrentDatasetIndex = i;
93  if ( calculateDataset() )
94  ++i; //calculation succeeds
95  else
96  mDatasetTimes.removeAt( i ); //calculation fails, remove this time step
97  }
98 
100 }
101 
103 {
104  return mDatasetTimes.count();
105 }
106 
108 {
109  if ( index < 0 || index >= mDatasetTimes.count() )
110  return nullptr;
111 
112  if ( index != mCurrentDatasetIndex )
113  {
114  mCurrentDatasetIndex = index;
115  calculateDataset();
116  }
117 
118  return mCacheDataset.get();
119 }
120 
122 {
123  if ( datasetIndex < 0 && datasetIndex >= mDatasetMetaData.count() )
124  return QgsMeshDatasetMetadata();
125 
126  return mDatasetMetaData.at( datasetIndex );
127 }
128 
130 {
131  return mDatasetGroupNameUsed;
132 }
133 
134 QDomElement QgsMeshVirtualDatasetGroup::writeXml( QDomDocument &doc, const QgsReadWriteContext &context ) const
135 {
136  Q_UNUSED( context )
137  QDomElement elemDataset = doc.createElement( QStringLiteral( "mesh-dataset" ) );
138  elemDataset.setAttribute( QStringLiteral( "source-type" ), QStringLiteral( "virtual" ) );
139  elemDataset.setAttribute( QStringLiteral( "name" ), name() );
140  elemDataset.setAttribute( QStringLiteral( "formula" ), mFormula );
141  elemDataset.setAttribute( QStringLiteral( "start-time" ), mStartTime );
142  elemDataset.setAttribute( QStringLiteral( "end-time" ), mEndTime );
143 
144  return elemDataset;
145 }
146 
148 {
149  return mFormula;
150 }
151 
152 bool QgsMeshVirtualDatasetGroup::calculateDataset() const
153 {
154  if ( !mLayer )
155  return false;
156 
157  const QgsMeshCalcUtils dsu( mLayer,
158  mDatasetGroupNameUsed,
159  mDatasetGroupNameUsedForAggregate,
160  QgsInterval( mDatasetTimes[mCurrentDatasetIndex] / 1000.0 ),
161  QgsInterval( mStartTime / 1000.0 ),
162  QgsInterval( mEndTime / 1000.0 ) );
163 
164  if ( !dsu.isValid() )
165  return false;
166 
167  //open output dataset
168  std::unique_ptr<QgsMeshMemoryDatasetGroup> outputGroup = std::make_unique<QgsMeshMemoryDatasetGroup> ( QString(), dsu.outputType() );
169  mCalcNode->calculate( dsu, *outputGroup );
170 
171  if ( outputGroup->memoryDatasets.isEmpty() )
172  return false;
173 
174  mCacheDataset = outputGroup->memoryDatasets[0];
175  if ( !mDatasetMetaData[mCurrentDatasetIndex].isValid() )
176  {
177  mCacheDataset->calculateMinMax();
178  mCacheDataset->time = mDatasetTimes[mCurrentDatasetIndex] / 3600.0 / 1000.0;
179  mDatasetMetaData[mCurrentDatasetIndex] = mCacheDataset->metadata();
180  }
181 
182  return true;
183 }
QgsMeshLayer::datasetGroupsIndexes
QList< int > datasetGroupsIndexes() const
Returns the list of indexes of dataset groups handled by the layer.
Definition: qgsmeshlayer.cpp:394
QgsReadWriteContext
The class is used as a container of context for various read/write operations on other objects.
Definition: qgsreadwritecontext.h:34
qgsmeshvirtualdatasetgroup.h
QgsMeshVirtualDatasetGroup::datasetGroupNamesDependentOn
QStringList datasetGroupNamesDependentOn() const override
Returns the dataset group variable name which this dataset group depends on.
Definition: qgsmeshvirtualdatasetgroup.cpp:129
QgsMeshDataset
Abstract class that represents a dataset.
Definition: qgsmeshdataset.h:543
QgsMeshVirtualDatasetGroup::description
QString description() const override
Returns some information about the dataset group.
Definition: qgsmeshvirtualdatasetgroup.cpp:147
QgsMeshVirtualDatasetGroup::writeXml
QDomElement writeXml(QDomDocument &doc, const QgsReadWriteContext &context) const override
Write dataset group information in a DOM element.
Definition: qgsmeshvirtualdatasetgroup.cpp:134
QgsMeshDatasetMetadata
QgsMeshDatasetMetadata is a collection of mesh dataset metadata such as whether the data is valid or ...
Definition: qgsmeshdataset.h:478
QgsMeshVirtualDatasetGroup::datasetMetadata
QgsMeshDatasetMetadata datasetMetadata(int datasetIndex) const override
Returns the metadata of the dataset with index datasetIndex.
Definition: qgsmeshvirtualdatasetgroup.cpp:121
QgsMeshVirtualDatasetGroup::datasetCount
int datasetCount() const override
Returns the count of datasets in the group.
Definition: qgsmeshvirtualdatasetgroup.cpp:102
QgsMeshDatasetIndex
QgsMeshDatasetIndex is index that identifies the dataset group (e.g. wind speed) and a dataset in thi...
Definition: qgsmeshdataset.h:48
QgsMeshLayer
Represents a mesh layer supporting display of data on structured or unstructured meshes.
Definition: qgsmeshlayer.h:98
QgsMeshLayer::datasetCount
int datasetCount(const QgsMeshDatasetIndex &index) const
Returns the dataset count in the dataset groups.
Definition: qgsmeshlayer.cpp:409
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:928
QgsMeshDatasetGroupMetadata::name
QString name() const
Returns name of the dataset group.
Definition: qgsmeshdataset.cpp:167
QgsMeshDatasetGroup
Abstract class that represents a dataset group.
Definition: qgsmeshdataset.h:578
QgsMeshDatasetGroup::calculateStatistic
void calculateStatistic() const
Calculates the statistics (minimum and maximum)
Definition: qgsmeshdataset.cpp:976
QgsMeshVirtualDatasetGroup::dataset
QgsMeshDataset * dataset(int index) const override
Returns the dataset with index.
Definition: qgsmeshvirtualdatasetgroup.cpp:107
QgsInterval
A representation of the interval between two datetime values.
Definition: qgsinterval.h:41
QgsMeshLayer::datasetGroupMetadata
QgsMeshDatasetGroupMetadata datasetGroupMetadata(const QgsMeshDatasetIndex &index) const
Returns the dataset groups metadata.
Definition: qgsmeshlayer.cpp:404
QgsMeshDatasetGroup::name
QString name() const
Returns the name of the dataset group.
Definition: qgsmeshdataset.cpp:1055
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:1070
INVALID_MESHLAYER_TIME
#define INVALID_MESHLAYER_TIME
Definition: qgsmeshdataprovidertemporalcapabilities.h:25