From c49a18c587b660779276ebeff1d1a4f2011645df Mon Sep 17 00:00:00 2001 From: Roel Huybrechts Date: Mon, 9 Feb 2015 21:19:42 +0100 Subject: [PATCH] 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) --- src/core/symbology/qgsrenderer.cpp | 58 ++++++++++++++++-------------- 1 file changed, 31 insertions(+), 27 deletions(-) diff --git a/src/core/symbology/qgsrenderer.cpp b/src/core/symbology/qgsrenderer.cpp index 4106af35c86..28bcc409a02 100644 --- a/src/core/symbology/qgsrenderer.cpp +++ b/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; + } - 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; }