Skip to content

Commit

Permalink
Use new getLegendGraphics methods
Browse files Browse the repository at this point in the history
  • Loading branch information
pblottiere committed Apr 9, 2019
1 parent 81f029d commit 4d4d229
Show file tree
Hide file tree
Showing 6 changed files with 171 additions and 12 deletions.
13 changes: 11 additions & 2 deletions src/core/layertree/qgslayertreelayer.cpp
Expand Up @@ -76,12 +76,12 @@ void QgsLayerTreeLayer::attachToLayer()

QString QgsLayerTreeLayer::name() const
{
return mRef ? mRef->name() : mLayerName;
return ( mRef && mUseLayerName ) ? mRef->name() : mLayerName;
}

void QgsLayerTreeLayer::setName( const QString &n )
{
if ( mRef )
if ( mRef && mUseLayerName )
{
if ( mRef->name() == n )
return;
Expand Down Expand Up @@ -173,6 +173,15 @@ void QgsLayerTreeLayer::layerWillBeDeleted()

}

void QgsLayerTreeLayer::setUseLayerName( const bool use )
{
mUseLayerName = use;
}

bool QgsLayerTreeLayer::useLayerName() const
{
return mUseLayerName;
}

void QgsLayerTreeLayer::layerNameChanged()
{
Expand Down
9 changes: 8 additions & 1 deletion src/core/layertree/qgslayertreelayer.h
Expand Up @@ -90,6 +90,10 @@ class CORE_EXPORT QgsLayerTreeLayer : public QgsLayerTreeNode
*/
void setName( const QString &n ) override;

void setUseLayerName( bool use = true );

bool useLayerName() const;

/**
* Read layer node from XML. Returns new instance.
* Does not resolve textual references to layers. Call resolveReferences() afterwards to do it.
Expand Down Expand Up @@ -133,9 +137,12 @@ class CORE_EXPORT QgsLayerTreeLayer : public QgsLayerTreeNode

//! Weak reference to the layer (or just it's ID if the reference is not resolved yet)
QgsMapLayerRef mRef;
//! Layer name - only used if layer does not exist
//! Layer name - only used if layer does not exist or if mUseLayerName is false
QString mLayerName;

//!
bool mUseLayerName = true;

private slots:

/**
Expand Down
66 changes: 59 additions & 7 deletions src/server/services/wms/qgswmsgetlegendgraphics.cpp
Expand Up @@ -22,6 +22,8 @@
#include "qgslegendrenderer.h"
#include "qgsvectorlayer.h"
#include "qgsvectorlayerfeaturecounter.h"
#include "qgssymbollayerutils.h"
#include "qgsmaplayerlegend.h"

#include "qgswmsutils.h"
#include "qgswmsserviceexception.h"
Expand Down Expand Up @@ -89,7 +91,25 @@ namespace QgsWms
#endif
QgsRenderer renderer( context );

std::unique_ptr<QImage> result( renderer.getLegendGraphics() );
// retrieve legend settings and model
std::unique_ptr<QgsLayerTree> tree( layerTree( context ) );
std::unique_ptr<QgsLayerTreeModel> model( legendModel( context, *tree.get() ) );

// rendering
QgsRenderer renderer( context );

std::unique_ptr<QImage> result;
if ( !parameters.rule().isEmpty() )
{
QgsLayerTreeModelLegendNode *node = legendNode( parameters.rule(), *model.get() );
result.reset( renderer.getLegendGraphics( *node ) );
}
else
{
result.reset( renderer.getLegendGraphics( *model.get() ) );
}

tree->clear();

if ( result )
{
Expand Down Expand Up @@ -152,7 +172,38 @@ namespace QgsWms
QgsRenderer renderer( context );
const QgsRenderer::HitTest symbols = renderer.symbols();

// TODO
for ( QgsLayerTreeNode *node : tree.children() )
{
QgsLayerTreeLayer *layer = QgsLayerTree::toLayer( node );

QgsVectorLayer *vl = qobject_cast<QgsVectorLayer *>( layer->layer() );
if ( !vl || !vl->renderer() )
continue;

QList<int> order;
int i = 0;

for ( const QgsLegendSymbolItem &item : vl->renderer()->legendSymbolItems() )
{
const QString prop = QgsSymbolLayerUtils::symbolProperties( item.legacyRuleKey() );
if ( symbols[vl].contains( prop ) )
{
order.append( i );
}
++i;
}

// either remove the whole layer or just filter out some items
if ( order.isEmpty() )
{
tree.removeChildNode( layer );
}
else
{
QgsMapLayerLegendUtils::setLegendNodeOrder( layer, order );
model->refreshLayerLegend( layer );
}
}
}

// if legend is not based on rendering rules
Expand Down Expand Up @@ -194,18 +245,19 @@ namespace QgsWms

QgsLayerTree *layerTree( const QgsWmsRenderContext &context )
{
std::unique_ptr<QgsLayerTree> tree;
std::unique_ptr<QgsLayerTree> tree( new QgsLayerTree() );

QList<QgsVectorLayerFeatureCounter *> counters;
for ( QgsMapLayer *ml : context.layersToRender() )
{
QgsLayerTreeLayer *lt = tree->addLayer( ml );
lt->setUseLayerName( false ); // do not modify underlying layer

// name
if ( !ml->title().isEmpty() )
lt->setName( ml->title() );

//show feature count
// show feature count
const bool showFeatureCount = context.parameters().showFeatureCountAsBool();
const QString property = QStringLiteral( "showFeatureCount" );
lt->setCustomProperty( property, showFeatureCount );
Expand All @@ -229,11 +281,11 @@ namespace QgsWms
return tree.release();
}

QgsLayerTreeModelLegendNode *legendNode( const QgsLayerTreeModel &model, const QString &rule )
QgsLayerTreeModelLegendNode *legendNode( const QString &rule, QgsLayerTreeModel &model )
{
for ( QgsLayerTreeLayer *layer : model->rootGroup()->findLayers() )
for ( QgsLayerTreeLayer *layer : model.rootGroup()->findLayers() )
{
for ( QgsLayerTreeModelLegendNode *node : model->layerLegendNodes( layer ) )
for ( QgsLayerTreeModelLegendNode *node : model.layerLegendNodes( layer ) )
{
if ( node->data( Qt::DisplayRole ).toString().compare( rule ) == 0 )
return node;
Expand Down
2 changes: 1 addition & 1 deletion src/server/services/wms/qgswmsgetlegendgraphics.h
Expand Up @@ -38,5 +38,5 @@ namespace QgsWms

QgsLayerTree *layerTree( const QgsWmsRenderContext &context );

QgsLayerTreeModelLegendNode *legendNode( const QgsLayerTreeModel &model, const QString &rule );
QgsLayerTreeModelLegendNode *legendNode( const QString &rule, QgsLayerTreeModel &model );
} // namespace QgsWms
88 changes: 87 additions & 1 deletion src/server/services/wms/qgswmsrenderer.cpp
Expand Up @@ -31,7 +31,6 @@
#include "qgsmapserviceexception.h"
#include "qgslayertree.h"
#include "qgslayertreemodel.h"
#include "qgslayertreemodellegendnode.h"
#include "qgslegendrenderer.h"
#include "qgsmaplayer.h"
#include "qgsmaplayerlegend.h"
Expand Down Expand Up @@ -201,6 +200,93 @@ namespace QgsWms
return image.release();
}

QImage *QgsRenderer::getLegendGraphics( QgsLayerTreeModel &model )
{
// get layers
std::unique_ptr<QgsLayerRestorer> restorer;
restorer.reset( new QgsLayerRestorer( mContext.layers() ) );

// configure layers
QList<QgsMapLayer *> layers = mContext.layersToRender();
configureLayers( layers );

// getting scale from bbox
QgsLegendSettings settings = mWmsParameters.legendSettings();
if ( !mWmsParameters.bbox().isEmpty() )
{
QgsMapSettings mapSettings;
std::unique_ptr<QImage> tmp( createImage( width(), height(), false ) );
configureMapSettings( tmp.get(), mapSettings );
settings.setMapScale( mapSettings.scale() );
settings.setMapUnitsPerPixel( mapSettings.mapUnitsPerPixel() );
}

// init renderer
QgsLegendRenderer renderer( &model, settings );

// create image
std::unique_ptr<QImage> image;
const qreal dpmm = mContext.dotsPerMm();
const QSizeF minSize = renderer.minimumSize();
const QSize size( minSize.width() * dpmm, minSize.height() * dpmm );
image.reset( createImage( size.width(), size.height(), false ) );

// configure painter
std::unique_ptr<QPainter> painter;
painter.reset( new QPainter( image.get() ) );
painter->setRenderHint( QPainter::Antialiasing, true );
painter->scale( dpmm, dpmm );

// rendering
renderer.drawLegend( painter.get() );
painter->end();

return image.release();
}

QImage *QgsRenderer::getLegendGraphics( QgsLayerTreeModelLegendNode &node )
{
// get layers
std::unique_ptr<QgsLayerRestorer> restorer;
restorer.reset( new QgsLayerRestorer( mContext.layers() ) );

// configure layers
QList<QgsMapLayer *> layers = mContext.layersToRender();
configureLayers( layers );

// getting scale from bbox
QgsLegendSettings settings = mWmsParameters.legendSettings();
if ( !mWmsParameters.bbox().isEmpty() )
{
QgsMapSettings mapSettings;
std::unique_ptr<QImage> tmp( createImage( width(), height(), false ) );
configureMapSettings( tmp.get(), mapSettings );
settings.setMapScale( mapSettings.scale() );
settings.setMapUnitsPerPixel( mapSettings.mapUnitsPerPixel() );
}

// create image
const int width = mWmsParameters.widthAsInt();
const int height = mWmsParameters.heightAsInt();
std::unique_ptr<QImage> image( createImage( width, height, false ) );

// configure painter
const qreal dpmm = mContext.dotsPerMm();
std::unique_ptr<QPainter> painter;
painter.reset( new QPainter( image.get() ) );
painter->setRenderHint( QPainter::Antialiasing, true );
painter->scale( dpmm, dpmm );

// rendering
QgsLayerTreeModelLegendNode::ItemContext ctx;
ctx.painter = painter.get();
ctx.labelXOffset = 0;
ctx.point = QPointF();
node.drawSymbol( settings, &ctx, height / dpmm );
painter->end();

return image.release();
}
void QgsRenderer::runHitTest( const QgsMapSettings &mapSettings, HitTest &hitTest ) const
{
QgsRenderContext context = QgsRenderContext::fromMapSettings( mapSettings );
Expand Down
5 changes: 5 additions & 0 deletions src/server/services/wms/qgswmsrenderer.h
Expand Up @@ -24,6 +24,7 @@
#include "qgswmsparameters.h"
#include "qgswmsrendercontext.h"
#include "qgsfeaturefilter.h"
#include "qgslayertreemodellegendnode.h"
#include <QDomDocument>
#include <QMap>
#include <QString>
Expand Down Expand Up @@ -80,6 +81,10 @@ namespace QgsWms
of the image object*/
QImage *getLegendGraphics();

QImage *getLegendGraphics( QgsLayerTreeModel &model );

QImage *getLegendGraphics( QgsLayerTreeModelLegendNode &node );

typedef QSet<QString> SymbolSet;
typedef QHash<QgsVectorLayer *, SymbolSet> HitTest;

Expand Down

0 comments on commit 4d4d229

Please sign in to comment.