101118_qgis_featurecount.diff

Marco Hugentobler, 2010-11-18 01:16 AM

Download (18.9 KB)

View differences:

src/app/legend/qgslegendlayer.cpp (Arbeitskopie)
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 )
......
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 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 222
      }
220 223
    }
221 224

  
225
    bool countFeatures = settings.value( "/qgis/showNumberOfFeaturesInLegend", false ).toBool();
226
    QMap< QgsSymbol*, int > featureCountMap;
227
    if ( countFeatures )
228
    {
229
      updateItemListCount( layer, sym, featureCountMap );
230
    }
231

  
222 232
    for ( QList<QgsSymbol*>::const_iterator it = sym.begin(); it != sym.end(); ++it )
223 233
    {
224 234
      QImage img;
......
258 268
        values += label;
259 269
      }
260 270

  
271
      if ( countFeatures )
272
      {
273
        int fCount = featureCountMap[*it];
274
        if ( fCount >= 0 )
275
        {
276
          values += ( " (" + QString::number( fCount ) + ")" );
277
        }
278
      }
279

  
261 280
      QPixmap pix = QPixmap::fromImage( img ); // convert to pixmap
262 281
      itemList.append( qMakePair( values, pix ) );
263 282
    }
......
270 289
{
271 290
  QSize iconSize( 16, 16 );
272 291

  
273
#if 0 // unused
292
  SymbologyList itemList = layer->rendererV2()->legendSymbologyItems( iconSize );
274 293
  QSettings settings;
275
  bool showClassifiers = settings.value( "/qgis/showLegendClassifiers", false ).toBool();
276
#endif
294
  if ( settings.value( "/qgis/showNumberOfFeaturesInLegend", false ).toBool() )
295
  {
296
    updateItemListCountV2( itemList, layer );
297
  }
277 298

  
278
  SymbologyList itemList = layer->rendererV2()->legendSymbologyItems( iconSize );
279

  
280 299
  changeSymbologySettings( layer, itemList );
281 300
}
282 301

  
......
503 522
  QString name = mLyr.layer()->name();
504 523
  setText( 0, name );
