Skip to content

Commit 6fcfb97

Browse files
committed
Merge pull request #1593 from rldhont/qgis-server-print-legend
[FEATURE][QGIS-Server] Legend filtering based on map in GetPrint Request
2 parents 0c6576c + 251a8a4 commit 6fcfb97

10 files changed

+136
-9
lines changed

python/core/layertree/qgslayertreegroup.sip

+2
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@ class QgsLayerTreeGroup : QgsLayerTreeNode
4141
void removeLayer( QgsMapLayer* layer );
4242
//! Remove child nodes from index "from". The nodes will be deleted.
4343
void removeChildren( int from, int count );
44+
//! Remove all child group nodes without layers. The groupnodes will be deleted.
45+
void removeChildrenGroupWithoutLayers();
4446
//! Remove all child nodes. The nodes will be deleted.
4547
void removeAllChildren();
4648

src/core/composer/qgscomposerlabel.cpp

-2
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,6 @@ void QgsComposerLabel::paint( QPainter* painter, const QStyleOptionGraphicsItem*
9898
if ( mHtmlState )
9999
{
100100
painter->scale( 1.0 / mHtmlUnitsToMM / 10.0, 1.0 / mHtmlUnitsToMM / 10.0 );
101-
102101
QWebPage *webPage = new QWebPage();
103102
webPage->setNetworkAccessManager( QgsNetworkAccessManager::instance() );
104103

@@ -149,7 +148,6 @@ void QgsComposerLabel::paint( QPainter* painter, const QStyleOptionGraphicsItem*
149148
// Pause until html is loaded
150149
loop.exec();
151150
}
152-
153151
webPage->mainFrame()->render( painter );//DELETE WEBPAGE ?
154152
}
155153
else

src/core/layertree/qgslayertreegroup.cpp

+16
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,22 @@ void QgsLayerTreeGroup::removeChildren( int from, int count )
119119
updateVisibilityFromChildren();
120120
}
121121

