Skip to content

Commit

Permalink
Introduce scale-based filtering of legend nodes (in WMS)
Browse files Browse the repository at this point in the history
  • Loading branch information
wonder-sk committed Sep 1, 2014
1 parent 1406feb commit 872fe7a
Show file tree
Hide file tree
Showing 4 changed files with 57 additions and 9 deletions.
39 changes: 34 additions & 5 deletions src/core/layertree/qgslayertreemodel.cpp
Expand Up @@ -43,9 +43,10 @@ QgsLayerTreeModel::QgsLayerTreeModel( QgsLayerTreeGroup* rootNode, QObject *pare

QgsLayerTreeModel::~QgsLayerTreeModel()
{
foreach ( QList<QgsLayerTreeModelLegendNode*> nodeL, mSymbologyNodes )
foreach ( QList<QgsLayerTreeModelLegendNode*> nodeL, mOriginalSymbologyNodes )
qDeleteAll( nodeL );
mSymbologyNodes.clear();
mOriginalSymbologyNodes.clear();
mSymbologyNodes.clear(); // does not own the nodes
}

QgsLayerTreeNode* QgsLayerTreeModel::index2node( const QModelIndex& index ) const
Expand Down Expand Up @@ -458,6 +459,7 @@ void QgsLayerTreeModel::setRootGroup( QgsLayerTreeGroup* newRootGroup )
disconnectFromRootNode();

Q_ASSERT( mSymbologyNodes.isEmpty() );
Q_ASSERT( mOriginalSymbologyNodes.isEmpty() );

mRootNode = newRootGroup;

Expand Down Expand Up @@ -541,6 +543,16 @@ QFont QgsLayerTreeModel::layerTreeNodeFont( int nodeType ) const
}
}

void QgsLayerTreeModel::setLegendFilterByScale( double scaleDenominator )
{
mLegendFilterByScale = scaleDenominator;

// this could be later done in more efficient way
// by just updating active legend nodes, without refreshing original legend nodes
foreach ( QgsLayerTreeLayer* nodeLayer, mRootNode->findLayers() )
refreshLayerSymbology( nodeLayer );
}

void QgsLayerTreeModel::nodeWillAddChildren( QgsLayerTreeNode* node, int indexFrom, int indexTo )
{
Q_ASSERT( node );
Expand Down Expand Up @@ -664,7 +676,8 @@ void QgsLayerTreeModel::removeSymbologyFromLayer( QgsLayerTreeLayer* nodeLayer )
{
if ( mSymbologyNodes.contains( nodeLayer ) )
{
qDeleteAll( mSymbologyNodes[nodeLayer] );
qDeleteAll( mOriginalSymbologyNodes[nodeLayer] );
mOriginalSymbologyNodes.remove( nodeLayer );
mSymbologyNodes.remove( nodeLayer );
}
}
Expand All @@ -681,12 +694,15 @@ void QgsLayerTreeModel::addSymbologyToLayer( QgsLayerTreeLayer* nodeL )

QList<QgsLayerTreeModelLegendNode*> lstNew = layerLegend->createLayerTreeModelLegendNodes( nodeL );

beginInsertRows( node2index( nodeL ), 0, lstNew.count() - 1 );
QList<QgsLayerTreeModelLegendNode*> filteredLstNew = filterLegendNodes( lstNew );

beginInsertRows( node2index( nodeL ), 0, filteredLstNew.count() - 1 );

foreach ( QgsLayerTreeModelLegendNode* n, lstNew )
n->setParent( nodeL );

mSymbologyNodes[nodeL] = lstNew;
mOriginalSymbologyNodes[nodeL] = lstNew;
mSymbologyNodes[nodeL] = filteredLstNew;

endInsertRows();
}
Expand Down Expand Up @@ -954,3 +970,16 @@ const QIcon& QgsLayerTreeModel::iconGroup()

return icon;
}

