37 QDomElement rulesElem = elem.firstChildElement( QStringLiteral(
"rules" ) );
56 , mFilterExp( filterExp )
57 , mDescription( description )
58 , mElseRule( elseRule )
66 qDeleteAll( mChildren );
72 if ( mSymbol.get() ==
symbol )
75 mSymbol.reset( symbol );
81 for (
Rule *
c : mChildren )
84 l +=
c->descendants();
89 void QgsRuleBased3DRenderer::Rule::initFilter()
91 if ( mElseRule || mFilterExp.compare( QLatin1String(
"ELSE" ), Qt::CaseInsensitive ) == 0 )
94 mFilter.reset(
nullptr );
96 else if ( !mFilterExp.isEmpty() )
102 mFilter.reset(
nullptr );
106 void QgsRuleBased3DRenderer::Rule::updateElseRules()
109 for (
Rule *rule : qgis::as_const( mChildren ) )
111 if ( rule->isElse() )
119 mChildren.append( rule );
120 rule->mParent =
this;
126 mChildren.insert( i, rule );
127 rule->mParent =
this;
133 delete mChildren.at( i );
134 mChildren.removeAt( i );
142 if ( key == mRuleKey )
145 for (
Rule *rule : qgis::as_const( mChildren ) )
156 if ( key == mRuleKey )
159 for (
Rule *rule : qgis::as_const( mChildren ) )
171 Rule *newrule =
new Rule( symbol, mFilterExp, mDescription );
174 for (
Rule *rule : qgis::as_const( mChildren ) )
182 QDomElement elemSymbol = ruleElem.firstChildElement( QStringLiteral(
"symbol" ) );
183 if ( !elemSymbol.isNull() )
185 QString symbolType = elemSymbol.attribute( QStringLiteral(
"type" ) );
186 if ( symbolType == QLatin1String(
"polygon" ) )
188 else if ( symbolType == QLatin1String(
"point" ) )
190 else if ( symbolType == QLatin1String(
"line" ) )
194 symbol->
readXml( elemSymbol, context );
197 QString filterExp = ruleElem.attribute( QStringLiteral(
"filter" ) );
198 QString
description = ruleElem.attribute( QStringLiteral(
"description" ) );
199 QString
ruleKey = ruleElem.attribute( QStringLiteral(
"key" ) );
200 Rule *rule =
new Rule( symbol, filterExp, description );
202 if ( !ruleKey.isEmpty() )
203 rule->mRuleKey = ruleKey;
205 rule->
setActive( ruleElem.attribute( QStringLiteral(
"active" ), QStringLiteral(
"1" ) ).toInt() );
207 QDomElement childRuleElem = ruleElem.firstChildElement( QStringLiteral(
"rule" ) );
208 while ( !childRuleElem.isNull() )
210 Rule *childRule =
create( childRuleElem, context );
219 childRuleElem = childRuleElem.nextSiblingElement( QStringLiteral(
"rule" ) );
227 QDomElement ruleElem = doc.createElement( QStringLiteral(
"rule" ) );
231 QDomElement elemSymbol = doc.createElement( QStringLiteral(
"symbol" ) );
232 elemSymbol.setAttribute( QStringLiteral(
"type" ), mSymbol->type() );
233 mSymbol->writeXml( elemSymbol, context );
234 ruleElem.appendChild( elemSymbol );
237 if ( !mFilterExp.isEmpty() )
238 ruleElem.setAttribute( QStringLiteral(
"filter" ), mFilterExp );
239 if ( !mDescription.isEmpty() )
240 ruleElem.setAttribute( QStringLiteral(
"description" ), mDescription );
242 ruleElem.setAttribute( QStringLiteral(
"active" ), 0 );
243 ruleElem.setAttribute( QStringLiteral(
"key" ), mRuleKey );
245 for ( RuleList::const_iterator it = mChildren.constBegin(); it != mChildren.constEnd(); ++it )
259 Q_ASSERT( !handlers.value(
this ) );
260 QgsFeature3DHandler *handler =
nullptr;
261 if ( mSymbol->type() == QLatin1String(
"polygon" ) )
263 handler = Qgs3DSymbolImpl::handlerForPolygon3DSymbol( layer, *static_cast<QgsPolygon3DSymbol *>( mSymbol.get() ) );
265 else if ( mSymbol->type() == QLatin1String(
"point" ) )
267 handler = Qgs3DSymbolImpl::handlerForPoint3DSymbol( layer, *static_cast<QgsPoint3DSymbol *>( mSymbol.get() ) );
269 else if ( mSymbol->type() == QLatin1String(
"line" ) )
271 handler = Qgs3DSymbolImpl::handlerForLine3DSymbol( layer, *static_cast<QgsLine3DSymbol *>( mSymbol.get() ) );
275 handlers[
this] = handler;
279 for (
Rule *rule : qgis::as_const( mChildren ) )
281 rule->createHandlers( layer, handlers );
290 QgsFeature3DHandler *handler = handlers[
this];
291 if ( !handler->prepare( context, attributeNames ) )
293 handlers.remove(
this );
300 attributeNames.unite( mFilter->referencedColumns() );
301 mFilter->prepare( &context.expressionContext() );
305 for (
Rule *rule : qgis::as_const( mChildren ) )
307 rule->prepare( context, attributeNames, handlers );
313 if ( !isFilterOK( feature, context ) )
316 bool registered =
false;
319 if ( handlers.contains(
this ) && mIsActive )
321 handlers[
this]->processFeature( feature, context );
325 bool willRegisterSomething =
false;
328 for (
Rule *rule : qgis::as_const( mChildren ) )
331 if ( !rule->isElse() )
333 RegisterResult res = rule->registerFeature( feature, context, handlers );
336 registered |= willRegisterSomething;
341 if ( !willRegisterSomething )
343 for (
Rule *rule : qgis::as_const( mElseRules ) )
345 registered |= rule->registerFeature( feature, context, handlers ) !=
Filtered;
351 else if ( registered )
358 bool QgsRuleBased3DRenderer::Rule::isFilterOK(
QgsFeature &f, Qgs3DRenderContext &context )
const 360 if ( ! mFilter || mElseRule )
363 context.expressionContext().setFeature( f );
364 QVariant res = mFilter->evaluate( &context.expressionContext() );
365 return res.toInt() != 0;
391 Q_ASSERT( origDescendants.count() == clonedDescendants.count() );
392 for (
int i = 0; i < origDescendants.count(); ++i )
393 clonedDescendants[i]->setRuleKey( origDescendants[i]->ruleKey() );
396 r->mLayerRef = mLayerRef;
417 Qgs3DRenderContext context( map );
421 context.setExpressionContext( exprContext );
426 QSet<QString> attributeNames;
427 mRootRule->
prepare( context, attributeNames, handlers );
437 context.expressionContext().setFeature( f );
441 Qt3DCore::QEntity *entity =
new Qt3DCore::QEntity;
442 for ( QgsFeature3DHandler *handler : handlers.values() )
443 handler->finalize( entity, context );
445 qDeleteAll( handlers.values() );
453 QDomDocument doc = elem.ownerDocument();
455 elem.setAttribute( QStringLiteral(
"layer" ), mLayerRef.
layerId );
457 QDomElement rulesElem = mRootRule->
save( doc, context );
458 rulesElem.setTagName( QStringLiteral(
"rules" ) );
459 elem.appendChild( rulesElem );
465 mLayerRef =
QgsMapLayerRef( elem.attribute( QStringLiteral(
"layer" ) ) );
void setSymbol(QgsAbstract3DSymbol *symbol)
Sets new symbol (or NULL). Deletes old symbol if any.
Class for parsing and evaluation of expressions (formerly called "search strings").
QgsFeatureRequest & setDestinationCrs(const QgsCoordinateReferenceSystem &crs, const QgsCoordinateTransformContext &context)
Sets the destination crs for feature's geometries.
void setLayer(QgsVectorLayer *layer)
Sets vector layer associated with the renderer.
The class is used as a container of context for various read/write operations on other objects...
Wrapper for iterator of features from vector data provider or vector layer.
_LayerRef< QgsMapLayer > QgsMapLayerRef
RegisterResult registerFeature(QgsFeature &feature, Qgs3DRenderContext &context, RuleToHandlerMap &handlers) const
register individual features
QgsCoordinateReferenceSystem crs() const
Returns coordinate reference system used in the 3D scene.
Base class for all renderers that may to participate in 3D view.
QList< QgsRuleBased3DRenderer::Rule * > RuleList
QMap< const QgsRuleBased3DRenderer::Rule *, QgsFeature3DHandler * > RuleToHandlerMap
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
QgsFeatureRequest & setSubsetOfAttributes(const QgsAttributeList &attrs)
Set a subset of attributes that will be fetched.
3 3D symbol that draws polygon geometries as planar polygons, optionally extruded (with added walls)...
QgsAbstract3DSymbol * symbol() const
Gets 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)
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
QString layerId
Original layer ID.
QgsCoordinateTransformContext transformContext() const
Returns the coordinate transform context, which stores various information regarding which datum tran...
QgsFields fields() const FINAL
Returns the list of fields of this layer.
QPointer< TYPE > layer
Weak pointer to map layer.
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
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
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.
This class wraps a request for features to a vector layer (or directly its vector data provider)...
Reads and writes project states.
3 3D symbol that draws linestring geometries as planar polygons (created from lines using a buffer wi...
void setLayer(TYPE *l)
Sets the reference to point to a specified layer.
QgsRuleBased3DRenderer::RuleList descendants() const
Returns all children, grand-children, grand-grand-children, grand-gra...
Something was registered.
void setFields(const QgsFields &fields)
Convenience function for setting a fields for the context.
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
void resolveReferences(const QgsProject &project) override
Resolves references to other objects - second phase of loading - after readXml()
RegisterResult
The result of registering a rule.
void removeChildAt(int i)
delete child rule
~QgsRuleBased3DRenderer() override
QgsVectorLayer * layer() const
Returns vector layer associated with the renderer.
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.
QgsMapLayer * mapLayer(const QString &layerId) const
Retrieve a pointer to a registered layer by layer ID.
static QgsExpressionContext globalProjectLayerExpressionContext(QgsVectorLayer *layer)
Returns expression context for use in preparation of 3D data of a layer.
QgsFeatureIterator getFeatures(const QgsFeatureRequest &request=QgsFeatureRequest()) const FINAL
Query the layer for features specified in request.
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
void setActive(bool state)
Sets if this rule is active.
bool nextFeature(QgsFeature &f)
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