Skip to content

Commit

Permalink
Merge pull request #1593 from rldhont/qgis-server-print-legend
Browse files Browse the repository at this point in the history
[FEATURE][QGIS-Server] Legend filtering based on map in GetPrint Request
  • Loading branch information
mhugent committed Sep 26, 2014
2 parents 0c6576c + 251a8a4 commit 6fcfb97
Show file tree
Hide file tree
Showing 10 changed files with 136 additions and 9 deletions.
2 changes: 2 additions & 0 deletions python/core/layertree/qgslayertreegroup.sip
Expand Up @@ -41,6 +41,8 @@ class QgsLayerTreeGroup : QgsLayerTreeNode
void removeLayer( QgsMapLayer* layer );
//! Remove child nodes from index "from". The nodes will be deleted.
void removeChildren( int from, int count );
//! Remove all child group nodes without layers. The groupnodes will be deleted.
void removeChildrenGroupWithoutLayers();
//! Remove all child nodes. The nodes will be deleted.
void removeAllChildren();

Expand Down
2 changes: 0 additions & 2 deletions src/core/composer/qgscomposerlabel.cpp
Expand Up @@ -98,7 +98,6 @@ void QgsComposerLabel::paint( QPainter* painter, const QStyleOptionGraphicsItem*
if ( mHtmlState )
{
painter->scale( 1.0 / mHtmlUnitsToMM / 10.0, 1.0 / mHtmlUnitsToMM / 10.0 );

QWebPage *webPage = new QWebPage();
webPage->setNetworkAccessManager( QgsNetworkAccessManager::instance() );

Expand Down Expand Up @@ -149,7 +148,6 @@ void QgsComposerLabel::paint( QPainter* painter, const QStyleOptionGraphicsItem*
// Pause until html is loaded
loop.exec();
}

webPage->mainFrame()->render( painter );//DELETE WEBPAGE ?
}
else
Expand Down
16 changes: 16 additions & 0 deletions src/core/layertree/qgslayertreegroup.cpp
Expand Up @@ -119,6 +119,22 @@ void QgsLayerTreeGroup::removeChildren( int from, int count )
updateVisibilityFromChildren();
}

void QgsLayerTreeGroup::removeChildrenGroupWithoutLayers()
{
// clean the layer tree by removing empty group
foreach ( QgsLayerTreeNode* treeNode, children() )
{
if ( treeNode->nodeType() == QgsLayerTreeNode::NodeGroup )
{
QgsLayerTreeGroup* treeGroup = qobject_cast<QgsLayerTreeGroup*>( treeNode );
if ( treeGroup->findLayerIds().count() == 0 )
removeChildNode( treeNode );
else
treeGroup->removeChildrenGroupWithoutLayers();
}
}
}

