19 #include <QTextStream> 36 if ( !file.open( QIODevice::ReadOnly ) )
38 errorMessage = QStringLiteral(
"Can not open file" );
44 if ( !doc.setContent( &file, &message ) )
46 errorMessage = message;
50 QFileInfo fileinfo( file );
51 QDir::setCurrent( fileinfo.absoluteDir().path() );
61 Q_UNUSED( errorMessage );
71 QVector<QDomNode> clonedSorted;
72 Q_FOREACH (
const QDomNode &node, sortedLayerNodes )
74 clonedSorted << node.cloneNode();
76 QDomNode layersNode = doc.elementsByTagName( QStringLiteral(
"maplayers" ) ).at( 0 );
78 QDomNodeList childNodes = layersNode.childNodes();
79 for (
int i = 0; i < childNodes.size(); i++ )
81 layersNode.replaceChild( clonedSorted.at( i ), childNodes.at( i ) );
88 QDomNodeList ids = doc.elementsByTagName( QStringLiteral(
"id" ) );
89 for (
int i = 0; i < ids.size(); ++i )
91 QDomNode idnode = ids.at( i );
92 QDomElement idElem = idnode.toElement();
93 QString oldid = idElem.text();
95 QString layername = oldid.left( oldid.length() - 17 );
96 QDateTime dt = QDateTime::currentDateTime();
97 QString newid = layername + dt.toString( QStringLiteral(
"yyyyMMddhhmmsszzz" ) ) + QString::number( qrand() );
98 idElem.firstChild().setNodeValue( newid );
99 QDomNodeList treeLayerNodes = doc.elementsByTagName( QStringLiteral(
"layer-tree-layer" ) );
101 for (
int i = 0; i < treeLayerNodes.count(); ++i )
103 QDomNode layerNode = treeLayerNodes.at( i );
104 QDomElement layerElem = layerNode.toElement();
105 if ( layerElem.attribute( QStringLiteral(
"id" ) ) == oldid )
107 layerNode.toElement().setAttribute( QStringLiteral(
"id" ), newid );
112 QDomNodeList vectorJoinNodes = doc.elementsByTagName( QStringLiteral(
"join" ) );
113 for (
int j = 0; j < vectorJoinNodes.size(); ++j )
115 QDomNode joinNode = vectorJoinNodes.at( j );
116 QDomElement joinElement = joinNode.toElement();
117 if ( joinElement.attribute( QStringLiteral(
"joinLayerId" ) ) == oldid )
119 joinNode.toElement().setAttribute( QStringLiteral(
"joinLayerId" ), newid );
124 QDomNodeList dataDeps = doc.elementsByTagName( QStringLiteral(
"dataDependencies" ) );
125 for (
int i = 0; i < dataDeps.size(); i++ )
127 QDomNodeList layers = dataDeps.at( i ).childNodes();
128 for (
int j = 0; j < layers.size(); j++ )
130 QDomElement elt = layers.at( j ).toElement();
131 if ( elt.attribute( QStringLiteral(
"id" ) ) == oldid )
133 elt.setAttribute( QStringLiteral(
"id" ), newid );
140 QDomElement layerTreeElem = doc.documentElement().firstChildElement( QStringLiteral(
"layer-tree-group" ) );
141 bool loadInLegend =
true;
142 if ( !layerTreeElem.isNull() )
145 loadInLegend =
false;
155 if (
QgsVectorLayer *vlayer = qobject_cast< QgsVectorLayer * >( layer ) )
157 vlayer->resolveReferences( project );
163 QList<QgsLayerTreeNode *> nodes = root->
children();
176 if ( !path.endsWith( QLatin1String(
".qlr" ) ) )
177 path = path.append(
".qlr" );
181 if ( !file.open( QFile::WriteOnly | QFile::Truncate ) )
183 errorMessage = file.errorString();
190 QDomDocument doc( QStringLiteral(
"qgis-layer-definition" ) );
194 QTextStream qlayerstream( &file );
195 doc.save( qlayerstream, 2 );
201 Q_UNUSED( errorMessage );
202 QDomElement qgiselm = doc.createElement( QStringLiteral(
"qlr" ) );
203 doc.appendChild( qgiselm );
204 QList<QgsLayerTreeNode *> nodes = selectedTreeNodes;
213 QDomElement layerselm = doc.createElement( QStringLiteral(
"maplayers" ) );
214 QList<QgsLayerTreeLayer *> layers = root->
findLayers();
217 QDomElement layerelm = doc.createElement( QStringLiteral(
"maplayer" ) );
219 layerselm.appendChild( layerelm );
221 qgiselm.appendChild( layerselm );
227 QDomDocument doc( QStringLiteral(
"qgis-layer-definition" ) );
228 QDomElement qgiselm = doc.createElement( QStringLiteral(
"qlr" ) );
229 doc.appendChild( qgiselm );
230 QDomElement layerselm = doc.createElement( QStringLiteral(
"maplayers" ) );
233 QDomElement layerelm = doc.createElement( QStringLiteral(
"maplayer" ) );
235 layerselm.appendChild( layerelm );
237 qgiselm.appendChild( layerselm );
243 QList<QgsMapLayer *> layers;
244 QDomNodeList layernodes = document.elementsByTagName( QStringLiteral(
"maplayer" ) );
245 for (
int i = 0; i < layernodes.size(); ++i )
247 QDomNode layernode = layernodes.at( i );
248 QDomElement layerElem = layernode.toElement();
250 QString type = layerElem.attribute( QStringLiteral(
"type" ) );
254 if ( type == QLatin1String(
"vector" ) )
258 else if ( type == QLatin1String(
"raster" ) )
262 else if ( type == QLatin1String(
"plugin" ) )
264 QString typeName = layerElem.attribute( QStringLiteral(
"name" ) );
281 QFile file( qlrfile );
282 if ( !file.open( QIODevice::ReadOnly ) )
285 return QList<QgsMapLayer *>();
289 if ( !doc.setContent( &file ) )
292 return QList<QgsMapLayer *>();
301 void QgsLayerDefinition::DependencySorter::init(
const QDomDocument &doc )
304 QMap< QString, QVector< QString > > dependencies;
305 QStringList sortedLayers;
306 QList< QPair<QString, QDomNode> > layersToSort;
307 QStringList layerIds;
309 QDomNodeList nl = doc.elementsByTagName( QStringLiteral(
"maplayer" ) );
310 layerIds.reserve( nl.count() );
311 QVector<QString> deps;
312 for (
int i = 0; i < nl.count(); i++ )
315 QDomNode node = nl.item( i );
317 QString
id = node.namedItem( QStringLiteral(
"id" ) ).toElement().text();
321 QDomElement layerDependenciesElem = node.firstChildElement( QStringLiteral(
"layerDependencies" ) );
322 if ( !layerDependenciesElem.isNull() )
324 QDomNodeList dependencyList = layerDependenciesElem.elementsByTagName( QStringLiteral(
"layer" ) );
325 for (
int j = 0; j < dependencyList.size(); ++j )
327 QDomElement depElem = dependencyList.at( j ).toElement();
328 deps << depElem.attribute( QStringLiteral(
"id" ) );
331 dependencies[id] = deps;
336 mSortedLayerNodes << node;
337 mSortedLayerIds << id;
340 layersToSort << qMakePair(
id, node );
344 Q_FOREACH (
const QVector< QString > &ids, dependencies )
346 Q_FOREACH (
const QString &depId, ids )
348 if ( !dependencies.contains( depId ) )
351 mHasMissingDependency =
true;
352 for (
int i = 0; i < nl.size(); i++ )
353 mSortedLayerNodes << nl.at( i );
354 mSortedLayerIds = layerIds;
364 while ( !layersToSort.empty() && !mHasCycle )
366 QList< QPair<QString, QDomNode> >::iterator it = layersToSort.begin();
367 while ( it != layersToSort.end() )
369 QString idToSort = it->first;
370 QDomNode node = it->second;
372 bool resolved =
true;
373 Q_FOREACH (
const QString &dep, dependencies[idToSort] )
375 if ( !sortedLayers.contains( dep ) )
383 sortedLayers << idToSort;
384 mSortedLayerNodes << node;
385 mSortedLayerIds << idToSort;
386 it = layersToSort.erase( it );
399 , mHasMissingDependency( false )
406 , mHasMissingDependency( false )
409 QFile pFile( fileName );
410 ( void )pFile.open( QIODevice::ReadOnly );
411 ( void )doc.setContent( &pFile );
Layer tree group node serves as a container for layers and further groups.
The class is used as a container of context for various read/write operations on other objects...
void readChildrenFromXml(QDomElement &element, const QgsReadWriteContext &context)
Read children from XML and append them to the group.
static QDomDocument exportLayerDefinitionLayers(const QList< QgsMapLayer *> &layers, const QgsReadWriteContext &context)
Returns the given layer as a layer definition document Layer definitions store the data source as wel...
QList< QgsMapLayer * > addMapLayers(const QList< QgsMapLayer *> &mapLayers, bool addToLegend=true, bool takeOwnership=true)
Add a list of layers to the map of loaded layers.
Base class for all map layer types.
void setPathResolver(const QgsPathResolver &resolver)
Sets up path resolver for conversion between relative and absolute paths.
bool takeChild(QgsLayerTreeNode *node)
Remove a child from a node.
static bool loadLayerDefinition(const QString &path, QgsProject *project, QgsLayerTreeGroup *rootGroup, QString &errorMessage)
Loads the QLR at path into QGIS. New layers are added to given project into layer tree specified by r...
This class provides qgis with the ability to render raster datasets onto the mapcanvas.
virtual QgsLayerTreeNode * clone() const =0
Create a copy of the node. Returns new instance.
Class used to work with layer dependencies stored in a XML project or layer definition file...
QVector< QDomNode > sortedLayerNodes() const
Get the layer nodes in an order where they can be loaded incrementally without dependency break...
void writeXml(QDomElement &parentElement, const QgsReadWriteContext &context) override
Write group (tree) as XML element <layer-tree-group> and add it to the given parent element...
static QgsPluginLayerRegistry * pluginLayerRegistry()
Returns the application's plugin layer registry, used for managing plugin layer types.
void resolveReferences(const QgsProject *project, bool looseMatching=false) override
Calls resolveReferences() on child tree nodes.
DependencySorter(const QDomDocument &doc)
Constructor.
QList< QgsLayerTreeNode * > children()
Get list of children of the node. Children are owned by the parent.
static QList< QgsMapLayer * > loadLayerDefinitionLayers(QDomDocument &document, const QgsReadWriteContext &context)
Creates new layers from a layer definition document.
This class is a base class for nodes in a layer tree.
Reads and writes project states.
void insertChildNodes(int index, const QList< QgsLayerTreeNode *> &nodes)
Insert existing nodes at specified position.
bool readLayerXml(const QDomElement &layerElement, const QgsReadWriteContext &context)
Sets state from Dom document.
bool hasMissingDependency() const
Whether some dependency is missing.
QgsMapLayer * layer() const
static bool exportLayerDefinition(QString path, const QList< QgsLayerTreeNode *> &selectedTreeNodes, QString &errorMessage)
Export the selected layer tree nodes to a QLR file.
void addChildNode(QgsLayerTreeNode *node)
Append an existing node.
QList< QgsLayerTreeLayer * > findLayers() const
Find all layer nodes.
Resolves relative paths into absolute paths and vice versa.
Represents a vector layer which manages a vector based data sets.
bool writeLayerXml(QDomElement &layerElement, QDomDocument &document, const QgsReadWriteContext &context) const
Stores state in Dom node.
QgsPluginLayer * createLayer(const QString &typeName, const QString &uri=QString())
Returns new layer if corresponding plugin has been found else returns a nullptr.
Layer tree node points to a map layer.