505 524
}
525

  
526
void QgsLegendLayer::updateAfterLayerModification( bool onlyGeomChanged )
527
{
528
  if ( onlyGeomChanged )
529
  {
530
    return;
531
  }
532

  
533
  double widthScale = 1.0;
534
  QgsMapCanvas* canvas = QgisApp::instance()->mapCanvas();
535
  if ( canvas && canvas->map() )
536
  {
537
    widthScale = canvas->map()->paintDevice().logicalDpiX() / 25.4;
538
  }
539
  refreshSymbology( mLyr.layer()->getLayerID(), widthScale );
540
}
541

  
542
void QgsLegendLayer::updateItemListCountV2( SymbologyList& itemList, QgsVectorLayer* layer )
543
{
544
  if ( !layer )
545
  {
546
    return;
547
  }
548

  
549
  QgsFeatureRendererV2* renderer = layer->rendererV2();
550
  if ( !renderer )
551
  {
552
    return;
553
  }
554
  QgsRenderContext dummyContext;
555
  renderer->startRender( dummyContext, layer );
556

  
557
  //create map holding the symbol count
558
  QMap< QgsSymbolV2*, int > mSymbolCountMap;
559
  QgsLegendSymbolList symbolList = renderer->legendSymbolItems();
560
  QgsLegendSymbolList::const_iterator symbolIt = symbolList.constBegin();
561
  for ( ; symbolIt != symbolList.constEnd(); ++symbolIt )
562
  {
563
    mSymbolCountMap.insert( symbolIt->second, 0 );
564
  }
565

  
566
  //go through all features and count the number of occurrences
567
  int nFeatures = layer->pendingFeatureCount();
568
  QProgressDialog p( tr( "Updating feature count for layer " ) + layer->name(), tr( "Abort" ), 0, nFeatures );
569
  p.setWindowModality( Qt::WindowModal );
570
  int featuresCounted = 0;
571

  
572

  
573
  layer->select( layer->pendingAllAttributesList(), QgsRectangle(), false, false );
574
  QgsFeature f;
575
  QgsSymbolV2* currentSymbol = 0;
576

  
577
  while ( layer->nextFeature( f ) )
578
  {
579
    currentSymbol = renderer->symbolForFeature( f );
580
    mSymbolCountMap[currentSymbol] += 1;
581
    ++featuresCounted;
582
    if ( featuresCounted % 50 == 0 )
583
    {
584
      if ( featuresCounted > nFeatures ) //sometimes the feature count is not correct
585
      {
586
        p.setMaximum( 0 );
587
      }
588
      p.setValue( featuresCounted );
589
      if ( p.wasCanceled() )
590
      {
591
        return;
592
      }
593
    }
594
  }
595
  p.setValue( nFeatures );
596

  
597
  QMap<QString, QPixmap> itemMap;
598
  SymbologyList::const_iterator symbologyIt = itemList.constBegin();
599
  for ( ; symbologyIt != itemList.constEnd(); ++ symbologyIt )
600
  {
601
    itemMap.insert( symbologyIt->first, symbologyIt->second );
602
  }
603
  itemList.clear();
604

  
605
  //
606
  symbolIt = symbolList.constBegin();
607
  for ( ; symbolIt != symbolList.constEnd(); ++symbolIt )
608
  {
609
    QgsSymbolV2* debug = symbolIt->second;
610
    itemList.push_back( qMakePair( symbolIt->first + " (" + QString::number( mSymbolCountMap[symbolIt->second] ) + ")", itemMap[symbolIt->first] ) );
611
  }
612
}
613

  
614
void QgsLegendLayer::updateItemListCount( QgsVectorLayer* layer, const QList<QgsSymbol*>& sym, QMap< QgsSymbol*, int >& featureCountMap )
615
{
616
  featureCountMap.clear();
617
  QList<QgsSymbol*>::const_iterator symbolIt = sym.constBegin();
618
  for ( ; symbolIt != sym.constEnd(); ++symbolIt )
619
  {
620
    featureCountMap.insert( *symbolIt, 0 );
621
  }
622

  
623
  QgsRenderer* renderer = const_cast<QgsRenderer*>( layer->renderer() );
624
  if ( !renderer )
625
  {
626
    return;
627
  }
628

  
629
  //go through all features and count the number of occurrences
630
  int nFeatures = layer->pendingFeatureCount();
631
  QProgressDialog p( tr( "Updating feature count for layer " ) + layer->name(), tr( "Abort" ), 0, nFeatures );
632
  p.setWindowModality( Qt::WindowModal );
633
  int featuresCounted = 0;
634

  
635
  layer->select( layer->pendingAllAttributesList(), QgsRectangle(), false, false );
636
  QgsFeature f;
637
  QgsSymbol* currentSymbol = 0;
638

  
639
  while ( layer->nextFeature( f ) )
640
  {
641
    currentSymbol = renderer->symbolForFeature( &f );
642
    if ( currentSymbol )
643
    {
644
      featureCountMap[currentSymbol] += 1;
645
    }
646
    ++featuresCounted;
647

  
648
    if ( featuresCounted % 50 == 0 )
649
    {
650
      if ( featuresCounted > nFeatures ) //sometimes the feature count is not correct
651
      {
652
        p.setMaximum( 0 );
653
      }
654
      p.setValue( featuresCounted );
655
      if ( p.wasCanceled() ) //set all entries to -1 (= invalid)
656
      {
657
        QMap< QgsSymbol*, int >::iterator cIt = featureCountMap.begin();
658
        for ( ; cIt != featureCountMap.end(); ++cIt )
659
        {
660
          cIt.value() = -1;
661
        }
662
        return;
663
      }
664
    }
665
  }
666
  p.setValue( nFeatures );
667
}
src/app/legend/qgslegendlayer.h (Arbeitskopie)
29 29
class QgsLegendPropertyGroup;
30 30
class QgsMapLayer;
31 31
class QgsRasterLayer;
32
class QgsSymbol;
32 33
class QgsVectorLayer;
33 34

  
34 35
class QTreeWidget;
......
87 88
    /**Layer name has changed - set it also in legend*/
88 89
    void layerNameChanged();
89 90

  
91
    /**Update symbology (e.g. to update feature count in the legend after editing operations)*/
