Skip to content

Commit b46a593

Browse files
author
Hugo Mercier
committedJan 6, 2016
Merge pull request #2617 from SebDieBln/FixLayerDefVectorJoins
Make vector joins work within layer-definition-files
2 parents 946f4e4 + c136f9f commit b46a593

File tree

4 files changed

+103
-13
lines changed

4 files changed

+103
-13
lines changed
 

‎python/core/qgslayerdefinition.sip

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,5 +17,7 @@ class QgsLayerDefinition
1717
static bool loadLayerDefinition( QDomDocument doc, QgsLayerTreeGroup* rootGroup, QString &errorMessage /Out/ );
1818
/** Export the selected layer tree nodes to a QLR file */
1919
static bool exportLayerDefinition( QString path, const QList<QgsLayerTreeNode*>& selectedTreeNodes, QString &errorMessage /Out/ );
20+
/** Export the selected layer tree nodes to a QLR-XML document */
21+
static bool exportLayerDefinition( QDomDocument doc, const QList<QgsLayerTreeNode*>& selectedTreeNodes, QString &errorMessage, const QString& relativeBasePath = QString::null );
2022
};
2123

‎src/core/qgslayerdefinition.cpp

Lines changed: 44 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
#include "qgslogger.h"
88
#include "qgsmaplayer.h"
9+
#include "qgsvectorlayer.h"
910
#include "qgslayertree.h"
1011
#include "qgsmaplayerregistry.h"
1112
#include "qgslayerdefinition.h"
@@ -62,6 +63,18 @@ bool QgsLayerDefinition::loadLayerDefinition( QDomDocument doc, QgsLayerTreeGrou
6263
layerNode.toElement().setAttribute( "id", newid );
6364
}
6465
}
66+
67+
// change layer IDs for vector joins
68+
QDomNodeList vectorJoinNodes = doc.elementsByTagName( "join" ); // TODO: Find a better way of searching for vectorjoins, there might be other <join> elements within the project.
69+
for ( int j = 0; j < vectorJoinNodes.size(); ++j )
70+
{
71+
QDomNode joinNode = vectorJoinNodes.at( j );
72+
QDomElement joinElement = joinNode.toElement();
73+
if ( joinElement.attribute( "joinLayerId" ) == oldid )
74+
{
75+
joinNode.toElement().setAttribute( "joinLayerId", newid );
76+
}
77+
}
6578
}
6679

6780
QDomElement layerTreeElem = doc.documentElement().firstChildElement( "layer-tree-group" );
@@ -75,6 +88,17 @@ bool QgsLayerDefinition::loadLayerDefinition( QDomDocument doc, QgsLayerTreeGrou
7588
QList<QgsMapLayer*> layers = QgsMapLayer::fromLayerDefinition( doc );
7689
QgsMapLayerRegistry::instance()->addMapLayers( layers, loadInLegend );
7790

91+
// Now that all layers are loaded, refresh the vectorjoins to get the joined fields
92+
Q_FOREACH ( QgsMapLayer* layer, layers )
93+
{
94+
QgsVectorLayer* vlayer = static_cast< QgsVectorLayer * >( layer );
95+
if ( vlayer )
96+
{
97+
vlayer->createJoinCaches();
98+
vlayer->updateFields();
99+
}
100+
}
101+
78102
QList<QgsLayerTreeNode*> nodes = root->children();
79103
Q_FOREACH ( QgsLayerTreeNode *node, nodes )
80104
root->takeChild( node );
@@ -95,6 +119,24 @@ bool QgsLayerDefinition::exportLayerDefinition( QString path, const QList<QgsLay
95119
QFileInfo fileinfo( file );
96120

97121
QDomDocument doc( "qgis-layer-definition" );
122+
if ( !exportLayerDefinition( doc, selectedTreeNodes, errorMessage, fileinfo.canonicalFilePath() ) )
123+
return false;
124+
if ( file.open( QFile::WriteOnly | QFile::Truncate ) )
125+
{
126+
QTextStream qlayerstream( &file );
127+
doc.save( qlayerstream, 2 );
128+
return true;
129+
}
130+
else
131+
{
132+
errorMessage = file.errorString();
133+
return false;
134+
}
135+
}
136+
137+
bool QgsLayerDefinition::exportLayerDefinition( QDomDocument doc, const QList<QgsLayerTreeNode*>& selectedTreeNodes, QString &errorMessage, const QString& relativeBasePath )
138+
{
139+
Q_UNUSED( errorMessage );
98140
QDomElement qgiselm = doc.createElement( "qlr" );
99141
doc.appendChild( qgiselm );
100142
QList<QgsLayerTreeNode*> nodes = selectedTreeNodes;
@@ -111,20 +153,9 @@ bool QgsLayerDefinition::exportLayerDefinition( QString path, const QList<QgsLay
111153
Q_FOREACH ( QgsLayerTreeLayer* layer, layers )
112154
{
113155
QDomElement layerelm = doc.createElement( "maplayer" );
114-
layer->layer()->writeLayerXML( layerelm, doc, fileinfo.canonicalFilePath() );
156+
layer->layer()->writeLayerXML( layerelm, doc, relativeBasePath );
115157
layerselm.appendChild( layerelm );
116158
}
117159
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-
}
160+
return true;
130161
}

‎src/core/qgslayerdefinition.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ class CORE_EXPORT QgsLayerDefinition
1919
static bool loadLayerDefinition( QDomDocument doc, QgsLayerTreeGroup* rootGroup, QString &errorMessage );
2020
/** Export the selected layer tree nodes to a QLR file */
2121
static bool exportLayerDefinition( QString path, const QList<QgsLayerTreeNode*>& selectedTreeNodes, QString &errorMessage );
22+
/** Export the selected layer tree nodes to a QLR-XML document */
23+
static bool exportLayerDefinition( QDomDocument doc, const QList<QgsLayerTreeNode*>& selectedTreeNodes, QString &errorMessage, const QString& relativeBasePath = QString::null );
2224
};
2325

