Skip to content
Permalink
Browse files
implement setDataSource for mesh layer
  • Loading branch information
vcloarec authored and nyalldawson committed May 20, 2021
1 parent fa195f1 commit 7a1c29d3979df98fece8e934e425f56585507739
@@ -49,13 +49,36 @@ QgsMeshDatasetGroupStore::QgsMeshDatasetGroupStore( QgsMeshLayer *layer ):
{}

void QgsMeshDatasetGroupStore::setPersistentProvider( QgsMeshDataProvider *provider )
{
setPersistentProvider( provider, QStringList() );
}

void QgsMeshDatasetGroupStore::setPersistentProvider( QgsMeshDataProvider *provider, const QStringList &extraDatasetUri )
{
removePersistentProvider();
mPersistentProvider = provider;
if ( !mPersistentProvider )
return;
connect( mPersistentProvider, &QgsMeshDataProvider::datasetGroupsAdded, this, &QgsMeshDatasetGroupStore::onPersistentDatasetAdded );
for ( const QString &uri : extraDatasetUri )
mPersistentProvider->addDataset( uri );

onPersistentDatasetAdded( mPersistentProvider->datasetGroupCount() );

checkDatasetConsistency( mPersistentProvider );
removeUnregisteredItemFromTree();

//Once everything is in place, initialize the extra dataset groups
if ( mExtraDatasets )
{
int groupCount = mExtraDatasets->datasetGroupCount();
for ( int i = 0; i < groupCount; ++i )
if ( mExtraDatasets->datasetGroup( i ) )
mExtraDatasets->datasetGroup( i )->initialize();
}

mExtraDatasets->updateTemporalCapabilities();

connect( mPersistentProvider, &QgsMeshDataProvider::datasetGroupsAdded, this, &QgsMeshDatasetGroupStore::onPersistentDatasetAdded );
}

