QGIS API Documentation  2.8.6-Wien
qgslayerdefinition.cpp
Go to the documentation of this file.
1 #include <QDomNode>
2 #include <QFileInfo>
3 #include <QFile>
4 #include <QDir>
5 #include <QTextStream>
6 
7 #include "qgslogger.h"
8 #include "qgsmaplayer.h"
9 #include "qgslayertree.h"
10 #include "qgsmaplayerregistry.h"
11 #include "qgslayerdefinition.h"
12 
13 bool QgsLayerDefinition::loadLayerDefinition( const QString &path, QgsLayerTreeGroup *rootGroup, QString &errorMessage )
14 {
15  QFile file( path );
16  if ( !file.open( QIODevice::ReadOnly ) )
17  {
18  errorMessage = QString( "Can not open file" );
19  return false;
20  }
21 
22  QDomDocument doc;
23  QString message;
24  if ( !doc.setContent( &file, &message ) )
25  {
26  errorMessage = message;
27  return false;
28  }
29 
30  QFileInfo fileinfo( file );
31  QDir::setCurrent( fileinfo.absoluteDir().path() );
32 
33  return loadLayerDefinition( doc, rootGroup, errorMessage );
34 }
35 
36 bool QgsLayerDefinition::loadLayerDefinition( QDomDocument doc, QgsLayerTreeGroup *rootGroup, QString &errorMessage )
37 {
38  Q_UNUSED( errorMessage );
39 
41 
42  // We have to replace the IDs before we load them because it's too late once they are loaded
43  QDomNodeList ids = doc.elementsByTagName( "id" );
44  for ( int i = 0; i < ids.size(); ++i )
45  {
46  QDomNode idnode = ids.at( i );
47  QDomElement idElem = idnode.toElement();
48  QString oldid = idElem.text();
49  // Strip the date part because we will replace it.
50  QString layername = oldid.left( oldid.length() - 17 );
51  QDateTime dt = QDateTime::currentDateTime();
52  QString newid = layername + dt.toString( "yyyyMMddhhmmsszzz" ) + QString::number( qrand() );
53  idElem.firstChild().setNodeValue( newid );
54  QDomNodeList treeLayerNodes = doc.elementsByTagName( "layer-tree-layer" );
55 
56  for ( int i = 0; i < treeLayerNodes.count(); ++i )
57  {
58  QDomNode layerNode = treeLayerNodes.at( i );
59  QDomElement layerElem = layerNode.toElement();
60  if ( layerElem.attribute( "id" ) == oldid )
61  {
62  layerNode.toElement().setAttribute( "id", newid );
63  }
64  }
65  }
66 
67  QDomElement layerTreeElem = doc.documentElement().firstChildElement( "layer-tree-group" );
68  bool loadInLegend = true;
69  if ( !layerTreeElem.isNull() )
70  {
71  root->readChildrenFromXML( layerTreeElem );
72  loadInLegend = false;
73  }
74 
75  QList<QgsMapLayer*> layers = QgsMapLayer::fromLayerDefinition( doc );
76  QgsMapLayerRegistry::instance()->addMapLayers( layers, loadInLegend );
77 
78  QList<QgsLayerTreeNode*> nodes = root->children();
79  foreach ( QgsLayerTreeNode *node, nodes )
80  root->takeChild( node );
81  delete root;
82 
83  rootGroup->insertChildNodes( -1, nodes );
84 
85  return true;
86 
87 }
88 
89 bool QgsLayerDefinition::exportLayerDefinition( QString path, QList<QgsLayerTreeNode*> selectedTreeNodes, QString &errorMessage )
90 {
91  if ( !path.endsWith( ".qlr" ) )
92  path = path.append( ".qlr" );
93 
94  QFile file( path );
95  QFileInfo fileinfo( file );
96 
97  QDomDocument doc( "qgis-layer-definition" );
98  QDomElement qgiselm = doc.createElement( "qlr" );
99  doc.appendChild( qgiselm );
100  QList<QgsLayerTreeNode*> nodes = selectedTreeNodes;
102  foreach ( QgsLayerTreeNode* node, nodes )
103  {
104  QgsLayerTreeNode* newnode = node->clone();
105  root->addChildNode( newnode );
106  }
107  root->writeXML( qgiselm );
108 
109  QDomElement layerselm = doc.createElement( "maplayers" );
110  QList<QgsLayerTreeLayer*> layers = root->findLayers();
111  foreach ( QgsLayerTreeLayer* layer, layers )
112  {
113  QDomElement layerelm = doc.createElement( "maplayer" );
114  layer->layer()->writeLayerXML( layerelm, doc, fileinfo.canonicalFilePath() );
115  layerselm.appendChild( layerelm );
116  }
117  qgiselm.appendChild( layerselm );
118 
119  if ( file.open( QFile::WriteOnly | QFile::Truncate ) )
120  {
121  QTextStream qlayerstream( &file );
122  doc.save( qlayerstream, 2 );
123  return true;
124  }
125  else
126  {
127  errorMessage = file.errorString();
128  return false;
129  }
130 }
Layer tree group node serves as a container for layers and further groups.
void readChildrenFromXML(QDomElement &element)
Read children from XML and append them to the group.
bool writeLayerXML(QDomElement &layerElement, QDomDocument &document, QString relativeBasePath=QString::null)
stores state in Dom node
bool takeChild(QgsLayerTreeNode *node)
Remove a child from a node.
QgsMapLayer * layer() const
virtual QgsLayerTreeNode * clone() const =0
Create a copy of the node. Returns new instance.
static QgsMapLayerRegistry * instance()
Definition: qgssingleton.h:23
static bool exportLayerDefinition(QString path, QList< QgsLayerTreeNode * > selectedTreeNodes, QString &errorMessage)
void insertChildNodes(int index, QList< QgsLayerTreeNode * > nodes)
Insert existing nodes at specified position. The nodes must not have a parent yet. The nodes will be owned by this group.
QList< QgsMapLayer * > addMapLayers(QList< QgsMapLayer * > theMapLayers, bool addToLegend=true, bool takeOwnership=true)
Add a list of layers to the map of loaded layers.
QList< QgsLayerTreeLayer * > findLayers() const
Find all layer nodes. Searches recursively the whole sub-tree.
This class is a base class for nodes in a layer tree.
QList< QgsLayerTreeNode * > children()
Get list of children of the node. Children are owned by the parent.
virtual void writeXML(QDomElement &parentElement) override
Write group (tree) as XML element <layer-tree-group> and add it to the given parent element...
void addChildNode(QgsLayerTreeNode *node)
Append an existing node. The node must not have a parent yet. The node will be owned by this group...
static QList< QgsMapLayer * > fromLayerDefinition(QDomDocument &document)
Creates a new layer from a layer defininition document.
static bool loadLayerDefinition(const QString &path, QgsLayerTreeGroup *rootGroup, QString &errorMessage)
Layer tree node points to a map layer.