Skip to content

Commit 872fe7a

Browse files
committed
Introduce scale-based filtering of legend nodes (in WMS)
1 parent 1406feb commit 872fe7a

File tree

4 files changed

+57
-9
lines changed

4 files changed

+57
-9
lines changed

src/core/layertree/qgslayertreemodel.cpp

Lines changed: 34 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -43,9 +43,10 @@ QgsLayerTreeModel::QgsLayerTreeModel( QgsLayerTreeGroup* rootNode, QObject *pare
4343

4444
QgsLayerTreeModel::~QgsLayerTreeModel()
4545
{
46-
foreach ( QList<QgsLayerTreeModelLegendNode*> nodeL, mSymbologyNodes )
46+
foreach ( QList<QgsLayerTreeModelLegendNode*> nodeL, mOriginalSymbologyNodes )
4747
qDeleteAll( nodeL );
48-
mSymbologyNodes.clear();
48+
mOriginalSymbologyNodes.clear();
49+
mSymbologyNodes.clear(); // does not own the nodes
4950
}
5051

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

460461
Q_ASSERT( mSymbologyNodes.isEmpty() );
462+
Q_ASSERT( mOriginalSymbologyNodes.isEmpty() );
461463

462464
mRootNode = newRootGroup;
463465

@@ -541,6 +543,16 @@ QFont QgsLayerTreeModel::layerTreeNodeFont( int nodeType ) const
541543
}
542544
}
543545

546+
void QgsLayerTreeModel::setLegendFilterByScale( double scaleDenominator )
547+
{
548+
mLegendFilterByScale = scaleDenominator;
549+
550+
// this could be later done in more efficient way
551+
// by just updating active legend nodes, without refreshing original legend nodes
552+
foreach ( QgsLayerTreeLayer* nodeLayer, mRootNode->findLayers() )
553+
refreshLayerSymbology( nodeLayer );
554+
}
555+
544556
void QgsLayerTreeModel::nodeWillAddChildren( QgsLayerTreeNode* node, int indexFrom, int indexTo )
545557
{
546558
Q_ASSERT( node );
@@ -664,7 +676,8 @@ void QgsLayerTreeModel::removeSymbologyFromLayer( QgsLayerTreeLayer* nodeLayer )
664676
{
665677
if ( mSymbologyNodes.contains( nodeLayer ) )
666678
{
667-
qDeleteAll( mSymbologyNodes[nodeLayer] );
679+
qDeleteAll( mOriginalSymbologyNodes[nodeLayer] );
680+
mOriginalSymbologyNodes.remove( nodeLayer );
668681
mSymbologyNodes.remove( nodeLayer );
669682
}
670683
}
@@ -681,12 +694,15 @@ void QgsLayerTreeModel::addSymbologyToLayer( QgsLayerTreeLayer* nodeL )
681694

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

684-
beginInsertRows( node2index( nodeL ), 0, lstNew.count() - 1 );
697+
QList<QgsLayerTreeModelLegendNode*> filteredLstNew = filterLegendNodes( lstNew );
698+
699+
beginInsertRows( node2index( nodeL ), 0, filteredLstNew.count() - 1 );
685700

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

689-
mSymbologyNodes[nodeL] = lstNew;
704+
mOriginalSymbologyNodes[nodeL] = lstNew;
705+
mSymbologyNodes[nodeL] = filteredLstNew;
690706

691707
endInsertRows();
692708
}
@@ -954,3 +970,16 @@ const QIcon& QgsLayerTreeModel::iconGroup()
954970

955971
return icon;
956972
}
973+
974+
QList<QgsLayerTreeModelLegendNode*> QgsLayerTreeModel::filterLegendNodes( const QList<QgsLayerTreeModelLegendNode*>& nodes )
975+
{
976+
QList<QgsLayerTreeModelLegendNode*> filtered;
977+
foreach ( QgsLayerTreeModelLegendNode* node, nodes )
978+
{
979+
if ( mLegendFilterByScale > 0 && !node->isScaleOK( mLegendFilterByScale ) )
980+
continue;
981+
982+
filtered << node;
983+
}
984+
return filtered;
985+
}

