Skip to content
Permalink
Browse files

Add support for reading SLD's with multiple FeatureTypeStyle elements.

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 c49a18c587b660779276ebeff1d1a4f2011645df
Showing with 31 additions and 27 deletions.
  1. +31 −27 src/core/symbology/qgsrenderer.cpp
@@ -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;
@@ -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;
}

0 comments on commit c49a18c

Please sign in to comment.
You can’t perform that action at this time.