Skip to content
Permalink
Browse files

Tidy up layer definitions code + removal of QgsProject::instance()

Moved code related to layer definitions away from QgsMapLayer
  • Loading branch information
wonder-sk committed Jan 29, 2017
1 parent c96a32a commit 8ba609e516e40bf7ffb2802ab0aca14488d540ba
@@ -1181,6 +1181,12 @@ QgsLabelingEngineInterface {#qgis_api_break_3_0_QgsLabelingEngineInterfac
- labelsWithinRect() was removed. Use takeResults() and methods of QgsLabelingResults.


QgsLayerDefinition {#qgis_api_break_3_0_QgsLayerDefinition}
------------------

- loadLayerDefinition() now also requires QgsProject as the second argument


QgsLayerPropertiesWidget {#qgis_api_break_3_0_QgsLayerPropertiesWidget}
------------------------

@@ -1298,6 +1304,7 @@ screenUpdateRequested() were removed. These members have had no effect for a num
- readLayerXML() was renamed to readLayerXml()
- writeLayerXML() was renamed to writeLayerXml()
- capitaliseLayerName() was renamed to capitalizeLayerName() <!--#spellok-->
- asLayerDefinition(), fromLayerDefinition(), fromLayerDefinitionFile() were moved to QgsLayerDefinition class and renamed to exportLayerDefinitionLayers() resp. loadLayerDefinitionLayers()


QgsMapLayerRegistry {#qgis_api_break_3_0_QgsMapLayerRegistry}
@@ -11,15 +11,15 @@ class QgsLayerDefinition
#include <qgslayerdefinition.h>
%End
public:
/** Loads the QLR at path into QGIS. New layers are added to rootGroup and the map layer registry*/
static bool loadLayerDefinition( const QString & path, QgsLayerTreeGroup* rootGroup, QString &errorMessage /Out/ );
/** Loads the QLR from the XML document. New layers are added to rootGroup and the map layer registry */
static bool loadLayerDefinition( QDomDocument doc, QgsLayerTreeGroup* rootGroup, QString &errorMessage /Out/ );
/** Export the selected layer tree nodes to a QLR file */
static bool loadLayerDefinition( const QString & path, QgsProject* project, QgsLayerTreeGroup* rootGroup, QString &errorMessage /Out/ );
static bool loadLayerDefinition( QDomDocument doc, QgsProject* project, QgsLayerTreeGroup* rootGroup, QString &errorMessage /Out/ );
static bool exportLayerDefinition( QString path, const QList<QgsLayerTreeNode*>& selectedTreeNodes, QString &errorMessage /Out/ );
/** Export the selected layer tree nodes to a QLR-XML document */
static bool exportLayerDefinition( QDomDocument doc, const QList<QgsLayerTreeNode*>& selectedTreeNodes, QString &errorMessage, const QString& relativeBasePath = QString::null );

static QDomDocument exportLayerDefinitionLayers( const QList<QgsMapLayer*>& layers, const QString& relativeBasePath = QString::null );
static QList<QgsMapLayer*> loadLayerDefinitionLayers( QDomDocument& document ) /Factory/;
static QList<QgsMapLayer*> loadLayerDefinitionLayers( const QString &qlrfile ) /Factory/;

/**
* Class used to work with layer dependencies stored in a XML project or layer definition file
*/
@@ -355,18 +355,6 @@ class QgsMapLayer : QObject
*/
bool writeLayerXml( QDomElement& layerElement, QDomDocument& document, const QString& relativeBasePath = QString::null ) const;

/** Returns the given layer as a layer definition document
* Layer definitions store the data source as well as styling and custom properties.
*
* Layer definitions can be used to load a layer and styling all from a single file.
*/
static QDomDocument asLayerDefinition( const QList<QgsMapLayer*>& layers, const QString& relativeBasePath = QString::null );

/** Creates a new layer from a layer definition document
*/
static QList<QgsMapLayer*> fromLayerDefinition( QDomDocument& document, bool addToRegistry = false, bool addToLegend = false );
static QList<QgsMapLayer*> fromLayerDefinitionFile( const QString &qlrfile );

/** Set a custom property for layer. Properties are stored in a map and saved in project file.
* @see customProperty()
* @see removeCustomProperty()
@@ -5249,7 +5249,7 @@ void QgisApp::dwgImport()
void QgisApp::openLayerDefinition( const QString & path )
{
QString errorMessage;
bool loaded = QgsLayerDefinition::loadLayerDefinition( path, QgsProject::instance()->layerTreeRoot(), errorMessage );
bool loaded = QgsLayerDefinition::loadLayerDefinition( path, QgsProject::instance(), QgsProject::instance()->layerTreeRoot(), errorMessage );
if ( !loaded )
{
QgsDebugMsg( errorMessage );
@@ -18,14 +18,17 @@
#include <QDir>
#include <QTextStream>

#include "qgslayerdefinition.h"
#include "qgslayertree.h"
#include "qgslogger.h"
#include "qgsmaplayer.h"
#include "qgsvectorlayer.h"
#include "qgslayertree.h"
#include "qgslayerdefinition.h"
#include "qgspluginlayer.h"
#include "qgspluginlayerregistry.h"
#include "qgsproject.h"
#include "qgsrasterlayer.h"
#include "qgsvectorlayer.h"

bool QgsLayerDefinition::loadLayerDefinition( const QString &path, QgsLayerTreeGroup *rootGroup, QString &errorMessage )
bool QgsLayerDefinition::loadLayerDefinition( const QString &path, QgsProject* project, QgsLayerTreeGroup *rootGroup, QString &errorMessage )
{
QFile file( path );
if ( !file.open( QIODevice::ReadOnly ) )
@@ -45,10 +48,10 @@ bool QgsLayerDefinition::loadLayerDefinition( const QString &path, QgsLayerTreeG
QFileInfo fileinfo( file );
QDir::setCurrent( fileinfo.absoluteDir().path() );

return loadLayerDefinition( doc, rootGroup, errorMessage );
return loadLayerDefinition( doc, project, rootGroup, errorMessage );
}

bool QgsLayerDefinition::loadLayerDefinition( QDomDocument doc, QgsLayerTreeGroup *rootGroup, QString &errorMessage )
bool QgsLayerDefinition::loadLayerDefinition( QDomDocument doc, QgsProject* project, QgsLayerTreeGroup *rootGroup, QString &errorMessage )
{
Q_UNUSED( errorMessage );

@@ -137,7 +140,9 @@ bool QgsLayerDefinition::loadLayerDefinition( QDomDocument doc, QgsLayerTreeGrou
loadInLegend = false;
}

QList<QgsMapLayer*> layers = QgsMapLayer::fromLayerDefinition( doc, /*addToRegistry*/ true, loadInLegend );
QList<QgsMapLayer*> layers = QgsLayerDefinition::loadLayerDefinitionLayers( doc );

project->addMapLayers( layers, loadInLegend );

// Now that all layers are loaded, refresh the vectorjoins to get the joined fields
Q_FOREACH ( QgsMapLayer* layer, layers )
@@ -150,7 +155,7 @@ bool QgsLayerDefinition::loadLayerDefinition( QDomDocument doc, QgsLayerTreeGrou
}
}

root->resolveReferences( QgsProject::instance() );
root->resolveReferences( project );

QList<QgsLayerTreeNode*> nodes = root->children();
Q_FOREACH ( QgsLayerTreeNode *node, nodes )
@@ -213,6 +218,82 @@ bool QgsLayerDefinition::exportLayerDefinition( QDomDocument doc, const QList<Qg
return true;
}

QDomDocument QgsLayerDefinition::exportLayerDefinitionLayers( const QList<QgsMapLayer *>& layers, const QString& relativeBasePath )
{
QDomDocument doc( QStringLiteral( "qgis-layer-definition" ) );
QDomElement qgiselm = doc.createElement( QStringLiteral( "qlr" ) );
doc.appendChild( qgiselm );
QDomElement layerselm = doc.createElement( QStringLiteral( "maplayers" ) );
Q_FOREACH ( QgsMapLayer* layer, layers )
{
QDomElement layerelm = doc.createElement( QStringLiteral( "maplayer" ) );
layer->writeLayerXml( layerelm, doc, relativeBasePath );
layerselm.appendChild( layerelm );
}
qgiselm.appendChild( layerselm );
return doc;
}

QList<QgsMapLayer*> QgsLayerDefinition::loadLayerDefinitionLayers( QDomDocument& document )
{
QList<QgsMapLayer*> layers;
QDomNodeList layernodes = document.elementsByTagName( QStringLiteral( "maplayer" ) );
for ( int i = 0; i < layernodes.size(); ++i )
{
QDomNode layernode = layernodes.at( i );
QDomElement layerElem = layernode.toElement();

QString type = layerElem.attribute( QStringLiteral( "type" ) );
QgsDebugMsg( type );
QgsMapLayer *layer = nullptr;

if ( type == QLatin1String( "vector" ) )
{
layer = new QgsVectorLayer;
}
else if ( type == QLatin1String( "raster" ) )
{
layer = new QgsRasterLayer;
}
else if ( type == QLatin1String( "plugin" ) )
{
QString typeName = layerElem.attribute( QStringLiteral( "name" ) );
layer = QgsApplication::pluginLayerRegistry()->createLayer( typeName );
}

if ( !layer )
continue;

if ( layer->readLayerXml( layerElem ) )
{
layers << layer;
}
}
return layers;
}

QList<QgsMapLayer *> QgsLayerDefinition::loadLayerDefinitionLayers( const QString &qlrfile )
{
QFile file( qlrfile );
if ( !file.open( QIODevice::ReadOnly ) )
{
QgsDebugMsg( "Can't open file" );
return QList<QgsMapLayer*>();
}

QDomDocument doc;
if ( !doc.setContent( &file ) )
{
QgsDebugMsg( "Can't set content" );
return QList<QgsMapLayer*>();
}

QFileInfo fileinfo( file );
QDir::setCurrent( fileinfo.absoluteDir().path() );
return QgsLayerDefinition::loadLayerDefinitionLayers( doc );
}


void QgsLayerDefinition::DependencySorter::init( const QDomDocument& doc )
{
// Determine a loading order of layers based on a graph of dependencies
@@ -17,10 +17,17 @@


#include "qgis_core.h"

#include <QString>
#include <QVector>

class QDomNode;
class QDomDocument;

class QgsLayerTreeGroup;
class QgsLayerTreeNode;
class QgsMapLayer;
class QgsProject;

/** \ingroup core
* @brief The QgsLayerDefinition class holds generic methods for loading/exporting QLR files.
@@ -32,15 +39,34 @@ class QgsLayerTreeNode;
class CORE_EXPORT QgsLayerDefinition
{
public:
//! Loads the QLR at path into QGIS. New layers are added to rootGroup and the map layer registry
static bool loadLayerDefinition( const QString & path, QgsLayerTreeGroup* rootGroup, QString &errorMessage );
//! Loads the QLR from the XML document. New layers are added to rootGroup and the map layer registry
static bool loadLayerDefinition( QDomDocument doc, QgsLayerTreeGroup* rootGroup, QString &errorMessage );
//! Loads the QLR at path into QGIS. New layers are added to given project into layer tree specified by rootGroup
static bool loadLayerDefinition( const QString & path, QgsProject* project, QgsLayerTreeGroup* rootGroup, QString &errorMessage );
//! Loads the QLR from the XML document. New layers are added to given project into layer tree specified by rootGroup
static bool loadLayerDefinition( QDomDocument doc, QgsProject* project, QgsLayerTreeGroup* rootGroup, QString &errorMessage );
//! Export the selected layer tree nodes to a QLR file
static bool exportLayerDefinition( QString path, const QList<QgsLayerTreeNode*>& selectedTreeNodes, QString &errorMessage );
//! Export the selected layer tree nodes to a QLR-XML document
static bool exportLayerDefinition( QDomDocument doc, const QList<QgsLayerTreeNode*>& selectedTreeNodes, QString &errorMessage, const QString& relativeBasePath = QString::null );

/** Returns the given layer as a layer definition document
* Layer definitions store the data source as well as styling and custom properties.
*
* Layer definitions can be used to load a layer and styling all from a single file.
*
* This is a low-level routine that does not write layer tree.
* @see exportLayerDefinition()
*/
static QDomDocument exportLayerDefinitionLayers( const QList<QgsMapLayer*>& layers, const QString& relativeBasePath = QString::null );

//! Creates new layers from a layer definition document.
//! This is a low-level routine that does not resolve layer ID conflicts, dependencies and joins
//! @see loadLayerDefinition()
static QList<QgsMapLayer*> loadLayerDefinitionLayers( QDomDocument& document );
//! Creates new layers from a layer definition file (.QLR)
//! This is a low-level routine that does not resolve layer ID conflicts, dependencies and joins
//! @see loadLayerDefinition()
static QList<QgsMapLayer*> loadLayerDefinitionLayers( const QString &qlrfile );

/**
* \ingroup core
* Class used to work with layer dependencies stored in a XML project or layer definition file
@@ -38,8 +38,6 @@
#include "qgsmaplayer.h"
#include "qgsmaplayerlegend.h"
#include "qgsmaplayerstylemanager.h"
#include "qgspluginlayer.h"
#include "qgspluginlayerregistry.h"
#include "qgsprojectfiletransform.h"
#include "qgsproject.h"
#include "qgsproviderregistry.h"
@@ -783,84 +781,6 @@ bool QgsMapLayer::writeLayerXml( QDomElement& layerElement, QDomDocument& docume

} // bool QgsMapLayer::writeXml

QDomDocument QgsMapLayer::asLayerDefinition( const QList<QgsMapLayer *>& layers, const QString& relativeBasePath )
{
QDomDocument doc( QStringLiteral( "qgis-layer-definition" ) );
QDomElement qgiselm = doc.createElement( QStringLiteral( "qlr" ) );
doc.appendChild( qgiselm );
QDomElement layerselm = doc.createElement( QStringLiteral( "maplayers" ) );
Q_FOREACH ( QgsMapLayer* layer, layers )
{
QDomElement layerelm = doc.createElement( QStringLiteral( "maplayer" ) );
layer->writeLayerXml( layerelm, doc, relativeBasePath );
layerselm.appendChild( layerelm );
}
qgiselm.appendChild( layerselm );
return doc;
}

QList<QgsMapLayer*> QgsMapLayer::fromLayerDefinition( QDomDocument& document, bool addToRegistry, bool addToLegend )
{
QList<QgsMapLayer*> layers;
QDomNodeList layernodes = document.elementsByTagName( QStringLiteral( "maplayer" ) );
for ( int i = 0; i < layernodes.size(); ++i )
{
QDomNode layernode = layernodes.at( i );
QDomElement layerElem = layernode.toElement();

QString type = layerElem.attribute( QStringLiteral( "type" ) );
QgsDebugMsg( type );
QgsMapLayer *layer = nullptr;

if ( type == QLatin1String( "vector" ) )
{
layer = new QgsVectorLayer;
}
else if ( type == QLatin1String( "raster" ) )
{
layer = new QgsRasterLayer;
}
else if ( type == QLatin1String( "plugin" ) )
{
QString typeName = layerElem.attribute( QStringLiteral( "name" ) );
layer = QgsApplication::pluginLayerRegistry()->createLayer( typeName );
}

if ( !layer )
continue;

bool ok = layer->readLayerXml( layerElem );
if ( ok )
{
layers << layer;
if ( addToRegistry )
QgsProject::instance()->addMapLayer( layer, addToLegend );
}
}
return layers;
}

QList<QgsMapLayer *> QgsMapLayer::fromLayerDefinitionFile( const QString &qlrfile )
{
QFile file( qlrfile );
if ( !file.open( QIODevice::ReadOnly ) )
{
QgsDebugMsg( "Can't open file" );
return QList<QgsMapLayer*>();
}

QDomDocument doc;
if ( !doc.setContent( &file ) )
{
QgsDebugMsg( "Can't set content" );
return QList<QgsMapLayer*>();
}

QFileInfo fileinfo( file );
QDir::setCurrent( fileinfo.absoluteDir().path() );
return QgsMapLayer::fromLayerDefinition( doc );
}


bool QgsMapLayer::writeXml( QDomNode & layer_node, QDomDocument & document ) const
{
@@ -383,18 +383,6 @@ class CORE_EXPORT QgsMapLayer : public QObject
*/
bool writeLayerXml( QDomElement& layerElement, QDomDocument& document, const QString& relativeBasePath = QString::null ) const;

/** Returns the given layer as a layer definition document
* Layer definitions store the data source as well as styling and custom properties.
*
* Layer definitions can be used to load a layer and styling all from a single file.
*/
static QDomDocument asLayerDefinition( const QList<QgsMapLayer*>& layers, const QString& relativeBasePath = QString::null );

/** Creates a new layer from a layer definition document
*/
static QList<QgsMapLayer*> fromLayerDefinition( QDomDocument& document, bool addToRegistry = false, bool addToLegend = false );
static QList<QgsMapLayer*> fromLayerDefinitionFile( const QString &qlrfile );

/** Set a custom property for layer. Properties are stored in a map and saved in project file.
* @see customProperty()
* @see removeCustomProperty()
@@ -505,7 +505,7 @@ void TestVectorLayerJoinBuffer::testJoinLayerDefinitionFile()
QgsProject::instance()->removeAllMapLayers();

// Load QLR
r = QgsLayerDefinition::loadLayerDefinition( qlrDoc, QgsProject::instance()->layerTreeRoot(), errorMessage );
r = QgsLayerDefinition::loadLayerDefinition( qlrDoc, QgsProject::instance(), QgsProject::instance()->layerTreeRoot(), errorMessage );
QVERIFY2( r, errorMessage.toUtf8().constData() );

// Get layer
@@ -196,7 +196,7 @@ def test_layerDefinitionRewriteId(self):
QgsLayerDefinition.exportLayerDefinition(tmpfile, [ltr])

grp = ltr.addGroup("imported")
QgsLayerDefinition.loadLayerDefinition(tmpfile, grp)
QgsLayerDefinition.loadLayerDefinition(tmpfile, QgsProject.instance(), grp)

newPointsLayer = None
newLinesLayer = None

0 comments on commit 8ba609e

Please sign in to comment.
You can’t perform that action at this time.