30 #include <QDomDocument>
31 #include <QDomElement>
36 : mParent( NULL ), mSymbol( symbol )
37 , mScaleMinDenom( scaleMinDenom ), mScaleMaxDenom( scaleMaxDenom )
38 , mFilterExp( filterExp ), mLabel( label ), mDescription( description )
39 , mElseRule( elseRule )
43 mRuleKey = QUuid::createUuid().toString();
51 qDeleteAll( mChildren );
57 if ( mElseRule || mFilterExp.compare(
"ELSE", Qt::CaseInsensitive ) == 0 )
62 else if ( !mFilterExp.isEmpty() )
75 mChildren.append( rule );
82 mChildren.insert( i, rule );
89 mChildren.removeAll( rule );
96 Rule* rule = mChildren[i];
97 mChildren.removeAt( i );
104 mChildren.removeAll( rule );
111 Rule* rule = mChildren.takeAt( i );
121 if ( key == mRuleKey )
124 foreach (
Rule* rule, mChildren )
136 foreach (
Rule* rule, mChildren )
147 off.fill( QChar(
' ' ), offset );
148 QString symbolDump = ( mSymbol ? mSymbol->dump() : QString(
"[]" ) );
149 QString msg = off + QString(
"RULE %1 - scale [%2,%3] - filter %4 - symbol %5\n" )
150 .arg( mLabel ).arg( mScaleMinDenom ).arg( mScaleMaxDenom )
151 .arg( mFilterExp ).arg( symbolDump );
154 foreach (
Rule* rule, mChildren )
156 lst.append( rule->
dump( offset + 2 ) );
158 msg += lst.join(
"\n" );
167 attrs.unite( mFilter->referencedColumns().toSet() );
169 attrs.unite( mSymbol->usedAttributes() );
172 for ( RuleList::iterator it = mChildren.begin(); it != mChildren.end(); ++it )
184 lst.append( mSymbol );
186 for ( RuleList::iterator it = mChildren.begin(); it != mChildren.end(); ++it )
203 if ( mSymbol && ( ruleFilter.isEmpty() || mLabel == ruleFilter ) )
204 lst << qMakePair( mLabel, mSymbol );
206 for ( RuleList::iterator it = mChildren.begin(); it != mChildren.end(); ++it )
209 if ( scaleDenominator == -1 || rule->
isScaleOK( scaleDenominator ) )
220 if ( currentLevel != -1 )
222 lst <<
QgsLegendSymbolItemV2( mSymbol, mLabel, mRuleKey,
true, mScaleMinDenom, mScaleMaxDenom, currentLevel, mParent ? mParent->mRuleKey : QString() );
225 for ( RuleList::const_iterator it = mChildren.constBegin(); it != mChildren.constEnd(); ++it )
236 if ( ! mFilter || mElseRule )
239 QVariant res = mFilter->evaluate( &f );
240 return res.toInt() != 0;
247 if ( mScaleMinDenom == 0 && mScaleMaxDenom == 0 )
249 if ( mScaleMinDenom != 0 && mScaleMinDenom > scale )
251 if ( mScaleMaxDenom != 0 && mScaleMaxDenom < scale )
259 Rule* newrule =
new Rule( sym, mScaleMinDenom, mScaleMaxDenom, mFilterExp, mLabel, mDescription );
262 foreach (
Rule* rule, mChildren )
269 QDomElement ruleElem = doc.createElement(
"rule" );
273 int symbolIndex = symbolMap.size();
274 symbolMap[QString::number( symbolIndex )] = mSymbol;
275 ruleElem.setAttribute(
"symbol", symbolIndex );
277 if ( !mFilterExp.isEmpty() )
278 ruleElem.setAttribute(
"filter", mFilterExp );
279 if ( mScaleMinDenom != 0 )
280 ruleElem.setAttribute(
"scalemindenom", mScaleMinDenom );
281 if ( mScaleMaxDenom != 0 )
282 ruleElem.setAttribute(
"scalemaxdenom", mScaleMaxDenom );
283 if ( !mLabel.isEmpty() )
284 ruleElem.setAttribute(
"label", mLabel );
285 if ( !mDescription.isEmpty() )
286 ruleElem.setAttribute(
"description", mDescription );
288 ruleElem.setAttribute(
"checkstate", 0 );
289 ruleElem.setAttribute(
"key", mRuleKey );
291 for ( RuleList::iterator it = mChildren.begin(); it != mChildren.end(); ++it )
305 if ( !mFilterExp.isEmpty() )
307 if ( !props.value(
"filter",
"" ).isEmpty() )
308 props[
"filter" ] +=
" AND ";
309 props[
"filter" ] += mFilterExp;
312 if ( mScaleMinDenom != 0 )
315 int parentScaleMinDenom = props.value(
"scaleMinDenom",
"0" ).toInt( &ok );
316 if ( !ok || parentScaleMinDenom <= 0 )
317 props[
"scaleMinDenom" ] = QString::number( mScaleMinDenom );
319 props[
"scaleMinDenom" ] = QString::number( qMax( parentScaleMinDenom, mScaleMinDenom ) );
322 if ( mScaleMaxDenom != 0 )
325 int parentScaleMaxDenom = props.value(
"scaleMaxDenom",
"0" ).toInt( &ok );
326 if ( !ok || parentScaleMaxDenom <= 0 )
327 props[
"scaleMaxDenom" ] = QString::number( mScaleMaxDenom );
329 props[
"scaleMaxDenom" ] = QString::number( qMin( parentScaleMaxDenom, mScaleMaxDenom ) );
334 QDomElement ruleElem = doc.createElement(
"se:Rule" );
335 element.appendChild( ruleElem );
339 QDomElement nameElem = doc.createElement(
"se:Name" );
340 nameElem.appendChild( doc.createTextNode( mLabel ) );
341 ruleElem.appendChild( nameElem );
343 if ( !mLabel.isEmpty() || !mDescription.isEmpty() )
345 QDomElement descrElem = doc.createElement(
"se:Description" );
346 if ( !mLabel.isEmpty() )
348 QDomElement titleElem = doc.createElement(
"se:Title" );
349 titleElem.appendChild( doc.createTextNode( mLabel ) );
350 descrElem.appendChild( titleElem );
352 if ( !mDescription.isEmpty() )
354 QDomElement abstractElem = doc.createElement(
"se:Abstract" );
355 abstractElem.appendChild( doc.createTextNode( mDescription ) );
356 descrElem.appendChild( abstractElem );
358 ruleElem.appendChild( descrElem );
361 if ( !props.value(
"filter",
"" ).isEmpty() )
366 if ( !props.value(
"scaleMinDenom",
"" ).isEmpty() )
368 QDomElement scaleMinDenomElem = doc.createElement(
"se:MinScaleDenominator" );
369 scaleMinDenomElem.appendChild( doc.createTextNode( props.value(
"scaleMinDenom",
"" ) ) );
370 ruleElem.appendChild( scaleMinDenomElem );
373 if ( !props.value(
"scaleMaxDenom",
"" ).isEmpty() )
375 QDomElement scaleMaxDenomElem = doc.createElement(
"se:MaxScaleDenominator" );
376 scaleMaxDenomElem.appendChild( doc.createTextNode( props.value(
"scaleMaxDenom",
"" ) ) );
377 ruleElem.appendChild( scaleMaxDenomElem );
380 mSymbol->toSld( doc, ruleElem, props );
384 for ( RuleList::iterator it = mChildren.begin(); it != mChildren.end(); ++it )
386 ( *it )->toSld( doc, element, props );
392 mActiveChildren.clear();
403 mFilter->prepare( fields );
405 mSymbol->startRender( context, &fields );
409 for ( RuleList::iterator it = mChildren.begin(); it != mChildren.end(); ++it )
415 mActiveChildren.append( rule );
423 QSet<int> symbolZLevelsSet;
429 for (
int i = 0; i < mSymbol->symbolLayerCount(); i++ )
431 symbolZLevelsSet.insert( mSymbol->symbolLayer( i )->renderingPass() );
436 QList<Rule*>::iterator it;
437 for ( it = mActiveChildren.begin(); it != mActiveChildren.end(); ++it )
442 return symbolZLevelsSet;
449 for (
int i = 0; i < mSymbol->symbolLayerCount(); i++ )
451 int normLevel = zLevelsToNormLevels.value( mSymbol->symbolLayer( i )->renderingPass() );
452 mSymbolNormZLevels.append( normLevel );
457 for ( QList<Rule*>::iterator it = mActiveChildren.begin(); it != mActiveChildren.end(); ++it )
467 if ( !isFilterOK( featToRender.
feat ) )
470 bool rendered =
false;
476 foreach (
int normZLevel, mSymbolNormZLevels )
479 renderQueue[normZLevel].jobs.append(
new RenderJob( featToRender, mSymbol ) );
484 bool willrendersomething =
false;
487 for ( QList<Rule*>::iterator it = mActiveChildren.begin(); it != mActiveChildren.end(); ++it )
495 willrendersomething |= rule->
renderFeature( featToRender, context, renderQueue );
496 rendered |= willrendersomething;
500 if ( !willrendersomething )
502 foreach (
Rule* rule, mElseRules )
504 rendered |= rule->
renderFeature( featToRender, context, renderQueue );
513 if ( !isFilterOK( feat ) )
518 for ( QList<Rule*>::iterator it = mActiveChildren.begin(); it != mActiveChildren.end(); ++it )
530 if ( !isFilterOK( feat ) )
533 lst.append( mSymbol );
535 for ( QList<Rule*>::iterator it = mActiveChildren.begin(); it != mActiveChildren.end(); ++it )
546 if ( !isFilterOK( feat ) )
552 for ( QList<Rule*>::iterator it = mActiveChildren.begin(); it != mActiveChildren.end(); ++it )
563 mSymbol->stopRender( context );
565 for ( QList<Rule*>::iterator it = mActiveChildren.begin(); it != mActiveChildren.end(); ++it )
571 mActiveChildren.clear();
572 mSymbolNormZLevels.clear();
577 QString symbolIdx = ruleElem.attribute(
"symbol" );
579 if ( !symbolIdx.isEmpty() )
581 if ( symbolMap.contains( symbolIdx ) )
583 symbol = symbolMap.take( symbolIdx );
587 QgsDebugMsg(
"symbol for rule " + symbolIdx +
" not found!" );
591 QString filterExp = ruleElem.attribute(
"filter" );
592 QString label = ruleElem.attribute(
"label" );
593 QString description = ruleElem.attribute(
"description" );
594 int scaleMinDenom = ruleElem.attribute(
"scalemindenom",
"0" ).toInt();
595 int scaleMaxDenom = ruleElem.attribute(
"scalemaxdenom",
"0" ).toInt();
596 QString ruleKey = ruleElem.attribute(
"key" );
597 Rule* rule =
new Rule( symbol, scaleMinDenom, scaleMaxDenom, filterExp, label, description );
599 if ( !ruleKey.isEmpty() )
602 rule->
setCheckState( ruleElem.attribute(
"checkstate",
"1" ).toInt() );
604 QDomElement childRuleElem = ruleElem.firstChildElement(
"rule" );
605 while ( !childRuleElem.isNull() )
607 Rule* childRule =
create( childRuleElem, symbolMap );
616 childRuleElem = childRuleElem.nextSiblingElement(
"rule" );
624 if ( ruleElem.localName() !=
"Rule" )
626 QgsDebugMsg( QString(
"invalid element: Rule element expected, %1 found!" ).arg( ruleElem.tagName() ) );
630 QString label, description, filterExp;
631 int scaleMinDenom = 0, scaleMaxDenom = 0;
635 QDomElement childElem = ruleElem.firstChildElement();
636 while ( !childElem.isNull() )
638 if ( childElem.localName() ==
"Name" )
642 if ( label.isEmpty() )
643 label = childElem.firstChild().nodeValue();
645 else if ( childElem.localName() ==
"Description" )
648 QDomElement titleElem = childElem.firstChildElement(
"Title" );
649 if ( !titleElem.isNull() )
651 label = titleElem.firstChild().nodeValue();
654 QDomElement abstractElem = childElem.firstChildElement(
"Abstract" );
655 if ( !abstractElem.isNull() )
657 description = abstractElem.firstChild().nodeValue();
660 else if ( childElem.localName() ==
"Abstract" )
663 description = childElem.firstChild().nodeValue();
665 else if ( childElem.localName() ==
"Title" )
668 label = childElem.firstChild().nodeValue();
670 else if ( childElem.localName() ==
"Filter" )
686 else if ( childElem.localName() ==
"MinScaleDenominator" )
689 int v = childElem.firstChild().nodeValue().toInt( &ok );
693 else if ( childElem.localName() ==
"MaxScaleDenominator" )
696 int v = childElem.firstChild().nodeValue().toInt( &ok );
700 else if ( childElem.localName().endsWith(
"Symbolizer" ) )
706 childElem = childElem.nextSiblingElement();
711 if ( layers.size() > 0 )
728 QgsDebugMsg( QString(
"invalid geometry type: found %1" ).arg( geomType ) );
734 return new Rule( symbol, scaleMinDenom, scaleMaxDenom, filterExp, label, description );
768 bool drawVertexMarker )
786 QList<int> symbolZLevels = symbolZLevelsSet.toList();
787 qSort( symbolZLevels );
791 QMap<int, int> zLevelsToNormLevels;
792 int maxNormLevel = -1;
793 foreach (
int zLevel, symbolZLevels )
795 zLevelsToNormLevels[zLevel] = ++maxNormLevel;
797 QgsDebugMsg( QString(
"zLevel %1 -> %2" ).arg( zLevel ).arg( maxNormLevel ) );
820 for (
int i = 0; i < count; i++ )
847 return attrs.values();
859 Q_ASSERT( origDescendants.count() == clonedDescendants.count() );
860 for (
int i = 0; i < origDescendants.count(); ++i )
861 clonedDescendants[i]->setRuleKey( origDescendants[i]->ruleKey() );
883 rendererElem.setAttribute(
"type",
"RuleRenderer" );
889 rulesElem.setTagName(
"rules" );
890 rendererElem.appendChild( rulesElem );
893 rendererElem.appendChild( symbolsElem );
902 for ( QgsLegendSymbolList::iterator it = items.begin(); it != items.end(); ++it )
904 QPair<QString, QgsSymbolV2*> pair = *it;
906 lst << qMakePair( pair.first, pix );
943 QDomElement symbolsElem = element.firstChildElement(
"symbols" );
944 if ( symbolsElem.isNull() )
949 QDomElement rulesElem = element.firstChildElement(
"rules" );
968 QDomElement ruleElem = element.firstChildElement(
"Rule" );
969 while ( !ruleElem.isNull() )
976 root =
new Rule( 0 );
981 ruleElem = ruleElem.nextSiblingElement(
"Rule" );
1004 if ( cat.
value().type() == QVariant::Int )
1005 value = cat.
value().toString();
1006 else if ( cat.
value().type() == QVariant::Double )
1009 value = QString::number( cat.
value().toDouble(),
'f', 4 );
1012 QString filter = QString(
"%1 = %2" ).arg( attr ).arg( value );
1013 QString label = filter;
1025 QString filter = QString(
"%1 >= %2 AND %1 <= %3" ).arg( attr )
1026 .arg( QString::number( rng.
lowerValue(),
'f', 4 ) )
1027 .arg( QString::number( rng.
upperValue(),
'f', 4 ) );
1028 QString label = filter;
1039 foreach (
int scale, scales )
1043 if ( maxDenom != 0 && maxDenom <= scale )
1045 initialRule->
appendChild(
new Rule( symbol->
clone(), oldScale, scale, QString(), QString(
"%1 - %2" ).arg( oldScale ).arg( scale ) ) );
1049 initialRule->
appendChild(
new Rule( symbol->
clone(), oldScale, maxDenom, QString(), QString(
"%1 - %2" ).arg( oldScale ).arg( maxDenom ) ) );
1054 QString msg(
"Rule-based renderer:\n" );
1076 if ( renderer->
type() ==
"RuleRenderer" )
1081 if ( renderer->
type() ==
"singleSymbol" )
1084 if ( !singleSymbolRenderer )
1092 if ( renderer->
type() ==
"categorizedSymbol" )
1095 if ( !categorizedRenderer )
1103 for (
int i = 0; i < categorizedRenderer->
categories().size(); ++i )
1105 category = categorizedRenderer->
categories().value( i );
1112 if ( QVariant( category.
value() ).convert( QVariant::Double ) )
1114 value = category.
value().toString();
1118 value =
"'" + category.
value().toString() +
"'";
1122 if ( value ==
"''" )
1124 expression =
"ELSE";
1128 expression = categorizedRenderer->
classAttribute() +
" = " + value;
1146 if ( renderer->
type() ==
"graduatedSymbol" )
1150 if ( !graduatedRenderer )
1157 for (
int i = 0; i < graduatedRenderer->
ranges().size();++i )
1159 range = graduatedRenderer->
ranges().value( i );
1164 expression = graduatedRenderer->
classAttribute() +
" >= " + QString::number( range.
lowerValue(),
'f' ) +
" AND " + \
1169 expression = graduatedRenderer->
classAttribute() +
" > " + QString::number( range.
lowerValue(),
'f' ) +
" AND " + \
1189 if ( renderer->
type() ==
"pointDisplacement" )
1192 if ( pointDisplacementRenderer )
1195 if ( renderer->
type() ==
"invertedPolygonRenderer" )
1198 if ( invertedPolygonRenderer )
1207 QString sizeExpression;
1208 switch ( symbol->
type() )
1214 if ( ! sizeScaleField.isNull() )
1216 sizeExpression = QString(
"%1*(%2)" ).arg( msl->
size() ).arg( sizeScaleField );
1219 if ( ! rotationField.isNull() )
1226 if ( ! sizeScaleField.isNull() )
1233 sizeExpression = QString(
"%1*(%2)" ).arg( lsl->
width() ).arg( sizeScaleField );
1242 sizeExpression = QString(
"%1*(%2)" ).arg( msl->
size() ).arg( sizeScaleField );