31using namespace Qt::StringLiterals;
40 QDomElement rulesElem = elem.firstChildElement( u
"rules"_s );
59 , mFilterExp( filterExp )
61 , mElseRule( elseRule )
69 qDeleteAll( mChildren );
75 if ( mSymbol.get() ==
symbol )
84 for (
Rule *
c : mChildren )
87 l +=
c->descendants();
92void QgsRuleBased3DRenderer::Rule::initFilter()
94 if ( mElseRule || mFilterExp.compare(
"ELSE"_L1, Qt::CaseInsensitive ) == 0 )
97 mFilter.reset(
nullptr );
99 else if ( !mFilterExp.isEmpty() )
101 mFilter = std::make_unique<QgsExpression>( mFilterExp );
105 mFilter.reset(
nullptr );
109void QgsRuleBased3DRenderer::Rule::updateElseRules()
112 for (
Rule *rule : std::as_const( mChildren ) )
114 if ( rule->isElse() )
122 mChildren.append( rule );
123 rule->mParent =
this;
129 mChildren.insert( i, rule );
130 rule->mParent =
this;
136 delete mChildren.at( i );
137 mChildren.removeAt( i );
145 if ( key == mRuleKey )
148 for (
Rule *rule : std::as_const( mChildren ) )
150 const Rule *r = rule->findRuleByKey( key );
159 if ( key == mRuleKey )
162 for (
Rule *rule : std::as_const( mChildren ) )
164 Rule *r = rule->findRuleByKey( key );
177 for (
Rule *rule : std::as_const( mChildren ) )
185 QDomElement elemSymbol = ruleElem.firstChildElement( u
"symbol"_s );
186 if ( !elemSymbol.isNull() )
188 QString symbolType = elemSymbol.attribute( u
"type"_s );
191 symbol->readXml( elemSymbol, context );
194 QString filterExp = ruleElem.attribute( u
"filter"_s );
195 QString
description = ruleElem.attribute( u
"description"_s );
196 QString
ruleKey = ruleElem.attribute( u
"key"_s );
202 rule->
setActive( ruleElem.attribute( u
"active"_s, u
"1"_s ).toInt() );
204 QDomElement childRuleElem = ruleElem.firstChildElement( u
"rule"_s );
205 while ( !childRuleElem.isNull() )
207 Rule *childRule =
create( childRuleElem, context );
216 childRuleElem = childRuleElem.nextSiblingElement( u
"rule"_s );
224 QDomElement ruleElem = doc.createElement( u
"rule"_s );
228 QDomElement elemSymbol = doc.createElement( u
"symbol"_s );
229 elemSymbol.setAttribute( u
"type"_s, mSymbol->type() );
230 mSymbol->writeXml( elemSymbol, context );
231 ruleElem.appendChild( elemSymbol );
234 if ( !mFilterExp.isEmpty() )
235 ruleElem.setAttribute( u
"filter"_s, mFilterExp );
236 if ( !mDescription.isEmpty() )
237 ruleElem.setAttribute( u
"description"_s, mDescription );
239 ruleElem.setAttribute( u
"active"_s, 0 );
240 ruleElem.setAttribute( u
"key"_s, mRuleKey );
242 for ( RuleList::const_iterator it = mChildren.constBegin(); it != mChildren.constEnd(); ++it )
245 ruleElem.appendChild( rule->
save( doc, context ) );
256 Q_ASSERT( !handlers.value(
this ) );
259 handlers[
this] = handler;
263 for (
Rule *rule : std::as_const( mChildren ) )
265 rule->createHandlers(
layer, handlers );
274 QgsFeature3DHandler *handler = handlers[
this];
275 if ( !handler->prepare( context, attributeNames, chunkExtent ) )
277 handlers.remove(
this );
284 attributeNames.unite( mFilter->referencedColumns() );
289 for (
Rule *rule : std::as_const( mChildren ) )
291 rule->prepare( context, attributeNames, chunkExtent, handlers );
297 if ( !isFilterOK( feature, context ) )
300 bool registered =
false;
303 if ( handlers.contains(
this ) && mIsActive )
305 handlers[
this]->processFeature( feature, context );
309 bool matchedAChild =
false;
312 for (
Rule *rule : std::as_const( mChildren ) )
315 if ( !rule->isElse() )
317 const RegisterResult res = rule->registerFeature( feature, context, handlers );
320 registered |= matchedAChild;
325 if ( !matchedAChild )
327 for (
Rule *rule : std::as_const( mElseRules ) )
329 const RegisterResult res = rule->registerFeature( feature, context, handlers );
335 if ( !mIsActive || ( matchedAChild && !registered ) )
337 else if ( registered )
346 if ( !mFilter || mElseRule )
351 return res.toInt() != 0;
374 rootRule->setRuleKey( mRootRule->ruleKey() );
375 RuleList origDescendants = mRootRule->descendants();
377 Q_ASSERT( origDescendants.count() == clonedDescendants.count() );
378 for (
int i = 0; i < origDescendants.count(); ++i )
379 clonedDescendants[i]->setRuleKey( origDescendants[i]->ruleKey() );
398 constexpr double MINIMUM_VECTOR_Z_ESTIMATE = -100000;
399 constexpr double MAXIMUM_VECTOR_Z_ESTIMATE = 100000;
401 return new QgsRuleBasedChunkedEntity( map, vl, MINIMUM_VECTOR_Z_ESTIMATE, MAXIMUM_VECTOR_Z_ESTIMATE,
tilingSettings(), mRootRule );
406 QDomDocument doc = elem.ownerDocument();
410 QDomElement rulesElem = mRootRule->save( doc, context );
411 rulesElem.setTagName( u
"rules"_s );
412 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.
A 3-dimensional box composed of x, y, z coordinates.
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 prepare(const Qgs3DRenderContext &context, QSet< QString > &attributeNames, const QgsBox3D &chunkExtent, RuleToHandlerMap &handlers) const
call prepare() on handlers and populate attributeNames
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).
RegisterResult
The result of registering a rule.
@ Registered
Something was registered.
@ Inactive
The rule is inactive.
@ Filtered
The rule does not apply.
RegisterResult registerFeature(const QgsFeature &feature, Qgs3DRenderContext &context, const 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
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