27 #include <QDomDocument>
28 #include <QDomElement>
33 : mParent( NULL ), mSymbol( symbol )
34 , mScaleMinDenom( scaleMinDenom ), mScaleMaxDenom( scaleMaxDenom )
35 , mFilterExp( filterExp ), mLabel( label ), mDescription( description )
36 , mElseRule( elseRule ), mFilter( NULL )
45 qDeleteAll( mChildren );
51 if ( mElseRule || mFilterExp.compare(
"ELSE", Qt::CaseInsensitive ) == 0 )
56 else if ( !mFilterExp.isEmpty() )
69 mChildren.append( rule );
76 mChildren.insert( i, rule );
83 mChildren.removeAll( rule );
90 Rule* rule = mChildren[i];
91 mChildren.removeAt( i );
98 mChildren.removeAll( rule );
105 Rule* rule = mChildren.takeAt( i );
114 foreach (
Rule* rule, mChildren )
125 off.fill( QChar(
' ' ), offset );
126 QString symbolDump = ( mSymbol ? mSymbol->dump() : QString(
"[]" ) );
127 QString msg = off + QString(
"RULE %1 - scale [%2,%3] - filter %4 - symbol %5\n" )
128 .arg( mLabel ).arg( mScaleMinDenom ).arg( mScaleMaxDenom )
129 .arg( mFilterExp ).arg( symbolDump );
132 foreach (
Rule* rule, mChildren )
134 lst.append( rule->
dump( offset + 2 ) );
136 msg += lst.join(
"\n" );
145 attrs.unite( mFilter->referencedColumns().toSet() );
147 attrs.unite( mSymbol->usedAttributes() );
150 for ( RuleList::iterator it = mChildren.begin(); it != mChildren.end(); ++it )
162 lst.append( mSymbol );
164 for ( RuleList::iterator it = mChildren.begin(); it != mChildren.end(); ++it )
181 if ( mSymbol && ( ruleFilter.isEmpty() || mLabel == ruleFilter ) )
182 lst << qMakePair( mLabel, mSymbol );
184 for ( RuleList::iterator it = mChildren.begin(); it != mChildren.end(); ++it )
187 if ( scaleDenominator == -1 || rule->
isScaleOK( scaleDenominator ) )
198 if ( ! mFilter || mElseRule )
201 QVariant res = mFilter->evaluate( &f );
202 return res.toInt() != 0;
209 if ( mScaleMinDenom == 0 && mScaleMaxDenom == 0 )
211 if ( mScaleMinDenom != 0 && mScaleMinDenom > scale )
213 if ( mScaleMaxDenom != 0 && mScaleMaxDenom < scale )
221 Rule* newrule =
new Rule( sym, mScaleMinDenom, mScaleMaxDenom, mFilterExp, mLabel, mDescription );
223 foreach (
Rule* rule, mChildren )
230 QDomElement ruleElem = doc.createElement(
"rule" );
234 int symbolIndex = symbolMap.size();
235 symbolMap[QString::number( symbolIndex )] = mSymbol;
236 ruleElem.setAttribute(
"symbol", symbolIndex );
238 if ( !mFilterExp.isEmpty() )
239 ruleElem.setAttribute(
"filter", mFilterExp );
240 if ( mScaleMinDenom != 0 )
241 ruleElem.setAttribute(
"scalemindenom", mScaleMinDenom );
242 if ( mScaleMaxDenom != 0 )
243 ruleElem.setAttribute(
"scalemaxdenom", mScaleMaxDenom );
244 if ( !mLabel.isEmpty() )
245 ruleElem.setAttribute(
"label", mLabel );
246 if ( !mDescription.isEmpty() )
247 ruleElem.setAttribute(
"description", mDescription );
249 for ( RuleList::iterator it = mChildren.begin(); it != mChildren.end(); ++it )
263 if ( !mFilterExp.isEmpty() )
265 if ( !props.value(
"filter",
"" ).isEmpty() )
266 props[
"filter" ] +=
" AND ";
267 props[
"filter" ] += mFilterExp;
270 if ( mScaleMinDenom != 0 )
273 int parentScaleMinDenom = props.value(
"scaleMinDenom",
"0" ).toInt( &ok );
274 if ( !ok || parentScaleMinDenom <= 0 )
275 props[
"scaleMinDenom" ] = QString::number( mScaleMinDenom );
277 props[
"scaleMinDenom" ] = QString::number( qMax( parentScaleMinDenom, mScaleMinDenom ) );
280 if ( mScaleMaxDenom != 0 )
283 int parentScaleMaxDenom = props.value(
"scaleMaxDenom",
"0" ).toInt( &ok );
284 if ( !ok || parentScaleMaxDenom <= 0 )
285 props[
"scaleMaxDenom" ] = QString::number( mScaleMaxDenom );
287 props[
"scaleMaxDenom" ] = QString::number( qMin( parentScaleMaxDenom, mScaleMaxDenom ) );
292 QDomElement ruleElem = doc.createElement(
"se:Rule" );
293 element.appendChild( ruleElem );
297 QDomElement nameElem = doc.createElement(
"se:Name" );
298 nameElem.appendChild( doc.createTextNode( mLabel ) );
299 ruleElem.appendChild( nameElem );
301 if ( !mLabel.isEmpty() || !mDescription.isEmpty() )
303 QDomElement descrElem = doc.createElement(
"se:Description" );
304 if ( !mLabel.isEmpty() )
306 QDomElement titleElem = doc.createElement(
"se:Title" );
307 titleElem.appendChild( doc.createTextNode( mLabel ) );
308 descrElem.appendChild( titleElem );
310 if ( !mDescription.isEmpty() )
312 QDomElement abstractElem = doc.createElement(
"se:Abstract" );
313 abstractElem.appendChild( doc.createTextNode( mDescription ) );
314 descrElem.appendChild( abstractElem );
316 ruleElem.appendChild( descrElem );
319 if ( !props.value(
"filter",
"" ).isEmpty() )
324 if ( !props.value(
"scaleMinDenom",
"" ).isEmpty() )
326 QDomElement scaleMinDenomElem = doc.createElement(
"se:MinScaleDenominator" );
327 scaleMinDenomElem.appendChild( doc.createTextNode( props.value(
"scaleMinDenom",
"" ) ) );
328 ruleElem.appendChild( scaleMinDenomElem );
331 if ( !props.value(
"scaleMaxDenom",
"" ).isEmpty() )
333 QDomElement scaleMaxDenomElem = doc.createElement(
"se:MaxScaleDenominator" );
334 scaleMaxDenomElem.appendChild( doc.createTextNode( props.value(
"scaleMaxDenom",
"" ) ) );
335 ruleElem.appendChild( scaleMaxDenomElem );
338 mSymbol->toSld( doc, ruleElem, props );
342 for ( RuleList::iterator it = mChildren.begin(); it != mChildren.end(); ++it )
344 ( *it )->toSld( doc, element, props );
350 mActiveChildren.clear();
360 mSymbol->startRender( context, vlayer );
364 for ( RuleList::iterator it = mChildren.begin(); it != mChildren.end(); ++it )
370 mActiveChildren.append( rule );
378 QSet<int> symbolZLevelsSet;
384 for (
int i = 0; i < mSymbol->symbolLayerCount(); i++ )
386 symbolZLevelsSet.insert( mSymbol->symbolLayer( i )->renderingPass() );
391 QList<Rule*>::iterator it;
392 for ( it = mActiveChildren.begin(); it != mActiveChildren.end(); ++it )
397 return symbolZLevelsSet;
404 for (
int i = 0; i < mSymbol->symbolLayerCount(); i++ )
406 int normLevel = zLevelsToNormLevels.value( mSymbol->symbolLayer( i )->renderingPass() );
407 mSymbolNormZLevels.append( normLevel );
412 for ( QList<Rule*>::iterator it = mActiveChildren.begin(); it != mActiveChildren.end(); ++it )
422 if ( !isFilterOK( featToRender.
feat ) )
425 bool rendered =
false;
431 foreach (
int normZLevel, mSymbolNormZLevels )
434 renderQueue[normZLevel].jobs.append(
new RenderJob( featToRender, mSymbol ) );
439 bool willrendersomething =
false;
442 for ( QList<Rule*>::iterator it = mActiveChildren.begin(); it != mActiveChildren.end(); ++it )
450 willrendersomething |= rule->
renderFeature( featToRender, context, renderQueue );
451 rendered |= willrendersomething;
455 if ( !willrendersomething )
457 foreach (
Rule* rule, mElseRules )
459 rendered |= rule->
renderFeature( featToRender, context, renderQueue );
468 if ( !isFilterOK( feat ) )
473 for ( QList<Rule*>::iterator it = mActiveChildren.begin(); it != mActiveChildren.end(); ++it )
485 if ( !isFilterOK( feat ) )
488 lst.append( mSymbol );
490 for ( QList<Rule*>::iterator it = mActiveChildren.begin(); it != mActiveChildren.end(); ++it )
501 if ( !isFilterOK( feat ) )
507 for ( QList<Rule*>::iterator it = mActiveChildren.begin(); it != mActiveChildren.end(); ++it )
518 mSymbol->stopRender( context );
520 for ( QList<Rule*>::iterator it = mActiveChildren.begin(); it != mActiveChildren.end(); ++it )
526 mActiveChildren.clear();
527 mSymbolNormZLevels.clear();
532 QString symbolIdx = ruleElem.attribute(
"symbol" );
534 if ( !symbolIdx.isEmpty() )
536 if ( symbolMap.contains( symbolIdx ) )
538 symbol = symbolMap.take( symbolIdx );
542 QgsDebugMsg(
"symbol for rule " + symbolIdx +
" not found!" );
546 QString filterExp = ruleElem.attribute(
"filter" );
547 QString label = ruleElem.attribute(
"label" );
548 QString description = ruleElem.attribute(
"description" );
549 int scaleMinDenom = ruleElem.attribute(
"scalemindenom",
"0" ).toInt();
550 int scaleMaxDenom = ruleElem.attribute(
"scalemaxdenom",
"0" ).toInt();
551 Rule* rule =
new Rule( symbol, scaleMinDenom, scaleMaxDenom, filterExp, label, description );
553 QDomElement childRuleElem = ruleElem.firstChildElement(
"rule" );
554 while ( !childRuleElem.isNull() )
556 Rule* childRule =
create( childRuleElem, symbolMap );
565 childRuleElem = childRuleElem.nextSiblingElement(
"rule" );
573 if ( ruleElem.localName() !=
"Rule" )
575 QgsDebugMsg( QString(
"invalid element: Rule element expected, %1 found!" ).arg( ruleElem.tagName() ) );
579 QString label, description, filterExp;
580 int scaleMinDenom = 0, scaleMaxDenom = 0;
584 QDomElement childElem = ruleElem.firstChildElement();
585 while ( !childElem.isNull() )
587 if ( childElem.localName() ==
"Name" )
591 if ( label.isEmpty() )
592 label = childElem.firstChild().nodeValue();
594 else if ( childElem.localName() ==
"Description" )
597 QDomElement titleElem = childElem.firstChildElement(
"Title" );
598 if ( !titleElem.isNull() )
600 label = titleElem.firstChild().nodeValue();
603 QDomElement abstractElem = childElem.firstChildElement(
"Abstract" );
604 if ( !abstractElem.isNull() )
606 description = abstractElem.firstChild().nodeValue();
609 else if ( childElem.localName() ==
"Abstract" )
612 description = childElem.firstChild().nodeValue();
614 else if ( childElem.localName() ==
"Title" )
617 label = childElem.firstChild().nodeValue();
619 else if ( childElem.localName() ==
"Filter" )
635 else if ( childElem.localName() ==
"MinScaleDenominator" )
638 int v = childElem.firstChild().nodeValue().toInt( &ok );
642 else if ( childElem.localName() ==
"MaxScaleDenominator" )
645 int v = childElem.firstChild().nodeValue().toInt( &ok );
649 else if ( childElem.localName().endsWith(
"Symbolizer" ) )
655 childElem = childElem.nextSiblingElement();
660 if ( layers.size() > 0 )
677 QgsDebugMsg( QString(
"invalid geometry type: found %1" ).arg( geomType ) );
683 return new Rule( symbol, scaleMinDenom, scaleMaxDenom, filterExp, label, description );
717 bool drawVertexMarker )
735 QList<int> symbolZLevels = symbolZLevelsSet.toList();
736 qSort( symbolZLevels );
740 QMap<int, int> zLevelsToNormLevels;
741 int maxNormLevel = -1;
742 foreach (
int zLevel, symbolZLevels )
744 zLevelsToNormLevels[zLevel] = ++maxNormLevel;
746 QgsDebugMsg( QString(
"zLevel %1 -> %2" ).arg( zLevel ).arg( maxNormLevel ) );
769 for (
int i = 0; i < count; i++ )
796 return attrs.values();
822 rendererElem.setAttribute(
"type",
"RuleRenderer" );
828 rulesElem.setTagName(
"rules" );
829 rendererElem.appendChild( rulesElem );
832 rendererElem.appendChild( symbolsElem );
841 for ( QgsLegendSymbolList::iterator it = items.begin(); it != items.end(); ++it )
843 QPair<QString, QgsSymbolV2*> pair = *it;
845 lst << qMakePair( pair.first, pix );
859 QDomElement symbolsElem = element.firstChildElement(
"symbols" );
860 if ( symbolsElem.isNull() )
865 QDomElement rulesElem = element.firstChildElement(
"rules" );
884 QDomElement ruleElem = element.firstChildElement(
"Rule" );
885 while ( !ruleElem.isNull() )
892 root =
new Rule( 0 );
897 ruleElem = ruleElem.nextSiblingElement(
"Rule" );
920 if ( cat.
value().type() == QVariant::Int )
921 value = cat.
value().toString();
922 else if ( cat.
value().type() == QVariant::Double )
925 value = QString::number( cat.
value().toDouble(),
'f', 4 );
928 QString filter = QString(
"%1 = %2" ).arg( attr ).arg( value );
929 QString label = filter;
941 QString filter = QString(
"%1 >= %2 AND %1 <= %3" ).arg( attr )
942 .arg( QString::number( rng.
lowerValue(),
'f', 4 ) )
943 .arg( QString::number( rng.
upperValue(),
'f', 4 ) );
944 QString label = filter;
955 foreach (
int scale, scales )
959 if ( maxDenom != 0 && maxDenom <= scale )
961 initialRule->
appendChild(
new Rule( symbol->
clone(), oldScale, scale, QString(), QString(
"%1 - %2" ).arg( oldScale ).arg( scale ) ) );
965 initialRule->
appendChild(
new Rule( symbol->
clone(), oldScale, maxDenom, QString(), QString(
"%1 - %2" ).arg( oldScale ).arg( maxDenom ) ) );
970 QString msg(
"Rule-based renderer:\n" );