92
    void updateAfterLayerModification( bool onlyGeomChanged );
93

  
90 94
  protected:
91 95

  
92 96
    /** Prepare and change symbology for vector layer */
93
    void vectorLayerSymbology( const QgsVectorLayer* mapLayer, double widthScale = 1.0 );
97
    void vectorLayerSymbology( QgsVectorLayer* mapLayer, double widthScale = 1.0 );
94 98

  
95 99
    void vectorLayerSymbologyV2( QgsVectorLayer* vlayer );
96 100

  
......
100 104
    /** Removes the symbology items of a layer and adds new ones. */
101 105
    void changeSymbologySettings( const QgsMapLayer* mapLayer, const SymbologyList& newSymbologyItems );
102 106

  
107
    /**Adds feature counts to the symbology items (for symbology v2)*/
108
    void updateItemListCountV2( SymbologyList& itemList, QgsVectorLayer* layer );
109
    /**Calculates feature count for the individual symbols (old symbology)*/
110
    void updateItemListCount( QgsVectorLayer* layer, const QList<QgsSymbol*>& sym, QMap< QgsSymbol*, int >& featureCountMap );
111

  
103 112
    QPixmap getOriginalPixmap();
104 113

  
105 114
  private:
src/app/qgsoptions.cpp (Arbeitskopie)
246 246
  chkUseQPixmap->setChecked( !( settings.value( "/qgis/use_qimage_to_render", true ).toBool() ) );
247 247
  chkAddedVisibility->setChecked( settings.value( "/qgis/new_layers_visible", true ).toBool() );
248 248
  cbxLegendClassifiers->setChecked( settings.value( "/qgis/showLegendClassifiers", false ).toBool() );
249
  cbxNFeaturesLegend->setChecked( settings.value( "/qgis/showNumberOfFeaturesInLegend", false ).toBool() );
249 250
  cbxHideSplash->setChecked( settings.value( "/qgis/hideSplash", false ).toBool() );
250 251
  cbxAttributeTableDocked->setChecked( settings.value( "/qgis/dockAttributeTable", false ).toBool() );
251 252
  cbxIdentifyResultsDocked->setChecked( settings.value( "/qgis/dockIdentifyResults", false ).toBool() );
......
478 479
  settings.setValue( "proxy/proxyType", mProxyTypeComboBox->currentText() );
479 480

  
480 481
  settings.setValue( "cache/directory", mCacheDirectory->text() );
481
  settings.setValue( "cache/size", QVariant::fromValue( mCacheSize->value()*1024L ) );
482
  settings.setValue( "cache/size", QVariant::fromValue( mCacheSize->value() * 1024L ) );
482 483

  
483 484
  //url to exclude from proxys
484 485
  QString proxyExcludeString;
......
502 503
  settings.setValue( "/Map/identifyAutoFeatureForm", cbxAutoFeatureForm->isChecked() );
503 504
  settings.setValue( "/Map/identifyRadius", spinBoxIdentifyValue->value() );
504 505
  settings.setValue( "/qgis/showLegendClassifiers", cbxLegendClassifiers->isChecked() );
506
  settings.setValue( "/qgis/showNumberOfFeaturesInLegend", cbxNFeaturesLegend->isChecked() );
505 507
  settings.setValue( "/qgis/hideSplash", cbxHideSplash->isChecked() );
506 508
  settings.setValue( "/qgis/dockAttributeTable", cbxAttributeTableDocked->isChecked() );
507 509
  settings.setValue( "/qgis/attributeTableBehaviour", cmbAttrTableBehaviour->currentIndex() );
src/core/renderer/qgssinglesymbolrenderer.h (Arbeitskopie)
64 64
    const QList<QgsSymbol*> symbols() const;
65 65
    /**Returns a deep copy of this renderer*/
66 66
    QgsRenderer* clone() const;
67

  
68
    /**Returns renderer symbol for a feature
69
        @note: this method was added in version 1.6*/
70
    QgsSymbol* symbolForFeature( const QgsFeature* f ) { return mSymbol0; }
71

  
67 72
  protected:
68 73
    /**Object containing symbology information*/
69 74
    QgsSymbol *mSymbol0;