QList<QgsLayerTreeModelLegendNode*> QgsLayerTreeModel::filterLegendNodes( const QList<QgsLayerTreeModelLegendNode*>& nodes )
{
QList<QgsLayerTreeModelLegendNode*> filtered;
foreach ( QgsLayerTreeModelLegendNode* node, nodes )
{
if ( mLegendFilterByScale > 0 && !node->isScaleOK( mLegendFilterByScale ) )
continue;

filtered << node;
}
return filtered;
}
18 changes: 17 additions & 1 deletion src/core/layertree/qgslayertreemodel.h
Expand Up @@ -137,6 +137,12 @@ class CORE_EXPORT QgsLayerTreeModel : public QAbstractItemModel
//! Return at what number of symbology nodes the layer node should be collapsed. -1 means no auto-collapse (default).
int autoCollapseSymbologyNodes() const { return mAutoCollapseSymNodesCount; }

//! Force only display of legend nodes which are valid for given scale denominator.
//! Setting value <= 0 will disable the functionality
//! @note added in 2.6
void setLegendFilterByScale( double scaleDenominator );
double legendFilterByScale() const { return mLegendFilterByScale; }

signals:

protected slots:
Expand Down Expand Up @@ -172,20 +178,30 @@ class CORE_EXPORT QgsLayerTreeModel : public QAbstractItemModel

static const QIcon& iconGroup();

//! Filter nodes from QgsMapLayerLegend according to the current filtering rules
QList<QgsLayerTreeModelLegendNode*> filterLegendNodes( const QList<QgsLayerTreeModelLegendNode*>& nodes );

protected:
//! Pointer to the root node of the layer tree. Not owned by the model
QgsLayerTreeGroup* mRootNode;
//! Set of flags for the model
Flags mFlags;
//! Data structure for storage of symbology nodes for each layer
//! Active symbology nodes for each layer node. May have been filtered.
//! Owner of legend nodes is still mOriginalSymbologyNodes !
QMap<QgsLayerTreeLayer*, QList<QgsLayerTreeModelLegendNode*> > mSymbologyNodes;
//! Data structure for storage of symbology nodes for each layer.
//! These are nodes as received from QgsMapLayerLegend
QMap<QgsLayerTreeLayer*, QList<QgsLayerTreeModelLegendNode*> > mOriginalSymbologyNodes;
//! Current index - will be underlined
QPersistentModelIndex mCurrentIndex;
//! Minimal number of nodes when symbology should be automatically collapsed. -1 = disabled
int mAutoCollapseSymNodesCount;

QFont mFontLayer;
QFont mFontGroup;

//! scale denominator for filtering of legend nodes (<= 0 means no filtering)
double mLegendFilterByScale;
};

Q_DECLARE_OPERATORS_FOR_FLAGS( QgsLayerTreeModel::Flags )
Expand Down
4 changes: 4 additions & 0 deletions src/core/layertree/qgslayertreemodellegendnode.h
Expand Up @@ -58,6 +58,8 @@ class CORE_EXPORT QgsLayerTreeModelLegendNode : public QObject
virtual QString userLabel() const { return mUserLabel; }
virtual void setUserLabel( const QString& userLabel ) { mUserLabel = userLabel; }

virtual bool isScaleOK( double scale ) const { Q_UNUSED( scale ); return true; }

struct ItemContext
{
//! Painter
Expand Down Expand Up @@ -133,6 +135,8 @@ class CORE_EXPORT QgsSymbolV2LegendNode : public QgsLayerTreeModelLegendNode

void setUserLabel( const QString& userLabel ) { mUserLabel = userLabel; updateLabel(); }

virtual bool isScaleOK( double scale ) const { return mItem.isScaleOK( scale ); }

private:
void updateLabel();

Expand Down
5 changes: 2 additions & 3 deletions src/mapserver/qgswmsserver.cpp
Expand Up @@ -619,9 +619,8 @@ QImage* QgsWMSServer::getLegendGraphics()

QList<QgsLayerTreeNode*> rootChildren = rootGroup.children();

// TODO: scale
//if ( scaleDenominator > 0 )
// legendModel.setLegendFilterByScale( scaleDenominator );
if ( scaleDenominator > 0 )
legendModel.setLegendFilterByScale( scaleDenominator );

// find out DPI
QImage* tmpImage = createImage( 1, 1 );
Expand Down

0 comments on commit 872fe7a

Please sign in to comment.