diff --git a/python/core/symbology-ng/qgsrendererv2.sip b/python/core/symbology-ng/qgsrendererv2.sip index 5a6006363c1..b2577e87dcf 100644 --- a/python/core/symbology-ng/qgsrendererv2.sip +++ b/python/core/symbology-ng/qgsrendererv2.sip @@ -148,6 +148,11 @@ class QgsFeatureRendererV2 */ virtual QList usedAttributes() = 0; + /** + * Returns true if this renderer requires the geometry to apply the filter. + */ + virtual bool filterNeedsGeometry() const; + virtual ~QgsFeatureRendererV2(); virtual QgsFeatureRendererV2* clone() const = 0 /Factory/; diff --git a/python/core/symbology-ng/qgsrulebasedrendererv2.sip b/python/core/symbology-ng/qgsrulebasedrendererv2.sip index fa9ba90e929..7ab1b8d6617 100644 --- a/python/core/symbology-ng/qgsrulebasedrendererv2.sip +++ b/python/core/symbology-ng/qgsrulebasedrendererv2.sip @@ -80,7 +80,12 @@ class QgsRuleBasedRendererV2 : QgsFeatureRendererV2 * Return the attributes used to evaluate the expression of this rule * @return A set of attribute names */ - QSet usedAttributes(); + QSet usedAttributes() const; + + /** + * Returns true if this rule or one of its chilren needs the geometry to be applied. + */ + bool needsGeometry() const; //! @note available in python bindings as symbol2 QgsSymbolV2List symbols( const QgsRenderContext& context = QgsRenderContext() ) /PyName=symbols2/; @@ -357,6 +362,8 @@ class QgsRuleBasedRendererV2 : QgsFeatureRendererV2 virtual QList usedAttributes(); + virtual bool filterNeedsGeometry() const; + virtual QgsRuleBasedRendererV2* clone() const /Factory/; virtual void toSld( QDomDocument& doc, QDomElement &element ) const; diff --git a/src/core/qgsvectorlayer.cpp b/src/core/qgsvectorlayer.cpp index c6458420758..b58eb86b2a3 100644 --- a/src/core/qgsvectorlayer.cpp +++ b/src/core/qgsvectorlayer.cpp @@ -881,7 +881,11 @@ bool QgsVectorLayer::countSymbolFeatures( bool showProgress ) } int featuresCounted = 0; - QgsFeatureIterator fit = getFeatures( QgsFeatureRequest().setFlags( QgsFeatureRequest::NoGeometry ) ); + QgsFeatureRequest request; + if ( !mRendererV2->filterNeedsGeometry() ) + request.setFlags( QgsFeatureRequest::NoGeometry ); + request.setSubsetOfAttributes( mRendererV2->usedAttributes(), mUpdatedFields ); + QgsFeatureIterator fit = getFeatures( request ); QgsVectorLayerInterruptionCheckerDuringCountSymbolFeatures interruptionCheck( &progressDialog ); if ( showProgress ) { diff --git a/src/core/symbology-ng/qgsrendererv2.cpp b/src/core/symbology-ng/qgsrendererv2.cpp index ba80dd66a21..658e633d8fa 100644 --- a/src/core/symbology-ng/qgsrendererv2.cpp +++ b/src/core/symbology-ng/qgsrendererv2.cpp @@ -153,6 +153,11 @@ void QgsFeatureRendererV2::startRender( QgsRenderContext& context, const QgsVect startRender( context, vlayer->fields() ); } +bool QgsFeatureRendererV2::filterNeedsGeometry() const +{ + return false; +} + bool QgsFeatureRendererV2::renderFeature( QgsFeature& feature, QgsRenderContext& context, int layer, bool selected, bool drawVertexMarker ) { QgsSymbolV2* symbol = symbolForFeature( feature, context ); diff --git a/src/core/symbology-ng/qgsrendererv2.h b/src/core/symbology-ng/qgsrendererv2.h index 1e96ee3fa95..2ce7e27bb76 100644 --- a/src/core/symbology-ng/qgsrendererv2.h +++ b/src/core/symbology-ng/qgsrendererv2.h @@ -169,6 +169,11 @@ class CORE_EXPORT QgsFeatureRendererV2 */ virtual QList usedAttributes() = 0; + /** + * Returns true if this renderer requires the geometry to apply the filter. + */ + virtual bool filterNeedsGeometry() const; + virtual ~QgsFeatureRendererV2(); virtual QgsFeatureRendererV2* clone() const = 0; @@ -190,11 +195,11 @@ class CORE_EXPORT QgsFeatureRendererV2 enum Capabilities { - SymbolLevels = 1, // rendering with symbol levels (i.e. implements symbols(), symbolForFeature()) - RotationField = 1 << 1, // rotate symbols by attribute value - MoreSymbolsPerFeature = 1 << 2, // may use more than one symbol to render a feature: symbolsForFeature() will return them - Filter = 1 << 3, // features may be filtered, i.e. some features may not be rendered (categorized, rule based ...) - ScaleDependent = 1 << 4 // depends on scale if feature will be rendered (rule based ) + SymbolLevels = 1, //!< rendering with symbol levels (i.e. implements symbols(), symbolForFeature()) + RotationField = 1 << 1, //!< rotate symbols by attribute value + MoreSymbolsPerFeature = 1 << 2, //!< may use more than one symbol to render a feature: symbolsForFeature() will return them + Filter = 1 << 3, //!< features may be filtered, i.e. some features may not be rendered (categorized, rule based ...) + ScaleDependent = 1 << 4 //!< depends on scale if feature will be rendered (rule based ) }; //! returns bitwise OR-ed capabilities of the renderer diff --git a/src/core/symbology-ng/qgsrulebasedrendererv2.cpp b/src/core/symbology-ng/qgsrulebasedrendererv2.cpp index a8176534dc7..3d4c23f476a 100644 --- a/src/core/symbology-ng/qgsrulebasedrendererv2.cpp +++ b/src/core/symbology-ng/qgsrulebasedrendererv2.cpp @@ -197,6 +197,20 @@ QSet QgsRuleBasedRendererV2::Rule::usedAttributes() const return attrs; } +bool QgsRuleBasedRendererV2::Rule::needsGeometry() const +{ + if ( mFilter && mFilter->needsGeometry() ) + return true; + + Q_FOREACH ( Rule* rule, mChildren ) + { + if ( rule->needsGeometry() ) + return true; + } + + return false; +} + QgsSymbolV2List QgsRuleBasedRendererV2::Rule::symbols( const QgsRenderContext& context ) const { QgsSymbolV2List lst; @@ -935,7 +949,12 @@ QString QgsRuleBasedRendererV2::filter( const QgsFields& ) QList QgsRuleBasedRendererV2::usedAttributes() { QSet attrs = mRootRule->usedAttributes(); - return attrs.values(); + return attrs.toList(); +} + +bool QgsRuleBasedRendererV2::filterNeedsGeometry() const +{ + return mRootRule->needsGeometry(); } QgsRuleBasedRendererV2* QgsRuleBasedRendererV2::clone() const diff --git a/src/core/symbology-ng/qgsrulebasedrendererv2.h b/src/core/symbology-ng/qgsrulebasedrendererv2.h index 63684144438..5fb43ffed4d 100644 --- a/src/core/symbology-ng/qgsrulebasedrendererv2.h +++ b/src/core/symbology-ng/qgsrulebasedrendererv2.h @@ -136,6 +136,11 @@ class CORE_EXPORT QgsRuleBasedRendererV2 : public QgsFeatureRendererV2 */ QSet usedAttributes() const; + /** + * Returns true if this rule or one of its chilren needs the geometry to be applied. + */ + bool needsGeometry() const; + //! @note available in python bindings as symbol2 QgsSymbolV2List symbols( const QgsRenderContext& context = QgsRenderContext() ) const; @@ -428,6 +433,8 @@ class CORE_EXPORT QgsRuleBasedRendererV2 : public QgsFeatureRendererV2 virtual QList usedAttributes() override; + virtual bool filterNeedsGeometry() const override; + virtual QgsRuleBasedRendererV2* clone() const override; virtual void toSld( QDomDocument& doc, QDomElement &element ) const override;