src/core/renderer/qgsrenderer.h (Arbeitskopie)
112 112
     This is a hint for QgsVectorLayer to not use the transparency setting on layer level in this cases*/
113 113
    virtual bool usesTransparency() const {return false;}
114 114

  
115
    /**Returns renderer symbol for a feature.
116
        @note: this method was added in version 1.6*/
117
    virtual QgsSymbol* symbolForFeature( const QgsFeature* f ) { return 0;}
118

  
115 119
    /**Scales a brush to a given raster scale factor (e.g. for printing)*/
116 120
    static void scaleBrush( QBrush& b, double rasterScaleFactor );
117 121

  
src/core/renderer/qgsuniquevaluerenderer.h (Arbeitskopie)
67 67
       @note added in 1.4 */
68 68
    const QMap<QString, QgsSymbol*> symbolMap() const { return mSymbols; }
69 69
    QgsRenderer* clone() const;
70

  
71
    /**Returns the symbol for a feature or 0 if there isn't any*/
72
    QgsSymbol *symbolForFeature( const QgsFeature* f );
73

  
70 74
  protected:
71 75
    /**Field index used for classification*/
72 76
    int mClassificationField;
73 77
    /**Symbols for the unique values*/
74 78
    QMap<QString, QgsSymbol*> mSymbols;
75
    /**Returns the symbol for a feature or 0 if there isn't any*/
76
    QgsSymbol *symbolForFeature( const QgsFeature* f );
79

  
77 80
    /**Cached copy of all underlying symbols required attribute fields*/
78 81
    QgsAttributeList mSymbolAttributes;
79 82
    bool mSymbolAttributesDirty;  // insertValue was called
src/core/renderer/qgsgraduatedsymbolrenderer.h (Arbeitskopie)
107 107
    /**Returns a copy of the renderer (a deep copy on the heap)*/
108 108
    QgsRenderer* clone() const;
109 109

  
110
    QgsSymbol *symbolForFeature( const QgsFeature* f );
111

  
110 112
  protected:
111 113
    /** The graduation mode */
112 114
    Mode mMode;
......
117 119
    /**List holding the symbols for the individual classes*/
118 120
    QList<QgsSymbol*> mSymbols;
119 121

  
120
    QgsSymbol *symbolForFeature( const QgsFeature* f );
121

  
122 122
    /**Cached copy of all underlying symbols required attribute fields*/
123 123
    QgsAttributeList mSymbolAttributes;
124

  
125

  
126 124
};
127 125

  
128 126
inline void QgsGraduatedSymbolRenderer::addSymbol( QgsSymbol* sy )
src/core/symbology-ng/qgscategorizedsymbolrendererv2.cpp (Arbeitskopie)
75 75
    mAttrName( attrName ),
76 76
    mCategories( categories ),
77 77
    mSourceSymbol( NULL ),
78
    mSourceColorRamp( NULL )
78
    mSourceColorRamp( NULL ),
79
    mRotationFieldIdx( -1 ),
80
    mSizeScaleFieldIdx( -1 )
