mirror of
https://github.com/qgis/QGIS.git
synced 2025-04-15 00:04:00 -04:00
Allow to declare layer dependencies on a vector layer
This commit is contained in:
parent
f8f056e0b2
commit
020dac0702
@ -322,6 +322,11 @@ class QgsVectorDataProvider : QgsDataProvider
|
||||
|
||||
virtual void forceReload();
|
||||
|
||||
/**
|
||||
* Get the list of layer ids on which this layer depends. This in particular determines the order of layer loading.
|
||||
*/
|
||||
virtual QSet<QString> layerDependencies() const;
|
||||
|
||||
protected:
|
||||
void clearMinMaxCache();
|
||||
void fillMinMaxCache();
|
||||
|
@ -441,6 +441,11 @@ class QgsVectorLayer : QgsMapLayer
|
||||
|
||||
const QList<QgsVectorJoinInfo> vectorJoins() const;
|
||||
|
||||
/**
|
||||
* Get the list of layer ids on which this layer depends. This in particular determines the order of layer loading.
|
||||
*/
|
||||
virtual QSet<QString> layerDependencies() const;
|
||||
|
||||
/**
|
||||
* Add a new field which is calculated by the expression specified
|
||||
*
|
||||
|
@ -672,12 +672,82 @@ QPair< bool, QList<QDomNode> > QgsProject::_getMapLayers( QDomDocument const &do
|
||||
|
||||
emit layerLoaded( 0, nl.count() );
|
||||
|
||||
// Collect vector layers with joins.
|
||||
// They need to refresh join caches and symbology infos after all layers are loaded
|
||||
QList< QPair< QgsVectorLayer*, QDomElement > > vLayerList;
|
||||
// Determine a loading order of layers based on a graph of dependencies
|
||||
QMap< QString, QVector< QString > > dependencies;
|
||||
QVector<QString> sortedLayers;
|
||||
QMap<QString, int> layerIdIdx;
|
||||
QList<QString> layersToSort;
|
||||
|
||||
for ( int i = 0; i < nl.count(); i++ )
|
||||
{
|
||||
QVector<QString> deps;
|
||||
QDomNode node = nl.item( i );
|
||||
QDomElement element = node.toElement();
|
||||
|
||||
QString id = node.namedItem( "id" ).toElement().text();
|
||||
|
||||
// dependencies for this layer
|
||||
QDomElement layerDependenciesElem = node.firstChildElement( "layerDependencies" );
|
||||
if ( !layerDependenciesElem.isNull() )
|
||||
{
|
||||
QDomNodeList dependencyList = layerDependenciesElem.elementsByTagName( "layer" );
|
||||
for ( int j = 0; j < dependencyList.size(); ++j )
|
||||
{
|
||||
QDomElement depElem = dependencyList.at( j ).toElement();
|
||||
deps << depElem.attribute( "id" );
|
||||
}
|
||||
}
|
||||
dependencies[id] = deps;
|
||||
|
||||
if ( deps.empty() )
|
||||
sortedLayers << id;
|
||||
else
|
||||
layersToSort << id;
|
||||
layerIdIdx[id] = i;
|
||||
}
|
||||
|
||||
bool hasCycle = false;
|
||||
while ( !layersToSort.empty() && !hasCycle )
|
||||
{
|
||||
QList<QString>::iterator it = layersToSort.begin();
|
||||
while ( it != layersToSort.end() )
|
||||
{
|
||||
hasCycle = true;
|
||||
bool resolved = true;
|
||||
foreach ( QString dep, dependencies[*it] )
|
||||
{
|
||||
if ( !sortedLayers.contains( dep ) )
|
||||
{
|
||||
resolved = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ( resolved ) // dependencies for this layer are resolved
|
||||
{
|
||||
sortedLayers << *it;
|
||||
it = layersToSort.erase( it ); // erase and go to the next
|
||||
hasCycle = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
it++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( hasCycle )
|
||||
{
|
||||
// should not happen, since layers with cyclic dependencies may only be created by
|
||||
// manually modifying the project file
|
||||
return qMakePair( false, QList<QDomNode>() );
|
||||
}
|
||||
|
||||
// Collect vector layers with joins.
|
||||
// They need to refresh join caches and symbology infos after all layers are loaded
|
||||
QList< QPair< QgsVectorLayer*, QDomElement > > vLayerList;
|
||||
foreach ( QString id, sortedLayers )
|
||||
{
|
||||
int i = layerIdIdx[id];
|
||||
QDomNode node = nl.item( i );
|
||||
QDomElement element = node.toElement();
|
||||
|
||||
|
@ -548,4 +548,9 @@ void QgsVectorDataProvider::pushError( const QString& msg )
|
||||
mErrors << msg;
|
||||
}
|
||||
|
||||
QSet<QString> QgsVectorDataProvider::layerDependencies() const
|
||||
{
|
||||
return QSet<QString>();
|
||||
}
|
||||
|
||||
QStringList QgsVectorDataProvider::smEncodings;
|
||||
|
@ -383,6 +383,11 @@ class CORE_EXPORT QgsVectorDataProvider : public QgsDataProvider
|
||||
emit dataChanged();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the list of layer ids on which this layer depends. This in particular determines the order of layer loading.
|
||||
*/
|
||||
virtual QSet<QString> layerDependencies() const;
|
||||
|
||||
protected:
|
||||
void clearMinMaxCache();
|
||||
void fillMinMaxCache();
|
||||
|
@ -1620,6 +1620,16 @@ bool QgsVectorLayer::writeXml( QDomNode & layer_node,
|
||||
//save joins
|
||||
mJoinBuffer->writeXml( layer_node, document );
|
||||
|
||||
// dependencies
|
||||
QDomElement dependenciesElement = document.createElement( "layerDependencies" );
|
||||
foreach ( QString layerId, layerDependencies() )
|
||||
{
|
||||
QDomElement depElem = document.createElement( "layer" );
|
||||
depElem.setAttribute( "id", layerId );
|
||||
dependenciesElement.appendChild( depElem );
|
||||
}
|
||||
layer_node.appendChild( dependenciesElement );
|
||||
|
||||
// save expression fields
|
||||
mExpressionFieldBuffer->writeXml( layer_node, document );
|
||||
|
||||
@ -3911,3 +3921,12 @@ bool QgsAttributeEditorRelation::init( QgsRelationManager* relationManager )
|
||||
mRelation = relationManager->relation( mRelationId );
|
||||
return mRelation.isValid();
|
||||
}
|
||||
|
||||
QSet<QString> QgsVectorLayer::layerDependencies() const
|
||||
{
|
||||
if ( mDataProvider )
|
||||
{
|
||||
return mDataProvider->layerDependencies();
|
||||
}
|
||||
return QSet<QString>();
|
||||
}
|
||||
|
@ -548,6 +548,11 @@ class CORE_EXPORT QgsVectorLayer : public QgsMapLayer
|
||||
|
||||
const QList<QgsVectorJoinInfo> vectorJoins() const;
|
||||
|
||||
/**
|
||||
* Get the list of layer ids on which this layer depends. This in particular determines the order of layer loading.
|
||||
*/
|
||||
virtual QSet<QString> layerDependencies() const;
|
||||
|
||||
/**
|
||||
* Add a new field which is calculated by the expression specified
|
||||
*
|
||||
|
Loading…
x
Reference in New Issue
Block a user