Skip to content

Commit

Permalink
Add support for reading SLD's with multiple FeatureTypeStyle elements.
Browse files Browse the repository at this point in the history
Introduce a virtual FeatureTypeStyle to add support for reading SLD documents with more than one FeatureTypeStyle element.

Still supports SLD's with one FeatureTypeStyle, as well as SLD's with multiple FeatureTypeStyles, including empty FeatureTypeStyles (not breaking single symbol rendering in that case). Complies with SLD's painter's model for rendering, appending Rules from subsequent FeatureTypeStyles in order.

Fix #6413 (http://hub.qgis.org/issues/6413)
  • Loading branch information
Roel authored and m-kuhn committed May 31, 2018
1 parent 8cf7447 commit c49a18c
Showing 1 changed file with 31 additions and 27 deletions.
58 changes: 31 additions & 27 deletions src/core/symbology/qgsrenderer.cpp
Expand Up @@ -223,47 +223,51 @@ QgsFeatureRenderer *QgsFeatureRenderer::loadSld( const QDomNode &node, QgsWkbTyp
return nullptr;
}

// create empty FeatureTypeStyle element to merge Rule's from all FeatureTypeStyle's
QDomElement mergedFeatTypeStyle = featTypeStyleElem.cloneNode( false ).toElement();

// use the RuleRenderer when more rules are present or the rule
// has filters or min/max scale denominators set,
// otherwise use the SingleSymbol renderer
bool needRuleRenderer = false;
int ruleCount = 0;

QDomElement ruleElem = featTypeStyleElem.firstChildElement( QStringLiteral( "Rule" ) );
while ( !ruleElem.isNull() )
while ( !featTypeStyleElem.isNull() )
{
ruleCount++;

// more rules present, use the RuleRenderer
if ( ruleCount > 1 )
QDomElement ruleElem = featTypeStyleElem.firstChildElement( QStringLiteral( "Rule" ) );
while ( !ruleElem.isNull() )
{
QgsDebugMsg( "more Rule elements found: need a RuleRenderer" );
needRuleRenderer = true;
break;
}
ruleCount++;

QDomElement ruleChildElem = ruleElem.firstChildElement();
while ( !ruleChildElem.isNull() )
{
// rule has filter or min/max scale denominator, use the RuleRenderer
if ( ruleChildElem.localName() == QLatin1String( "Filter" ) ||
ruleChildElem.localName() == QLatin1String( "MinScaleDenominator" ) ||
ruleChildElem.localName() == QLatin1String( "MaxScaleDenominator" ) )
// append a clone of all Rules to the merged FeatureTypeStyle element
mergedFeatTypeStyle.appendChild( ruleElem.cloneNode().toElement() );
// more rules present, use the RuleRenderer

if ( ruleCount > 1 )
{
QgsDebugMsg( "Filter or Min/MaxScaleDenominator element found: need a RuleRenderer" );
QgsDebugMsg( "more Rule elements found: need a RuleRenderer" );
needRuleRenderer = true;
break;
}

ruleChildElem = ruleChildElem.nextSiblingElement();
}
QDomElement ruleChildElem = ruleElem.firstChildElement();
while ( !ruleChildElem.isNull() )
{
// rule has filter or min/max scale denominator, use the RuleRenderer
if ( ruleChildElem.localName() == QLatin1String( "Filter" ) ||
ruleChildElem.localName() == QLatin1String( "MinScaleDenominator" ) ||
ruleChildElem.localName() == QLatin1String( "MaxScaleDenominator" ) )
{
QgsDebugMsg( "Filter or Min/MaxScaleDenominator element found: need a RuleRenderer" );
needRuleRenderer = true;
break;
}

ruleChildElem = ruleChildElem.nextSiblingElement();
}

if ( needRuleRenderer )
{
break;
ruleElem = ruleElem.nextSiblingElement( QStringLiteral( "Rule" ) );
}

ruleElem = ruleElem.nextSiblingElement( QStringLiteral( "Rule" ) );
featTypeStyleElem = featTypeStyleElem.nextSiblingElement( QStringLiteral( "FeatureTypeStyle" ) );
}

QString rendererType;
Expand All @@ -285,7 +289,7 @@ QgsFeatureRenderer *QgsFeatureRenderer::loadSld( const QDomNode &node, QgsWkbTyp
return nullptr;
}

QgsFeatureRenderer *r = m->createRendererFromSld( featTypeStyleElem, geomType );
QgsFeatureRenderer *r = m->createRendererFromSld( mergedFeatTypeStyle, geomType );
return r;
}

Expand Down

0 comments on commit c49a18c

Please sign in to comment.