Skip to content
Permalink
Browse files

Merge pull request #1593 from rldhont/qgis-server-print-legend

[FEATURE][QGIS-Server] Legend filtering based on map in GetPrint Request
  • Loading branch information
mhugent committed Sep 26, 2014
2 parents 0c6576c + 251a8a4 commit 6fcfb97bf6c8073c493a55a35d14af9d7103fc7c
@@ -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();

@@ -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() );

@@ -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
@@ -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() );
@@ -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();

@@ -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;
}
@@ -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;
@@ -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()
{

@@ -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;
@@ -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 )
@@ -22,6 +22,7 @@

class QgsComposerHtml;
class QgsComposerLabel;
class QgsComposerLegend;
class QgsComposerMap;
class QgsComposition;
class QgsMapLayer;
@@ -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;
@@ -34,6 +34,7 @@
#include "qgscomposerpicture.h"
#include "qgscomposerscalebar.h"
#include "qgscomposershape.h"
#include "qgslayertreegroup.h"

#include <QFileInfo>
#include <QTextDocument>
@@ -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 );
@@ -394,6 +395,7 @@ QgsComposition* QgsWMSProjectParser::initComposition( const QString& composerTem

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

QList<QgsComposerItem* > itemList;
@@ -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 )
{
@@ -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 );
@@ -20,6 +20,7 @@

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

class QTextDocument;
class QSvgRenderer;
@@ -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;

@@ -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 );

0 comments on commit 6fcfb97

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