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 );
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 );
void setSymbol(QgsAbstract3DSymbol *symbol)
Sets new symbol (or nullptr). Deletes old symbol if any.
Class for parsing and evaluation of expressions (formerly called "search strings").
The class is used as a container of context for various read/write operations on other objects...
RegisterResult registerFeature(QgsFeature &feature, Qgs3DRenderContext &context, RuleToHandlerMap &handlers) const
register individual features
static void estimateVectorLayerZRange(QgsVectorLayer *layer, double &zMin, double &zMax)
Try to estimate range of Z values used in the given vector layer and store that in zMin and zMax...
Base class for all renderers that may to participate in 3D view.
QList< QgsRuleBased3DRenderer::Rule * > RuleList
QgsVectorLayer3DTilingSettings tilingSettings() const
Returns tiling settings of the renderer.
const QgsRuleBased3DRenderer::Rule * findRuleByKey(const QString &key) const
Try to find a rule given its unique key.
void appendChild(QgsRuleBased3DRenderer::Rule *rule)
add child rule, take ownership, sets this as parent
QgsVectorLayer * layer() const
Returns vector layer associated with the renderer.
3 3D symbol that draws polygon geometries as planar polygons, optionally extruded (with added walls)...
QgsAbstract3DSymbol * symbol() const
Returns the labeling settings.
void writeXml(QDomElement &elem, const QgsReadWriteContext &context) const override
Writes renderer's properties to given XML element.
QString ruleKey() const
Unique rule identifier (for identification of rule within labeling, used as provider ID) ...
QString description() const
A human readable description for this rule.
The feature class encapsulates a single feature including its id, geometry and a list of field/values...
3 Definition of the world
3 Abstract base class for 3D symbols that are used by VectorLayer3DRenderer objects.
QgsRuleBased3DRenderer(QgsRuleBased3DRenderer::Rule *root)
Construct renderer with the given root rule (takes ownership)
void copyBaseProperties(QgsAbstractVectorLayer3DRenderer *r) const
Copies common properties of this object to another object.
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
3 Rule-based 3D renderer.
QDomElement save(QDomDocument &doc, const QgsReadWriteContext &context) const
store labeling info to XML element
3 3D symbol that draws point geometries as 3D objects using one of the predefined shapes...
void insertChild(int i, QgsRuleBased3DRenderer::Rule *rule)
add child rule, take ownership, sets this as parent
void createHandlers(QgsVectorLayer *layer, RuleToHandlerMap &handlers) const
add handlers
Qt3DCore::QEntity * createEntity(const Qgs3DMapSettings &map) const override
Returns a 3D entity that will be used to show renderer's data in 3D scene.
3 3D symbol that draws linestring geometries as planar polygons (created from lines using a buffer wi...
QgsRuleBased3DRenderer::RuleList descendants() const
Returns all children, grand-children, grand-grand-children, grand-gra...
Something was registered.
QgsRuleBased3DRenderer::Rule * rootRule()
Returns pointer to the root rule.
void prepare(const Qgs3DRenderContext &context, QSet< QString > &attributeNames, RuleToHandlerMap &handlers) const
call prepare() on handlers and populate attributeNames
RegisterResult
The result of registering a rule.
void removeChildAt(int i)
delete child rule
~QgsRuleBased3DRenderer() override
void writeXmlBaseProperties(QDomElement &elem, const QgsReadWriteContext &context) const
Writes common properties of this object to DOM element.
void readXml(const QDomElement &elem, const QgsReadWriteContext &context) override
Reads renderer's properties from given XML element.
virtual void readXml(const QDomElement &elem, const QgsReadWriteContext &context)=0
Reads symbol configuration from the given DOM element.
QgsRuleBased3DRenderer * clone() const override
Returns a cloned instance.
Rule(QgsAbstract3DSymbol *symbol, const QString &filterExp=QString(), const QString &description=QString(), bool elseRule=false)
takes ownership of symbol, symbol may be nullptr
QHash< const QgsRuleBased3DRenderer::Rule *, QgsFeature3DHandler * > RuleToHandlerMap
void setActive(bool state)
Sets if this rule is active.
Represents a vector layer which manages a vector based data sets.
void setRuleKey(const QString &key)
Override the assigned rule key (should be used just internally by rule-based renderer) ...
static QgsRuleBased3DRenderer::Rule * create(const QDomElement &ruleElem, const QgsReadWriteContext &context)
Create a rule from an XML definition.
QgsRuleBased3DRenderer::Rule * clone() const
clone this rule, return new instance
void readXmlBaseProperties(const QDomElement &elem, const QgsReadWriteContext &context)
Reads common properties of this object from DOM element.