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