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