2727
2828#include " qgsapplication.h"
2929#include " qgsfield.h"
30+ #include " qgsmapcanvasmap.h"
3031#include " qgsmaplayerregistry.h"
3132#include " qgsrasterlayer.h"
3233#include " qgsrenderer.h"
5051#include < QPainter>
5152#include < QSettings>
5253#include < QFileDialog>
54+ #include < QProgressDialog>
5355
5456
5557QgsLegendLayer::QgsLegendLayer ( QgsMapLayer* layer )
5658 : QgsLegendItem( ),
57- mLyr( layer )
59+ mLyr( layer ), mShowFeatureCount( false )
5860{
5961 mType = LEGEND_LAYER;
6062
@@ -91,6 +93,7 @@ QgsLegendLayer::QgsLegendLayer( QgsMapLayer* layer )
9193 QgsDebugMsg ( " Connecting signals for updating icons, layer " + layer->name () );
9294 connect ( layer, SIGNAL ( editingStarted () ), this , SLOT ( updateIcon () ) );
9395 connect ( layer, SIGNAL ( editingStopped () ), this , SLOT ( updateIcon () ) );
96+ connect ( layer, SIGNAL ( layerModified ( bool ) ), this , SLOT ( updateAfterLayerModification ( bool ) ) );
9497 }
9598 connect ( layer, SIGNAL ( layerNameChanged () ), this , SLOT ( layerNameChanged () ) );
9699
@@ -184,7 +187,7 @@ void QgsLegendLayer::changeSymbologySettings( const QgsMapLayer* theMapLayer,
184187
185188
186189
187- void QgsLegendLayer::vectorLayerSymbology ( const QgsVectorLayer* layer, double widthScale )
190+ void QgsLegendLayer::vectorLayerSymbology ( QgsVectorLayer* layer, double widthScale )
188191{
189192 if ( !layer )
190193 {
@@ -219,6 +222,12 @@ void QgsLegendLayer::vectorLayerSymbology( const QgsVectorLayer* layer, double w
219222 }
220223 }
221224
225+ QMap< QgsSymbol*, int > featureCountMap;
226+ if ( mShowFeatureCount )
227+ {
228+ updateItemListCount ( layer, sym, featureCountMap );
229+ }
230+
222231 for ( QList<QgsSymbol*>::const_iterator it = sym.begin (); it != sym.end (); ++it )
223232 {
224233 QImage img;
@@ -258,6 +267,15 @@ void QgsLegendLayer::vectorLayerSymbology( const QgsVectorLayer* layer, double w
258267 values += label;
259268 }
260269
270+ if ( mShowFeatureCount )
271+ {
272+ int fCount = featureCountMap[*it];
273+ if ( fCount >= 0 )
274+ {
275+ values += ( " [" + QString::number ( fCount ) + " ]" );
276+ }
277+ }
278+
261279 QPixmap pix = QPixmap::fromImage ( img ); // convert to pixmap
262280 itemList.append ( qMakePair ( values, pix ) );
263281 }
@@ -270,12 +288,11 @@ void QgsLegendLayer::vectorLayerSymbologyV2( QgsVectorLayer* layer )
270288{
271289 QSize iconSize ( 16 , 16 );
272290
273- #if 0 // unused
274- QSettings settings;
275- bool showClassifiers = settings.value( "/qgis/showLegendClassifiers", false ).toBool();
276- #endif
277-
278291 SymbologyList itemList = layer->rendererV2 ()->legendSymbologyItems ( iconSize );
292+ if ( mShowFeatureCount )
293+ {
294+ updateItemListCountV2 ( itemList, layer );
295+ }
279296
280297 changeSymbologySettings ( layer, itemList );
281298}
@@ -436,6 +453,12 @@ void QgsLegendLayer::addToPopupMenu( QMenu& theMenu )
436453 if ( !vlayer->isEditable () && vlayer->dataProvider ()->supportsSubsetString () )
437454 theMenu.addAction ( tr ( " &Query..." ), QgisApp::instance (), SLOT ( layerSubsetString () ) );
438455
456+ // show number of features in legend if requested
457+ QAction* showNFeaturesAction = new QAction ( tr ( " Show feature count" ), &theMenu );
458+ showNFeaturesAction->setCheckable ( true );
459+ showNFeaturesAction->setChecked ( mShowFeatureCount );
460+ QObject::connect ( showNFeaturesAction, SIGNAL ( toggled ( bool ) ), this , SLOT ( setShowFeatureCount ( bool ) ) );
461+ theMenu.addAction ( showNFeaturesAction );
439462 theMenu.addSeparator ();
440463 }
441464
@@ -503,3 +526,158 @@ void QgsLegendLayer::layerNameChanged()
503526 QString name = mLyr .layer ()->name ();
504527 setText ( 0 , name );
505528}
529+
530+ void QgsLegendLayer::updateAfterLayerModification ( bool onlyGeomChanged )
531+ {
532+ if ( onlyGeomChanged )
533+ {
534+ return ;
535+ }
536+
537+ double widthScale = 1.0 ;
538+ QgsMapCanvas* canvas = QgisApp::instance ()->mapCanvas ();
539+ if ( canvas && canvas->map () )
540+ {
541+ widthScale = canvas->map ()->paintDevice ().logicalDpiX () / 25.4 ;
542+ }
543+ refreshSymbology ( mLyr .layer ()->getLayerID (), widthScale );
544+ }
545+
546+ void QgsLegendLayer::updateItemListCountV2 ( SymbologyList& itemList, QgsVectorLayer* layer )
547+ {
548+ if ( !layer )
549+ {
550+ return ;
551+ }
552+
553+ QgsFeatureRendererV2* renderer = layer->rendererV2 ();
554+ if ( !renderer )
555+ {
556+ return ;
557+ }
558+ QgsRenderContext dummyContext;
559+ renderer->startRender ( dummyContext, layer );
560+
561+ // create map holding the symbol count
562+ QMap< QgsSymbolV2*, int > mSymbolCountMap ;
563+ QgsLegendSymbolList symbolList = renderer->legendSymbolItems ();
564+ QgsLegendSymbolList::const_iterator symbolIt = symbolList.constBegin ();
565+ for ( ; symbolIt != symbolList.constEnd (); ++symbolIt )
566+ {
567+ mSymbolCountMap .insert ( symbolIt->second , 0 );
568+ }
569+
570+ // go through all features and count the number of occurrences
571+ int nFeatures = layer->pendingFeatureCount ();
572+ QProgressDialog p ( tr ( " Updating feature count for layer " ) + layer->name (), tr ( " Abort" ), 0 , nFeatures );
573+ p.setWindowModality ( Qt::WindowModal );
574+ int featuresCounted = 0 ;
575+
576+
577+ layer->select ( layer->pendingAllAttributesList (), QgsRectangle (), false , false );
578+ QgsFeature f;
579+ QgsSymbolV2* currentSymbol = 0 ;
580+
581+ while ( layer->nextFeature ( f ) )
582+ {
583+ currentSymbol = renderer->symbolForFeature ( f );
584+ mSymbolCountMap [currentSymbol] += 1 ;
585+ ++featuresCounted;
586+ if ( featuresCounted % 50 == 0 )
587+ {
588+ if ( featuresCounted > nFeatures ) // sometimes the feature count is not correct
589+ {
590+ p.setMaximum ( 0 );
591+ }
592+ p.setValue ( featuresCounted );
593+ if ( p.wasCanceled () )
594+ {
595+ return ;
596+ }
597+ }
598+ }
599+ p.setValue ( nFeatures );
600+
601+ QMap<QString, QPixmap> itemMap;
602+ SymbologyList::const_iterator symbologyIt = itemList.constBegin ();
603+ for ( ; symbologyIt != itemList.constEnd (); ++ symbologyIt )
604+ {
605+ itemMap.insert ( symbologyIt->first , symbologyIt->second );
606+ }
607+ itemList.clear ();
608+
609+ //
610+ symbolIt = symbolList.constBegin ();
611+ for ( ; symbolIt != symbolList.constEnd (); ++symbolIt )
612+ {
613+ QgsSymbolV2* debug = symbolIt->second ;
614+ itemList.push_back ( qMakePair ( symbolIt->first + " [" + QString::number ( mSymbolCountMap [symbolIt->second ] ) + " ]" , itemMap[symbolIt->first ] ) );
615+ }
616+ }
617+
618+ void QgsLegendLayer::updateItemListCount ( QgsVectorLayer* layer, const QList<QgsSymbol*>& sym, QMap< QgsSymbol*, int >& featureCountMap )
619+ {
620+ featureCountMap.clear ();
621+ QList<QgsSymbol*>::const_iterator symbolIt = sym.constBegin ();
622+ for ( ; symbolIt != sym.constEnd (); ++symbolIt )
623+ {
624+ featureCountMap.insert ( *symbolIt, 0 );
625+ }
626+
627+ QgsRenderer* renderer = const_cast <QgsRenderer*>( layer->renderer () );
628+ if ( !renderer )
629+ {
630+ return ;
631+ }
632+
633+ // go through all features and count the number of occurrences
634+ int nFeatures = layer->pendingFeatureCount ();
635+ QProgressDialog p ( tr ( " Updating feature count for layer " ) + layer->name (), tr ( " Abort" ), 0 , nFeatures );
636+ p.setWindowModality ( Qt::WindowModal );
637+ int featuresCounted = 0 ;
638+
639+ layer->select ( layer->pendingAllAttributesList (), QgsRectangle (), false , false );
640+ QgsFeature f;
641+ QgsSymbol* currentSymbol = 0 ;
642+
643+ while ( layer->nextFeature ( f ) )
644+ {
645+ currentSymbol = renderer->symbolForFeature ( &f );
646+ if ( currentSymbol )
647+ {
648+ featureCountMap[currentSymbol] += 1 ;
649+ }
650+ ++featuresCounted;
651+
652+ if ( featuresCounted % 50 == 0 )
653+ {
654+ if ( featuresCounted > nFeatures ) // sometimes the feature count is not correct
655+ {
656+ p.setMaximum ( 0 );
657+ }
658+ p.setValue ( featuresCounted );
659+ if ( p.wasCanceled () ) // set all entries to -1 (= invalid)
660+ {
661+ QMap< QgsSymbol*, int >::iterator cIt = featureCountMap.begin ();
662+ for ( ; cIt != featureCountMap.end (); ++cIt )
663+ {
664+ cIt.value () = -1 ;
665+ }
666+ return ;
667+ }
668+ }
669+ }
670+ p.setValue ( nFeatures );
671+ }
672+
673+ void QgsLegendLayer::setShowFeatureCount ( bool show, bool update )
674+ {
675+ if ( show != mShowFeatureCount )
676+ {
677+ mShowFeatureCount = show;
678+ if ( update )
679+ {
680+ updateAfterLayerModification ( false );
681+ }
682+ }
683+ }
0 commit comments