39 QDomElement rulesElem = elem.firstChildElement( QStringLiteral(
"rules" ) );
58 , mFilterExp( filterExp )
59 , mDescription( description )
60 , mElseRule( elseRule )
68 qDeleteAll( mChildren );
74 if ( mSymbol.get() == symbol )
77 mSymbol.reset( symbol );
83 for (
Rule *
c : mChildren )
86 l +=
c->descendants();
91 void QgsRuleBased3DRenderer::Rule::initFilter()
93 if ( mElseRule || mFilterExp.compare( QLatin1String(
"ELSE" ), Qt::CaseInsensitive ) == 0 )
96 mFilter.reset(
nullptr );
98 else if ( !mFilterExp.isEmpty() )
104 mFilter.reset(
nullptr );
108 void QgsRuleBased3DRenderer::Rule::updateElseRules()
111 for ( Rule *rule : qgis::as_const( mChildren ) )
113 if ( rule->isElse() )
121 mChildren.append( rule );
122 rule->mParent =
this;
128 mChildren.insert( i, rule );
129 rule->mParent =
this;
135 delete mChildren.at( i );
136 mChildren.removeAt( i );
144 if ( key == mRuleKey )
147 for (
Rule *rule : qgis::as_const( mChildren ) )
158 if ( key == mRuleKey )
161 for (
Rule *rule : qgis::as_const( mChildren ) )
173 Rule *newrule =
new Rule( symbol, mFilterExp, mDescription );
176 for (
Rule *rule : qgis::as_const( mChildren ) )
184 QDomElement elemSymbol = ruleElem.firstChildElement( QStringLiteral(
"symbol" ) );
185 if ( !elemSymbol.isNull() )
187 QString symbolType = elemSymbol.attribute( QStringLiteral(
"type" ) );
188 if ( symbolType == QLatin1String(
"polygon" ) )
190 else if ( symbolType == QLatin1String(
"point" ) )
192 else if ( symbolType == QLatin1String(
"line" ) )
196 symbol->
readXml( elemSymbol, context );
199 QString filterExp = ruleElem.attribute( QStringLiteral(
"filter" ) );
200 QString description = ruleElem.attribute( QStringLiteral(
"description" ) );
201 QString ruleKey = ruleElem.attribute( QStringLiteral(
"key" ) );
202 Rule *rule =
new Rule( symbol, filterExp, description );
204 if ( !ruleKey.isEmpty() )
205 rule->mRuleKey = ruleKey;
207 rule->
setActive( ruleElem.attribute( QStringLiteral(
"active" ), QStringLiteral(
"1" ) ).toInt() );
209 QDomElement childRuleElem = ruleElem.firstChildElement( QStringLiteral(
"rule" ) );
210 while ( !childRuleElem.isNull() )
212 Rule *childRule = create( childRuleElem, context );
221 childRuleElem = childRuleElem.nextSiblingElement( QStringLiteral(
"rule" ) );
229 QDomElement ruleElem = doc.createElement( QStringLiteral(
"rule" ) );
233 QDomElement elemSymbol = doc.createElement( QStringLiteral(
"symbol" ) );
234 elemSymbol.setAttribute( QStringLiteral(
"type" ), mSymbol->type() );
235 mSymbol->writeXml( elemSymbol, context );
236 ruleElem.appendChild( elemSymbol );
239 if ( !mFilterExp.isEmpty() )
240 ruleElem.setAttribute( QStringLiteral(
"filter" ), mFilterExp );
241 if ( !mDescription.isEmpty() )
242 ruleElem.setAttribute( QStringLiteral(
"description" ), mDescription );
244 ruleElem.setAttribute( QStringLiteral(
"active" ), 0 );
245 ruleElem.setAttribute( QStringLiteral(
"key" ), mRuleKey );
247 for ( RuleList::const_iterator it = mChildren.constBegin(); it != mChildren.constEnd(); ++it )
261 Q_ASSERT( !handlers.value(
this ) );
262 QgsFeature3DHandler *handler =
nullptr;
263 if ( mSymbol->type() == QLatin1String(
"polygon" ) )
265 handler = Qgs3DSymbolImpl::handlerForPolygon3DSymbol(
layer, *
static_cast<QgsPolygon3DSymbol *
>( mSymbol.get() ) );
267 else if ( mSymbol->type() == QLatin1String(
"point" ) )
269 handler = Qgs3DSymbolImpl::handlerForPoint3DSymbol(
layer, *
static_cast<QgsPoint3DSymbol *
>( mSymbol.get() ) );
271 else if ( mSymbol->type() == QLatin1String(
"line" ) )
273 handler = Qgs3DSymbolImpl::handlerForLine3DSymbol(
layer, *
static_cast<QgsLine3DSymbol *
>( mSymbol.get() ) );
277 handlers[
this] = handler;
281 for (
Rule *rule : qgis::as_const( mChildren ) )
283 rule->createHandlers(
layer, handlers );
292 QgsFeature3DHandler *handler = handlers[
this];
293 if ( !handler->prepare( context, attributeNames ) )
295 handlers.remove(
this );
302 attributeNames.unite( mFilter->referencedColumns() );
303 mFilter->prepare( &context.expressionContext() );
307 for (
Rule *rule : qgis::as_const( mChildren ) )
309 rule->prepare( context, attributeNames, handlers );
315 if ( !isFilterOK( feature, context ) )
318 bool registered =
false;
321 if ( handlers.contains(
this ) && mIsActive )
323 handlers[
this]->processFeature( feature, context );
327 bool willRegisterSomething =
false;
330 for (
Rule *rule : qgis::as_const( mChildren ) )
333 if ( !rule->isElse() )
335 RegisterResult res = rule->registerFeature( feature, context, handlers );
337 willRegisterSomething |= ( res == Registered || res == Inactive );
338 registered |= willRegisterSomething;
343 if ( !willRegisterSomething )
345 for (
Rule *rule : qgis::as_const( mElseRules ) )
347 registered |= rule->registerFeature( feature, context, handlers ) != Filtered;
353 else if ( registered )
360 bool QgsRuleBased3DRenderer::Rule::isFilterOK(
QgsFeature &f, Qgs3DRenderContext &context )
const
362 if ( ! mFilter || mElseRule )
365 context.expressionContext().setFeature( f );
366 QVariant res = mFilter->evaluate( &context.expressionContext() );
367 return res.toInt() != 0;
393 Q_ASSERT( origDescendants.count() == clonedDescendants.count() );
394 for (
int i = 0; i < origDescendants.count(); ++i )
395 clonedDescendants[i]->setRuleKey( origDescendants[i]->ruleKey() );
412 return new QgsRuleBasedChunkedEntity( vl, zMin, zMax,
tilingSettings(), mRootRule, map );
417 QDomDocument doc = elem.ownerDocument();
421 QDomElement rulesElem = mRootRule->
save( doc, context );
422 rulesElem.setTagName( QStringLiteral(
"rules" ) );
423 elem.appendChild( rulesElem );