27
27
28
28
#include " qgsapplication.h"
29
29
#include " qgsfield.h"
30
+ #include " qgsmapcanvasmap.h"
30
31
#include " qgsmaplayerregistry.h"
31
32
#include " qgsrasterlayer.h"
32
33
#include " qgsrenderer.h"
50
51
#include < QPainter>
51
52
#include < QSettings>
52
53
#include < QFileDialog>
54
+ #include < QProgressDialog>
53
55
54
56
55
57
QgsLegendLayer::QgsLegendLayer ( QgsMapLayer* layer )
56
58
: QgsLegendItem( ),
57
- mLyr( layer )
59
+ mLyr( layer ), mShowFeatureCount( false )
58
60
{
59
61
mType = LEGEND_LAYER;
60
62
@@ -91,6 +93,7 @@ QgsLegendLayer::QgsLegendLayer( QgsMapLayer* layer )
91
93
QgsDebugMsg ( " Connecting signals for updating icons, layer " + layer->name () );
92
94
connect ( layer, SIGNAL ( editingStarted () ), this , SLOT ( updateIcon () ) );
93
95
connect ( layer, SIGNAL ( editingStopped () ), this , SLOT ( updateIcon () ) );
96
+ connect ( layer, SIGNAL ( layerModified ( bool ) ), this , SLOT ( updateAfterLayerModification ( bool ) ) );
94
97
}
95
98
connect ( layer, SIGNAL ( layerNameChanged () ), this , SLOT ( layerNameChanged () ) );
96
99
@@ -184,7 +187,7 @@ void QgsLegendLayer::changeSymbologySettings( const QgsMapLayer* theMapLayer,
184
187
185
188
186
189
187
- void QgsLegendLayer::vectorLayerSymbology ( const QgsVectorLayer* layer, double widthScale )
190
+ void QgsLegendLayer::vectorLayerSymbology ( QgsVectorLayer* layer, double widthScale )
188
191
{
189
192
if ( !layer )
190
193
{
@@ -219,6 +222,12 @@ void QgsLegendLayer::vectorLayerSymbology( const QgsVectorLayer* layer, double w
219
222
}
220
223
}
221
224
225
+ QMap< QgsSymbol*, int > featureCountMap;
226
+ if ( mShowFeatureCount )
227
+ {
228
+ updateItemListCount ( layer, sym, featureCountMap );
229
+ }
230
+
222
231
for ( QList<QgsSymbol*>::const_iterator it = sym.begin (); it != sym.end (); ++it )
223
232
{
224
233
QImage img;
@@ -258,6 +267,15 @@ void QgsLegendLayer::vectorLayerSymbology( const QgsVectorLayer* layer, double w
258
267
values += label;
259
268
}
260
269
270
+ if ( mShowFeatureCount )
271
+ {
272
+ int fCount = featureCountMap[*it];
273
+ if ( fCount >= 0 )
274
+ {
275
+ values += ( " [" + QString::number ( fCount ) + " ]" );
276
+ }
277
+ }
278
+
261
279
QPixmap pix = QPixmap::fromImage ( img ); // convert to pixmap
262
280
itemList.append ( qMakePair ( values, pix ) );
263
281
}
@@ -270,12 +288,11 @@ void QgsLegendLayer::vectorLayerSymbologyV2( QgsVectorLayer* layer )
270
288
{
271
289
QSize iconSize ( 16 , 16 );
272
290
273
- #if 0 // unused
274
- QSettings settings;
275
- bool showClassifiers = settings.value( "/qgis/showLegendClassifiers", false ).toBool();
276
- #endif
277
-
278
291
SymbologyList itemList = layer->rendererV2 ()->legendSymbologyItems ( iconSize );
292
+ if ( mShowFeatureCount )
293
+ {
294
+ updateItemListCountV2 ( itemList, layer );
295
+ }
279
296
280
297
changeSymbologySettings ( layer, itemList );
281
298
}
@@ -436,6 +453,12 @@ void QgsLegendLayer::addToPopupMenu( QMenu& theMenu )
436
453
if ( !vlayer->isEditable () && vlayer->dataProvider ()->supportsSubsetString () )
437
454
theMenu.addAction ( tr ( " &Query..." ), QgisApp::instance (), SLOT ( layerSubsetString () ) );
438
455
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 );
439
462
theMenu.addSeparator ();
440
463
}
441
464
@@ -503,3 +526,158 @@ void QgsLegendLayer::layerNameChanged()
503
526
QString name = mLyr .layer ()->name ();
504
527
setText ( 0 , name );
505
528
}
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