Skip to content
Permalink
Browse files
Rule based renderer exposes filter where clause
This filter can then be sent to the server to reduce the amount of fetched
features
  • Loading branch information
m-kuhn committed Jul 29, 2015
1 parent cfe91f8 commit 1d7a6a4909e70fe03251c021336e51d311c02116
@@ -105,7 +105,9 @@ class QgsRuleBasedRendererV2 : QgsFeatureRendererV2
QDomElement save( QDomDocument& doc, QgsSymbolV2Map& symbolMap );

//! prepare the rule for rendering and its children (build active children array)
bool startRender( QgsRenderContext& context, const QgsFields& fields );
bool startRender( QgsRenderContext& context, const QgsFields& fields ) /Deprecated/;
//! prepare the rule for rendering and its children (build active children array)
bool startRender( QgsRenderContext& context, const QgsFields& fields, QString& filter );
//! get all used z-levels from this rule and children
QSet<int> collectZLevels();
//! assign normalized z-levels [0..N-1] for this rule's symbol for quick access during rendering
@@ -134,7 +134,7 @@ bool QgsVectorLayerRenderer::render()
mContext.painter()->setCompositionMode( mFeatureBlendMode );
}

mRendererV2->startRender( mContext, mFields );
QgsRenderOptions opts = mRendererV2->startRender( mContext, mFields );

QgsRectangle requestExtent = mContext.extent();
mRendererV2->modifyRequestExtent( requestExtent, mContext );
@@ -143,6 +143,11 @@ bool QgsVectorLayerRenderer::render()
.setFilterRect( requestExtent )
.setSubsetOfAttributes( mAttrNames, mFields );

if ( !opts.whereClause().isNull() )
{
featureRequest.setFilterExpression( opts.whereClause() );
}

// enable the simplification of the geometries (Using the current map2pixel context) before send it to renderer engine.
if ( mSimplifyGeometry )
{
@@ -64,6 +64,9 @@ class CORE_EXPORT QgsSymbolV2LevelItem
class CORE_EXPORT QgsRenderOptions
{
public:
QgsRenderOptions() {}
QgsRenderOptions( const QString& whereClause ) { mWhereClause = whereClause; }

void setWhereClause( const QString& whereClause ) { mWhereClause = whereClause; }
QString whereClause() { return mWhereClause; }
private:
@@ -390,6 +390,12 @@ void QgsRuleBasedRendererV2::Rule::toSld( QDomDocument& doc, QDomElement &elemen
}

bool QgsRuleBasedRendererV2::Rule::startRender( QgsRenderContext& context, const QgsFields& fields )
{
QString filter;
return startRender( context, fields, filter );
}

bool QgsRuleBasedRendererV2::Rule::startRender( QgsRenderContext& context, const QgsFields& fields, QString& filter )
{
mActiveChildren.clear();

@@ -408,15 +414,37 @@ bool QgsRuleBasedRendererV2::Rule::startRender( QgsRenderContext& context, const

// init children
// build temporary list of active rules (usable with this scale)
QStringList subfilters;
for ( RuleList::iterator it = mChildren.begin(); it != mChildren.end(); ++it )
{
QString subfilter;
Rule* rule = *it;
if ( rule->startRender( context, fields ) )
if ( rule->startRender( context, fields , subfilter ) )
{
// only add those which are active with current scale
mActiveChildren.append( rule );
subfilters.append( subfilter );
}
}

// subfilters (on the same level) are joined with OR and finally joined with AND with their parent (this) filter
QString sf;
if ( subfilters.length() )
sf = subfilters.join( ") OR (" ).prepend( "(" ).append( ")" );

if ( isElse() )
{
if ( !sf.length() )
filter = "1";
else
filter = sf;
}
else if ( mFilterExp.length() && sf.length() )
filter = QString( "(%1) AND (%2)" ).arg( mFilterExp ).arg( sf );
else if ( mFilterExp.length() )
filter = mFilterExp;
else
filter = sf;
return true;
}

@@ -781,8 +809,9 @@ bool QgsRuleBasedRendererV2::renderFeature( QgsFeature& feature,

QgsRenderOptions QgsRuleBasedRendererV2::startRender( QgsRenderContext& context, const QgsFields& fields )
{
QString filter;
// prepare active children
mRootRule->startRender( context, fields );
mRootRule->startRender( context, fields, filter );

QSet<int> symbolZLevelsSet = mRootRule->collectZLevels();
QList<int> symbolZLevels = symbolZLevelsSet.toList();
@@ -800,7 +829,7 @@ QgsRenderOptions QgsRuleBasedRendererV2::startRender( QgsRenderContext& context,
}

mRootRule->setNormZLevels( zLevelsToNormLevels );
return QgsRenderOptions();
return QgsRenderOptions( filter );
}

void QgsRuleBasedRendererV2::stopRender( QgsRenderContext& context )
@@ -135,7 +135,9 @@ class CORE_EXPORT QgsRuleBasedRendererV2 : public QgsFeatureRendererV2
QDomElement save( QDomDocument& doc, QgsSymbolV2Map& symbolMap );

//! prepare the rule for rendering and its children (build active children array)
bool startRender( QgsRenderContext& context, const QgsFields& fields );
Q_DECL_DEPRECATED bool startRender( QgsRenderContext& context, const QgsFields& fields );
//! prepare the rule for rendering and its children (build active children array)
bool startRender( QgsRenderContext& context, const QgsFields& fields, QString& filter );
//! get all used z-levels from this rule and children
QSet<int> collectZLevels();
//! assign normalized z-levels [0..N-1] for this rule's symbol for quick access during rendering

4 comments on commit 1d7a6a4

@SebDieBln

This comment has been minimized.

Copy link
Contributor

@SebDieBln SebDieBln replied Jan 16, 2016

@m-kuhn
May I draw your attention to Redmine 13708 about a regression caused by this commit?
Do you have an easy fix for it or should I continue working on that?

@m-kuhn

This comment has been minimized.

Copy link
Member Author

@m-kuhn m-kuhn replied Jan 18, 2016

@SebDieBln I think everything related to subfilters should be removed here:

1d7a6a4#diff-e0287682f72c4a2b59150b1f2bfefaf3R417

The generated request should just combine all top-level rules (Or simply return 1 if there is an else clause). Does that sound plausible?

@SebDieBln

This comment has been minimized.

Copy link
Contributor

@SebDieBln SebDieBln replied Jan 18, 2016

@m-kuhn

The generated request should just combine all top-level rules (Or simply return 1 if there is an else clause). Does that sound plausible?

Yes, that should fix it.

@SebDieBln

This comment has been minimized.

Copy link
Contributor

@SebDieBln SebDieBln replied Jan 18, 2016

Just linking to the corresponding PR #2691.

Please sign in to comment.