36 QDomElement rulesElem = elem.firstChildElement( QStringLiteral(
"rules" ) );
55 , mFilterExp( filterExp )
57 , mElseRule( elseRule )
65 qDeleteAll( mChildren );
71 if ( mSymbol.get() ==
symbol )
80 for (
Rule *
c : mChildren )
83 l +=
c->descendants();
88void QgsRuleBased3DRenderer::Rule::initFilter()
90 if ( mElseRule || mFilterExp.compare( QLatin1String(
"ELSE" ), Qt::CaseInsensitive ) == 0 )
93 mFilter.reset(
nullptr );
95 else if ( !mFilterExp.isEmpty() )
97 mFilter = std::make_unique<QgsExpression>( mFilterExp );
101 mFilter.reset(
nullptr );
105void QgsRuleBased3DRenderer::Rule::updateElseRules()
108 for (
Rule *rule : std::as_const( mChildren ) )
110 if ( rule->isElse() )
118 mChildren.append( rule );
119 rule->mParent =
this;
125 mChildren.insert( i, rule );
126 rule->mParent =
this;
132 delete mChildren.at( i );
133 mChildren.removeAt( i );
141 if ( key == mRuleKey )
144 for (
Rule *rule : std::as_const( mChildren ) )
146 const Rule *r = rule->findRuleByKey( key );
155 if ( key == mRuleKey )
158 for (
Rule *rule : std::as_const( mChildren ) )
160 Rule *r = rule->findRuleByKey( key );
173 for (
Rule *rule : std::as_const( mChildren ) )
181 QDomElement elemSymbol = ruleElem.firstChildElement( QStringLiteral(
"symbol" ) );
182 if ( !elemSymbol.isNull() )
184 QString symbolType = elemSymbol.attribute( QStringLiteral(
"type" ) );
187 symbol->readXml( elemSymbol, context );
190 QString filterExp = ruleElem.attribute( QStringLiteral(
"filter" ) );
191 QString
description = ruleElem.attribute( QStringLiteral(
"description" ) );
192 QString
ruleKey = ruleElem.attribute( QStringLiteral(
"key" ) );
198 rule->
setActive( ruleElem.attribute( QStringLiteral(
"active" ), QStringLiteral(
"1" ) ).toInt() );
200 QDomElement childRuleElem = ruleElem.firstChildElement( QStringLiteral(
"rule" ) );
201 while ( !childRuleElem.isNull() )
203 Rule *childRule =
create( childRuleElem, context );
212 childRuleElem = childRuleElem.nextSiblingElement( QStringLiteral(
"rule" ) );
220 QDomElement ruleElem = doc.createElement( QStringLiteral(
"rule" ) );
224 QDomElement elemSymbol = doc.createElement( QStringLiteral(
"symbol" ) );
225 elemSymbol.setAttribute( QStringLiteral(
"type" ), mSymbol->type() );
226 mSymbol->writeXml( elemSymbol, context );
227 ruleElem.appendChild( elemSymbol );
230 if ( !mFilterExp.isEmpty() )
231 ruleElem.setAttribute( QStringLiteral(
"filter" ), mFilterExp );
232 if ( !mDescription.isEmpty() )
233 ruleElem.setAttribute( QStringLiteral(
"description" ), mDescription );
235 ruleElem.setAttribute( QStringLiteral(
"active" ), 0 );
236 ruleElem.setAttribute( QStringLiteral(
"key" ), mRuleKey );
238 for ( RuleList::const_iterator it = mChildren.constBegin(); it != mChildren.constEnd(); ++it )
241 ruleElem.appendChild( rule->
save( doc, context ) );
252 Q_ASSERT( !handlers.value(
this ) );
255 handlers[
this] = handler;
259 for (
Rule *rule : std::as_const( mChildren ) )
261 rule->createHandlers(
layer, handlers );
270 QgsFeature3DHandler *handler = handlers[
this];
271 if ( !handler->prepare( context, attributeNames, chunkOrigin ) )
273 handlers.remove(
this );
280 attributeNames.unite( mFilter->referencedColumns() );
285 for (
Rule *rule : std::as_const( mChildren ) )
287 rule->prepare( context, attributeNames, chunkOrigin, handlers );
293 if ( !isFilterOK( feature, context ) )
296 bool registered =
false;
299 if ( handlers.contains(
this ) && mIsActive )
301 handlers[
this]->processFeature( feature, context );
305 bool matchedAChild =
false;
308 for (
Rule *rule : std::as_const( mChildren ) )
311 if ( !rule->isElse() )
313 const RegisterResult res = rule->registerFeature( feature, context, handlers );
316 registered |= matchedAChild;
321 if ( !matchedAChild )
323 for (
Rule *rule : std::as_const( mElseRules ) )
325 const RegisterResult res = rule->registerFeature( feature, context, handlers );
331 if ( !mIsActive || ( matchedAChild && !registered ) )
333 else if ( registered )
342 if ( !mFilter || mElseRule )
347 return res.toInt() != 0;
370 rootRule->setRuleKey( mRootRule->ruleKey() );
371 RuleList origDescendants = mRootRule->descendants();
373 Q_ASSERT( origDescendants.count() == clonedDescendants.count() );
374 for (
int i = 0; i < origDescendants.count(); ++i )
375 clonedDescendants[i]->setRuleKey( origDescendants[i]->ruleKey() );
394 constexpr double MINIMUM_VECTOR_Z_ESTIMATE = -100000;
395 constexpr double MAXIMUM_VECTOR_Z_ESTIMATE = 100000;
397 return new QgsRuleBasedChunkedEntity( map, vl, MINIMUM_VECTOR_Z_ESTIMATE, MAXIMUM_VECTOR_Z_ESTIMATE,
tilingSettings(), mRootRule );
402 QDomDocument doc = elem.ownerDocument();
406 QDomElement rulesElem = mRootRule->save( doc, context );
407 rulesElem.setTagName( QStringLiteral(
"rules" ) );
408 elem.appendChild( rulesElem );
Rendering context for preparation of 3D entities.
QgsExpressionContext & expressionContext()
Gets the expression context.
QgsAbstract3DSymbol * createSymbol(const QString &type) const
Creates a new instance of a symbol of the specified type.
QgsFeature3DHandler * createHandlerForSymbol(QgsVectorLayer *layer, const QgsAbstract3DSymbol *symbol)
Creates a feature handler for a symbol, for the specified vector layer.
Base class for all renderers that participate in 3D views.
Abstract base class for 3D symbols that are used by VectorLayer3DRenderer objects.
QgsVectorLayer3DTilingSettings tilingSettings() const
Returns tiling settings of the renderer.
void writeXmlBaseProperties(QDomElement &elem, const QgsReadWriteContext &context) const
Writes common properties of this object to DOM element.
void readXmlBaseProperties(const QDomElement &elem, const QgsReadWriteContext &context)
Reads common properties of this object from DOM element.
void copyBaseProperties(QgsAbstractVectorLayer3DRenderer *r) const
Copies common properties of this object to another object.
QgsVectorLayer * layer() const
Returns vector layer associated with the renderer.
static Qgs3DSymbolRegistry * symbol3DRegistry()
Returns registry of available 3D symbols.
void setFeature(const QgsFeature &feature)
Convenience function for setting a feature for the context.
The feature class encapsulates a single feature including its unique ID, geometry and a list of field...
A container for the context for various read/write operations on objects.
A child rule for a QgsRuleBased3DRenderer.
void insertChild(int i, QgsRuleBased3DRenderer::Rule *rule)
add child rule, take ownership, sets this as parent
const QgsRuleBased3DRenderer::Rule * findRuleByKey(const QString &key) const
Try to find a rule given its unique key.
void setSymbol(QgsAbstract3DSymbol *symbol)
Sets new symbol (or nullptr). Deletes old symbol if any.
Rule(QgsAbstract3DSymbol *symbol, const QString &filterExp=QString(), const QString &description=QString(), bool elseRule=false)
takes ownership of symbol, symbol may be nullptr
void setActive(bool state)
Sets if this rule is active.
QString ruleKey() const
Unique rule identifier (for identification of rule within labeling, used as provider ID).
void prepare(const Qgs3DRenderContext &context, QSet< QString > &attributeNames, const QgsVector3D &chunkOrigin, RuleToHandlerMap &handlers) const
call prepare() on handlers and populate attributeNames
RegisterResult
The result of registering a rule.
@ Registered
Something was registered.
@ Inactive
The rule is inactive.
@ Filtered
The rule does not apply.
RegisterResult registerFeature(QgsFeature &feature, Qgs3DRenderContext &context, RuleToHandlerMap &handlers) const
register individual features
QgsRuleBased3DRenderer::Rule * clone() const
clone this rule, return new instance
QgsRuleBased3DRenderer::RuleList descendants() const
Returns all children, grand-children, grand-grand-children, grand-gra... you get it.
void createHandlers(QgsVectorLayer *layer, RuleToHandlerMap &handlers) const
add handlers
QDomElement save(QDomDocument &doc, const QgsReadWriteContext &context) const
store labeling info to XML element
static QgsRuleBased3DRenderer::Rule * create(const QDomElement &ruleElem, const QgsReadWriteContext &context)
Create a rule from an XML definition.
void removeChildAt(int i)
delete child rule
QgsAbstract3DSymbol * symbol() const
Returns the labeling settings.
void appendChild(QgsRuleBased3DRenderer::Rule *rule)
add child rule, take ownership, sets this as parent
QString description() const
A human readable description for this rule.
QgsRuleBased3DRenderer * clone() const override
Returns a cloned instance.
QHash< const QgsRuleBased3DRenderer::Rule *, QgsFeature3DHandler * > RuleToHandlerMap
Qt3DCore::QEntity * createEntity(Qgs3DMapSettings *map) const override
Returns a 3D entity that will be used to show renderer's data in 3D scene.
QgsRuleBased3DRenderer(QgsRuleBased3DRenderer::Rule *root)
Construct renderer with the given root rule (takes ownership).
QgsRuleBased3DRenderer::Rule * rootRule()
Returns pointer to the root rule.
void readXml(const QDomElement &elem, const QgsReadWriteContext &context) override
Reads renderer's properties from given XML element.
void writeXml(QDomElement &elem, const QgsReadWriteContext &context) const override
Writes renderer's properties to given XML element.
~QgsRuleBased3DRenderer() override
QList< QgsRuleBased3DRenderer::Rule * > RuleList
A 3D vector (similar to QVector3D) with the difference that it uses double precision instead of singl...
Represents a vector layer which manages a vector based dataset.
As part of the API refactoring and improvements which landed in the Processing API was substantially reworked from the x version This was done in order to allow much of the underlying Processing framework to be ported into c