QGIS API Documentation 4.0.0-Norrköping (1ddcee3d0e4)
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
24QgsMeshVirtualDatasetGroup::QgsMeshVirtualDatasetGroup( const QString &name, const QString &formulaString, QgsMeshLayer *layer, qint64 relativeStartTime, qint64 relativeEndTime )
26 , mFormula( formulaString )
27 , mLayer( layer )
28 , mStartTime( relativeStartTime )
29 , mEndTime( relativeEndTime )
30{}
31
33{
34 QString errMessage;
35 mCalcNode.reset( QgsMeshCalcNode::parseMeshCalcString( mFormula, errMessage ) );
36
37 if ( !mCalcNode || !mLayer )
38 return;
39
40 mDatasetGroupNameUsed = mCalcNode->notAggregatedUsedDatasetGroupNames();
41 mDatasetGroupNameUsedForAggregate = mCalcNode->aggregatedUsedDatasetGroupNames();
42 setDataType( QgsMeshCalcUtils::determineResultDataType( mLayer, mDatasetGroupNameUsed + mDatasetGroupNameUsedForAggregate ) );
43
44 //populate used group indexes
45 QMap<QString, int> usedDatasetGroupindexes;
46 const QList<int> &indexes = mLayer->datasetGroupsIndexes();
47 for ( const int i : indexes )
48 {
49 const QString usedName = mLayer->datasetGroupMetadata( i ).name();
50 if ( mDatasetGroupNameUsed.contains( usedName ) )
51 usedDatasetGroupindexes[usedName] = i;
52 }
53
54 QSet<qint64> times;
55 if ( !mCalcNode->isNonTemporal() )
56 {
57 //populate dataset index with time;
58 const QList<int> &usedIndexes = usedDatasetGroupindexes.values();
59 for ( const int groupIndex : usedIndexes )
60 {
61 const int dsCount = mLayer->datasetCount( groupIndex );
62 if ( dsCount == 0 )
63 return;
64
65 if ( dsCount == 1 ) //non temporal dataset group
66 continue;
67 for ( int i = 0; i < dsCount; i++ )
68 {
69 const qint64 time = mLayer->datasetRelativeTimeInMilliseconds( QgsMeshDatasetIndex( groupIndex, i ) );
70 if ( time != INVALID_MESHLAYER_TIME )
71 times.insert( time );
72 }
73 }
74 }
75
76 if ( times.isEmpty() )
77 times.insert( 0 );
78
79 mDatasetTimes = QList<qint64>( times.constBegin(), times.constEnd() );
80 std::sort( mDatasetTimes.begin(), mDatasetTimes.end() );
81
82 mDatasetMetaData = QVector<QgsMeshDatasetMetadata>( mDatasetTimes.count() );
83
84 //to fill metadata, calculate all the datasets one time
85 int i = 0;
86 while ( i < mDatasetTimes.count() )
87 {
88 mCurrentDatasetIndex = i;
89 if ( calculateDataset() )
90 ++i; //calculation succeeds
91 else
92 mDatasetTimes.removeAt( i ); //calculation fails, remove this time step
93 }
94
96}
97
99{
100 return mDatasetTimes.count();
101}
102
104{
105 if ( index < 0 || index >= mDatasetTimes.count() )
106 return nullptr;
107
108 if ( index != mCurrentDatasetIndex )
109 {
110 mCurrentDatasetIndex = index;
111 calculateDataset();
112 }
113
114 return mCacheDataset.get();
115}
116
118{
119 if ( datasetIndex < 0 && datasetIndex >= mDatasetMetaData.count() )
120 return QgsMeshDatasetMetadata();
121
122 return mDatasetMetaData.at( datasetIndex );
123}
124
126{
127 return mDatasetGroupNameUsed;
128}
129
130QDomElement QgsMeshVirtualDatasetGroup::writeXml( QDomDocument &doc, const QgsReadWriteContext &context ) const
131{
132 Q_UNUSED( context )
133 QDomElement elemDataset = doc.createElement( u"mesh-dataset"_s );
134 elemDataset.setAttribute( u"source-type"_s, u"virtual"_s );
135 elemDataset.setAttribute( u"name"_s, name() );
136 elemDataset.setAttribute( u"formula"_s, mFormula );
137 elemDataset.setAttribute( u"start-time"_s, mStartTime );
138 elemDataset.setAttribute( u"end-time"_s, mEndTime );
139
140 return elemDataset;
141}
142
144{
145 return mFormula;
146}
147
148bool QgsMeshVirtualDatasetGroup::calculateDataset() const
149{
150 if ( !mLayer )
151 return false;
152
153 const QgsMeshCalcUtils
154 dsu( mLayer, mDatasetGroupNameUsed, mDatasetGroupNameUsedForAggregate, QgsInterval( mDatasetTimes[mCurrentDatasetIndex] / 1000.0 ), QgsInterval( mStartTime / 1000.0 ), QgsInterval( mEndTime / 1000.0 ) );
155
156 if ( !dsu.isValid() )
157 return false;
158
159 //open output dataset
160 auto outputGroup = std::make_unique<QgsMeshMemoryDatasetGroup>( QString(), dsu.outputType() );
161 mCalcNode->calculate( dsu, *outputGroup );
162
163 if ( outputGroup->memoryDatasets.isEmpty() )
164 return false;
165
166 mCacheDataset = outputGroup->memoryDatasets[0];
167 if ( !mDatasetMetaData[mCurrentDatasetIndex].isValid() )
168 {
169 mCacheDataset->calculateMinMax();
170 mCacheDataset->time = mDatasetTimes[mCurrentDatasetIndex] / 3600.0 / 1000.0;
171 mDatasetMetaData[mCurrentDatasetIndex] = mCacheDataset->metadata();
172 }
173
174 return true;
175}
A representation of the interval between two datetime values.
Definition qgsinterval.h:52
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.