27 #include <QDomDocument>
28 #include <QDomElement>
33 : mParent( NULL ), mSymbol( symbol ),
34 mScaleMinDenom( scaleMinDenom ), mScaleMaxDenom( scaleMaxDenom ),
35 mFilterExp( filterExp ), mLabel( label ), mDescription( description ),
45 qDeleteAll( mChildren );
51 if ( !mFilterExp.isEmpty() )
65 off.fill( QChar(
' ' ), offset );
66 QString symbolDump = ( mSymbol ? mSymbol->dump() : QString(
"[]" ) );
67 QString msg = off + QString(
"RULE %1 - scale [%2,%3] - filter %4 - symbol %5\n" )
68 .arg( mLabel ).arg( mScaleMinDenom ).arg( mScaleMaxDenom )
69 .arg( mFilterExp ).arg( symbolDump );
72 foreach (
Rule* rule, mChildren )
74 lst.append( rule->
dump( offset + 2 ) );
76 msg += lst.join(
"\n" );
85 attrs.unite( mFilter->referencedColumns().toSet() );
87 attrs.unite( mSymbol->usedAttributes() );
90 for ( RuleList::iterator it = mChildren.begin(); it != mChildren.end(); ++it )
102 lst.append( mSymbol );
104 for ( RuleList::iterator it = mChildren.begin(); it != mChildren.end(); ++it )
122 lst << qMakePair( mLabel, mSymbol );
124 for ( RuleList::iterator it = mChildren.begin(); it != mChildren.end(); ++it )
138 QVariant res = mFilter->evaluate( &f );
139 return res.toInt() != 0;
146 if ( mScaleMinDenom == 0 && mScaleMaxDenom == 0 )
148 if ( mScaleMinDenom != 0 && mScaleMinDenom > scale )
150 if ( mScaleMaxDenom != 0 && mScaleMaxDenom < scale )
158 Rule* newrule =
new Rule( sym, mScaleMinDenom, mScaleMaxDenom, mFilterExp, mLabel, mDescription );
160 foreach (
Rule* rule, mChildren )
167 QDomElement ruleElem = doc.createElement(
"rule" );
171 int symbolIndex = symbolMap.size();
172 symbolMap[QString::number( symbolIndex )] = mSymbol;
173 ruleElem.setAttribute(
"symbol", symbolIndex );
175 if ( !mFilterExp.isEmpty() )
176 ruleElem.setAttribute(
"filter", mFilterExp );
177 if ( mScaleMinDenom != 0 )
178 ruleElem.setAttribute(
"scalemindenom", mScaleMinDenom );
179 if ( mScaleMaxDenom != 0 )
180 ruleElem.setAttribute(
"scalemaxdenom", mScaleMaxDenom );
181 if ( !mLabel.isEmpty() )
182 ruleElem.setAttribute(
"label", mLabel );
183 if ( !mDescription.isEmpty() )
184 ruleElem.setAttribute(
"description", mDescription );
186 for ( RuleList::iterator it = mChildren.begin(); it != mChildren.end(); ++it )
200 if ( !mFilterExp.isEmpty() )
202 if ( !props.value(
"filter",
"" ).isEmpty() )
203 props[
"filter" ] +=
" AND ";
204 props[
"filter" ] += mFilterExp;
207 if ( mScaleMinDenom != 0 )
210 int parentScaleMinDenom = props.value(
"scaleMinDenom",
"0" ).toInt( &ok );
211 if ( !ok || parentScaleMinDenom <= 0 )
212 props[
"scaleMinDenom" ] = QString::number( mScaleMinDenom );
214 props[
"scaleMinDenom" ] = QString::number( qMax( parentScaleMinDenom, mScaleMinDenom ) );
217 if ( mScaleMaxDenom != 0 )
220 int parentScaleMaxDenom = props.value(
"scaleMaxDenom",
"0" ).toInt( &ok );
221 if ( !ok || parentScaleMaxDenom <= 0 )
222 props[
"scaleMaxDenom" ] = QString::number( mScaleMaxDenom );
224 props[
"scaleMaxDenom" ] = QString::number( qMin( parentScaleMaxDenom, mScaleMaxDenom ) );
229 QDomElement ruleElem = doc.createElement(
"se:Rule" );
230 element.appendChild( ruleElem );
234 QDomElement nameElem = doc.createElement(
"se:Name" );
235 nameElem.appendChild( doc.createTextNode( mLabel ) );
236 ruleElem.appendChild( nameElem );
238 if ( !mLabel.isEmpty() || !mDescription.isEmpty() )
240 QDomElement descrElem = doc.createElement(
"se:Description" );
241 if ( !mLabel.isEmpty() )
243 QDomElement titleElem = doc.createElement(
"se:Title" );
244 titleElem.appendChild( doc.createTextNode( mLabel ) );
245 descrElem.appendChild( titleElem );
247 if ( !mDescription.isEmpty() )
249 QDomElement abstractElem = doc.createElement(
"se:Abstract" );
250 abstractElem.appendChild( doc.createTextNode( mDescription ) );
251 descrElem.appendChild( abstractElem );
253 ruleElem.appendChild( descrElem );
256 if ( !props.value(
"filter",
"" ).isEmpty() )
261 if ( !props.value(
"scaleMinDenom",
"" ).isEmpty() )
263 QDomElement scaleMinDenomElem = doc.createElement(
"se:MinScaleDenominator" );
264 scaleMinDenomElem.appendChild( doc.createTextNode( props.value(
"scaleMinDenom",
"" ) ) );
265 ruleElem.appendChild( scaleMinDenomElem );
268 if ( !props.value(
"scaleMaxDenom",
"" ).isEmpty() )
270 QDomElement scaleMaxDenomElem = doc.createElement(
"se:MaxScaleDenominator" );
271 scaleMaxDenomElem.appendChild( doc.createTextNode( props.value(
"scaleMaxDenom",
"" ) ) );
272 ruleElem.appendChild( scaleMaxDenomElem );
275 mSymbol->toSld( doc, ruleElem, props );
279 for ( RuleList::iterator it = mChildren.begin(); it != mChildren.end(); ++it )
281 ( *it )->toSld( doc, element, props );
287 mActiveChildren.clear();
297 mSymbol->startRender( context, vlayer );
301 for ( RuleList::iterator it = mChildren.begin(); it != mChildren.end(); ++it )
307 mActiveChildren.append( rule );
315 QSet<int> symbolZLevelsSet;
321 for (
int i = 0; i < mSymbol->symbolLayerCount(); i++ )
323 symbolZLevelsSet.insert( mSymbol->symbolLayer( i )->renderingPass() );
328 QList<Rule*>::iterator it;
329 for ( it = mActiveChildren.begin(); it != mActiveChildren.end(); ++it )
334 return symbolZLevelsSet;
341 for (
int i = 0; i < mSymbol->symbolLayerCount(); i++ )
343 int normLevel = zLevelsToNormLevels.value( mSymbol->symbolLayer( i )->renderingPass() );
344 mSymbolNormZLevels.append( normLevel );
349 for ( QList<Rule*>::iterator it = mActiveChildren.begin(); it != mActiveChildren.end(); ++it )
359 if ( !isFilterOK( featToRender.
feat ) )
362 bool rendered =
false;
368 foreach (
int normZLevel, mSymbolNormZLevels )
371 renderQueue[normZLevel].jobs.append(
new RenderJob( featToRender, mSymbol ) );
377 for ( QList<Rule*>::iterator it = mActiveChildren.begin(); it != mActiveChildren.end(); ++it )
380 rendered |= rule->
renderFeature( featToRender, context, renderQueue );
387 if ( !isFilterOK( feat ) )
392 for ( QList<Rule*>::iterator it = mActiveChildren.begin(); it != mActiveChildren.end(); ++it )
404 if ( !isFilterOK( feat ) )
407 lst.append( mSymbol );
409 for ( QList<Rule*>::iterator it = mActiveChildren.begin(); it != mActiveChildren.end(); ++it )
420 if ( !isFilterOK( feat ) )
426 for ( QList<Rule*>::iterator it = mActiveChildren.begin(); it != mActiveChildren.end(); ++it )
437 mSymbol->stopRender( context );
439 for ( QList<Rule*>::iterator it = mActiveChildren.begin(); it != mActiveChildren.end(); ++it )
445 mActiveChildren.clear();
446 mSymbolNormZLevels.clear();
451 QString symbolIdx = ruleElem.attribute(
"symbol" );
453 if ( !symbolIdx.isEmpty() )
455 if ( symbolMap.contains( symbolIdx ) )
457 symbol = symbolMap.take( symbolIdx );
461 QgsDebugMsg(
"symbol for rule " + symbolIdx +
" not found!" );
465 QString filterExp = ruleElem.attribute(
"filter" );
466 QString label = ruleElem.attribute(
"label" );
467 QString description = ruleElem.attribute(
"description" );
468 int scaleMinDenom = ruleElem.attribute(
"scalemindenom",
"0" ).toInt();
469 int scaleMaxDenom = ruleElem.attribute(
"scalemaxdenom",
"0" ).toInt();
470 Rule* rule =
new Rule( symbol, scaleMinDenom, scaleMaxDenom, filterExp, label, description );
472 QDomElement childRuleElem = ruleElem.firstChildElement(
"rule" );
473 while ( !childRuleElem.isNull() )
475 Rule* childRule =
create( childRuleElem, symbolMap );
484 childRuleElem = childRuleElem.nextSiblingElement(
"rule" );
492 if ( ruleElem.localName() !=
"Rule" )
494 QgsDebugMsg( QString(
"invalid element: Rule element expected, %1 found!" ).arg( ruleElem.tagName() ) );
498 QString label, description, filterExp;
499 int scaleMinDenom = 0, scaleMaxDenom = 0;
503 QDomElement childElem = ruleElem.firstChildElement();
504 while ( !childElem.isNull() )
506 if ( childElem.localName() ==
"Name" )
510 if ( label.isEmpty() )
511 label = childElem.firstChild().nodeValue();
513 else if ( childElem.localName() ==
"Description" )
516 QDomElement titleElem = childElem.firstChildElement(
"Title" );
517 if ( !titleElem.isNull() )
519 label = titleElem.firstChild().nodeValue();
522 QDomElement abstractElem = childElem.firstChildElement(
"Abstract" );
523 if ( !abstractElem.isNull() )
525 description = abstractElem.firstChild().nodeValue();
528 else if ( childElem.localName() ==
"Abstract" )
531 description = childElem.firstChild().nodeValue();
533 else if ( childElem.localName() ==
"Title" )
536 label = childElem.firstChild().nodeValue();
538 else if ( childElem.localName() ==
"Filter" )
549 filterExp = filter->
dump();
554 else if ( childElem.localName() ==
"MinScaleDenominator" )
557 int v = childElem.firstChild().nodeValue().toInt( &ok );
561 else if ( childElem.localName() ==
"MaxScaleDenominator" )
564 int v = childElem.firstChild().nodeValue().toInt( &ok );
568 else if ( childElem.localName().endsWith(
"Symbolizer" ) )
574 childElem = childElem.nextSiblingElement();
579 if ( layers.size() > 0 )
596 QgsDebugMsg( QString(
"invalid geometry type: found %1" ).arg( geomType ) );
602 return new Rule( symbol, scaleMinDenom, scaleMaxDenom, filterExp, label, description );
636 bool drawVertexMarker )
654 QList<int> symbolZLevels = symbolZLevelsSet.toList();
655 qSort( symbolZLevels );
659 QMap<int, int> zLevelsToNormLevels;
660 int maxNormLevel = -1;
661 foreach (
int zLevel, symbolZLevels )
663 zLevelsToNormLevels[zLevel] = ++maxNormLevel;
665 QgsDebugMsg( QString(
"zLevel %1 -> %2" ).arg( zLevel ).arg( maxNormLevel ) );
688 for (
int i = 0; i < count; i++ )
715 return attrs.values();
741 rendererElem.setAttribute(
"type",
"RuleRenderer" );
747 rulesElem.setTagName(
"rules" );
748 rendererElem.appendChild( rulesElem );
751 rendererElem.appendChild( symbolsElem );
760 for ( QgsLegendSymbolList::iterator it = items.begin(); it != items.end(); it++ )
762 QPair<QString, QgsSymbolV2*> pair = *it;
764 lst << qMakePair( pair.first, pix );
778 QDomElement symbolsElem = element.firstChildElement(
"symbols" );
779 if ( symbolsElem.isNull() )
784 QDomElement rulesElem = element.firstChildElement(
"rules" );
803 QDomElement ruleElem = element.firstChildElement(
"Rule" );
804 while ( !ruleElem.isNull() )
811 root =
new Rule( 0 );
816 ruleElem = ruleElem.nextSiblingElement(
"Rule" );
839 if ( cat.
value().type() == QVariant::Int )
840 value = cat.
value().toString();
841 else if ( cat.
value().type() == QVariant::Double )
844 value = QString::number( cat.
value().toDouble(),
'f', 4 );
847 QString filter = QString(
"%1 = %2" ).arg( attr ).arg( value );
848 QString label = filter;
860 QString filter = QString(
"%1 >= %2 AND %1 <= %3" ).arg( attr )
861 .arg( QString::number( rng.
lowerValue(),
'f', 4 ) )
862 .arg( QString::number( rng.
upperValue(),
'f', 4 ) );
863 QString label = filter;
874 foreach (
int scale, scales )
878 if ( maxDenom != 0 && maxDenom <= scale )
880 initialRule->
appendChild(
new Rule( symbol->
clone(), oldScale, scale, QString(), QString(
"%1 - %2" ).arg( oldScale ).arg( scale ) ) );
884 initialRule->
appendChild(
new Rule( symbol->
clone(), oldScale, maxDenom, QString(), QString(
"%1 - %2" ).arg( oldScale ).arg( maxDenom ) ) );
889 QString msg(
"Rule-based renderer:\n" );