122+
void QgsLayerTreeGroup::removeChildrenGroupWithoutLayers()
123+
{
124+
// clean the layer tree by removing empty group
125+
foreach ( QgsLayerTreeNode* treeNode, children() )
126+
{
127+
if ( treeNode->nodeType() == QgsLayerTreeNode::NodeGroup )
128+
{
129+
QgsLayerTreeGroup* treeGroup = qobject_cast<QgsLayerTreeGroup*>( treeNode );
130+
if ( treeGroup->findLayerIds().count() == 0 )
131+
removeChildNode( treeNode );
132+
else
133+
treeGroup->removeChildrenGroupWithoutLayers();
134+
}
135+
}
136+
}
137+
122138
void QgsLayerTreeGroup::removeAllChildren()
123139
{
124140
removeChildren( 0, mChildren.count() );

src/core/layertree/qgslayertreegroup.h

+2
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,8 @@ class CORE_EXPORT QgsLayerTreeGroup : public QgsLayerTreeNode
6262
void removeLayer( QgsMapLayer* layer );
6363
//! Remove child nodes from index "from". The nodes will be deleted.
6464
void removeChildren( int from, int count );
65+
//! Remove all child group nodes without layers. The groupnodes will be deleted.
66+
void removeChildrenGroupWithoutLayers();
6567
//! Remove all child nodes. The nodes will be deleted.
6668
void removeAllChildren();
6769

src/mapserver/qgssldconfigparser.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -696,11 +696,11 @@ QgsComposition* QgsSLDConfigParser::createPrintComposition( const QString& compo
696696
return 0;
697697
}
698698

699-
QgsComposition* QgsSLDConfigParser::initComposition( const QString& composerTemplate, QgsMapRenderer* mapRenderer, QList< QgsComposerMap*>& mapList, QList< QgsComposerLabel* >& labelList, QList<const QgsComposerHtml *>& htmlFrameList ) const
699+
QgsComposition* QgsSLDConfigParser::initComposition( const QString& composerTemplate, QgsMapRenderer* mapRenderer, QList< QgsComposerMap*>& mapList, QList< QgsComposerLegend* >& legendList, QList< QgsComposerLabel* >& labelList, QList<const QgsComposerHtml *>& htmlFrameList ) const
700700
{
701701
if ( mFallbackParser )
702702
{
703-
return mFallbackParser->initComposition( composerTemplate, mapRenderer, mapList, labelList, htmlFrameList );
703+
return mFallbackParser->initComposition( composerTemplate, mapRenderer, mapList, legendList, labelList, htmlFrameList );
704704
}
705705
return 0;
706706
}

src/mapserver/qgssldconfigparser.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ class QgsSLDConfigParser : public QgsWMSConfigParser
107107
QgsComposition* createPrintComposition( const QString& composerTemplate, QgsMapRenderer* mapRenderer, const QMap< QString, QString >& parameterMap ) const;
108108

109109
/**Creates a composition from the project file (probably delegated to the fallback parser)*/
110-
QgsComposition* initComposition( const QString& composerTemplate, QgsMapRenderer* mapRenderer, QList< QgsComposerMap*>& mapList, QList< QgsComposerLabel* >& labelList, QList<const QgsComposerHtml *>& htmlFrameList ) const;
110+
QgsComposition* initComposition( const QString& composerTemplate, QgsMapRenderer* mapRenderer, QList< QgsComposerMap*>& mapList, QList< QgsComposerLegend* >& legendList, QList< QgsComposerLabel* >& labelList, QList<const QgsComposerHtml *>& htmlFrameList ) const;
111111

112112
/**Adds print capabilities to xml document. ParentElem usually is the <Capabilities> element*/
113113
void printCapabilities( QDomElement& parentElement, QDomDocument& doc ) const;

src/mapserver/qgswmsconfigparser.cpp

+67-1
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,18 @@
1717

1818
#include "qgswmsconfigparser.h"
1919
#include "qgsmaplayer.h"
20+
#include "qgsmapserviceexception.h"
2021

2122
#include "qgscomposerlabel.h"
23+
#include "qgscomposerlegend.h"
2224
#include "qgscomposermap.h"
2325
#include "qgscomposerhtml.h"
2426
#include "qgscomposerframe.h"
2527
#include "qgscomposition.h"
2628

29+
#include "qgslayertreegroup.h"
30+
#include "qgslayertreelayer.h"
31+
2732
QgsWMSConfigParser::QgsWMSConfigParser()
2833
{
2934

@@ -37,10 +42,11 @@ QgsWMSConfigParser::~QgsWMSConfigParser()
3742
QgsComposition* QgsWMSConfigParser::createPrintComposition( const QString& composerTemplate, QgsMapRenderer* mapRenderer, const QMap< QString, QString >& parameterMap ) const
3843
{
3944
QList<QgsComposerMap*> composerMaps;
45+
QList<QgsComposerLegend*> composerLegends;
4046
QList<QgsComposerLabel*> composerLabels;
4147
QList<const QgsComposerHtml*> composerHtmls;
4248

43-
QgsComposition* c = initComposition( composerTemplate, mapRenderer, composerMaps, composerLabels, composerHtmls );
49+
QgsComposition* c = initComposition( composerTemplate, mapRenderer, composerMaps, composerLegends, composerLabels, composerHtmls );
4450
if ( !c )
4551
{
4652
return 0;
@@ -158,6 +164,66 @@ QgsComposition* QgsWMSConfigParser::createPrintComposition( const QString& compo
158164
currentMap->setGridIntervalX( parameterMap.value( mapId + ":GRID_INTERVAL_X" ).toDouble() );
159165
currentMap->setGridIntervalY( parameterMap.value( mapId + ":GRID_INTERVAL_Y" ).toDouble() );
160166
}
167+
//update legend
168+
// if it has an auto-update model
169+
foreach ( QgsComposerLegend* currentLegend, composerLegends )
170+
{
171+
if ( !currentLegend )
172+
{
173+
continue;
174+
}
175+
176+
if ( currentLegend->autoUpdateModel() || currentLegend->legendFilterByMapEnabled() )
177+
{
178+
// the legend has an auto-update model or
179+
// has to be filter by map
180+
// we will update it with map's layers
181+
const QgsComposerMap* map = currentLegend->composerMap();
182+
if ( !map )
183+
{
184+
continue;
185+
}
186+
187+
// get model and layer tree root of the legend
188+
QgsLegendModelV2* model = currentLegend->modelV2();
189+
QgsLayerTreeGroup* root = model->rootGroup();
190+
191+
192+
// get layerIds find in the layer tree root
193+
QStringList layerIds = root->findLayerIds();
194+
// get map layerIds
195+
QStringList layerSet = map->layerSet();
196+
197+
// get map scale
198+
double scale = map->scale();
199+
200+
// foreach layer find in the layer tree
201+
// remove it if the layer id is not in map layerIds
202+
foreach ( QString layerId, layerIds )
203+
{
204+
QgsLayerTreeLayer* nodeLayer = root->findLayer( layerId );
205+
if ( !nodeLayer ) {
206+
continue;
207+
}
208+
if ( !layerSet.contains( layerId ) )
209+
{
210+
qobject_cast<QgsLayerTreeGroup*>( nodeLayer->parent() )->removeChildNode( nodeLayer );
211+
}
212+
else
213+
{
214+
QgsMapLayer* layer = nodeLayer->layer();
215+
if ( layer->hasScaleBasedVisibility() )
216+
{
217+
if ( layer->minimumScale() > scale )
218+
qobject_cast<QgsLayerTreeGroup*>( nodeLayer->parent() )->removeChildNode( nodeLayer );
219+
else if ( layer->maximumScale() < scale )
220+
qobject_cast<QgsLayerTreeGroup*>( nodeLayer->parent() )->removeChildNode( nodeLayer );
221+
}
222+
}
223+
}
224+
root->removeChildrenGroupWithoutLayers();
225+
}
226+
}
161227

162228
//replace label text
163229
foreach ( QgsComposerLabel *currentLabel, composerLabels )

src/mapserver/qgswmsconfigparser.h

+2-1
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222

2323
class QgsComposerHtml;
2424
class QgsComposerLabel;
25+
class QgsComposerLegend;
2526
class QgsComposerMap;
2627
class QgsComposition;
2728
class QgsMapLayer;
@@ -107,7 +108,7 @@ class QgsWMSConfigParser
107108
QgsComposition* createPrintComposition( const QString& composerTemplate, QgsMapRenderer* mapRenderer, const QMap< QString, QString >& parameterMap ) const;
108109

109110
/**Creates a composition from the project file (probably delegated to the fallback parser)*/
110-
virtual QgsComposition* initComposition( const QString& composerTemplate, QgsMapRenderer* mapRenderer, QList< QgsComposerMap*>& mapList, QList< QgsComposerLabel* >& labelList, QList<const QgsComposerHtml *>& htmlFrameList ) const = 0;
111+
virtual QgsComposition* initComposition( const QString& composerTemplate, QgsMapRenderer* mapRenderer, QList< QgsComposerMap*>& mapList, QList< QgsComposerLegend* >& legendList, QList< QgsComposerLabel* >& labelList, QList<const QgsComposerHtml *>& htmlFrameList ) const = 0;
111112

112113
/**Adds print capabilities to xml document. ParentElem usually is the <Capabilities> element*/
113114
virtual void printCapabilities( QDomElement& parentElement, QDomDocument& doc ) const = 0;

src/mapserver/qgswmsprojectparser.cpp

+41-1
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
#include "qgscomposerpicture.h"
3535
#include "qgscomposerscalebar.h"
3636
#include "qgscomposershape.h"
37+
#include "qgslayertreegroup.h"
3738

3839
#include <QFileInfo>
3940
#include <QTextDocument>
@@ -368,7 +369,7 @@ int QgsWMSProjectParser::WMSPrecision() const
368369
return WMSPrecision;
369370
}
370371

371-
QgsComposition* QgsWMSProjectParser::initComposition( const QString& composerTemplate, QgsMapRenderer* mapRenderer, QList< QgsComposerMap*>& mapList, QList< QgsComposerLabel* >& labelList, QList<const QgsComposerHtml *>& htmlList ) const
372+
QgsComposition* QgsWMSProjectParser::initComposition( const QString& composerTemplate, QgsMapRenderer* mapRenderer, QList< QgsComposerMap* >& mapList, QList< QgsComposerLegend* >& legendList, QList< QgsComposerLabel* >& labelList, QList<const QgsComposerHtml *>& htmlList ) const
372373
{
373374
//Create composition from xml
374375
QDomElement composerElem = composerByName( composerTemplate );
@@ -394,6 +395,7 @@ QgsComposition* QgsWMSProjectParser::initComposition( const QString& composerTem
394395

395396
labelList.clear();
396397
mapList.clear();
398+
legendList.clear();
397399
htmlList.clear();
398400

399401
QList<QgsComposerItem* > itemList;
@@ -413,6 +415,23 @@ QgsComposition* QgsWMSProjectParser::initComposition( const QString& composerTem
413415
mapList.push_back( map );
414416
continue;
415417
}
418+
QgsComposerLegend* legend = dynamic_cast< QgsComposerLegend *>( *itemIt );
419+
if ( legend )
420+
{
421+
/*
422+
QgsLegendModelV2* model = legend->modelV2();
423+
QgsLayerTreeGroup* root = model->rootGroup();
424+
QStringList layerIds = root->findLayerIds();
425+
throw QgsMapServiceException( "Error", "Composer legend layerIds "+layerIds.join(" ,") );
426+
*/
427+
if ( legend->autoUpdateModel() )
428+
{
429+
QgsLegendModelV2* model = legend->modelV2();
430+
model->setRootGroup( projectLayerTreeGroup() );
431+
}
432+
legendList.push_back( legend );
433+
continue;
434+
}
416435
QgsComposerPicture* pic = dynamic_cast< QgsComposerPicture *>( *itemIt );
417436
if ( pic )
418437
{
@@ -1913,6 +1932,27 @@ QDomElement QgsWMSProjectParser::composerByName( const QString& composerName ) c
19131932
return composerElem;
19141933
}
19151934

1935+
QgsLayerTreeGroup* QgsWMSProjectParser::projectLayerTreeGroup() const
1936+
{
1937+
const QDomDocument* projectDoc = mProjectParser.xmlDocument();
1938+
if ( !projectDoc )
1939+
{
1940+
return 0;
1941+
}
1942+
1943+
QDomElement qgisElem = projectDoc->documentElement();
1944+
if ( qgisElem.isNull() )
1945+
{
1946+
return 0;
1947+
}
1948+
QDomElement layerTreeElem = qgisElem.firstChildElement( "layer-tree-group" );
1949+
if ( layerTreeElem.isNull() )
1950+
{
1951+
return 0;
1952+
}
1953+
return QgsLayerTreeGroup::readXML( layerTreeElem );
1954+
}
1955+
19161956
bool QgsWMSProjectParser::annotationPosition( const QDomElement& elem, double scaleFactor, double& xPos, double& yPos )
19171957
{
19181958
Q_UNUSED( scaleFactor );

src/mapserver/qgswmsprojectparser.h

+3-1
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020

2121
#include "qgswmsconfigparser.h"
2222
#include "qgsserverprojectparser.h"
23+
#include "qgslayertreegroup.h"
2324

2425
class QTextDocument;
2526
class QSvgRenderer;
@@ -59,7 +60,7 @@ class QgsWMSProjectParser : public QgsWMSConfigParser
5960
int WMSPrecision() const;
6061

6162
//printing
62-
QgsComposition* initComposition( const QString& composerTemplate, QgsMapRenderer* mapRenderer, QList< QgsComposerMap*>& mapList, QList< QgsComposerLabel* >& labelList, QList<const QgsComposerHtml *>& htmlFrameList ) const;
63+
QgsComposition* initComposition( const QString& composerTemplate, QgsMapRenderer* mapRenderer, QList< QgsComposerMap* >& mapList, QList< QgsComposerLegend* >& legendList, QList< QgsComposerLabel* >& labelList, QList<const QgsComposerHtml *>& htmlFrameList ) const;
6364

6465
void printCapabilities( QDomElement& parentElement, QDomDocument& doc ) const;
6566

@@ -147,6 +148,7 @@ class QgsWMSProjectParser : public QgsWMSConfigParser
147148
void addLayersFromGroup( const QDomElement& legendGroupElem, QMap< int, QgsMapLayer*>& layers, bool useCache = true ) const;
148149

149150
QDomElement composerByName( const QString& composerName ) const;
151+
QgsLayerTreeGroup* projectLayerTreeGroup() const;
150152

151153
static bool annotationPosition( const QDomElement& elem, double scaleFactor, double& xPos, double& yPos );
152154
static void drawAnnotationRectangle( QPainter* p, const QDomElement& elem, double scaleFactor, double xPos, double yPos, int itemWidth, int itemHeight );

0 commit comments

Comments
 (0)