82 changes: 80 additions & 2 deletions src/core/qgsvectorlayer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
#include <QPainter>
#include <QPainterPath>
#include <QPolygonF>
#include <QProgressDialog>
#include <QSettings>
#include <QString>
#include <QDomNode>
Expand Down Expand Up @@ -106,6 +107,7 @@ QgsVectorLayer::QgsVectorLayer( QString vectorLayerPath,
, mDiagramRenderer( 0 )
, mDiagramLayerSettings( 0 )
, mValidExtent( false )
, mSymbolFeatureCounted( false )
{
mActions = new QgsAttributeAction( this );

Expand Down Expand Up @@ -1451,8 +1453,6 @@ QgsRectangle QgsVectorLayer::boundingBoxOfSelected()
return retval;
}



long QgsVectorLayer::featureCount() const
{
if ( !mDataProvider )
Expand All @@ -1464,6 +1464,82 @@ long QgsVectorLayer::featureCount() const
return mDataProvider->featureCount();
}

long QgsVectorLayer::featureCount( QgsSymbolV2* symbol )
{
if ( !mSymbolFeatureCounted ) return -1;
return mSymbolFeatureCountMap.value( symbol );
}

bool QgsVectorLayer::countSymbolFeatures( bool showProgress )
{
if ( mSymbolFeatureCounted ) return true;
mSymbolFeatureCountMap.clear();

if ( !mDataProvider )
{
QgsDebugMsg( "invoked with null mDataProvider" );
return false;
}
if ( !mRendererV2 )
{
QgsDebugMsg( "invoked with null mRendererV2" );
return false;
}

QgsLegendSymbolList symbolList = mRendererV2->legendSymbolItems();
QgsLegendSymbolList::const_iterator symbolIt = symbolList.constBegin();

for ( ; symbolIt != symbolList.constEnd(); ++symbolIt )
{
mSymbolFeatureCountMap.insert( symbolIt->second, 0 );
}

long nFeatures = pendingFeatureCount();
QProgressDialog progressDialog( tr( "Updating feature count for layer %1" ).arg( name() ), tr( "Abort" ), 0, nFeatures );
progressDialog.setWindowModality( Qt::WindowModal );
int featuresCounted = 0;

select( pendingAllAttributesList(), QgsRectangle(), false, false );
QgsFeature f;

// Renderer (rule based) may depend on context scale, with scale is ignored if 0
QgsRenderContext renderContext;
renderContext.setRendererScale( 0 );
mRendererV2->startRender( renderContext, this );

while ( nextFeature( f ) )
{
QgsSymbolV2List featureSymbolList = mRendererV2->symbolsForFeature( f );
for ( QgsSymbolV2List::iterator symbolIt = featureSymbolList.begin(); symbolIt != featureSymbolList.end(); ++symbolIt )
{
mSymbolFeatureCountMap[*symbolIt] += 1;
}
++featuresCounted;

if ( showProgress )
{
if ( featuresCounted % 50 == 0 )
{
if ( featuresCounted > nFeatures ) //sometimes the feature count is not correct
{
progressDialog.setMaximum( 0 );
}
progressDialog.setValue( featuresCounted );
if ( progressDialog.wasCanceled() )
{
mSymbolFeatureCountMap.clear();
mRendererV2->stopRender( renderContext );
return false;
}
}
}
}
mRendererV2->stopRender( renderContext );
progressDialog.setValue( nFeatures );
mSymbolFeatureCounted = true;
return true;
}

long QgsVectorLayer::updateFeatureCount() const
{
return -1;
Expand Down Expand Up @@ -4926,6 +5002,8 @@ void QgsVectorLayer::setRendererV2( QgsFeatureRendererV2 *r )
setUsingRendererV2( true );
delete mRendererV2;
mRendererV2 = r;
mSymbolFeatureCounted = false;
mSymbolFeatureCountMap.clear();
}
}
bool QgsVectorLayer::isUsingRendererV2()
Expand Down
22 changes: 22 additions & 0 deletions src/core/qgsvectorlayer.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ class QgsVectorLayerJoinBuffer;
class QgsFeatureRendererV2;
class QgsDiagramRendererV2;
class QgsDiagramLayerSettings;
class QgsSymbolV2;

typedef QList<int> QgsAttributeList;
typedef QSet<int> QgsAttributeIds;
Expand Down Expand Up @@ -417,6 +418,21 @@ class CORE_EXPORT QgsVectorLayer : public QgsMapLayer
*/
virtual long featureCount() const;

/**
* Number of features rendered with specified symbol. Features must be first
* calculated by countSymbolFeatures()
* @param symbol the symbol
* @return number of features rendered by symbol or -1 if failed or counts are not available
*/
long featureCount( QgsSymbolV2* symbol );

/**
* Count features for symbols. Feature counts may be get by featureCount( QgsSymbolV2*).
* @param showProgress show progress dialog
* @return true if calculated, false if failed or was canceled by user
*/
bool countSymbolFeatures( bool showProgress = true );