79 81
{
80 82
  for ( int i = 0; i < mCategories.count(); ++i )
81 83
  {
src/core/symbology-ng/qgsgraduatedsymbolrendererv2.cpp (Arbeitskopie)
100 100
    mRanges( ranges ),
101 101
    mMode( Custom ),
102 102
    mSourceSymbol( NULL ),
103
    mSourceColorRamp( NULL )
103
    mSourceColorRamp( NULL ),
104
    mRotationFieldIdx( -1 ),
105
    mSizeScaleFieldIdx( -1 )
104 106
{
105 107
  // TODO: check ranges for sanity (NULL symbols, invalid ranges)
106 108
}
......
421 423

  
422 424
  double base = pow( 10.0, floor( log10( cell ) ) );
423 425
  double unit = base;
424
  if (( 2 * base ) - cell < h * ( cell - unit ) )
426
  if (( 2 * base ) - cell < h *( cell - unit ) )
425 427
  {
426 428
    unit = 2.0 * base;
427
    if (( 5 * base ) - cell < adjustBias * ( cell - unit ) )
429
    if (( 5 * base ) - cell < adjustBias *( cell - unit ) )
428 430
    {
429 431
      unit = 5.0 * base;
430
      if (( 10.0 * base ) - cell < h * ( cell - unit ) )
432
      if (( 10.0 * base ) - cell < h *( cell - unit ) )
431 433
      {
432 434
        unit = 10.0 * base;
433 435
      }
src/core/symbology-ng/qgssinglesymbolrendererv2.cpp (Arbeitskopie)
12 12
#include <QDomElement>
13 13

  
14 14
QgsSingleSymbolRendererV2::QgsSingleSymbolRendererV2( QgsSymbolV2* symbol )
15
    : QgsFeatureRendererV2( "singleSymbol" )
16
    , mTempSymbol( NULL )
15
    : QgsFeatureRendererV2( "singleSymbol" ), mRotationFieldIdx( -1 ), mSizeScaleFieldIdx( -1 ), mTempSymbol( NULL )
17 16
{
18 17
  Q_ASSERT( symbol );
19 18
  mSymbol = symbol;
src/ui/qgsoptionsbase.ui (Arbeitskopie)
59 59
          <property name="geometry">
60 60
           <rect>
61 61
            <x>0</x>
62
            <y>0</y>
63
            <width>746</width>
64
            <height>545</height>
62
            <y>-29</y>
63
            <width>744</width>
64
            <height>508</height>
65 65
           </rect>
66 66
          </property>
67 67
          <layout class="QGridLayout" name="gridLayout_12">
......
226 226
               </widget>
227 227
              </item>
228 228
              <item>
229
               <widget class="QCheckBox" name="cbxNFeaturesLegend">
230
                <property name="text">
231
                 <string>Show number of features in legend</string>
232
                </property>
233
               </widget>
234
              </item>
235
              <item>
229 236
               <widget class="QCheckBox" name="cbxCreateRasterLegendIcons">
230 237
                <property name="text">
231 238
                 <string>Create raster icons in legend</string>
......
344 351
           <rect>
345 352
            <x>0</x>
346 353
            <y>0</y>
347
            <width>596</width>
348
            <height>466</height>
354
            <width>744</width>
355
            <height>475</height>
349 356
           </rect>
350 357
          </property>
351 358
          <layout class="QGridLayout" name="gridLayout_8">
......
515 522
           <rect>
516 523
            <x>0</x>
517 524
            <y>0</y>
518
            <width>507</width>
519
            <height>480</height>
525
            <width>760</width>
526
            <height>458</height>
520 527
           </rect>
521 528
          </property>
522 529
          <layout class="QGridLayout" name="gridLayout_4">
......
795 802
           <rect>
796 803
            <x>0</x>
797 804
            <y>0</y>
798
            <width>264</width>
799
            <height>86</height>
805
            <width>760</width>
806
            <height>458</height>
800 807
           </rect>
801 808
          </property>
802 809
          <layout class="QGridLayout" name="gridLayout_10">
......
870 877
           <rect>
871 878
            <x>0</x>
872 879
            <y>0</y>
873
            <width>724</width>
874
            <height>438</height>
880
            <width>760</width>
881
            <height>458</height>
875 882
           </rect>
876 883
          </property>
877 884
          <layout class="QGridLayout" name="gridLayout_13">
......
1200 1207
           <rect>
1201 1208
            <x>0</x>
1202 1209
            <y>0</y>
1203
            <width>371</width>
1204
            <height>557</height>
1210
            <width>744</width>
1211
            <height>519</height>
1205 1212
           </rect>
1206 1213
          </property>
1207 1214
          <layout class="QGridLayout" name="gridLayout_15">
......
1296 1303
           <rect>
1297 1304
            <x>0</x>
1298 1305
            <y>0</y>
1299
            <width>519</width>
1300
            <height>545</height>
1306
            <width>744</width>
1307
            <height>546</height>
1301 1308
           </rect>
1302 1309
          </property>
1303 1310
          <layout class="QGridLayout" name="gridLayout_17">
......
1387 1394
           <rect>
1388 1395
            <x>0</x>
1389 1396
            <y>0</y>
1390
            <width>329</width>
1391
            <height>531</height>
1397
            <width>744</width>
1398
            <height>520</height>
1392 1399
           </rect>
1393 1400
          </property>
1394 1401
          <layout class="QGridLayout" name="gridLayout_20">