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)
This commit is contained in:
Roel Huybrechts 2015-02-09 21:19:42 +01:00 committed by Matthias Kuhn
parent 8cf7447a2c
commit c49a18c587
No known key found for this signature in database
GPG Key ID: A0E766808764D73F

View File

@ -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;
}
if ( needRuleRenderer )
{
break;
}
ruleChildElem = ruleChildElem.nextSiblingElement();
}
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;
}