void QgsLayerTreeGroup::removeAllChildren()
{
removeChildren( 0, mChildren.count() );
Expand Down
2 changes: 2 additions & 0 deletions src/core/layertree/qgslayertreegroup.h
Expand Up @@ -62,6 +62,8 @@ class CORE_EXPORT QgsLayerTreeGroup : public QgsLayerTreeNode
void removeLayer( QgsMapLayer* layer );
//! Remove child nodes from index "from". The nodes will be deleted.
void removeChildren( int from, int count );
//! Remove all child group nodes without layers. The groupnodes will be deleted.
void removeChildrenGroupWithoutLayers();
//! Remove all child nodes. The nodes will be deleted.
void removeAllChildren();

Expand Down
4 changes: 2 additions & 2 deletions src/mapserver/qgssldconfigparser.cpp
Expand Up @@ -696,11 +696,11 @@ QgsComposition* QgsSLDConfigParser::createPrintComposition( const QString& compo
return 0;
}

QgsComposition* QgsSLDConfigParser::initComposition( const QString& composerTemplate, QgsMapRenderer* mapRenderer, QList< QgsComposerMap*>& mapList, QList< QgsComposerLabel* >& labelList, QList<const QgsComposerHtml *>& htmlFrameList ) const
QgsComposition* QgsSLDConfigParser::initComposition( const QString& composerTemplate, QgsMapRenderer* mapRenderer, QList< QgsComposerMap*>& mapList, QList< QgsComposerLegend* >& legendList, QList< QgsComposerLabel* >& labelList, QList<const QgsComposerHtml *>& htmlFrameList ) const
{
if ( mFallbackParser )
{
return mFallbackParser->initComposition( composerTemplate, mapRenderer, mapList, labelList, htmlFrameList );
return mFallbackParser->initComposition( composerTemplate, mapRenderer, mapList, legendList, labelList, htmlFrameList );
}
return 0;
}
Expand Down
2 changes: 1 addition & 1 deletion src/mapserver/qgssldconfigparser.h
Expand Up @@ -107,7 +107,7 @@ class QgsSLDConfigParser : public QgsWMSConfigParser
QgsComposition* createPrintComposition( const QString& composerTemplate, QgsMapRenderer* mapRenderer, const QMap< QString, QString >& parameterMap ) const;

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

/**Adds print capabilities to xml document. ParentElem usually is the <Capabilities> element*/
void printCapabilities( QDomElement& parentElement, QDomDocument& doc ) const;
Expand Down
68 changes: 67 additions & 1 deletion src/mapserver/qgswmsconfigparser.cpp
Expand Up @@ -17,13 +17,18 @@

#include "qgswmsconfigparser.h"
#include "qgsmaplayer.h"
#include "qgsmapserviceexception.h"

#include "qgscomposerlabel.h"
#include "qgscomposerlegend.h"
#include "qgscomposermap.h"
#include "qgscomposerhtml.h"
#include "qgscomposerframe.h"
#include "qgscomposition.h"

#include "qgslayertreegroup.h"
#include "qgslayertreelayer.h"

QgsWMSConfigParser::QgsWMSConfigParser()
{

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

QgsComposition* c = initComposition( composerTemplate, mapRenderer, composerMaps, composerLabels, composerHtmls );
QgsComposition* c = initComposition( composerTemplate, mapRenderer, composerMaps, composerLegends, composerLabels, composerHtmls );
if ( !c )
{
return 0;
Expand Down Expand Up @@ -158,6 +164,66 @@ QgsComposition* QgsWMSConfigParser::createPrintComposition( const QString& compo
currentMap->setGridIntervalX( parameterMap.value( mapId + ":GRID_INTERVAL_X" ).toDouble() );
currentMap->setGridIntervalY( parameterMap.value( mapId + ":GRID_INTERVAL_Y" ).toDouble() );
}
//update legend
// if it has an auto-update model
foreach ( QgsComposerLegend* currentLegend, composerLegends )
{
if ( !currentLegend )
{
continue;
}

if ( currentLegend->autoUpdateModel() || currentLegend->legendFilterByMapEnabled() )
{
// the legend has an auto-update model or
// has to be filter by map
// we will update it with map's layers
const QgsComposerMap* map = currentLegend->composerMap();
if ( !map )
{
continue;
}

// get model and layer tree root of the legend
QgsLegendModelV2* model = currentLegend->modelV2();
QgsLayerTreeGroup* root = model->rootGroup();


// get layerIds find in the layer tree root
QStringList layerIds = root->findLayerIds();
// get map layerIds
QStringList layerSet = map->layerSet();

// get map scale
double scale = map->scale();

// foreach layer find in the layer tree
// remove it if the layer id is not in map layerIds
foreach ( QString layerId, layerIds )
{
QgsLayerTreeLayer* nodeLayer = root->findLayer( layerId );
if ( !nodeLayer ) {
continue;
}
if ( !layerSet.contains( layerId ) )
{
qobject_cast<QgsLayerTreeGroup*>( nodeLayer->parent() )->removeChildNode( nodeLayer );
}
else
{
QgsMapLayer* layer = nodeLayer->layer();
if ( layer->hasScaleBasedVisibility() )
{
if ( layer->minimumScale() > scale )
qobject_cast<QgsLayerTreeGroup*>( nodeLayer->parent() )->removeChildNode( nodeLayer );
else if ( layer->maximumScale() < scale )
qobject_cast<QgsLayerTreeGroup*>( nodeLayer->parent() )->removeChildNode( nodeLayer );
}
}
}
root->removeChildrenGroupWithoutLayers();
}
}

//replace label text
foreach ( QgsComposerLabel *currentLabel, composerLabels )
Expand Down
3 changes: 2 additions & 1 deletion src/mapserver/qgswmsconfigparser.h
Expand Up @@ -22,6 +22,7 @@

class QgsComposerHtml;
class QgsComposerLabel;
class QgsComposerLegend;
class QgsComposerMap;
class QgsComposition;
class QgsMapLayer;
Expand Down Expand Up @@ -107,7 +108,7 @@ class QgsWMSConfigParser
QgsComposition* createPrintComposition( const QString& composerTemplate, QgsMapRenderer* mapRenderer, const QMap< QString, QString >& parameterMap ) const;

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

/**Adds print capabilities to xml document. ParentElem usually is the <Capabilities> element*/
virtual void printCapabilities( QDomElement& parentElement, QDomDocument& doc ) const = 0;
Expand Down
42 changes: 41 additions & 1 deletion src/mapserver/qgswmsprojectparser.cpp
Expand Up @@ -34,6 +34,7 @@
#include "qgscomposerpicture.h"
#include "qgscomposerscalebar.h"
#include "qgscomposershape.h"
#include "qgslayertreegroup.h"

#include <QFileInfo>
#include <QTextDocument>
Expand Down Expand Up @@ -368,7 +369,7 @@ int QgsWMSProjectParser::WMSPrecision() const
return WMSPrecision;
}

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

labelList.clear();
mapList.clear();
legendList.clear();
htmlList.clear();

QList<QgsComposerItem* > itemList;
Expand All @@ -413,6 +415,23 @@ QgsComposition* QgsWMSProjectParser::initComposition( const QString& composerTem
mapList.push_back( map );
continue;
}
QgsComposerLegend* legend = dynamic_cast< QgsComposerLegend *>( *itemIt );
if ( legend )
{
/*
QgsLegendModelV2* model = legend->modelV2();
QgsLayerTreeGroup* root = model->rootGroup();
QStringList layerIds = root->findLayerIds();
throw QgsMapServiceException( "Error", "Composer legend layerIds "+layerIds.join(" ,") );
*/
if ( legend->autoUpdateModel() )
{
QgsLegendModelV2* model = legend->modelV2();
model->setRootGroup( projectLayerTreeGroup() );
}
legendList.push_back( legend );
continue;
}
QgsComposerPicture* pic = dynamic_cast< QgsComposerPicture *>( *itemIt );
if ( pic )
{
Expand Down Expand Up @@ -1913,6 +1932,27 @@ QDomElement QgsWMSProjectParser::composerByName( const QString& composerName ) c
return composerElem;
}

QgsLayerTreeGroup* QgsWMSProjectParser::projectLayerTreeGroup() const
{
const QDomDocument* projectDoc = mProjectParser.xmlDocument();
if ( !projectDoc )
{
return 0;
}

QDomElement qgisElem = projectDoc->documentElement();
if ( qgisElem.isNull() )
{
return 0;
}
QDomElement layerTreeElem = qgisElem.firstChildElement( "layer-tree-group" );
if ( layerTreeElem.isNull() )
{
return 0;
}
return QgsLayerTreeGroup::readXML( layerTreeElem );
}

bool QgsWMSProjectParser::annotationPosition( const QDomElement& elem, double scaleFactor, double& xPos, double& yPos )
{
Q_UNUSED( scaleFactor );
Expand Down
4 changes: 3 additions & 1 deletion src/mapserver/qgswmsprojectparser.h
Expand Up @@ -20,6 +20,7 @@

#include "qgswmsconfigparser.h"
#include "qgsserverprojectparser.h"
#include "qgslayertreegroup.h"

class QTextDocument;
class QSvgRenderer;
Expand Down Expand Up @@ -59,7 +60,7 @@ class QgsWMSProjectParser : public QgsWMSConfigParser
int WMSPrecision() const;

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

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

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

QDomElement composerByName( const QString& composerName ) const;
QgsLayerTreeGroup* projectLayerTreeGroup() const;

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

0 comments on commit 6fcfb97

Please sign in to comment.