From c2bc0f63e353bf114dfc073b2a1aec2c4fbfd88d Mon Sep 17 00:00:00 2001 From: Vincent Cloarec Date: Mon, 27 Apr 2020 05:18:19 -0400 Subject: [PATCH] [MESH] fix mesh calculator saving for windows (#35963) fix mesh calculator saving for windows (fix #35549) --- .../mesh/qgsmeshdataprovider.sip.in | 46 ++++++++++++++++--- src/analysis/mesh/qgsmeshcalculator.cpp | 3 +- src/core/mesh/qgsmeshdataprovider.cpp | 21 +++++++++ src/core/mesh/qgsmeshdataprovider.h | 30 +++++++++++- .../meshmemory/qgsmeshmemorydataprovider.cpp | 9 ++-- .../meshmemory/qgsmeshmemorydataprovider.h | 3 +- src/providers/mdal/qgsmdalprovider.cpp | 32 +++++-------- src/providers/mdal/qgsmdalprovider.h | 3 +- tests/src/analysis/testqgsmeshcalculator.cpp | 24 ++++++++++ 9 files changed, 134 insertions(+), 37 deletions(-) diff --git a/python/core/auto_generated/mesh/qgsmeshdataprovider.sip.in b/python/core/auto_generated/mesh/qgsmeshdataprovider.sip.in index 380da3cc81b..e9ef9dc0169 100644 --- a/python/core/auto_generated/mesh/qgsmeshdataprovider.sip.in +++ b/python/core/auto_generated/mesh/qgsmeshdataprovider.sip.in @@ -267,12 +267,12 @@ Returns whether the faces are active for particular dataset .. versionadded:: 3.6 %End - virtual bool persistDatasetGroup( const QString &path, - const QgsMeshDatasetGroupMetadata &meta, - const QVector &datasetValues, - const QVector &datasetActive, - const QVector × - ) = 0; + virtual bool persistDatasetGroup( const QString &path, + const QgsMeshDatasetGroupMetadata &meta, + const QVector &datasetValues, + const QVector &datasetActive, + const QVector × + ) /Deprecated/; %Docstring Creates a new dataset group from a data and persists it into a destination path @@ -288,7 +288,41 @@ On success, the mesh's dataset group count is changed :return: ``True`` on failure, ``False`` on success +.. note:: + + Doesn't work if there is ":" in the path (e.g. Windows system) + + .. versionadded:: 3.6 + +.. deprecated:: + QGIS 3.12.3 +%End + + virtual bool persistDatasetGroup( const QString &outputFilePath, + const QString &outputDriver, + const QgsMeshDatasetGroupMetadata &meta, + const QVector &datasetValues, + const QVector &datasetActive, + const QVector × + ) = 0; +%Docstring +Creates a new dataset group from a data and +persists it into a destination path + +On success, the mesh's dataset group count is changed + +:param outputFilePath: destination path of the stored file +:param outputDriver: output driver name +:param meta: new group's metadata +:param datasetValues: scalar/vector values for all datasets and all faces/vertices in the group +:param datasetActive: active flag values for all datasets in the group. Empty array represents can be used + when all faces are active +:param times: times in hours for all datasets in the group + +:return: ``True`` on failure, ``False`` on success + +.. versionadded:: 3.12.3 %End }; diff --git a/src/analysis/mesh/qgsmeshcalculator.cpp b/src/analysis/mesh/qgsmeshcalculator.cpp index e7d344bd65c..7786f028543 100644 --- a/src/analysis/mesh/qgsmeshcalculator.cpp +++ b/src/analysis/mesh/qgsmeshcalculator.cpp @@ -235,7 +235,8 @@ QgsMeshCalculator::Result QgsMeshCalculator::processCalculation( QgsFeedback *fe const QgsMeshDatasetGroupMetadata meta = outputGroup->groupMetadata(); bool err = mMeshLayer->dataProvider()->persistDatasetGroup( - mOutputDriver + ':' + mOutputFile, + mOutputFile, + mOutputDriver, meta, datasetValues, datasetActive, diff --git a/src/core/mesh/qgsmeshdataprovider.cpp b/src/core/mesh/qgsmeshdataprovider.cpp index b701856c681..a10e7413de2 100644 --- a/src/core/mesh/qgsmeshdataprovider.cpp +++ b/src/core/mesh/qgsmeshdataprovider.cpp @@ -53,6 +53,27 @@ QgsMeshDatasetGroupMetadata QgsMeshDatasetSourceInterface::datasetGroupMetadata( return datasetGroupMetadata( index.group() ); } +bool QgsMeshDatasetSourceInterface::persistDatasetGroup( + const QString &path, + const QgsMeshDatasetGroupMetadata &meta, + const QVector &datasetValues, + const QVector &datasetActive, + const QVector × ) +{ + // Form DRIVER:filename + QString filename = path; + // ASCII dat supports face, edge and vertex datasets + QString driverName = QStringLiteral( "DAT" ); + QStringList parts = path.split( ':' ); + if ( parts.size() > 1 ) + { + driverName = parts[0]; + parts.removeFirst(); + filename = parts.join( QString() ); + } + return persistDatasetGroup( filename, driverName, meta, datasetValues, datasetActive, times ); +} + QgsMeshVertex QgsMesh::vertex( int index ) const { if ( index < vertices.size() && index >= 0 ) diff --git a/src/core/mesh/qgsmeshdataprovider.h b/src/core/mesh/qgsmeshdataprovider.h index 028edc4ec1c..ab01a031c96 100644 --- a/src/core/mesh/qgsmeshdataprovider.h +++ b/src/core/mesh/qgsmeshdataprovider.h @@ -298,9 +298,37 @@ class CORE_EXPORT QgsMeshDatasetSourceInterface SIP_ABSTRACT * \param times times in hours for all datasets in the group * \returns TRUE on failure, FALSE on success * + * \note Doesn't work if there is ":" in the path (e.g. Windows system) + * * \since QGIS 3.6 + * \deprecated QGIS 3.12.3 */ - virtual bool persistDatasetGroup( const QString &path, + Q_DECL_DEPRECATED virtual bool persistDatasetGroup( const QString &path, + const QgsMeshDatasetGroupMetadata &meta, + const QVector &datasetValues, + const QVector &datasetActive, + const QVector × + ) SIP_DEPRECATED; + + /** + * Creates a new dataset group from a data and + * persists it into a destination path + * + * On success, the mesh's dataset group count is changed + * + * \param outputFilePath destination path of the stored file + * \param outputDriver output driver name + * \param meta new group's metadata + * \param datasetValues scalar/vector values for all datasets and all faces/vertices in the group + * \param datasetActive active flag values for all datasets in the group. Empty array represents can be used + * when all faces are active + * \param times times in hours for all datasets in the group + * \returns TRUE on failure, FALSE on success + * + * \since QGIS 3.12.3 + */ + virtual bool persistDatasetGroup( const QString &outputFilePath, + const QString &outputDriver, const QgsMeshDatasetGroupMetadata &meta, const QVector &datasetValues, const QVector &datasetActive, diff --git a/src/core/providers/meshmemory/qgsmeshmemorydataprovider.cpp b/src/core/providers/meshmemory/qgsmeshmemorydataprovider.cpp index 27c1c601e35..c8706f4cd62 100644 --- a/src/core/providers/meshmemory/qgsmeshmemorydataprovider.cpp +++ b/src/core/providers/meshmemory/qgsmeshmemorydataprovider.cpp @@ -611,13 +611,10 @@ QgsMeshDataBlock QgsMeshMemoryDataset::areFacesActive( int faceIndex, int count return ret; } -bool QgsMeshMemoryDataProvider::persistDatasetGroup( const QString &path, - const QgsMeshDatasetGroupMetadata &meta, - const QVector &datasetValues, - const QVector &datasetActive, - const QVector × ) +bool QgsMeshMemoryDataProvider::persistDatasetGroup( const QString &outputFilePath, const QString &outputDriver, const QgsMeshDatasetGroupMetadata &meta, const QVector &datasetValues, const QVector &datasetActive, const QVector × ) { - Q_UNUSED( path ) + Q_UNUSED( outputFilePath ) + Q_UNUSED( outputDriver ) Q_UNUSED( meta ) Q_UNUSED( datasetValues ) Q_UNUSED( datasetActive ) diff --git a/src/core/providers/meshmemory/qgsmeshmemorydataprovider.h b/src/core/providers/meshmemory/qgsmeshmemorydataprovider.h index a3f1f27d9de..0207b79f394 100644 --- a/src/core/providers/meshmemory/qgsmeshmemorydataprovider.h +++ b/src/core/providers/meshmemory/qgsmeshmemorydataprovider.h @@ -172,7 +172,8 @@ class CORE_EXPORT QgsMeshMemoryDataProvider final: public QgsMeshDataProvider bool isFaceActive( QgsMeshDatasetIndex index, int faceIndex ) const override; QgsMeshDataBlock areFacesActive( QgsMeshDatasetIndex index, int faceIndex, int count ) const override; - bool persistDatasetGroup( const QString &path, + bool persistDatasetGroup( const QString &outputFilePath, + const QString &outputDriver, const QgsMeshDatasetGroupMetadata &meta, const QVector &datasetValues, const QVector &datasetActive, diff --git a/src/providers/mdal/qgsmdalprovider.cpp b/src/providers/mdal/qgsmdalprovider.cpp index 7d30c71fa5c..c5578a5a4ae 100644 --- a/src/providers/mdal/qgsmdalprovider.cpp +++ b/src/providers/mdal/qgsmdalprovider.cpp @@ -218,12 +218,14 @@ QgsRectangle QgsMdalProvider::extent() const return ret; } -bool QgsMdalProvider::persistDatasetGroup( const QString &path, - const QgsMeshDatasetGroupMetadata &meta, - const QVector &datasetValues, - const QVector &datasetActive, - const QVector × - ) +bool QgsMdalProvider::persistDatasetGroup( + const QString &outputFilePath, + const QString &outputDriver, + const QgsMeshDatasetGroupMetadata &meta, + const QVector &datasetValues, + const QVector &datasetActive, + const QVector × +) { if ( !mMeshH ) return true; @@ -246,22 +248,10 @@ bool QgsMdalProvider::persistDatasetGroup( const QString &path, return true; } - if ( path.isEmpty() ) + if ( outputFilePath.isEmpty() ) return true; - // Form DRIVER:filename - QString filename = path; - // ASCII dat supports face, edge and vertex datasets - QString driverName = QStringLiteral( "DAT" ); - QStringList parts = path.split( ':' ); - if ( parts.size() > 1 ) - { - driverName = parts[0]; - parts.removeFirst(); - filename = parts.join( QString() ); - } - - MDAL_DriverH driver = MDAL_driverFromName( driverName.toStdString().c_str() ); + MDAL_DriverH driver = MDAL_driverFromName( outputDriver.toStdString().c_str() ); if ( !driver ) return true; @@ -288,7 +278,7 @@ bool QgsMdalProvider::persistDatasetGroup( const QString &path, location, meta.isScalar(), driver, - filename.toStdString().c_str() + outputFilePath.toStdString().c_str() ); if ( !g ) return true; diff --git a/src/providers/mdal/qgsmdalprovider.h b/src/providers/mdal/qgsmdalprovider.h index 040df44a812..bd7611418fc 100644 --- a/src/providers/mdal/qgsmdalprovider.h +++ b/src/providers/mdal/qgsmdalprovider.h @@ -78,7 +78,8 @@ class QgsMdalProvider : public QgsMeshDataProvider QgsMeshDataBlock areFacesActive( QgsMeshDatasetIndex index, int faceIndex, int count ) const override; QgsRectangle extent() const override; - bool persistDatasetGroup( const QString &path, + bool persistDatasetGroup( const QString &outputFilePath, + const QString &outputDriver, const QgsMeshDatasetGroupMetadata &meta, const QVector &datasetValues, const QVector &datasetActive, diff --git a/tests/src/analysis/testqgsmeshcalculator.cpp b/tests/src/analysis/testqgsmeshcalculator.cpp index 3c6fe6c1e19..cde62992e83 100644 --- a/tests/src/analysis/testqgsmeshcalculator.cpp +++ b/tests/src/analysis/testqgsmeshcalculator.cpp @@ -48,6 +48,9 @@ class TestQgsMeshCalculator : public QObject void calcWithVertexLayers(); void calcWithFaceLayers(); void calcWithMixedLayers(); + + void calcAndSave(); + private: QgsMeshLayer *mpMeshLayer = nullptr; @@ -292,5 +295,26 @@ void TestQgsMeshCalculator::calcWithMixedLayers() QCOMPARE( val.scalar(), 2.0 ); } +void TestQgsMeshCalculator::calcAndSave() +{ + QgsRectangle extent( 1000.000, 1000.000, 3000.000, 3000.000 ); + + QString tempFilePath = QDir::tempPath() + '/' + "meshCalculatorResult.out"; + QgsMeshCalculator rc( QStringLiteral( "\"VertexScalarDataset\" + \"FaceScalarDataset\"" ), + QStringLiteral( "BINARY_DAT" ), + "NewMixScalarDataset", + tempFilePath, + extent, + 0, + 3600, + mpMeshLayer + ); + + rc.processCalculation(); + + QFileInfo fileInfo( tempFilePath ); + QVERIFY( fileInfo.exists() ); +} + QGSTEST_MAIN( TestQgsMeshCalculator ) #include "testqgsmeshcalculator.moc"