diff --git a/python/core/qgsfeaturefilterprovider.sip b/python/core/qgsfeaturefilterprovider.sip index 71875bb01f2..57c1ee11d0d 100644 --- a/python/core/qgsfeaturefilterprovider.sip +++ b/python/core/qgsfeaturefilterprovider.sip @@ -1,7 +1,9 @@ -/** - * Interface used by class that will filter the features of a layer. - * The only method `filterFeatures` fill the `QgsFeatureRequest` to get only the - * wanted features. +/** \ingroup core + * \class QgsFeatureFilterProvider + * Abstract interface for use by classes that filter the features of a layer. + * A QgsFeatureFilterProvider provides a method for modifying a QgsFeatureRequest in place to apply + * additional filters to the request. + * \note added in QGIS 2.14 **/ class QgsFeatureFilterProvider { @@ -10,15 +12,16 @@ class QgsFeatureFilterProvider %End public: - /** Add some filter to the feature request to don't have the unauthorized (unauthorised) features + + /** Add additional filters to the feature request to further restrict the features returned by the request. + * Derived classes must implement this method. * @param layer the layer to filter * @param featureRequest the feature request to update - * @note not available in Python bindings */ virtual void filterFeatures( const QgsVectorLayer* layer, QgsFeatureRequest& featureRequest ) const = 0; /** Create a clone of the feature filter provider * @return a new clone */ - virtual QgsFeatureFilterProvider* clone() const = 0; + virtual QgsFeatureFilterProvider* clone() const = 0 /Factory/; }; diff --git a/python/core/qgsfeaturerequest.sip b/python/core/qgsfeaturerequest.sip index 98632742ea1..fcb2da26f88 100644 --- a/python/core/qgsfeaturerequest.sip +++ b/python/core/qgsfeaturerequest.sip @@ -50,10 +50,26 @@ class QgsFeatureRequest QgsFeatureRequest& setFilterFids( const QgsFeatureIds& fids ); const QgsFeatureIds& filterFids() const; - //! Set filter expression. {@see QgsExpression} + /** Set the filter expression. {@see QgsExpression} + * @param expression expression string + * @see filterExpression + * @see setExpressionContext + */ QgsFeatureRequest& setFilterExpression( const QString& expression ); + + /** Returns the filter expression if set. + * @see setFilterExpression + * @see expressionContext + */ QgsExpression* filterExpression() const; + /** Modifies the existing filter expression to add an additional expression filter. The + * filter expressions are combined using AND, so only features matching both + * the existing expression and the additional expression will be returned. + * @note added in QGIS 2.14 + */ + QgsFeatureRequest& combineFilterExpression( const QString& expression ); + /** Returns the expression context used to evaluate filter expressions. * @note added in QGIS 2.12 * @see setExpressionContext diff --git a/python/core/qgsmaprenderer.sip b/python/core/qgsmaprenderer.sip index 5849c8bae83..bc81f3f1e3b 100644 --- a/python/core/qgsmaprenderer.sip +++ b/python/core/qgsmaprenderer.sip @@ -288,10 +288,12 @@ class QgsMapRenderer : QObject */ bool splitLayersExtent( QgsMapLayer* layer, QgsRectangle& extent /In,Out/, QgsRectangle& r2 /Out/ ); - /** Set a feature filter provider to filter the features + /** Set a feature filter provider to filter the features shown in the map. * @param ffp the feature filter provider + * @note added in QGIS 2.14 */ void setFeatureFilterProvider( const QgsFeatureFilterProvider* ffp ); + signals: //! @deprecated in 2.4 - not emitted anymore diff --git a/python/core/qgsrendercontext.sip b/python/core/qgsrendercontext.sip index a8954677953..01367c444c8 100644 --- a/python/core/qgsrendercontext.sip +++ b/python/core/qgsrendercontext.sip @@ -140,4 +140,18 @@ class QgsRenderContext /** Sets pointer to original (unsegmentized) geometry @geometry the geometry*/ void setGeometry( const QgsAbstractGeometryV2* geometry ); + + /** Set a filter feature provider used for additional filtering of rendered features. + * @param ffp the filter feature provider + * @note added in QGIS 2.14 + * @see featureFilterProvider() + */ + void setFeatureFilterProvider( const QgsFeatureFilterProvider* ffp ); + + /** Get the filter feature provider used for additional filtering of rendered features. + * @return the filter feature provider + * @note added in QGIS 2.14 + * @see setFeatureFilterProvider() + */ + const QgsFeatureFilterProvider* featureFilterProvider() const; }; diff --git a/src/core/qgsfeaturefilterprovider.h b/src/core/qgsfeaturefilterprovider.h index 2ec05845f65..5de614457db 100644 --- a/src/core/qgsfeaturefilterprovider.h +++ b/src/core/qgsfeaturefilterprovider.h @@ -26,21 +26,25 @@ class QgsFeatureRequest; /** \ingroup core - * Interface used by class that will filter the features of a layer. - * The only method `filterFeatures` fill the `QgsFeatureRequest` to get only the - * wanted features. + * \class QgsFeatureFilterProvider + * Abstract interface for use by classes that filter the features of a layer. + * A QgsFeatureFilterProvider provides a method for modifying a QgsFeatureRequest in place to apply + * additional filters to the request. + * \note added in QGIS 2.14 **/ + class CORE_EXPORT QgsFeatureFilterProvider { public: /** Constructor */ - QgsFeatureFilterProvider() {}; + QgsFeatureFilterProvider() {} /** Destructor */ - virtual ~QgsFeatureFilterProvider() {}; + virtual ~QgsFeatureFilterProvider() {} - /** Add some filter to the feature request to don't have the unauthorized (unauthorised) features + /** Add additional filters to the feature request to further restrict the features returned by the request. + * Derived classes must implement this method. * @param layer the layer to filter * @param featureRequest the feature request to update */ diff --git a/src/core/qgsfeaturerequest.cpp b/src/core/qgsfeaturerequest.cpp index 1de24332961..c21376e17f3 100644 --- a/src/core/qgsfeaturerequest.cpp +++ b/src/core/qgsfeaturerequest.cpp @@ -117,6 +117,19 @@ QgsFeatureRequest& QgsFeatureRequest::setFilterExpression( const QString& expres return *this; } +QgsFeatureRequest&QgsFeatureRequest::combineFilterExpression( const QString& expression ) +{ + if ( mFilterExpression ) + { + setFilterExpression( QString( "(%1) AND (%2)" ).arg( mFilterExpression->expression(), expression ) ); + } + else + { + setFilterExpression( expression ); + } + return *this; +} + QgsFeatureRequest &QgsFeatureRequest::setExpressionContext( const QgsExpressionContext &context ) { mExpressionContext = context; diff --git a/src/core/qgsfeaturerequest.h b/src/core/qgsfeaturerequest.h index 4721eed9834..f83a4cc0ee2 100644 --- a/src/core/qgsfeaturerequest.h +++ b/src/core/qgsfeaturerequest.h @@ -144,6 +144,13 @@ class CORE_EXPORT QgsFeatureRequest */ QgsExpression* filterExpression() const { return mFilterExpression; } + /** Modifies the existing filter expression to add an additional expression filter. The + * filter expressions are combined using AND, so only features matching both + * the existing expression and the additional expression will be returned. + * @note added in QGIS 2.14 + */ + QgsFeatureRequest& combineFilterExpression( const QString& expression ); + /** Returns the expression context used to evaluate filter expressions. * @note added in QGIS 2.12 * @see setExpressionContext diff --git a/src/core/qgsmaprenderer.h b/src/core/qgsmaprenderer.h index 49665f65b72..e9d4e3d5404 100644 --- a/src/core/qgsmaprenderer.h +++ b/src/core/qgsmaprenderer.h @@ -335,8 +335,9 @@ class CORE_EXPORT QgsMapRenderer : public QObject */ bool splitLayersExtent( QgsMapLayer* layer, QgsRectangle& extent, QgsRectangle& r2 ); - /** Set a feature filter provider to filter the features + /** Set a feature filter provider to filter the features shown in the map. * @param ffp the feature filter provider + * @note added in QGIS 2.14 */ void setFeatureFilterProvider( const QgsFeatureFilterProvider* ffp ) { diff --git a/src/core/qgsrendercontext.cpp b/src/core/qgsrendercontext.cpp index ec0e1bccca2..6de541ac034 100644 --- a/src/core/qgsrendercontext.cpp +++ b/src/core/qgsrendercontext.cpp @@ -21,6 +21,7 @@ #include "qgsmapsettings.h" #include "qgsexpression.h" #include "qgsvectorlayer.h" +#include "qgsfeaturefilterprovider.h" QgsRenderContext::QgsRenderContext() : mFlags( DrawEditingInfo | UseAdvancedEffects | DrawSelection | UseRenderingOptimization ) @@ -40,11 +41,8 @@ QgsRenderContext::QgsRenderContext() QgsRenderContext::~QgsRenderContext() { - if ( mFeatureFilterProvider ) - { - delete mFeatureFilterProvider; - mFeatureFilterProvider = 0; - } + delete mFeatureFilterProvider; + mFeatureFilterProvider = 0; } void QgsRenderContext::setFlags( const QgsRenderContext::Flags& flags ) @@ -151,11 +149,9 @@ void QgsRenderContext::setUseRenderingOptimization( bool enabled ) void QgsRenderContext::setFeatureFilterProvider( const QgsFeatureFilterProvider* ffp ) { - if ( mFeatureFilterProvider ) - { - delete mFeatureFilterProvider; - mFeatureFilterProvider = 0; - } + delete mFeatureFilterProvider; + mFeatureFilterProvider = 0; + if ( ffp ) { mFeatureFilterProvider = ffp->clone(); diff --git a/src/core/qgsrendercontext.h b/src/core/qgsrendercontext.h index b410b3287d4..a737e95d3e6 100644 --- a/src/core/qgsrendercontext.h +++ b/src/core/qgsrendercontext.h @@ -25,7 +25,6 @@ #include "qgsrectangle.h" #include "qgsvectorsimplifymethod.h" #include "qgsexpressioncontext.h" -#include "qgsfeaturefilterprovider.h" class QPainter; @@ -33,8 +32,7 @@ class QgsAbstractGeometryV2; class QgsLabelingEngineInterface; class QgsLabelingEngineV2; class QgsMapSettings; -class QgsExpression; -class QgsVectorLayer; +class QgsFeatureFilterProvider; /** \ingroup core @@ -199,17 +197,19 @@ class CORE_EXPORT QgsRenderContext /** Sets pointer to original (unsegmentized) geometry*/ void setGeometry( const QgsAbstractGeometryV2* geometry ) { mGeometry = geometry; } - /** Set a filter feature provider used to filter the features + /** Set a filter feature provider used for additional filtering of rendered features. * @param ffp the filter feature provider - * @note not available in Python bindings + * @note added in QGIS 2.14 + * @see featureFilterProvider() */ void setFeatureFilterProvider( const QgsFeatureFilterProvider* ffp ); - /** Get the filter feature provider used to filter the features + /** Get the filter feature provider used for additional filtering of rendered features. * @return the filter feature provider - * @note not available in Python bindings + * @note added in QGIS 2.14 + * @see setFeatureFilterProvider() */ - const QgsFeatureFilterProvider* featureFilterProvider() { return mFeatureFilterProvider; } + const QgsFeatureFilterProvider* featureFilterProvider() const { return mFeatureFilterProvider; } private: diff --git a/src/core/qgsvectorlayerrenderer.cpp b/src/core/qgsvectorlayerrenderer.cpp index 1e940590e4d..6b1afdac151 100644 --- a/src/core/qgsvectorlayerrenderer.cpp +++ b/src/core/qgsvectorlayerrenderer.cpp @@ -32,6 +32,7 @@ #include "qgsvectorlayerlabeling.h" #include "qgsvectorlayerlabelprovider.h" #include "qgspainteffect.h" +#include "qgsfeaturefilterprovider.h" #include #include @@ -151,25 +152,17 @@ bool QgsVectorLayerRenderer::render() QgsFeatureRequest featureRequest = QgsFeatureRequest() .setFilterRect( requestExtent ) - .setSubsetOfAttributes( mAttrNames, mFields ); + .setSubsetOfAttributes( mAttrNames, mFields ) + .setExpressionContext( mContext.expressionContext() ); const QgsFeatureFilterProvider* featureFilterProvider = mContext.featureFilterProvider(); if ( featureFilterProvider ) { featureFilterProvider->filterFeatures( mLayer, featureRequest ); } - if ( !rendererFilter.isNull() ) + if ( !rendererFilter.isEmpty() && rendererFilter != "TRUE" ) { - featureRequest.setExpressionContext( mContext.expressionContext() ); - if ( !featureRequest.filterExpression() ) - { - featureRequest.setFilterExpression( rendererFilter ); - } - else - { - featureRequest.setFilterExpression( QString( "(%s) AND (%s)" ) - .arg( rendererFilter, featureRequest.filterExpression()->expression() ) ); - } + featureRequest.combineFilterExpression( rendererFilter ); } // enable the simplification of the geometries (Using the current map2pixel context) before send it to renderer engine.