38 QDomElement rulesElem = elem.firstChildElement( QStringLiteral(
"rules" ) );
57 , mFilterExp( filterExp )
58 , mDescription( description )
59 , mElseRule( elseRule )
67 qDeleteAll( mChildren );
73 if ( mSymbol.get() == symbol )
76 mSymbol.reset( symbol );
82 for (
Rule *
c : mChildren )
85 l +=
c->descendants();
90void QgsRuleBased3DRenderer::Rule::initFilter()
92 if ( mElseRule || mFilterExp.compare( QLatin1String(
"ELSE" ), Qt::CaseInsensitive ) == 0 )
95 mFilter.reset(
nullptr );
97 else if ( !mFilterExp.isEmpty() )
103 mFilter.reset(
nullptr );
107void QgsRuleBased3DRenderer::Rule::updateElseRules()
110 for ( Rule *rule : std::as_const( mChildren ) )
112 if ( rule->isElse() )
120 mChildren.append( rule );
121 rule->mParent =
this;
127 mChildren.insert( i, rule );
128 rule->mParent =
this;
134 delete mChildren.at( i );
135 mChildren.removeAt( i );
143 if ( key == mRuleKey )
146 for (
Rule *rule : std::as_const( mChildren ) )
157 if ( key == mRuleKey )
160 for (
Rule *rule : std::as_const( mChildren ) )
172 Rule *newrule =
new Rule( symbol, mFilterExp, mDescription );
175 for (
Rule *rule : std::as_const( mChildren ) )
183 QDomElement elemSymbol = ruleElem.firstChildElement( QStringLiteral(
"symbol" ) );
184 if ( !elemSymbol.isNull() )
186 QString symbolType = elemSymbol.attribute( QStringLiteral(
"type" ) );
189 symbol->
readXml( elemSymbol, context );
192 QString filterExp = ruleElem.attribute( QStringLiteral(
"filter" ) );
193 QString description = ruleElem.attribute( QStringLiteral(
"description" ) );
194 QString ruleKey = ruleElem.attribute( QStringLiteral(
"key" ) );
195 Rule *rule =
new Rule( symbol, filterExp, description );
197 if ( !ruleKey.isEmpty() )
198 rule->mRuleKey = ruleKey;
200 rule->
setActive( ruleElem.attribute( QStringLiteral(
"active" ), QStringLiteral(
"1" ) ).toInt() );
202 QDomElement childRuleElem = ruleElem.firstChildElement( QStringLiteral(
"rule" ) );
203 while ( !childRuleElem.isNull() )
205 Rule *childRule = create( childRuleElem, context );
214 childRuleElem = childRuleElem.nextSiblingElement( QStringLiteral(
"rule" ) );
222 QDomElement ruleElem = doc.createElement( QStringLiteral(
"rule" ) );
226 QDomElement elemSymbol = doc.createElement( QStringLiteral(
"symbol" ) );
227 elemSymbol.setAttribute( QStringLiteral(
"type" ), mSymbol->type() );
228 mSymbol->writeXml( elemSymbol, context );
232 if ( !mFilterExp.isEmpty() )
233 ruleElem.setAttribute( QStringLiteral(
"filter" ), mFilterExp );
234 if ( !mDescription.isEmpty() )
235 ruleElem.setAttribute( QStringLiteral(
"description" ), mDescription );
237 ruleElem.setAttribute( QStringLiteral(
"active" ), 0 );
238 ruleElem.setAttribute( QStringLiteral(
"key" ), mRuleKey );
240 for ( RuleList::const_iterator it = mChildren.constBegin(); it != mChildren.constEnd(); ++it )
254 Q_ASSERT( !handlers.value(
this ) );
257 handlers[
this] = handler;
261 for (
Rule *rule : std::as_const( mChildren ) )
263 rule->createHandlers(
layer, handlers );
272 QgsFeature3DHandler *handler = handlers[
this];
273 if ( !handler->prepare( context, attributeNames ) )
275 handlers.remove(
this );
282 attributeNames.unite( mFilter->referencedColumns() );
283 mFilter->prepare( &context.expressionContext() );
287 for (
Rule *rule : std::as_const( mChildren ) )
289 rule->prepare( context, attributeNames, handlers );
295 if ( !isFilterOK( feature, context ) )
298 bool registered =
false;
301 if ( handlers.contains(
this ) && mIsActive )
303 handlers[
this]->processFeature( feature, context );
307 bool matchedAChild =
false;
310 for (
Rule *rule : std::as_const( mChildren ) )
313 if ( !rule->isElse() )
315 const RegisterResult res = rule->registerFeature( feature, context, handlers );
317 matchedAChild |= ( res == Registered || res == Inactive );
318 registered |= matchedAChild;
323 if ( !matchedAChild )
325 for (
Rule *rule : std::as_const( mElseRules ) )
327 const RegisterResult res = rule->registerFeature( feature, context, handlers );
328 matchedAChild |= ( res == Registered || res == Inactive );
329 registered |= res != Filtered;
333 if ( !mIsActive || ( matchedAChild && !registered ) )
335 else if ( registered )
342bool QgsRuleBased3DRenderer::Rule::isFilterOK(
QgsFeature &f, Qgs3DRenderContext &context )
const
344 if ( ! mFilter || mElseRule )
347 context.expressionContext().setFeature( f );
348 QVariant res = mFilter->evaluate( &context.expressionContext() );
349 return res.toInt() != 0;
375 Q_ASSERT( origDescendants.count() == clonedDescendants.count() );
376 for (
int i = 0; i < origDescendants.count(); ++i )
377 clonedDescendants[i]->setRuleKey( origDescendants[i]->ruleKey() );
396 constexpr double MINIMUM_VECTOR_Z_ESTIMATE = -100000;
397 constexpr double MAXIMUM_VECTOR_Z_ESTIMATE = 100000;
399 return new QgsRuleBasedChunkedEntity( vl, MINIMUM_VECTOR_Z_ESTIMATE, MAXIMUM_VECTOR_Z_ESTIMATE,
tilingSettings(), mRootRule, map );
404 QDomDocument doc = elem.ownerDocument();
408 QDomElement rulesElem = mRootRule->
save( doc, context );
409 rulesElem.setTagName( QStringLiteral(
"rules" ) );
410 elem.appendChild( rulesElem );
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 may to participate in 3D view.
virtual void readXml(const QDomElement &elem, const QgsReadWriteContext &context)=0
Reads symbol configuration from the given DOM element.
virtual QgsAbstract3DSymbol * clone() const =0
Returns a new instance of the symbol with the same settings.
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.
Class for parsing and evaluation of expressions (formerly called "search strings").
The feature class encapsulates a single feature including its unique ID, geometry and a list of field...
The class is used as a container of context for various read/write operations on other objects.
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 prepare(const Qgs3DRenderContext &context, QSet< QString > &attributeNames, RuleToHandlerMap &handlers) const
call prepare() on handlers and populate attributeNames
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.
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
void setRuleKey(const QString &key)
Override the assigned rule key (should be used just internally by rule-based renderer)
void appendChild(QgsRuleBased3DRenderer::Rule *rule)
add child rule, take ownership, sets this as parent
QgsRuleBased3DRenderer * clone() const override
Returns a cloned instance.
QHash< const QgsRuleBased3DRenderer::Rule *, QgsFeature3DHandler * > RuleToHandlerMap
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
Qt3DCore::QEntity * createEntity(const Qgs3DMapSettings &map) const override
Returns a 3D entity that will be used to show renderer's data in 3D scene.
Represents a vector layer which manages a vector based data sets.
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