src/core/layertree/qgslayertreemodel.h

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,12 @@ class CORE_EXPORT QgsLayerTreeModel : public QAbstractItemModel
137137
//! Return at what number of symbology nodes the layer node should be collapsed. -1 means no auto-collapse (default).
138138
int autoCollapseSymbologyNodes() const { return mAutoCollapseSymNodesCount; }
139139

140+
//! Force only display of legend nodes which are valid for given scale denominator.
141+
//! Setting value <= 0 will disable the functionality
142+
//! @note added in 2.6
143+
void setLegendFilterByScale( double scaleDenominator );
144+
double legendFilterByScale() const { return mLegendFilterByScale; }
145+
140146
signals:
141147

142148
protected slots:
@@ -172,20 +178,30 @@ class CORE_EXPORT QgsLayerTreeModel : public QAbstractItemModel
172178

173179
static const QIcon& iconGroup();
174180

181+
//! Filter nodes from QgsMapLayerLegend according to the current filtering rules
182+
QList<QgsLayerTreeModelLegendNode*> filterLegendNodes( const QList<QgsLayerTreeModelLegendNode*>& nodes );
183+
175184
protected:
176185
//! Pointer to the root node of the layer tree. Not owned by the model
177186
QgsLayerTreeGroup* mRootNode;
178187
//! Set of flags for the model
179188
Flags mFlags;
180-
//! Data structure for storage of symbology nodes for each layer
189+
//! Active symbology nodes for each layer node. May have been filtered.
190+
//! Owner of legend nodes is still mOriginalSymbologyNodes !
181191
QMap<QgsLayerTreeLayer*, QList<QgsLayerTreeModelLegendNode*> > mSymbologyNodes;
192+
//! Data structure for storage of symbology nodes for each layer.
193+
//! These are nodes as received from QgsMapLayerLegend
194+
QMap<QgsLayerTreeLayer*, QList<QgsLayerTreeModelLegendNode*> > mOriginalSymbologyNodes;
182195
//! Current index - will be underlined
183196
QPersistentModelIndex mCurrentIndex;
184197
//! Minimal number of nodes when symbology should be automatically collapsed. -1 = disabled
185198
int mAutoCollapseSymNodesCount;
186199

187200
QFont mFontLayer;
188201
QFont mFontGroup;
202+
203+
//! scale denominator for filtering of legend nodes (<= 0 means no filtering)
204+
double mLegendFilterByScale;
189205
};
190206

191207
Q_DECLARE_OPERATORS_FOR_FLAGS( QgsLayerTreeModel::Flags )

src/core/layertree/qgslayertreemodellegendnode.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,8 @@ class CORE_EXPORT QgsLayerTreeModelLegendNode : public QObject
5858
virtual QString userLabel() const { return mUserLabel; }
5959
virtual void setUserLabel( const QString& userLabel ) { mUserLabel = userLabel; }
6060

61+
virtual bool isScaleOK( double scale ) const { Q_UNUSED( scale ); return true; }
62+
6163
struct ItemContext
6264
{
6365
//! Painter
@@ -133,6 +135,8 @@ class CORE_EXPORT QgsSymbolV2LegendNode : public QgsLayerTreeModelLegendNode
133135

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

138+
virtual bool isScaleOK( double scale ) const { return mItem.isScaleOK( scale ); }
139+
136140
private:
137141
void updateLabel();
138142

src/mapserver/qgswmsserver.cpp

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -619,9 +619,8 @@ QImage* QgsWMSServer::getLegendGraphics()
619619

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

622-
// TODO: scale
623-
//if ( scaleDenominator > 0 )
624-
// legendModel.setLegendFilterByScale( scaleDenominator );
622+
if ( scaleDenominator > 0 )
623+
legendModel.setLegendFilterByScale( scaleDenominator );
625624

626625
// find out DPI
627626
QImage* tmpImage = createImage( 1, 1 );

0 commit comments

Comments
 (0)