2426
#endif // QGSLAYERDEFINITION_H

‎tests/src/core/testqgsvectorlayerjoinbuffer.cpp

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@
2323
#include <qgsapplication.h>
2424
#include <qgsvectorlayerjoinbuffer.h>
2525
#include <qgsmaplayerregistry.h>
26+
#include <qgslayerdefinition.h>
27+
#include <qgsproject.h>
2628

2729
/** @ingroup UnitTests
2830
* This is a unit test for the vector layer join buffer
@@ -53,6 +55,7 @@ class TestVectorLayerJoinBuffer : public QObject
5355
void testJoinSubset_data();
5456
void testJoinSubset();
5557
void testJoinTwoTimes();
58+
void testJoinLayerDefinitionFile();
5659

5760
private:
5861
QgsVectorLayer* mLayerA;
@@ -339,6 +342,58 @@ void TestVectorLayerJoinBuffer::testJoinTwoTimes()
339342
QCOMPARE( mLayerA->vectorJoins().count(), 0 );
340343
}
341344

345+
void TestVectorLayerJoinBuffer::testJoinLayerDefinitionFile()
346+
{
347+
bool r;
348+
349+
QgsMapLayerRegistry::instance()->removeAllMapLayers();
350+
351+
// Create two layers
352+
QgsVectorLayer* layerA = new QgsVectorLayer( "Point?crs=epsg:4326&field=key:integer&field=value:double&index=yes", "layerA", "memory" );
353+
QVERIFY( layerA );
354+
QgsMapLayerRegistry::instance()->addMapLayer( layerA );
355+
356+
QgsVectorLayer* layerB = new QgsVectorLayer( "Point?crs=epsg:4326&field=id:integer&index=yes", "layerB", "memory" );
357+
QVERIFY( layerB );
358+
QgsMapLayerRegistry::instance()->addMapLayer( layerB );
359+
360+
// Create vector join
361+
QgsVectorJoinInfo joinInfo;
362+
joinInfo.targetFieldName = "id";
363+
joinInfo.joinLayerId = layerA->id();
364+
joinInfo.joinFieldName = "key";
365+
joinInfo.memoryCache = true;
366+
joinInfo.prefix = "joined_";
367+
r = layerB->addJoin( joinInfo );
368+
QVERIFY( r );
369+
370+
// Generate QLR
371+
QDomDocument qlrDoc( "qgis-layer-definition" );
372+
QString errorMessage;
373+
r = QgsLayerDefinition::exportLayerDefinition( qlrDoc, QgsProject::instance()->layerTreeRoot()->children(), errorMessage );
374+
QVERIFY2( r, errorMessage.toUtf8().constData() );
375+
376+
// Clear
377+
QgsMapLayerRegistry::instance()->removeAllMapLayers();
378+
379+
// Load QLR
380+
r = QgsLayerDefinition::loadLayerDefinition( qlrDoc, QgsProject::instance()->layerTreeRoot(), errorMessage );
381+
QVERIFY2( r, errorMessage.toUtf8().constData() );
382+
383+
// Get layer
384+
QList<QgsMapLayer*> mapLayers = QgsMapLayerRegistry::instance()->mapLayersByName( "layerB" );
385+
QCOMPARE( mapLayers.count(), 1 );
386+
387+
QgsVectorLayer* vLayer = static_cast<QgsVectorLayer*>( mapLayers.value( 0 ) );
388+
QVERIFY( vLayer );
389+
390+
// Check for vector join
391+
QCOMPARE( vLayer->vectorJoins().count(), 1 );
392+
393+
// Check for joined field
394+
QVERIFY( vLayer->fieldNameIndex( joinInfo.prefix + "value" ) >= 0 );
395+
}
396+
342397

343398
QTEST_MAIN( TestVectorLayerJoinBuffer )
344399
#include "testqgsvectorlayerjoinbuffer.moc"

0 commit comments

Comments
 (0)
Please sign in to comment.