Skip to content
Permalink
Browse files
save mesh from URI (#44758)
[mesh] fix saving a mesh frame with URI
  • Loading branch information
vcloarec committed Aug 19, 2021
1 parent 2cdc666 commit bd6ac0e54df1332eb59c13787e3367090e503e65
@@ -396,13 +396,23 @@ Creates a new instance of the raster data provider.

virtual bool createMeshData(
const QgsMesh &mesh,
const QString uri,
const QString &fileName,
const QString &driverName,
const QgsCoordinateReferenceSystem &crs ) const;
%Docstring
Creates mesh data source, that is the mesh frame stored in file, memory or with other way (depending of the provider)
Creates mesh data source from a file name ``fileName`` and a driver ``driverName``, that is the mesh frame stored in file, memory or with other way (depending of the provider)

.. versionadded:: 3.16
%End

virtual bool createMeshData(
const QgsMesh &mesh,
const QString &uri,
const QgsCoordinateReferenceSystem &crs ) const;
%Docstring
Creates mesh data source from an ``uri``, that is the mesh frame stored in file, memory or with other way (depending of the provider)

.. versionadded:: 3.22
%End

virtual QList<QPair<QString, QString> > pyramidResamplingMethods();
@@ -192,11 +192,17 @@ QgsRasterDataProvider *QgsProviderMetadata::createRasterDataProvider(
return nullptr;
}

bool QgsProviderMetadata::createMeshData(
const QgsMesh &,
const QString,
const QString &,
const QgsCoordinateReferenceSystem & ) const
bool QgsProviderMetadata::createMeshData( const QgsMesh &,
const QString &,
const QString &,
const QgsCoordinateReferenceSystem & ) const
{
return false;
}

bool QgsProviderMetadata::createMeshData( const QgsMesh &,
const QString &,
const QgsCoordinateReferenceSystem & ) const
{
return false;
}
@@ -466,15 +466,24 @@ class CORE_EXPORT QgsProviderMetadata : public QObject
const QStringList &createOptions = QStringList() ) SIP_FACTORY;

/**
* Creates mesh data source, that is the mesh frame stored in file, memory or with other way (depending of the provider)
* Creates mesh data source from a file name \a fileName and a driver \a driverName, that is the mesh frame stored in file, memory or with other way (depending of the provider)
* \since QGIS 3.16
*/
virtual bool createMeshData(
const QgsMesh &mesh,
const QString uri,
const QString &fileName,
const QString &driverName,
const QgsCoordinateReferenceSystem &crs ) const;

/**
* Creates mesh data source from an \a uri, that is the mesh frame stored in file, memory or with other way (depending of the provider)
* \since QGIS 3.22
*/
virtual bool createMeshData(
const QgsMesh &mesh,
const QString &uri,
const QgsCoordinateReferenceSystem &crs ) const;

