QGIS API Documentation 3.99.0-Master (357b655ed83)
Loading...
Searching...
No Matches
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
20#include <QString>
21
22using namespace Qt::StringLiterals;
23
25 const QString &name,
26 const QString &formulaString,
27 QgsMeshLayer *layer,
28 qint64 relativeStartTime,
29 qint64 relativeEndTime ):
31 , mFormula( formulaString )
32 , mLayer( layer )
33 , mStartTime( relativeStartTime )
34 , mEndTime( relativeEndTime )
35{
36}
37
39{
40 QString errMessage;
41 mCalcNode.reset( QgsMeshCalcNode::parseMeshCalcString( mFormula, errMessage ) );
42
43 if ( !mCalcNode || !mLayer )
44 return;
45
46 mDatasetGroupNameUsed = mCalcNode->notAggregatedUsedDatasetGroupNames();
47 mDatasetGroupNameUsedForAggregate = mCalcNode->aggregatedUsedDatasetGroupNames();
48 setDataType( QgsMeshCalcUtils::determineResultDataType( mLayer,
49 mDatasetGroupNameUsed + mDatasetGroupNameUsedForAggregate ) );
50
51 //populate used group indexes
52 QMap<QString, int> usedDatasetGroupindexes;
53 const QList<int> &indexes = mLayer->datasetGroupsIndexes();
54 for ( const int i : indexes )
55 {
56 const QString usedName = mLayer->datasetGroupMetadata( i ).name();
57 if ( mDatasetGroupNameUsed.contains( usedName ) )
58 usedDatasetGroupindexes[usedName] = i;
59 }
60
61 QSet<qint64> times;
62 if ( !mCalcNode->isNonTemporal() )
63 {
64 //populate dataset index with time;
65 const QList<int> &usedIndexes = usedDatasetGroupindexes.values();
66 for ( const int groupIndex : usedIndexes )
67 {
68 const int dsCount = mLayer->datasetCount( groupIndex );
69 if ( dsCount == 0 )
70 return;
71
72 if ( dsCount == 1 ) //non temporal dataset group
73 continue;
74 for ( int i = 0; i < dsCount; i++ )
75 {
76 const qint64 time = mLayer->datasetRelativeTimeInMilliseconds( QgsMeshDatasetIndex( groupIndex, i ) );
77 if ( time != INVALID_MESHLAYER_TIME )
78 times.insert( time );
79 }
80 }
81 }
82
83 if ( times.isEmpty() )
84 times.insert( 0 );
85
86 mDatasetTimes = QList<qint64>( times.constBegin(), times.constEnd() );
87 std::sort( mDatasetTimes.begin(), mDatasetTimes.end() );
88
89 mDatasetMetaData = QVector<QgsMeshDatasetMetadata>( mDatasetTimes.count() );
90
91 //to fill metadata, calculate all the datasets one time
92 int i = 0;
93 while ( i < mDatasetTimes.count() )
94 {
95 mCurrentDatasetIndex = i;
96 if ( calculateDataset() )
97 ++i; //calculation succeeds
98 else
99 mDatasetTimes.removeAt( i ); //calculation fails, remove this time step
100 }
101
103}
104
106{
107 return mDatasetTimes.count();
108}
109
111{
112 if ( index < 0 || index >= mDatasetTimes.count() )
113 return nullptr;
114
115 if ( index != mCurrentDatasetIndex )
116 {
117 mCurrentDatasetIndex = index;
118 calculateDataset();
119 }
120
121 return mCacheDataset.get();
122}
123
125{
126 if ( datasetIndex < 0 && datasetIndex >= mDatasetMetaData.count() )
127 return QgsMeshDatasetMetadata();
128
129 return mDatasetMetaData.at( datasetIndex );
130}
131
133{
134 return mDatasetGroupNameUsed;
135}
136
137QDomElement QgsMeshVirtualDatasetGroup::writeXml( QDomDocument &doc, const QgsReadWriteContext &context ) const
138{
139 Q_UNUSED( context )
140 QDomElement elemDataset = doc.createElement( u"mesh-dataset"_s );
141 elemDataset.setAttribute( u"source-type"_s, u"virtual"_s );
142 elemDataset.setAttribute( u"name"_s, name() );
143 elemDataset.setAttribute( u"formula"_s, mFormula );
144 elemDataset.setAttribute( u"start-time"_s, mStartTime );
145 elemDataset.setAttribute( u"end-time"_s, mEndTime );
146
147 return elemDataset;
148}
149
151{
152 return mFormula;
153}
154
155bool QgsMeshVirtualDatasetGroup::calculateDataset() const
156{
157 if ( !mLayer )
158 return false;
159
160 const QgsMeshCalcUtils dsu( mLayer,
161 mDatasetGroupNameUsed,
162 mDatasetGroupNameUsedForAggregate,
163 QgsInterval( mDatasetTimes[mCurrentDatasetIndex] / 1000.0 ),
164 QgsInterval( mStartTime / 1000.0 ),
165 QgsInterval( mEndTime / 1000.0 ) );
166
167 if ( !dsu.isValid() )
168 return false;
169
170 //open output dataset
171 auto outputGroup = std::make_unique<QgsMeshMemoryDatasetGroup> ( QString(), dsu.outputType() );
172 mCalcNode->calculate( dsu, *outputGroup );
173
174 if ( outputGroup->memoryDatasets.isEmpty() )
175 return false;
176
177 mCacheDataset = outputGroup->memoryDatasets[0];
178 if ( !mDatasetMetaData[mCurrentDatasetIndex].isValid() )
179 {
180 mCacheDataset->calculateMinMax();
181 mCacheDataset->time = mDatasetTimes[mCurrentDatasetIndex] / 3600.0 / 1000.0;
182 mDatasetMetaData[mCurrentDatasetIndex] = mCacheDataset->metadata();
183 }
184
185 return true;
186}
A representation of the interval between two datetime values.
Definition qgsinterval.h:50
QgsMeshDatasetGroup()=default
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).
An index that identifies the dataset group (e.g.
Represents mesh dataset metadata, such as whether the data is valid or the associated time.
Abstract class that represents a mesh dataset.
Represents a mesh layer supporting display of data on structured or unstructured meshes.
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.
A container for the context for various read/write operations on objects.