00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #include "qgsrulebasedrendererv2.h"
00017 #include "qgssymbollayerv2.h"
00018 #include "qgsexpression.h"
00019 #include "qgssymbollayerv2utils.h"
00020 #include "qgsrendercontext.h"
00021 #include "qgsvectorlayer.h"
00022 #include "qgslogger.h"
00023
00024 #include <QSet>
00025
00026 #include <QDomDocument>
00027 #include <QDomElement>
00028
00029
00030
00031 QgsRuleBasedRendererV2::Rule::Rule( QgsSymbolV2* symbol, int scaleMinDenom, int scaleMaxDenom, QString filterExp, QString label, QString description )
00032 : mParent( NULL ), mSymbol( symbol ),
00033 mScaleMinDenom( scaleMinDenom ), mScaleMaxDenom( scaleMaxDenom ),
00034 mFilterExp( filterExp ), mLabel( label ), mDescription( description ),
00035 mFilter( NULL )
00036 {
00037 initFilter();
00038 }
00039
00040 QgsRuleBasedRendererV2::Rule::~Rule()
00041 {
00042 delete mSymbol;
00043 delete mFilter;
00044 qDeleteAll( mChildren );
00045
00046 }
00047
00048 void QgsRuleBasedRendererV2::Rule::initFilter()
00049 {
00050 if ( !mFilterExp.isEmpty() )
00051 {
00052 delete mFilter;
00053 mFilter = new QgsExpression( mFilterExp );
00054 }
00055 else
00056 {
00057 mFilter = NULL;
00058 }
00059 }
00060
00061 QString QgsRuleBasedRendererV2::Rule::dump( int offset ) const
00062 {
00063 QString off;
00064 off.fill( QChar( ' ' ), offset );
00065 QString symbolDump = ( mSymbol ? mSymbol->dump() : QString( "[]" ) );
00066 QString msg = off + QString( "RULE %1 - scale [%2,%3] - filter %4 - symbol %5\n" )
00067 .arg( mLabel ).arg( mScaleMinDenom ).arg( mScaleMaxDenom )
00068 .arg( mFilterExp ).arg( symbolDump );
00069
00070 QStringList lst;
00071 foreach( Rule* rule, mChildren )
00072 {
00073 lst.append( rule->dump( offset + 2 ) );
00074 }
00075 msg += lst.join( "\n" );
00076 return msg;
00077 }
00078
00079 QSet<QString> QgsRuleBasedRendererV2::Rule::usedAttributes()
00080 {
00081
00082 QSet<QString> attrs;
00083 if ( mFilter )
00084 attrs.unite( mFilter->referencedColumns().toSet() );
00085 if ( mSymbol )
00086 attrs.unite( mSymbol->usedAttributes() );
00087
00088
00089 for ( RuleList::iterator it = mChildren.begin(); it != mChildren.end(); ++it )
00090 {
00091 Rule* rule = *it;
00092 attrs.unite( rule->usedAttributes() );
00093 }
00094 return attrs;
00095 }
00096
00097 QgsSymbolV2List QgsRuleBasedRendererV2::Rule::symbols()
00098 {
00099 QgsSymbolV2List lst;
00100 if ( mSymbol )
00101 lst.append( mSymbol );
00102
00103 for ( RuleList::iterator it = mChildren.begin(); it != mChildren.end(); ++it )
00104 {
00105 Rule* rule = *it;
00106 lst += rule->symbols();
00107 }
00108 return lst;
00109 }
00110
00111 void QgsRuleBasedRendererV2::Rule::setSymbol( QgsSymbolV2* sym )
00112 {
00113 delete mSymbol;
00114 mSymbol = sym;
00115 }
00116
00117 QgsLegendSymbolList QgsRuleBasedRendererV2::Rule::legendSymbolItems()
00118 {
00119 QgsLegendSymbolList lst;
00120 if ( mSymbol )
00121 lst << qMakePair( mLabel, mSymbol );
00122
00123 for ( RuleList::iterator it = mChildren.begin(); it != mChildren.end(); ++it )
00124 {
00125 Rule* rule = *it;
00126 lst << rule->legendSymbolItems();
00127 }
00128 return lst;
00129 }
00130
00131
00132 bool QgsRuleBasedRendererV2::Rule::isFilterOK( QgsFeature& f ) const
00133 {
00134 if ( ! mFilter )
00135 return true;
00136
00137 QVariant res = mFilter->evaluate( &f );
00138 return res.toInt() != 0;
00139 }
00140
00141 bool QgsRuleBasedRendererV2::Rule::isScaleOK( double scale ) const
00142 {
00143 if ( mScaleMinDenom == 0 && mScaleMaxDenom == 0 )
00144 return true;
00145 if ( mScaleMinDenom != 0 && mScaleMinDenom > scale )
00146 return false;
00147 if ( mScaleMaxDenom != 0 && mScaleMaxDenom < scale )
00148 return false;
00149 return true;
00150 }
00151
00152 QgsRuleBasedRendererV2::Rule* QgsRuleBasedRendererV2::Rule::clone() const
00153 {
00154 QgsSymbolV2* sym = mSymbol ? mSymbol->clone() : NULL;
00155 Rule* newrule = new Rule( sym, mScaleMinDenom, mScaleMaxDenom, mFilterExp, mLabel, mDescription );
00156
00157 foreach( Rule* rule, mChildren )
00158 newrule->appendChild( rule->clone() );
00159 return newrule;
00160 }
00161
00162 QDomElement QgsRuleBasedRendererV2::Rule::save( QDomDocument& doc, QgsSymbolV2Map& symbolMap )
00163 {
00164 QDomElement ruleElem = doc.createElement( "rule" );
00165
00166 if ( mSymbol )
00167 {
00168 int symbolIndex = symbolMap.size();
00169 symbolMap[QString::number( symbolIndex )] = mSymbol;
00170 ruleElem.setAttribute( "symbol", symbolIndex );
00171 }
00172 if ( !mFilterExp.isEmpty() )
00173 ruleElem.setAttribute( "filter", mFilterExp );
00174 if ( mScaleMinDenom != 0 )
00175 ruleElem.setAttribute( "scalemindenom", mScaleMinDenom );
00176 if ( mScaleMaxDenom != 0 )
00177 ruleElem.setAttribute( "scalemaxdenom", mScaleMaxDenom );
00178 if ( !mLabel.isEmpty() )
00179 ruleElem.setAttribute( "label", mLabel );
00180 if ( !mDescription.isEmpty() )
00181 ruleElem.setAttribute( "description", mDescription );
00182
00183 for ( RuleList::iterator it = mChildren.begin(); it != mChildren.end(); ++it )
00184 {
00185 Rule* rule = *it;
00186 ruleElem.appendChild( rule->save( doc, symbolMap ) );
00187 }
00188 return ruleElem;
00189 }
00190
00191 void QgsRuleBasedRendererV2::Rule::toSld( QDomDocument& doc, QDomElement &element, QgsStringMap props )
00192 {
00193
00194 if ( symbols().isEmpty() )
00195 return;
00196
00197 if ( !mFilterExp.isEmpty() )
00198 {
00199 if ( !props.value( "filter", "" ).isEmpty() )
00200 props[ "filter" ] += " AND ";
00201 props[ "filter" ] += mFilterExp;
00202 }
00203
00204 if ( mScaleMinDenom != 0 )
00205 {
00206 bool ok;
00207 int parentScaleMinDenom = props.value( "scaleMinDenom", "0" ).toInt( &ok );
00208 if ( !ok || parentScaleMinDenom <= 0 )
00209 props[ "scaleMinDenom" ] = QString::number( mScaleMinDenom );
00210 else
00211 props[ "scaleMinDenom" ] = QString::number( qMax( parentScaleMinDenom, mScaleMinDenom ) );
00212 }
00213
00214 if ( mScaleMaxDenom != 0 )
00215 {
00216 bool ok;
00217 int parentScaleMaxDenom = props.value( "scaleMaxDenom", "0" ).toInt( &ok );
00218 if ( !ok || parentScaleMaxDenom <= 0 )
00219 props[ "scaleMaxDenom" ] = QString::number( mScaleMaxDenom );
00220 else
00221 props[ "scaleMaxDenom" ] = QString::number( qMin( parentScaleMaxDenom, mScaleMaxDenom ) );
00222 }
00223
00224 if ( mSymbol )
00225 {
00226 QDomElement ruleElem = doc.createElement( "se:Rule" );
00227 element.appendChild( ruleElem );
00228
00229 QDomElement nameElem = doc.createElement( "se:Name" );
00230 nameElem.appendChild( doc.createTextNode( mLabel ) );
00231 ruleElem.appendChild( nameElem );
00232
00233 if ( !mDescription.isEmpty() )
00234 {
00235 QDomElement descrElem = doc.createElement( "se:Description" );
00236 QDomElement abstractElem = doc.createElement( "se:Abstract" );
00237 abstractElem.appendChild( doc.createTextNode( mDescription ) );
00238 descrElem.appendChild( abstractElem );
00239 ruleElem.appendChild( descrElem );
00240 }
00241
00242 if ( !props.value( "filter", "" ).isEmpty() )
00243 {
00244 QDomElement filterElem = doc.createElement( "ogc:Filter" );
00245 QgsSymbolLayerV2Utils::createFunctionElement( doc, filterElem, props.value( "filter", "" ) );
00246 ruleElem.appendChild( filterElem );
00247 }
00248
00249 if ( !props.value( "scaleMinDenom", "" ).isEmpty() )
00250 {
00251 QDomElement scaleMinDenomElem = doc.createElement( "se:MinScaleDenominator" );
00252 scaleMinDenomElem.appendChild( doc.createTextNode( props.value( "scaleMinDenom", "" ) ) );
00253 ruleElem.appendChild( scaleMinDenomElem );
00254 }
00255
00256 if ( !props.value( "scaleMaxDenom", "" ).isEmpty() )
00257 {
00258 QDomElement scaleMaxDenomElem = doc.createElement( "se:MaxScaleDenominator" );
00259 scaleMaxDenomElem.appendChild( doc.createTextNode( props.value( "scaleMaxDenom", "" ) ) );
00260 ruleElem.appendChild( scaleMaxDenomElem );
00261 }
00262
00263 mSymbol->toSld( doc, ruleElem, props );
00264 }
00265
00266
00267 for ( RuleList::iterator it = mChildren.begin(); it != mChildren.end(); ++it )
00268 {
00269 ( *it )->toSld( doc, element, props );
00270 }
00271 }
00272
00273 bool QgsRuleBasedRendererV2::Rule::startRender( QgsRenderContext& context, const QgsVectorLayer *vlayer )
00274 {
00275 mActiveChildren.clear();
00276
00277
00278 if ( !isScaleOK( context.rendererScale() ) )
00279 return false;
00280
00281
00282 if ( mFilter )
00283 mFilter->prepare( vlayer->pendingFields() );
00284 if ( mSymbol )
00285 mSymbol->startRender( context, vlayer );
00286
00287
00288
00289 for ( RuleList::iterator it = mChildren.begin(); it != mChildren.end(); ++it )
00290 {
00291 Rule* rule = *it;
00292 if ( rule->startRender( context, vlayer ) )
00293 {
00294
00295 mActiveChildren.append( rule );
00296 }
00297 }
00298 return true;
00299 }
00300
00301 QSet<int> QgsRuleBasedRendererV2::Rule::collectZLevels()
00302 {
00303 QSet<int> symbolZLevelsSet;
00304
00305
00306 if ( mSymbol )
00307 {
00308
00309 for ( int i = 0; i < mSymbol->symbolLayerCount(); i++ )
00310 {
00311 symbolZLevelsSet.insert( mSymbol->symbolLayer( i )->renderingPass() );
00312 }
00313 }
00314
00315
00316 QList<Rule*>::iterator it;
00317 for ( it = mActiveChildren.begin(); it != mActiveChildren.end(); ++it )
00318 {
00319 Rule* rule = *it;
00320 symbolZLevelsSet.unite( rule->collectZLevels() );
00321 }
00322 return symbolZLevelsSet;
00323 }
00324
00325 void QgsRuleBasedRendererV2::Rule::setNormZLevels( const QMap<int, int>& zLevelsToNormLevels )
00326 {
00327 if ( mSymbol )
00328 {
00329 for ( int i = 0; i < mSymbol->symbolLayerCount(); i++ )
00330 {
00331 int normLevel = zLevelsToNormLevels.value( mSymbol->symbolLayer( i )->renderingPass() );
00332 mSymbolNormZLevels.append( normLevel );
00333 }
00334 }
00335
00336
00337 for ( QList<Rule*>::iterator it = mActiveChildren.begin(); it != mActiveChildren.end(); ++it )
00338 {
00339 Rule* rule = *it;
00340 rule->setNormZLevels( zLevelsToNormLevels );
00341 }
00342 }
00343
00344
00345 bool QgsRuleBasedRendererV2::Rule::renderFeature( QgsRuleBasedRendererV2::FeatureToRender& featToRender, QgsRenderContext& context, QgsRuleBasedRendererV2::RenderQueue& renderQueue )
00346 {
00347 if ( !isFilterOK( featToRender.feat ) )
00348 return false;
00349
00350 bool rendered = false;
00351
00352
00353 if ( mSymbol )
00354 {
00355
00356 foreach( int normZLevel, mSymbolNormZLevels )
00357 {
00358
00359 renderQueue[normZLevel].jobs.append( new RenderJob( featToRender, mSymbol ) );
00360 }
00361 rendered = true;
00362 }
00363
00364
00365 for ( QList<Rule*>::iterator it = mActiveChildren.begin(); it != mActiveChildren.end(); ++it )
00366 {
00367 Rule* rule = *it;
00368 rendered |= rule->renderFeature( featToRender, context, renderQueue );
00369 }
00370 return rendered;
00371 }
00372
00373 bool QgsRuleBasedRendererV2::Rule::willRenderFeature( QgsFeature& feat )
00374 {
00375 if ( !isFilterOK( feat ) )
00376 return false;
00377 if ( mSymbol )
00378 return true;
00379
00380 for ( QList<Rule*>::iterator it = mActiveChildren.begin(); it != mActiveChildren.end(); ++it )
00381 {
00382 Rule* rule = *it;
00383 if ( rule->willRenderFeature( feat ) )
00384 return true;
00385 }
00386 return false;
00387 }
00388
00389 QgsSymbolV2List QgsRuleBasedRendererV2::Rule::symbolsForFeature( QgsFeature& feat )
00390 {
00391 QgsSymbolV2List lst;
00392 if ( !isFilterOK( feat ) )
00393 return lst;
00394 if ( mSymbol )
00395 lst.append( mSymbol );
00396
00397 for ( QList<Rule*>::iterator it = mActiveChildren.begin(); it != mActiveChildren.end(); ++it )
00398 {
00399 Rule* rule = *it;
00400 lst += rule->symbolsForFeature( feat );
00401 }
00402 return lst;
00403 }
00404
00405
00406 void QgsRuleBasedRendererV2::Rule::stopRender( QgsRenderContext& context )
00407 {
00408 if ( mSymbol )
00409 mSymbol->stopRender( context );
00410
00411 for ( QList<Rule*>::iterator it = mActiveChildren.begin(); it != mActiveChildren.end(); ++it )
00412 {
00413 Rule* rule = *it;
00414 rule->stopRender( context );
00415 }
00416
00417 mActiveChildren.clear();
00418 mSymbolNormZLevels.clear();
00419 }
00420
00421 QgsRuleBasedRendererV2::Rule* QgsRuleBasedRendererV2::Rule::create( QDomElement& ruleElem, QgsSymbolV2Map& symbolMap )
00422 {
00423 QString symbolIdx = ruleElem.attribute( "symbol" );
00424 QgsSymbolV2* symbol = NULL;
00425 if ( !symbolIdx.isEmpty() )
00426 {
00427 if ( symbolMap.contains( symbolIdx ) )
00428 {
00429 symbol = symbolMap.take( symbolIdx );
00430 }
00431 else
00432 {
00433 QgsDebugMsg( "symbol for rule " + symbolIdx + " not found!" );
00434 }
00435 }
00436
00437 QString filterExp = ruleElem.attribute( "filter" );
00438 QString label = ruleElem.attribute( "label" );
00439 QString description = ruleElem.attribute( "description" );
00440 int scaleMinDenom = ruleElem.attribute( "scalemindenom", "0" ).toInt();
00441 int scaleMaxDenom = ruleElem.attribute( "scalemaxdenom", "0" ).toInt();
00442 Rule* rule = new Rule( symbol, scaleMinDenom, scaleMaxDenom, filterExp, label, description );
00443
00444 QDomElement childRuleElem = ruleElem.firstChildElement( "rule" );
00445 while ( !childRuleElem.isNull() )
00446 {
00447 Rule* childRule = create( childRuleElem, symbolMap );
00448 if ( childRule )
00449 {
00450 rule->appendChild( childRule );
00451 }
00452 else
00453 {
00454 QgsDebugMsg( "failed to init a child rule!" );
00455 }
00456 childRuleElem = childRuleElem.nextSiblingElement( "rule" );
00457 }
00458
00459 return rule;
00460 }
00461
00462 QgsRuleBasedRendererV2::Rule* QgsRuleBasedRendererV2::Rule::createFromSld( QDomElement& ruleElem, QGis::GeometryType geomType )
00463 {
00464 if ( ruleElem.localName() != "Rule" )
00465 {
00466 QgsDebugMsg( QString( "invalid element: Rule element expected, %1 found!" ).arg( ruleElem.tagName() ) );
00467 return NULL;
00468 }
00469
00470 QString label, description, filterExp;
00471 int scaleMinDenom = 0, scaleMaxDenom = 0;
00472 QgsSymbolLayerV2List layers;
00473
00474
00475 QDomElement childElem = ruleElem.firstChildElement();
00476 while ( !childElem.isNull() )
00477 {
00478 if ( childElem.localName() == "Name" )
00479 {
00480 label = childElem.firstChild().nodeValue();
00481 }
00482 else if ( childElem.localName() == "Description" )
00483 {
00484
00485
00486 QDomElement abstractElem = childElem.firstChildElement( "Abstract" );
00487 QDomElement titleElem = childElem.firstChildElement( "Title" );
00488 if ( !abstractElem.isNull() )
00489 {
00490 description = abstractElem.firstChild().nodeValue();
00491 }
00492 else if ( !titleElem.isNull() && description.isEmpty() )
00493 {
00494 description = titleElem.firstChild().nodeValue();
00495 }
00496 }
00497 else if ( childElem.localName() == "Abstract" )
00498 {
00499
00500 description = childElem.firstChild().nodeValue();
00501 }
00502 else if ( childElem.localName() == "Title" )
00503 {
00504
00505 if ( description.isEmpty() )
00506 description = childElem.firstChild().nodeValue();
00507 }
00508 else if ( childElem.localName() == "Filter" )
00509 {
00510 QgsExpression *filter = QgsExpression::createFromOgcFilter( childElem );
00511 if ( filter )
00512 {
00513 if ( filter->hasParserError() )
00514 {
00515 QgsDebugMsg( "parser error: " + filter->parserErrorString() );
00516 }
00517 else
00518 {
00519 filterExp = filter->dump();
00520 }
00521 delete filter;
00522 }
00523 }
00524 else if ( childElem.localName() == "MinScaleDenominator" )
00525 {
00526 bool ok;
00527 int v = childElem.firstChild().nodeValue().toInt( &ok );
00528 if ( ok )
00529 scaleMinDenom = v;
00530 }
00531 else if ( childElem.localName() == "MaxScaleDenominator" )
00532 {
00533 bool ok;
00534 int v = childElem.firstChild().nodeValue().toInt( &ok );
00535 if ( ok )
00536 scaleMaxDenom = v;
00537 }
00538 else if ( childElem.localName().endsWith( "Symbolizer" ) )
00539 {
00540
00541 QgsSymbolLayerV2Utils::createSymbolLayerV2ListFromSld( childElem, geomType, layers );
00542 }
00543
00544 childElem = childElem.nextSiblingElement();
00545 }
00546
00547
00548 QgsSymbolV2 *symbol = 0;
00549 if ( layers.size() > 0 )
00550 {
00551 switch ( geomType )
00552 {
00553 case QGis::Line:
00554 symbol = new QgsLineSymbolV2( layers );
00555 break;
00556
00557 case QGis::Polygon:
00558 symbol = new QgsFillSymbolV2( layers );
00559 break;
00560
00561 case QGis::Point:
00562 symbol = new QgsMarkerSymbolV2( layers );
00563 break;
00564
00565 default:
00566 QgsDebugMsg( QString( "invalid geometry type: found %1" ).arg( geomType ) );
00567 return NULL;
00568 }
00569 }
00570
00571
00572 return new Rule( symbol, scaleMinDenom, scaleMaxDenom, filterExp, label, description );
00573 }
00574
00575
00577
00578 QgsRuleBasedRendererV2::QgsRuleBasedRendererV2( QgsRuleBasedRendererV2::Rule* root )
00579 : QgsFeatureRendererV2( "RuleRenderer" ), mRootRule( root )
00580 {
00581 }
00582
00583 QgsRuleBasedRendererV2::QgsRuleBasedRendererV2( QgsSymbolV2* defaultSymbol )
00584 : QgsFeatureRendererV2( "RuleRenderer" )
00585 {
00586 mRootRule = new Rule( NULL );
00587 mRootRule->appendChild( new Rule( defaultSymbol ) );
00588 }
00589
00590 QgsRuleBasedRendererV2::~QgsRuleBasedRendererV2()
00591 {
00592 delete mRootRule;
00593 }
00594
00595
00596 QgsSymbolV2* QgsRuleBasedRendererV2::symbolForFeature( QgsFeature& )
00597 {
00598
00599 return 0;
00600 }
00601
00602 bool QgsRuleBasedRendererV2::renderFeature( QgsFeature& feature,
00603 QgsRenderContext& context,
00604 int layer,
00605 bool selected,
00606 bool drawVertexMarker )
00607 {
00608 Q_UNUSED( layer );
00609
00610 int flags = ( selected ? FeatIsSelected : 0 ) | ( drawVertexMarker ? FeatDrawMarkers : 0 );
00611 mCurrentFeatures.append( FeatureToRender( feature, flags ) );
00612
00613
00614 return mRootRule->renderFeature( mCurrentFeatures.last(), context, mRenderQueue );
00615 }
00616
00617
00618 void QgsRuleBasedRendererV2::startRender( QgsRenderContext& context, const QgsVectorLayer *vlayer )
00619 {
00620
00621 mRootRule->startRender( context, vlayer );
00622
00623 QSet<int> symbolZLevelsSet = mRootRule->collectZLevels();
00624
00625
00626
00627 QMap<int, int> zLevelsToNormLevels;
00628 int maxNormLevel = -1;
00629 foreach( int zLevel, symbolZLevelsSet.toList() )
00630 {
00631 zLevelsToNormLevels[zLevel] = ++maxNormLevel;
00632 mRenderQueue.append( RenderLevel( zLevel ) );
00633 QgsDebugMsg( QString( "zLevel %1 -> %2" ).arg( zLevel ).arg( maxNormLevel ) );
00634 }
00635
00636 mRootRule->setNormZLevels( zLevelsToNormLevels );
00637 }
00638
00639 void QgsRuleBasedRendererV2::stopRender( QgsRenderContext& context )
00640 {
00641
00642
00643
00644
00645
00646 foreach( const RenderLevel& level, mRenderQueue )
00647 {
00648
00649
00650 foreach( const RenderJob* job, level.jobs )
00651 {
00652
00653
00654 QgsSymbolV2* s = job->symbol;
00655 int count = s->symbolLayerCount();
00656 for ( int i = 0; i < count; i++ )
00657 {
00658
00659
00660
00661 if ( s->symbolLayer( i )->renderingPass() == level.zIndex )
00662 {
00663 int flags = job->ftr.flags;
00664 renderFeatureWithSymbol( job->ftr.feat, job->symbol, context, i, flags & FeatIsSelected, flags & FeatDrawMarkers );
00665 }
00666 }
00667 }
00668 }
00669
00670
00671 mCurrentFeatures.clear();
00672
00673
00674 mRenderQueue.clear();
00675
00676
00677 mRootRule->stopRender( context );
00678 }
00679
00680 QList<QString> QgsRuleBasedRendererV2::usedAttributes()
00681 {
00682 QSet<QString> attrs = mRootRule->usedAttributes();
00683 return attrs.values();
00684 }
00685
00686 QgsFeatureRendererV2* QgsRuleBasedRendererV2::clone()
00687 {
00688 QgsRuleBasedRendererV2* r = new QgsRuleBasedRendererV2( mRootRule->clone() );
00689
00690 r->setUsingSymbolLevels( usingSymbolLevels() );
00691 setUsingSymbolLevels( usingSymbolLevels() );
00692 return r;
00693 }
00694
00695 void QgsRuleBasedRendererV2::toSld( QDomDocument& doc, QDomElement &element ) const
00696 {
00697 mRootRule->toSld( doc, element, QgsStringMap() );
00698 }
00699
00700
00701 QgsSymbolV2List QgsRuleBasedRendererV2::symbols()
00702 {
00703 return mRootRule->symbols();
00704 }
00705
00706 QDomElement QgsRuleBasedRendererV2::save( QDomDocument& doc )
00707 {
00708 QDomElement rendererElem = doc.createElement( RENDERER_TAG_NAME );
00709 rendererElem.setAttribute( "type", "RuleRenderer" );
00710 rendererElem.setAttribute( "symbollevels", ( mUsingSymbolLevels ? "1" : "0" ) );
00711
00712 QgsSymbolV2Map symbols;
00713
00714 QDomElement rulesElem = mRootRule->save( doc, symbols );
00715 rulesElem.setTagName( "rules" );
00716 rendererElem.appendChild( rulesElem );
00717
00718 QDomElement symbolsElem = QgsSymbolLayerV2Utils::saveSymbols( symbols, "symbols", doc );
00719 rendererElem.appendChild( symbolsElem );
00720
00721 return rendererElem;
00722 }
00723
00724 QgsLegendSymbologyList QgsRuleBasedRendererV2::legendSymbologyItems( QSize iconSize )
00725 {
00726 QgsLegendSymbologyList lst;
00727 QgsLegendSymbolList items = legendSymbolItems();
00728 for ( QgsLegendSymbolList::iterator it = items.begin(); it != items.end(); it++ )
00729 {
00730 QPair<QString, QgsSymbolV2*> pair = *it;
00731 QPixmap pix = QgsSymbolLayerV2Utils::symbolPreviewPixmap( pair.second, iconSize );
00732 lst << qMakePair( pair.first, pix );
00733 }
00734 return lst;
00735 }
00736
00737 QgsLegendSymbolList QgsRuleBasedRendererV2::legendSymbolItems()
00738 {
00739 return mRootRule->legendSymbolItems();
00740 }
00741
00742
00743 QgsFeatureRendererV2* QgsRuleBasedRendererV2::create( QDomElement& element )
00744 {
00745
00746 QDomElement symbolsElem = element.firstChildElement( "symbols" );
00747 if ( symbolsElem.isNull() )
00748 return NULL;
00749
00750 QgsSymbolV2Map symbolMap = QgsSymbolLayerV2Utils::loadSymbols( symbolsElem );
00751
00752 QDomElement rulesElem = element.firstChildElement( "rules" );
00753
00754 Rule* root = Rule::create( rulesElem, symbolMap );
00755 if ( root == NULL )
00756 return NULL;
00757
00758 QgsRuleBasedRendererV2* r = new QgsRuleBasedRendererV2( root );
00759
00760
00761 QgsSymbolLayerV2Utils::clearSymbolMap( symbolMap );
00762
00763 return r;
00764 }
00765
00766 QgsFeatureRendererV2* QgsRuleBasedRendererV2::createFromSld( QDomElement& element, QGis::GeometryType geomType )
00767 {
00768
00769 Rule* root = 0;
00770
00771 QDomElement ruleElem = element.firstChildElement( "Rule" );
00772 while ( !ruleElem.isNull() )
00773 {
00774 Rule *child = Rule::createFromSld( ruleElem, geomType );
00775 if ( child )
00776 {
00777
00778 if ( !root )
00779 root = new Rule( 0 );
00780
00781 root->appendChild( child );
00782 }
00783
00784 ruleElem = ruleElem.nextSiblingElement( "Rule" );
00785 }
00786
00787 if ( !root )
00788 {
00789
00790 return NULL;
00791 }
00792
00793
00794 return new QgsRuleBasedRendererV2( root );
00795 }
00796
00797 #include "qgscategorizedsymbolrendererv2.h"
00798 #include "qgsgraduatedsymbolrendererv2.h"
00799
00800 void QgsRuleBasedRendererV2::refineRuleCategories( QgsRuleBasedRendererV2::Rule* initialRule, QgsCategorizedSymbolRendererV2* r )
00801 {
00802 foreach( const QgsRendererCategoryV2& cat, r->categories() )
00803 {
00804 QString filter = QString( "%1 = '%2'" ).arg( r->classAttribute() ).arg( cat.value().toString() );
00805 QString label = filter;
00806 initialRule->appendChild( new Rule( cat.symbol()->clone(), 0, 0, filter, label ) );
00807 }
00808 }
00809
00810 void QgsRuleBasedRendererV2::refineRuleRanges( QgsRuleBasedRendererV2::Rule* initialRule, QgsGraduatedSymbolRendererV2* r )
00811 {
00812 foreach( const QgsRendererRangeV2& rng, r->ranges() )
00813 {
00814 QString filter = QString( "%1 >= '%2' AND %1 <= '%3'" ).arg( r->classAttribute() ).arg( rng.lowerValue() ).arg( rng.upperValue() );
00815 QString label = filter;
00816 initialRule->appendChild( new Rule( rng.symbol()->clone(), 0, 0, filter, label ) );
00817 }
00818 }
00819
00820 void QgsRuleBasedRendererV2::refineRuleScales( QgsRuleBasedRendererV2::Rule* initialRule, QList<int> scales )
00821 {
00822 qSort( scales );
00823 int oldScale = initialRule->scaleMinDenom();
00824 int maxDenom = initialRule->scaleMaxDenom();
00825 QgsSymbolV2* symbol = initialRule->symbol();
00826 foreach( int scale, scales )
00827 {
00828 if ( initialRule->scaleMinDenom() >= scale )
00829 continue;
00830 if ( maxDenom != 0 && maxDenom <= scale )
00831 break;
00832 initialRule->appendChild( new Rule( symbol->clone(), oldScale, scale, QString(), QString( "%1 - %2" ).arg( oldScale ).arg( scale ) ) );
00833 oldScale = scale;
00834 }
00835
00836 initialRule->appendChild( new Rule( symbol->clone(), oldScale, maxDenom, QString(), QString( "%1 - %2" ).arg( oldScale ).arg( maxDenom ) ) );
00837 }
00838
00839 QString QgsRuleBasedRendererV2::dump()
00840 {
00841 QString msg( "Rule-based renderer:\n" );
00842 msg += mRootRule->dump();
00843 return msg;
00844 }
00845
00846 bool QgsRuleBasedRendererV2::willRenderFeature( QgsFeature& feat )
00847 {
00848 return mRootRule->willRenderFeature( feat );
00849 }
00850
00851 QgsSymbolV2List QgsRuleBasedRendererV2::symbolsForFeature( QgsFeature& feat )
00852 {
00853 return mRootRule->symbolsForFeature( feat );
00854 }