/**
* Returns pyramid resampling methods available for provider
* \since QGIS 3.10
@@ -459,7 +459,16 @@ bool QgsMdalProvider::persistDatasetGroup( const QString &outputFilePath, const
bool QgsMdalProvider::saveMeshFrame( const QgsMesh &mesh )
{
QgsMdalProviderMetadata mdalProviderMetaData;
return mdalProviderMetaData.createMeshData( mesh, dataSourceUri(), mDriverName, crs() );

QVariantMap uriComponent = mdalProviderMetaData.decodeUri( dataSourceUri() );

if ( uriComponent.contains( QStringLiteral( "driver" ) ) )
return mdalProviderMetaData.createMeshData( mesh, dataSourceUri(), crs() );
else if ( uriComponent.contains( QStringLiteral( "path" ) ) )
return mdalProviderMetaData.createMeshData( mesh, uriComponent.value( QStringLiteral( "path" ) ).toString(), mDriverName, crs() );

return false;

}

void QgsMdalProvider::close()
@@ -960,16 +969,17 @@ QgsMdalProvider *QgsMdalProviderMetadata::createProvider( const QString &uri, co
return new QgsMdalProvider( uri, options, flags );
}

bool QgsMdalProviderMetadata::createMeshData( const QgsMesh &mesh, const QString uri, const QString &driverName, const QgsCoordinateReferenceSystem &crs ) const

static MDAL_MeshH createMDALMesh( const QgsMesh &mesh, const QString &driverName, const QgsCoordinateReferenceSystem &crs )
{
MDAL_DriverH driver = MDAL_driverFromName( driverName.toStdString().c_str() );
if ( !driver )
return false;
return nullptr;

MDAL_MeshH mdalMesh = MDAL_CreateMesh( driver );

if ( !mdalMesh )
return false;
return nullptr;

int bufferSize = 2000;
int vertexIndex = 0;
@@ -1008,14 +1018,51 @@ bool QgsMdalProviderMetadata::createMeshData( const QgsMesh &mesh, const QString
if ( MDAL_LastStatus() != MDAL_Status::None )
{
MDAL_CloseMesh( mdalMesh );
return false;
return nullptr;
}
faceIndex += faceCount;
}

MDAL_M_setProjection( mdalMesh, crs.toWkt( QgsCoordinateReferenceSystem::WKT_PREFERRED ).toStdString().c_str() );

MDAL_SaveMesh( mdalMesh, uri.toStdString().c_str(), driverName.toStdString().c_str() );
return mdalMesh;
}


bool QgsMdalProviderMetadata::createMeshData( const QgsMesh &mesh, const QString &fileName, const QString &driverName, const QgsCoordinateReferenceSystem &crs ) const
{
MDAL_MeshH mdalMesh = createMDALMesh( mesh, driverName, crs );

if ( !mdalMesh )
return false;

MDAL_SaveMesh( mdalMesh, fileName.toStdString().c_str(), driverName.toStdString().c_str() );

if ( MDAL_LastStatus() != MDAL_Status::None )
{
MDAL_CloseMesh( mdalMesh );
return false;
}

MDAL_CloseMesh( mdalMesh );
return true;
}

bool QgsMdalProviderMetadata::createMeshData( const QgsMesh &mesh, const QString &uri, const QgsCoordinateReferenceSystem &crs ) const
{
QVariantMap uriComponents = decodeUri( uri );

if ( !uriComponents.contains( QStringLiteral( "driver" ) ) || !uriComponents.contains( QStringLiteral( "path" ) ) )
return false;

MDAL_MeshH mdalMesh = createMDALMesh( mesh,
uriComponents.value( QStringLiteral( "driver" ) ).toString()
, crs );

if ( !mdalMesh )
return false;

MDAL_SaveMeshWithUri( mdalMesh, uri.toStdString().c_str() );

if ( MDAL_LastStatus() != MDAL_Status::None )
{
@@ -1031,7 +1078,7 @@ QVariantMap QgsMdalProviderMetadata::decodeUri( const QString &uri ) const
{
QVariantMap uriComponents;

const QRegularExpression layerRegex( QStringLiteral( "^([a-zA-Z0-9]+?):\"(.*)\":([a-zA-Z0-9]+?)$" ) );
const QRegularExpression layerRegex( QStringLiteral( "^([a-zA-Z0-9]+?):\"(.*)\"(?::([a-zA-Z0-9]+?$)|($))" ) );
const QRegularExpressionMatch layerNameMatch = layerRegex.match( uri );
if ( layerNameMatch.hasMatch() )
{
@@ -1049,12 +1096,17 @@ QVariantMap QgsMdalProviderMetadata::decodeUri( const QString &uri ) const

QString QgsMdalProviderMetadata::encodeUri( const QVariantMap &parts ) const
{
if ( !parts.value( QStringLiteral( "layerName" ) ).toString().isEmpty() )
if ( !parts.value( QStringLiteral( "layerName" ) ).toString().isEmpty() && !parts.value( QStringLiteral( "driver" ) ).toString().isEmpty() )
{
return QStringLiteral( "%1:\"%2\":%3" ).arg( parts.value( QStringLiteral( "driver" ) ).toString(),
parts.value( QStringLiteral( "path" ) ).toString(),
parts.value( QStringLiteral( "layerName" ) ).toString() );
}
else if ( !parts.value( QStringLiteral( "driver" ) ).toString().isEmpty() )
{
return QStringLiteral( "%1:\"%2\"" ).arg( parts.value( QStringLiteral( "driver" ) ).toString(),
parts.value( QStringLiteral( "path" ) ).toString() );
}
else
{
return parts.value( QStringLiteral( "path" ) ).toString();
@@ -147,9 +147,12 @@ class QgsMdalProviderMetadata: public QgsProviderMetadata
QList<QgsMeshDriverMetadata> meshDriversMetadata() override;
QgsMdalProvider *createProvider( const QString &uri, const QgsDataProvider::ProviderOptions &options, QgsDataProvider::ReadFlags flags = QgsDataProvider::ReadFlags() ) override;
bool createMeshData( const QgsMesh &mesh,
const QString uri,
const QString &fileName,
const QString &driverName,
const QgsCoordinateReferenceSystem &crs ) const override;
bool createMeshData( const QgsMesh &mesh,
const QString &uri,
const QgsCoordinateReferenceSystem &crs ) const override;
QVariantMap decodeUri( const QString &uri ) const override;
QString encodeUri( const QVariantMap &parts ) const override;
ProviderCapabilities providerCapabilities() const override;
@@ -1610,7 +1610,7 @@ void TestQgsMeshLayer::testMdalProviderQuerySublayers()
QCOMPARE( res.at( 0 ).name(), QStringLiteral( "quad_and_triangle" ) );
QCOMPARE( res.at( 0 ).uri(), QStringLiteral( "2DM:\"%1/quad_and_triangle.2dm\"" ).arg( mDataDir ) );
QCOMPARE( res.at( 0 ).providerKey(), QStringLiteral( "mdal" ) );
QCOMPARE( res.at( 0 ).driverName(), QString() );
QCOMPARE( res.at( 0 ).driverName(), QStringLiteral( "2DM" ) );
QCOMPARE( res.at( 0 ).type(), QgsMapLayerType::MeshLayer );

// make sure result is valid to load layer from
@@ -1626,7 +1626,7 @@ void TestQgsMeshLayer::testMdalProviderQuerySublayers()
QCOMPARE( res.at( 0 ).uri(), QStringLiteral( "2DM:\"%1/quad_and_triangle.2dm\"" ).arg( mDataDir ) );
QCOMPARE( res.at( 0 ).providerKey(), QStringLiteral( "mdal" ) );
QCOMPARE( res.at( 0 ).type(), QgsMapLayerType::MeshLayer );
QCOMPARE( res.at( 0 ).driverName(), QString() );
QCOMPARE( res.at( 0 ).driverName(), "2DM" );
ml.reset( qgis::down_cast< QgsMeshLayer * >( res.at( 0 ).toLayer( options ) ) );
QVERIFY( ml->isValid() );

@@ -97,12 +97,19 @@ void TestQgsMdalProvider::encodeDecodeUri()
QCOMPARE( parts.value( QStringLiteral( "layerName" ) ).toString(), QString() );
QCOMPARE( mdalMetadata->encodeUri( parts ), QStringLiteral( "/home/data/test.nc" ) );

// uri with layer name
// uri with driver and layer name
parts = mdalMetadata->decodeUri( QStringLiteral( "netcdf:\"/home/data/test.nc\":layer3" ) );
QCOMPARE( parts.value( QStringLiteral( "path" ) ).toString(), QStringLiteral( "/home/data/test.nc" ) );
QCOMPARE( parts.value( QStringLiteral( "driver" ) ).toString(), QStringLiteral( "netcdf" ) );
QCOMPARE( parts.value( QStringLiteral( "layerName" ) ).toString(), QStringLiteral( "layer3" ) );
QCOMPARE( mdalMetadata->encodeUri( parts ), QStringLiteral( "netcdf:\"/home/data/test.nc\":layer3" ) );

// uri with driver
parts = mdalMetadata->decodeUri( QStringLiteral( "Ugrid:\"/home/data/test.nc\"" ) );
QCOMPARE( parts.value( QStringLiteral( "path" ) ).toString(), QStringLiteral( "/home/data/test.nc" ) );
QCOMPARE( parts.value( QStringLiteral( "driver" ) ).toString(), QStringLiteral( "Ugrid" ) );
QCOMPARE( parts.value( QStringLiteral( "layerName" ) ).toString(), QString() );
QCOMPARE( mdalMetadata->encodeUri( parts ), QStringLiteral( "Ugrid:\"/home/data/test.nc\"" ) );
}

void TestQgsMdalProvider::load()

0 comments on commit bd6ac0e

Please sign in to comment.