Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
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 1d7a6a4
Show file tree
Hide file tree
Showing 5 changed files with 47 additions and 6 deletions.
4 changes: 3 additions & 1 deletion python/core/symbology-ng/qgsrulebasedrendererv2.sip
Expand Up @@ -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
Expand Down
7 changes: 6 additions & 1 deletion src/core/qgsvectorlayerrenderer.cpp
Expand Up @@ -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 );
Expand All @@ -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 )
{
Expand Down
3 changes: 3 additions & 0 deletions src/core/symbology-ng/qgsrendererv2.h
Expand Up @@ -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:
Expand Down
35 changes: 32 additions & 3 deletions src/core/symbology-ng/qgsrulebasedrendererv2.cpp
Expand Up @@ -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();

Expand All @@ -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;
}

Expand Down Expand Up @@ -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();
Expand All @@ -800,7 +829,7 @@ QgsRenderOptions QgsRuleBasedRendererV2::startRender( QgsRenderContext& context,
}

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

void QgsRuleBasedRendererV2::stopRender( QgsRenderContext& context )
Expand Down
4 changes: 3 additions & 1 deletion src/core/symbology-ng/qgsrulebasedrendererv2.h
Expand Up @@ -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
Expand Down

4 comments on commit 1d7a6a4

@SebDieBln
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@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
Copy link
Member Author

@m-kuhn m-kuhn commented on 1d7a6a4 Jan 18, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@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
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@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
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just linking to the corresponding PR #2691.

Please sign in to comment.