mirror of
https://github.com/qgis/QGIS.git
synced 2025-04-15 00:04:00 -04:00
Merge pull request #6679 from pblottiere/bugfix_will_render_feature
[bugfix] Fixes identify action on deactivated rules for QgsRuleBasedRenderer
This commit is contained in:
commit
4be8baa683
@ -324,9 +324,14 @@ Returns which legend keys match the feature
|
|||||||
.. versionadded:: 2.14
|
.. versionadded:: 2.14
|
||||||
%End
|
%End
|
||||||
|
|
||||||
QgsRuleBasedRenderer::RuleList rulesForFeature( QgsFeature &feat, QgsRenderContext *context = 0 );
|
QgsRuleBasedRenderer::RuleList rulesForFeature( QgsFeature &feat, QgsRenderContext *context = 0, bool onlyActive = true );
|
||||||
%Docstring
|
%Docstring
|
||||||
tell which rules will be used to render the feature
|
Returns the list of rules used to render the feature in a specific
|
||||||
|
context.
|
||||||
|
|
||||||
|
:param feat: The feature for which rules have to be find
|
||||||
|
:param context: The rendering context
|
||||||
|
:param onlyActive: True to search for active rules only, false otherwise
|
||||||
%End
|
%End
|
||||||
|
|
||||||
void stopRender( QgsRenderContext &context );
|
void stopRender( QgsRenderContext &context );
|
||||||
@ -411,7 +416,7 @@ Sets if this rule is an ELSE rule
|
|||||||
:param iselse: If true, this rule is an ELSE rule
|
:param iselse: If true, this rule is an ELSE rule
|
||||||
%End
|
%End
|
||||||
|
|
||||||
bool isElse();
|
bool isElse() const;
|
||||||
%Docstring
|
%Docstring
|
||||||
Check if this rule is an ELSE rule
|
Check if this rule is an ELSE rule
|
||||||
|
|
||||||
|
@ -541,13 +541,26 @@ bool QgsRuleBasedRenderer::Rule::willRenderFeature( QgsFeature &feat, QgsRenderC
|
|||||||
{
|
{
|
||||||
if ( !isFilterOK( feat, context ) )
|
if ( !isFilterOK( feat, context ) )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if ( mSymbol )
|
if ( mSymbol )
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
Q_FOREACH ( Rule *rule, mActiveChildren )
|
Q_FOREACH ( Rule *rule, mActiveChildren )
|
||||||
{
|
{
|
||||||
if ( rule->willRenderFeature( feat, context ) )
|
if ( rule->isElse() )
|
||||||
|
{
|
||||||
|
RuleList lst = rulesForFeature( feat, context, false );
|
||||||
|
lst.removeOne( rule );
|
||||||
|
|
||||||
|
if ( lst.empty() )
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if ( !rule->isElse( ) && rule->willRenderFeature( feat, context ) )
|
||||||
|
{
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -576,12 +589,31 @@ QSet<QString> QgsRuleBasedRenderer::Rule::legendKeysForFeature( QgsFeature &feat
|
|||||||
|
|
||||||
Q_FOREACH ( Rule *rule, mActiveChildren )
|
Q_FOREACH ( Rule *rule, mActiveChildren )
|
||||||
{
|
{
|
||||||
lst.unite( rule->legendKeysForFeature( feat, context ) );
|
bool validKey = false;
|
||||||
|
if ( rule->isElse() )
|
||||||
|
{
|
||||||
|
RuleList lst = rulesForFeature( feat, context, false );
|
||||||
|
lst.removeOne( rule );
|
||||||
|
|
||||||
|
if ( lst.empty() )
|
||||||
|
{
|
||||||
|
validKey = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if ( !rule->isElse( ) && rule->willRenderFeature( feat, context ) )
|
||||||
|
{
|
||||||
|
validKey = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( validKey )
|
||||||
|
{
|
||||||
|
lst.unite( rule->legendKeysForFeature( feat, context ) );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return lst;
|
return lst;
|
||||||
}
|
}
|
||||||
|
|
||||||
QgsRuleBasedRenderer::RuleList QgsRuleBasedRenderer::Rule::rulesForFeature( QgsFeature &feat, QgsRenderContext *context )
|
QgsRuleBasedRenderer::RuleList QgsRuleBasedRenderer::Rule::rulesForFeature( QgsFeature &feat, QgsRenderContext *context, bool onlyActive )
|
||||||
{
|
{
|
||||||
RuleList lst;
|
RuleList lst;
|
||||||
if ( !isFilterOK( feat, context ) )
|
if ( !isFilterOK( feat, context ) )
|
||||||
@ -590,9 +622,13 @@ QgsRuleBasedRenderer::RuleList QgsRuleBasedRenderer::Rule::rulesForFeature( QgsF
|
|||||||
if ( mSymbol )
|
if ( mSymbol )
|
||||||
lst.append( this );
|
lst.append( this );
|
||||||
|
|
||||||
Q_FOREACH ( Rule *rule, mActiveChildren )
|
RuleList listChildren = children();
|
||||||
|
if ( onlyActive )
|
||||||
|
listChildren = mActiveChildren;
|
||||||
|
|
||||||
|
Q_FOREACH ( Rule *rule, listChildren )
|
||||||
{
|
{
|
||||||
lst += rule->rulesForFeature( feat, context );
|
lst += rule->rulesForFeature( feat, context, onlyActive );
|
||||||
}
|
}
|
||||||
return lst;
|
return lst;
|
||||||
}
|
}
|
||||||
|
@ -342,8 +342,15 @@ class CORE_EXPORT QgsRuleBasedRenderer : public QgsFeatureRenderer
|
|||||||
*/
|
*/
|
||||||
QSet< QString > legendKeysForFeature( QgsFeature &feat, QgsRenderContext *context = nullptr );
|
QSet< QString > legendKeysForFeature( QgsFeature &feat, QgsRenderContext *context = nullptr );
|
||||||
|
|
||||||
//! tell which rules will be used to render the feature
|
/**
|
||||||
QgsRuleBasedRenderer::RuleList rulesForFeature( QgsFeature &feat, QgsRenderContext *context = nullptr );
|
* Returns the list of rules used to render the feature in a specific
|
||||||
|
* context.
|
||||||
|
*
|
||||||
|
* \param feat The feature for which rules have to be find
|
||||||
|
* \param context The rendering context
|
||||||
|
* \param onlyActive True to search for active rules only, false otherwise
|
||||||
|
*/
|
||||||
|
QgsRuleBasedRenderer::RuleList rulesForFeature( QgsFeature &feat, QgsRenderContext *context = nullptr, bool onlyActive = true );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Stop a rendering process. Used to clean up the internal state of this rule
|
* Stop a rendering process. Used to clean up the internal state of this rule
|
||||||
@ -419,7 +426,7 @@ class CORE_EXPORT QgsRuleBasedRenderer : public QgsFeatureRenderer
|
|||||||
*
|
*
|
||||||
* \returns True if this rule is an else rule
|
* \returns True if this rule is an else rule
|
||||||
*/
|
*/
|
||||||
bool isElse() { return mElseRule; }
|
bool isElse() const { return mElseRule; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void initFilter();
|
void initFilter();
|
||||||
|
@ -40,7 +40,8 @@ from qgis.core import (QgsVectorLayer,
|
|||||||
QgsRendererCategory,
|
QgsRendererCategory,
|
||||||
QgsCategorizedSymbolRenderer,
|
QgsCategorizedSymbolRenderer,
|
||||||
QgsGraduatedSymbolRenderer,
|
QgsGraduatedSymbolRenderer,
|
||||||
QgsRendererRange
|
QgsRendererRange,
|
||||||
|
QgsRenderContext
|
||||||
)
|
)
|
||||||
from qgis.testing import start_app, unittest
|
from qgis.testing import start_app, unittest
|
||||||
from utilities import unitTestDataPath
|
from utilities import unitTestDataPath
|
||||||
@ -101,6 +102,52 @@ class TestQgsRulebasedRenderer(unittest.TestCase):
|
|||||||
|
|
||||||
assert result
|
assert result
|
||||||
|
|
||||||
|
def testWillRenderFeature(self):
|
||||||
|
vl = self.mapsettings.layers()[0]
|
||||||
|
ft = vl.getFeature(0) # 'id' = 1
|
||||||
|
renderer = vl.renderer()
|
||||||
|
|
||||||
|
ctx = QgsRenderContext.fromMapSettings(self.mapsettings)
|
||||||
|
ctx.expressionContext().setFeature(ft)
|
||||||
|
|
||||||
|
renderer.rootRule().children()[0].setActive(False)
|
||||||
|
renderer.rootRule().children()[1].setActive(True)
|
||||||
|
renderer.rootRule().children()[2].setActive(True)
|
||||||
|
|
||||||
|
renderer.startRender(ctx, vl.fields()) # build mActiveChlidren
|
||||||
|
rendered = renderer.willRenderFeature(ft, ctx)
|
||||||
|
renderer.stopRender(ctx)
|
||||||
|
renderer.rootRule().children()[0].setActive(True)
|
||||||
|
assert rendered == False
|
||||||
|
|
||||||
|
renderer.startRender(ctx, vl.fields()) # build mActiveChlidren
|
||||||
|
rendered = renderer.willRenderFeature(ft, ctx)
|
||||||
|
renderer.stopRender(ctx)
|
||||||
|
assert rendered == True
|
||||||
|
|
||||||
|
def testFeatureCount(self):
|
||||||
|
vl = self.mapsettings.layers()[0]
|
||||||
|
ft = vl.getFeature(2) # 'id' = 3 => ELSE
|
||||||
|
renderer = vl.renderer()
|
||||||
|
|
||||||
|
ctx = QgsRenderContext.fromMapSettings(self.mapsettings)
|
||||||
|
ctx.expressionContext().setFeature(ft)
|
||||||
|
|
||||||
|
counter = vl.countSymbolFeatures()
|
||||||
|
counter.waitForFinished()
|
||||||
|
|
||||||
|
renderer.startRender(ctx, vl.fields())
|
||||||
|
|
||||||
|
elseRule = None
|
||||||
|
for rule in renderer.rootRule().children():
|
||||||
|
if rule.filterExpression() == 'ELSE':
|
||||||
|
elseRule = rule
|
||||||
|
|
||||||
|
assert elseRule != None
|
||||||
|
|
||||||
|
cnt = counter.featureCount(elseRule.ruleKey())
|
||||||
|
assert cnt == 1
|
||||||
|
|
||||||
def testRefineWithCategories(self):
|
def testRefineWithCategories(self):
|
||||||
# Test refining rule with categories (refs #10815)
|
# Test refining rule with categories (refs #10815)
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user