/** This function does nothing useful, it's kept only for compatibility.
* @todo to be removed
*/
Expand Down Expand Up @@ -1165,6 +1181,12 @@ class CORE_EXPORT QgsVectorLayer : public QgsMapLayer
QgsDiagramLayerSettings *mDiagramLayerSettings;

bool mValidExtent;

// Features in renderer classes counted
bool mSymbolFeatureCounted;

// Feature counts for each renderer symbol
QMap<QgsSymbolV2*, long> mSymbolFeatureCountMap;
};

#endif
73 changes: 62 additions & 11 deletions src/ui/qgscomposerlegendwidgetbase.ui
Original file line number Diff line number Diff line change
Expand Up @@ -44,15 +44,15 @@
<item row="0" column="0">
<widget class="QToolBox" name="toolBox">
<property name="currentIndex">
<number>0</number>
<number>1</number>
</property>
<widget class="QWidget" name="page">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>374</width>
<height>549</height>
<width>370</width>
<height>467</height>
</rect>
</property>
<attribute name="label">
Expand Down Expand Up @@ -220,8 +220,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>393</width>
<height>162</height>
<width>427</width>
<height>401</height>
</rect>
</property>
<attribute name="label">
Expand All @@ -244,7 +244,7 @@
</property>
</widget>
</item>
<item row="1" column="0" colspan="9">
<item row="1" column="0" colspan="10">
<widget class="QTreeView" name="mItemTreeView">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Expanding">
Expand All @@ -264,6 +264,9 @@
<attribute name="headerVisible">
<bool>false</bool>
</attribute>
<attribute name="headerVisible">
<bool>false</bool>
</attribute>
</widget>
</item>
<item row="2" column="0">
Expand All @@ -277,6 +280,10 @@
<property name="text">
<string/>
</property>
<property name="icon">
<iconset resource="../../images/images.qrc">
<normaloff>:/images/themes/default/mActionArrowDown.png</normaloff>:/images/themes/default/mActionArrowDown.png</iconset>
</property>
<property name="iconSize">
<size>
<width>24</width>
Expand All @@ -290,6 +297,10 @@
<property name="text">
<string/>
</property>
<property name="icon">
<iconset resource="../../images/images.qrc">
<normaloff>:/images/themes/default/mActionArrowUp.png</normaloff>:/images/themes/default/mActionArrowUp.png</iconset>
</property>
<property name="iconSize">
<size>
<width>24</width>
Expand All @@ -303,6 +314,10 @@
<property name="text">
<string/>
</property>
<property name="icon">
<iconset resource="../../images/images.qrc">
<normaloff>:/images/themes/default/mActionSignPlus.png</normaloff>:/images/themes/default/mActionSignPlus.png</iconset>
</property>
<property name="iconSize">
<size>
<width>24</width>
Expand All @@ -316,6 +331,10 @@
<property name="text">
<string/>
</property>
<property name="icon">
<iconset resource="../../images/images.qrc">
<normaloff>:/images/themes/default/mActionSignMinus.png</normaloff>:/images/themes/default/mActionSignMinus.png</iconset>
</property>
<property name="iconSize">
<size>
<width>24</width>
Expand All @@ -329,6 +348,10 @@
<property name="text">
<string/>
</property>
<property name="icon">
<iconset resource="../../images/images.qrc">
<normaloff>:/images/themes/default/symbologyEdit.png</normaloff>:/images/themes/default/symbologyEdit.png</iconset>
</property>
<property name="iconSize">
<size>
<width>24</width>
Expand All @@ -337,7 +360,7 @@
</property>
</widget>
</item>
<item row="2" column="5">
<item row="2" column="6">
<widget class="QToolButton" name="mUpdatePushButton">
<property name="text">
<string>Update</string>
Expand All @@ -350,14 +373,14 @@
</property>
</widget>
</item>
<item row="2" column="6">
<item row="2" column="7">
<widget class="QToolButton" name="mUpdateAllPushButton">
<property name="text">
<string>All</string>
</property>
</widget>
</item>
<item row="2" column="8">
<item row="2" column="9">
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
Expand All @@ -370,13 +393,39 @@
</property>
</spacer>
</item>
<item row="2" column="7">
<item row="2" column="8">
<widget class="QToolButton" name="mAddGroupButton">
<property name="text">
<string>Add group</string>
</property>
</widget>
</item>
<item row="2" column="5">
<widget class="QToolButton" name="mCountToolButton">
<property name="enabled">
<bool>false</bool>
</property>
<property name="toolTip">
<string>Show feature count for each class of vector layer.</string>
</property>
<property name="text">
<string/>
</property>
<property name="icon">
<iconset resource="../../images/images.qrc">
<normaloff>:/images/themes/default/mActionSum.png</normaloff>:/images/themes/default/mActionSum.png</iconset>
</property>
<property name="iconSize">
<size>
<width>24</width>
<height>24</height>
</size>
</property>
<property name="checkable">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
</widget>
Expand Down Expand Up @@ -410,6 +459,8 @@
<tabstop>mUpdateAllPushButton</tabstop>
<tabstop>mAddGroupButton</tabstop>
</tabstops>
<resources/>
<resources>
<include location="../../images/images.qrc"/>
</resources>
<connections/>
</ui>