QgsMeshDatasetGroupStore::DatasetGroup QgsMeshDatasetGroupStore::datasetGroup( int index ) const
@@ -248,8 +271,8 @@ QDomElement QgsMeshDatasetGroupStore::writeXml( QDomDocument &doc, const QgsRead
QDomElement storeElement = doc.createElement( QStringLiteral( "mesh-dataset-groups-store" ) );
storeElement.appendChild( mDatasetGroupTreeRootItem->writeXml( doc, context ) );

QMap < int, DatasetGroup>::const_iterator it = mRegistery.begin();
while ( it != mRegistery.end() )
QMap < int, DatasetGroup>::const_iterator it = mRegistery.constBegin();
while ( it != mRegistery.constEnd() )
{
QDomElement elemDataset;
if ( it.value().first == mPersistentProvider )
@@ -258,7 +281,6 @@ QDomElement QgsMeshDatasetGroupStore::writeXml( QDomDocument &doc, const QgsRead
elemDataset.setAttribute( QStringLiteral( "global-index" ), it.key() );
elemDataset.setAttribute( QStringLiteral( "source-type" ), QStringLiteral( "persitent-provider" ) );
elemDataset.setAttribute( QStringLiteral( "source-index" ), it.value().second );

}
else if ( it.value().first == mExtraDatasets.get() )
{
@@ -294,6 +316,7 @@ void QgsMeshDatasetGroupStore::readXml( const QDomElement &storeElem, const QgsR
{
source = mPersistentProvider;
sourceIndex = datasetElem.attribute( QStringLiteral( "source-index" ) ).toInt();
mPersistentExtraDatasetGroupIndexes.append( globalIndex );
}
else if ( datasetElem.attribute( QStringLiteral( "source-type" ) ) == QLatin1String( "virtual" ) )
{
@@ -308,27 +331,17 @@ void QgsMeshDatasetGroupStore::readXml( const QDomElement &storeElem, const QgsR
sourceIndex = mExtraDatasets->addDatasetGroup( dsg );
}

if ( source )
mRegistery[globalIndex] = DatasetGroup{source, sourceIndex};
mRegistery[globalIndex] = DatasetGroup{source, sourceIndex};

datasetElem = datasetElem.nextSiblingElement( QStringLiteral( "mesh-dataset" ) );
}

QDomElement rootTreeItemElem = storeElem.firstChildElement( QStringLiteral( "mesh-dataset-group-tree-item" ) );
if ( !rootTreeItemElem.isNull() )
setDatasetGroupTreeItem( new QgsMeshDatasetGroupTreeItem( rootTreeItemElem, context ) );

checkDatasetConsistency( mPersistentProvider );
removeUnregisteredItemFromTree();

//Once everything is created, initialize the extra dataset groups
for ( int groupIndex : extraDatasetGroups.keys() )
extraDatasetGroups.value( groupIndex )->initialize();


mExtraDatasets->updateTemporalCapabilities();
}


bool QgsMeshDatasetGroupStore::saveDatasetGroup( QString filePath, int groupIndex, QString driver )
{
DatasetGroup group = datasetGroup( groupIndex );
@@ -361,15 +374,25 @@ void QgsMeshDatasetGroupStore::onPersistentDatasetAdded( int count )

int providerTotalCount = mPersistentProvider->datasetGroupCount();
int providerBeginIndex = mPersistentProvider->datasetGroupCount() - count;
QList<int> groupIndexes;
QList<int> newGroupIndexes;
for ( int i = providerBeginIndex; i < providerTotalCount; ++i )
groupIndexes.append( registerDatasetGroup( DatasetGroup{mPersistentProvider, i} ) );
{
if ( i < mPersistentExtraDatasetGroupIndexes.count() )
mRegistery[mPersistentExtraDatasetGroupIndexes.at( i )] = DatasetGroup( mPersistentProvider, i );
else
newGroupIndexes.append( registerDatasetGroup( DatasetGroup{mPersistentProvider, i} ) );
}

createDatasetGroupTreeItems( groupIndexes );
for ( int groupIndex : groupIndexes )
syncItemToDatasetGroup( groupIndex );
if ( !newGroupIndexes.isEmpty() )
{
createDatasetGroupTreeItems( newGroupIndexes );
mPersistentExtraDatasetGroupIndexes.append( newGroupIndexes );

emit datasetGroupsAdded( groupIndexes );
for ( int groupIndex : std::as_const( newGroupIndexes ) )
syncItemToDatasetGroup( groupIndex );

emit datasetGroupsAdded( newGroupIndexes );
}
}

void QgsMeshDatasetGroupStore::removePersistentProvider()
@@ -436,8 +459,8 @@ void QgsMeshDatasetGroupStore::eraseExtraDataset( int indexInExtraStore )

int QgsMeshDatasetGroupStore::nativeIndexToGroupIndex( QgsMeshDatasetSourceInterface *source, int nativeIndex )
{
QMap < int, DatasetGroup>::const_iterator it = mRegistery.begin();
while ( it != mRegistery.end() )
QMap < int, DatasetGroup>::const_iterator it = mRegistery.constBegin();
while ( it != mRegistery.constEnd() )
{
if ( it.value() == DatasetGroup{source, nativeIndex} )
return it.key();
@@ -456,8 +479,14 @@ void QgsMeshDatasetGroupStore::checkDatasetConsistency( QgsMeshDatasetSourceInte

if ( !indexes.isEmpty() )
createDatasetGroupTreeItems( indexes );
for ( int index : indexes )
syncItemToDatasetGroup( index );
// for ( int index : std::as_const( indexes ) )
// syncItemToDatasetGroup( index );

for ( int globalIndex : mRegistery.keys() )
{
if ( mRegistery.value( globalIndex ).first == source )
syncItemToDatasetGroup( globalIndex );
}
}

void QgsMeshDatasetGroupStore::removeUnregisteredItemFromTree()
@@ -112,7 +112,7 @@ class QgsMeshExtraDatasetStore: public QgsMeshDatasetSourceInterface
* The native group index is not exposed and global index can be obtained with datasetGroupIndexes() that returns the list of global index available.
* The dataset index is the same than in the native source (data provider or other dataset source)
*
* This class as also the responsibility to handle the dataset group tree item that contain information to display the available dataset (\see QgsMeshDatasetGroupTreeItem)
* This class has also the responsibility to handle the dataset group tree item that contain information to display the available dataset (\see QgsMeshDatasetGroupTreeItem)
*
* \since QGIS 3.16
*/
@@ -127,8 +127,19 @@ class QgsMeshDatasetGroupStore: public QObject
//! Constructor
QgsMeshDatasetGroupStore( QgsMeshLayer *layer );

//! Sets the persistent mesh data provider
void setPersistentProvider( QgsMeshDataProvider *provider );
/**
* Sets the persistent mesh data provider
*
* \deprecated since QGIS 3.20
*/
Q_DECL_DEPRECATED void setPersistentProvider( QgsMeshDataProvider *provider );

/**
* Sets the persistent mesh data provider with the path of its extra dataset
*
* \since QGIS 3.20
*/
void setPersistentProvider( QgsMeshDataProvider *provider, const QStringList &extraDatasetUri );

//! Adds persistent datasets from a file with \a path
bool addPersistentDatasets( const QString &path );
@@ -220,6 +231,7 @@ class QgsMeshDatasetGroupStore: public QObject
private:
QgsMeshLayer *mLayer = nullptr;
QgsMeshDataProvider *mPersistentProvider = nullptr;
QList<int> mPersistentExtraDatasetGroupIndexes;
std::unique_ptr<QgsMeshExtraDatasetStore> mExtraDatasets;
QMap < int, DatasetGroup> mRegistery;
std::unique_ptr<QgsMeshDatasetGroupTreeItem> mDatasetGroupTreeRootItem;
@@ -51,31 +51,18 @@ QgsMeshLayer::QgsMeshLayer( const QString &meshLayerPath,
{
mShouldValidateCrs = !options.skipCrsValidation;

setProviderType( providerKey );
// if we’re given a provider type, try to create and bind one to this layer
bool ok = false;
if ( !meshLayerPath.isEmpty() && !providerKey.isEmpty() )
QgsDataProvider::ProviderOptions providerOptions { options.transformContext };
QgsDataProvider::ReadFlags flags = QgsDataProvider::ReadFlags();
if ( mReadFlags & QgsMapLayer::FlagTrustLayerMetadata )
{
QgsDataProvider::ProviderOptions providerOptions { options.transformContext };
QgsDataProvider::ReadFlags flags = QgsDataProvider::ReadFlags();
if ( mReadFlags & QgsMapLayer::FlagTrustLayerMetadata )
{
flags |= QgsDataProvider::FlagTrustDataSource;
}
ok = setDataProvider( providerKey, providerOptions, flags );
flags |= QgsDataProvider::FlagTrustDataSource;
}

setDataSourcePrivate( meshLayerPath, baseName, providerKey, providerOptions, flags );
resetDatasetGroupTreeItem();
setLegend( QgsMapLayerLegend::defaultMeshLegend( this ) );
if ( ok )
{
setDefaultRendererSettings( mDatasetGroupStore->datasetGroupIndexes() );

if ( mDataProvider )
{
mTemporalProperties->setDefaultsFromDataProviderTemporalCapabilities( mDataProvider->temporalCapabilities() );
resetDatasetGroupTreeItem();
}
}
if ( isValid() )
setDefaultRendererSettings( mDatasetGroupStore->datasetGroupIndexes() );

connect( mDatasetGroupStore.get(), &QgsMeshDatasetGroupStore::datasetGroupsAdded, this, &QgsMeshLayer::onDatasetGroupsAdded );
}
@@ -199,6 +186,7 @@ bool QgsMeshLayer::addDatasets( const QString &path, const QDateTime &defaultRef
bool isTemporalBefore = dataProvider()->temporalCapabilities()->hasTemporalCapabilities();
if ( mDatasetGroupStore->addPersistentDatasets( path ) )
{
mExtraDatasetUri.append( path );
QgsMeshLayerTemporalProperties *temporalProperties = qobject_cast< QgsMeshLayerTemporalProperties * >( mTemporalProperties );
if ( !isTemporalBefore && dataProvider()->temporalCapabilities()->hasTemporalCapabilities() )
{
@@ -920,6 +908,26 @@ void QgsMeshLayer::updateActiveDatasetGroups()
emit activeVectorDatasetGroupChanged( settings.activeVectorDatasetGroup() );
}

void QgsMeshLayer::setDataSourcePrivate( const QString &dataSource, const QString &baseName, const QString &provider, const QgsDataProvider::ProviderOptions &options, QgsDataProvider::ReadFlags flags )
{
mDataSource = dataSource;
mLayerName = baseName;
setProviderType( provider );

// if we’re given a provider type, try to create and bind one to this layer
bool ok = false;
if ( !mDataSource.isEmpty() && !provider.isEmpty() )
{
ok = setDataProvider( provider, options, flags );
}

if ( ok )
{
mTemporalProperties->setDefaultsFromDataProviderTemporalCapabilities( mDataProvider->temporalCapabilities() );
mDataProvider->setTemporalUnit( mTemporalUnit );
}
}

QgsPointXY QgsMeshLayer::snapOnElement( QgsMesh::ElementType elementType, const QgsPointXY &point, double searchRadius )
{
switch ( elementType )
@@ -1170,10 +1178,6 @@ bool QgsMeshLayer::readXml( const QDomNode &layer_node, QgsReadWriteContext &con
{
flags |= QgsDataProvider::FlagTrustDataSource;
}
if ( !setDataProvider( mProviderKey, providerOptions, flags ) )
{
return false;
}

QDomElement elemExtraDatasets = layer_node.firstChildElement( QStringLiteral( "extra-datasets" ) );
if ( !elemExtraDatasets.isNull() )
@@ -1182,29 +1186,20 @@ bool QgsMeshLayer::readXml( const QDomNode &layer_node, QgsReadWriteContext &con
while ( !elemUri.isNull() )
{
QString uri = context.pathResolver().readPath( elemUri.text() );

bool res = mDataProvider->addDataset( uri );
#ifdef QGISDEBUG
QgsDebugMsg( QStringLiteral( "extra dataset (res %1): %2" ).arg( res ).arg( uri ) );
#else
( void )res; // avoid unused warning in release builds
#endif

mExtraDatasetUri.append( uri );
elemUri = elemUri.nextSiblingElement( QStringLiteral( "uri" ) );
}
}

if ( mDataProvider && pkeyNode.toElement().hasAttribute( QStringLiteral( "time-unit" ) ) )
mDataProvider->setTemporalUnit(
static_cast<QgsUnitTypes::TemporalUnit>( pkeyNode.toElement().attribute( QStringLiteral( "time-unit" ) ).toInt() ) );

// read dataset group store
QDomElement elemDatasetGroupsStore = layer_node.firstChildElement( QStringLiteral( "mesh-dataset-groups-store" ) );
if ( elemDatasetGroupsStore.isNull() )
resetDatasetGroupTreeItem();
else
mDatasetGroupStore->readXml( elemDatasetGroupsStore, context );

setDataProvider( mProviderKey, providerOptions, flags );

QString errorMsg;
readSymbology( layer_node, errorMsg, context );

@@ -1400,12 +1395,14 @@ QString QgsMeshLayer::htmlMetadata() const

bool QgsMeshLayer::setDataProvider( QString const &provider, const QgsDataProvider::ProviderOptions &options, QgsDataProvider::ReadFlags flags )
{
delete mDataProvider;
mDatasetGroupStore->setPersistentProvider( nullptr, QStringList() );

delete mDataProvider;
mProviderKey = provider;
QString dataSource = mDataSource;

mDataProvider = qobject_cast<QgsMeshDataProvider *>( QgsProviderRegistry::instance()->createProvider( provider, dataSource, options, flags ) );

if ( !mDataProvider )
{
QgsDebugMsgLevel( QStringLiteral( "Unable to get mesh data provider" ), 2 );
@@ -1422,6 +1419,8 @@ bool QgsMeshLayer::setDataProvider( QString const &provider, const QgsDataProvid
return false;
}

mDatasetGroupStore->setPersistentProvider( mDataProvider, mExtraDatasetUri );

setCrs( mDataProvider->crs() );

if ( provider == QLatin1String( "mesh_memory" ) )
@@ -1430,8 +1429,6 @@ bool QgsMeshLayer::setDataProvider( QString const &provider, const QgsDataProvid
mDataSource = mDataSource + QStringLiteral( "&uid=%1" ).arg( QUuid::createUuid().toString() );
}

mDatasetGroupStore->setPersistentProvider( mDataProvider );

for ( int i = 0; i < mDataProvider->datasetGroupCount(); ++i )
assignDefaultStyleToDatasetGroup( i );

@@ -788,6 +788,9 @@ class CORE_EXPORT QgsMeshLayer : public QgsMapLayer
//! Pointer to data provider derived from the abastract base class QgsMeshDataProvider
QgsMeshDataProvider *mDataProvider = nullptr;

//! List of extra dataset uri associated with this layer
QStringList mExtraDatasetUri;

std::unique_ptr<QgsMeshDatasetGroupStore> mDatasetGroupStore;

//! Pointer to native mesh structure, used as cache for rendering
@@ -808,7 +811,10 @@ class CORE_EXPORT QgsMeshLayer : public QgsMapLayer
//! Simplify mesh configuration
QgsMeshSimplificationSettings mSimplificationSettings;

QgsMeshLayerTemporalProperties *mTemporalProperties;
QgsMeshLayerTemporalProperties *mTemporalProperties = nullptr;

//! Temporal unit used by the provider
QgsUnitTypes::TemporalUnit mTemporalUnit = QgsUnitTypes::TemporalHours;

int mStaticScalarDatasetIndex = 0;
int mStaticVectorDatasetIndex = 0;
@@ -825,6 +831,9 @@ class CORE_EXPORT QgsMeshLayer : public QgsMapLayer
QgsPointXY snapOnFace( const QgsPointXY &point, double searchRadius );

void updateActiveDatasetGroups();

void setDataSourcePrivate( const QString &dataSource, const QString &baseName, const QString &provider,
const QgsDataProvider::ProviderOptions &options, QgsDataProvider::ReadFlags flags ) override;
};

#endif //QGSMESHLAYER_H

0 comments on commit 7a1c29d

Please sign in to comment.