QGIS API Documentation 3.39.0-Master (d85f3c2a281)
Loading...
Searching...
No Matches
qgs25drenderer.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgs25drenderer.cpp - qgs25drenderer
3 -----------------------------------
4
5 begin : 14.1.2016
6 Copyright : (C) 2016 Matthias Kuhn
7 Email : matthias at opengis dot ch
8 ***************************************************************************
9 * *
10 * This program is free software; you can redistribute it and/or modify *
11 * it under the terms of the GNU General Public License as published by *
12 * the Free Software Foundation; either version 2 of the License, or *
13 * (at your option) any later version. *
14 * *
15 ***************************************************************************/
16#include "qgs25drenderer.h"
18#include "qgsfillsymbollayer.h"
19#include "qgspainteffect.h"
20#include "qgseffectstack.h"
21#include "qgsgloweffect.h"
22#include "qgsproperty.h"
23#include "qgssymbollayerutils.h"
25#include "qgsfillsymbol.h"
26
27#define ROOF_EXPRESSION \
28 "translate(" \
29 " @geometry," \
30 " cos( radians( eval( @qgis_25d_angle ) ) ) * eval( @qgis_25d_height )," \
31 " sin( radians( eval( @qgis_25d_angle ) ) ) * eval( @qgis_25d_height )" \
32 ")"
33
34#define WALL_EXPRESSION \
35 "order_parts( "\
36 " extrude(" \
37 " segments_to_lines( @geometry )," \
38 " cos( radians( eval( @qgis_25d_angle ) ) ) * eval( @qgis_25d_height )," \
39 " sin( radians( eval( @qgis_25d_angle ) ) ) * eval( @qgis_25d_height )" \
40 " )," \
41 " 'distance( @geometry, translate( @map_extent_center, 1000 * @map_extent_width * cos( radians( @qgis_25d_angle + 180 ) ), 1000 * @map_extent_width * sin( radians( @qgis_25d_angle + 180 ) ) ))'," \
42 " False" \
43 ")"
44
45#define ORDER_BY_EXPRESSION \
46 "distance(" \
47 " @geometry," \
48 " translate(" \
49 " @map_extent_center," \
50 " 1000 * @map_extent_width * cos( radians( @qgis_25d_angle + 180 ) )," \
51 " 1000 * @map_extent_width * sin( radians( @qgis_25d_angle + 180 ) )" \
52 " )" \
53 ")"
54
55#define WALL_SHADING_EXPRESSION \
56 "set_color_part( " \
57 " @symbol_color," \
58 " 'value'," \
59 " 40 + 19 * abs( $pi - azimuth( " \
60 " point_n( geometry_n(@geometry, @geometry_part_num) , 1 ), " \
61 " point_n( geometry_n(@geometry, @geometry_part_num) , 2 )" \
62 " ) ) " \
63 ")"
64
66 : QgsFeatureRenderer( QStringLiteral( "25dRenderer" ) )
67{
68 mSymbol.reset( new QgsFillSymbol() );
69
70 mSymbol->deleteSymbolLayer( 0 ); // We never asked for the default layer
71
73
74 QVariantMap wallProperties;
75 wallProperties.insert( QStringLiteral( "geometryModifier" ), WALL_EXPRESSION );
76 wallProperties.insert( QStringLiteral( "symbolType" ), QStringLiteral( "Fill" ) );
78
79 QVariantMap roofProperties;
80 roofProperties.insert( QStringLiteral( "geometryModifier" ), ROOF_EXPRESSION );
81 roofProperties.insert( QStringLiteral( "symbolType" ), QStringLiteral( "Fill" ) );
83
84 floor->setLocked( true );
85
86 mSymbol->appendSymbolLayer( floor );
87 mSymbol->appendSymbolLayer( walls );
88 mSymbol->appendSymbolLayer( roof );
89
90 QgsEffectStack *effectStack = new QgsEffectStack();
91 QgsOuterGlowEffect *glowEffect = new QgsOuterGlowEffect();
92 glowEffect->setBlurLevel( 5 );
94 effectStack->appendEffect( glowEffect );
95 floor->setPaintEffect( effectStack );
96
97 // These methods must only be used after the above initialization!
98
99 setRoofColor( QColor( 177, 169, 124 ) );
100 setWallColor( QColor( 119, 119, 119 ) );
101
103
104 setShadowSpread( 4 );
105 setShadowColor( QColor( 17, 17, 17 ) );
106
110 false );
111
113 setOrderByEnabled( true );
114}
115
116QDomElement Qgs25DRenderer::save( QDomDocument &doc, const QgsReadWriteContext &context )
117{
118 QDomElement rendererElem = doc.createElement( RENDERER_TAG_NAME );
119
120 rendererElem.setAttribute( QStringLiteral( "type" ), QStringLiteral( "25dRenderer" ) );
121
122 const QDomElement symbolElem = QgsSymbolLayerUtils::saveSymbol( QStringLiteral( "symbol" ), mSymbol.get(), doc, context );
123
124 saveRendererData( doc, rendererElem, context );
125
126 rendererElem.appendChild( symbolElem );
127
128 return rendererElem;
129}
130
132{
134 if ( mSymbol && mSymbol->flags().testFlag( Qgis::SymbolFlag::AffectsLabeling ) )
136
137 return res;
138}
139
140QgsFeatureRenderer *Qgs25DRenderer::create( QDomElement &element, const QgsReadWriteContext &context )
141{
142 Qgs25DRenderer *renderer = new Qgs25DRenderer();
143
144 const QDomNodeList symbols = element.elementsByTagName( QStringLiteral( "symbol" ) );
145 if ( symbols.size() )
146 {
147 renderer->mSymbol.reset( QgsSymbolLayerUtils::loadSymbol( symbols.at( 0 ).toElement(), context ) );
148 }
149
150 return renderer;
151}
152
154{
155 QgsFeatureRenderer::startRender( context, fields );
156
157 mSymbol->startRender( context, fields );
158}
159
161{
163
164 mSymbol->stopRender( context );
165}
166
167QSet<QString> Qgs25DRenderer::usedAttributes( const QgsRenderContext &context ) const
168{
169 return mSymbol->usedAttributes( context );
170}
171
173{
175 c->mSymbol.reset( mSymbol->clone() );
176 return c;
177}
178
180{
181 Q_UNUSED( feature )
182 Q_UNUSED( context )
183 return mSymbol.get();
184}
185
187{
188 Q_UNUSED( context )
189 QgsSymbolList lst;
190 lst.append( mSymbol.get() );
191 return lst;
192}
193
195{
196 if ( mSymbol )
197 {
198 QgsStyleSymbolEntity entity( mSymbol.get() );
199 return visitor->visit( QgsStyleEntityVisitorInterface::StyleLeaf( &entity ) );
200 }
201 return true;
202}
203
204QgsFillSymbolLayer *Qgs25DRenderer::roofLayer() const
205{
206 return static_cast<QgsFillSymbolLayer *>( mSymbol->symbolLayer( 2 )->subSymbol()->symbolLayer( 0 ) );
207}
208
209QgsFillSymbolLayer *Qgs25DRenderer::wallLayer() const
210{
211 return static_cast<QgsFillSymbolLayer *>( mSymbol->symbolLayer( 1 )->subSymbol()->symbolLayer( 0 ) );
212}
213
214QgsOuterGlowEffect *Qgs25DRenderer::glowEffect() const
215{
216 QgsEffectStack *stack = static_cast<QgsEffectStack *>( mSymbol->symbolLayer( 0 )->paintEffect() );
217 return static_cast<QgsOuterGlowEffect *>( stack->effect( 0 ) );
218}
219
221{
222 return glowEffect()->enabled();
223}
224
225void Qgs25DRenderer::setShadowEnabled( bool value ) const
226{
227 glowEffect()->setEnabled( value );
228}
229
231{
232 return glowEffect()->color();
233}
234
235void Qgs25DRenderer::setShadowColor( const QColor &shadowColor ) const
236{
237 glowEffect()->setColor( shadowColor );
238}
239
241{
242 return glowEffect()->spread();
243}
244
245void Qgs25DRenderer::setShadowSpread( double spread ) const
246{
247 glowEffect()->setSpread( spread );
248}
249
251{
252 return wallLayer()->fillColor();
253}
254
255void Qgs25DRenderer::setWallColor( const QColor &wallColor ) const
256{
257 wallLayer()->setFillColor( wallColor );
258 wallLayer()->setStrokeColor( wallColor );
259}
260
262{
264}
265
270
272{
273 return roofLayer()->fillColor();
274}
275
276void Qgs25DRenderer::setRoofColor( const QColor &roofColor ) const
277{
278 roofLayer()->setFillColor( roofColor );
279 roofLayer()->setStrokeColor( roofColor );
280}
281
283{
284 if ( renderer->type() == QLatin1String( "25dRenderer" ) )
285 {
286 return static_cast<Qgs25DRenderer *>( renderer->clone() );
287 }
288 else
289 {
290 std::unique_ptr< Qgs25DRenderer > res = std::make_unique< Qgs25DRenderer >();
291 renderer->copyRendererData( res.get() );
292 return res.release();
293 }
294}
295
QFlags< FeatureRendererFlag > FeatureRendererFlags
Flags controlling behavior of vector feature renderers.
Definition qgis.h:772
@ AffectsLabeling
If present, indicates that the renderer will participate in the map labeling problem.
@ MapUnits
Map units.
@ AffectsLabeling
If present, indicates that the symbol will participate in the map labeling problem.
A vector renderer which represents 3D features in an isometric view.
Qgis::FeatureRendererFlags flags() const override
Returns flags associated with the renderer.
QgsSymbolList symbols(QgsRenderContext &context) const override
Returns list of symbols used by the renderer.
QgsSymbol * symbolForFeature(const QgsFeature &feature, QgsRenderContext &context) const override
To be overridden.
void stopRender(QgsRenderContext &context) override
Must be called when a render cycle has finished, to allow the renderer to clean up.
void setShadowSpread(double shadowSpread) const
Set the shadow's spread distance in map units.
QColor roofColor() const
Gets the roof color.
void setWallShadingEnabled(bool enabled) const
Set wall shading enabled.
QColor shadowColor() const
Gets the shadow's color.
QgsFeatureRenderer * clone() const override
Create a deep copy of this renderer.
static Qgs25DRenderer * convertFromRenderer(QgsFeatureRenderer *renderer)
Try to convert from an existing renderer.
double shadowSpread() const
Gets the shadow's spread distance in map units.
void startRender(QgsRenderContext &context, const QgsFields &fields) override
Must be called when a new render cycle is started.
bool accept(QgsStyleEntityVisitorInterface *visitor) const override
Accepts the specified symbology visitor, causing it to visit all symbols associated with the renderer...
static QgsFeatureRenderer * create(QDomElement &element, const QgsReadWriteContext &context)
Create a new 2.5D renderer from XML.
void setShadowColor(const QColor &shadowColor) const
Set the shadow's color.
QSet< QString > usedAttributes(const QgsRenderContext &context) const override
Returns a list of attributes required by this renderer.
bool wallShadingEnabled() const
Gets wall shading enabled.
bool shadowEnabled() const
Is the shadow enabled.
void setRoofColor(const QColor &roofColor) const
Set the roof color.
QDomElement save(QDomDocument &doc, const QgsReadWriteContext &context) override
Stores renderer properties to an XML element.
void setWallColor(const QColor &wallColor) const
Set the wall color.
QColor wallColor() const
Gets the wall color.
void setShadowEnabled(bool value) const
Enable or disable the shadow.
A paint effect which consists of a stack of other chained paint effects.
void appendEffect(QgsPaintEffect *effect)
Appends an effect to the end of the stack.
QgsPaintEffect * effect(int index) const
Returns a pointer to the effect at a specified index within the stack.
Abstract base class for all 2D vector feature renderers.
void setOrderBy(const QgsFeatureRequest::OrderBy &orderBy)
Define the order in which features shall be processed by this renderer.
void setOrderByEnabled(bool enabled)
Sets whether custom ordering should be applied before features are processed by this renderer.
virtual void stopRender(QgsRenderContext &context)
Must be called when a render cycle has finished, to allow the renderer to clean up.
QString type() const
void copyRendererData(QgsFeatureRenderer *destRenderer) const
Clones generic renderer data to another renderer.
void saveRendererData(QDomDocument &doc, QDomElement &element, const QgsReadWriteContext &context)
Saves generic renderer data into the specified element.
virtual void startRender(QgsRenderContext &context, const QgsFields &fields)
Must be called when a new render cycle is started.
QgsFeatureRequest::OrderBy orderBy() const
Gets the order in which features shall be processed by this renderer.
virtual QgsFeatureRenderer * clone() const =0
Create a deep copy of this renderer.
The OrderByClause class represents an order by clause for a QgsFeatureRequest.
Represents a list of OrderByClauses, with the most important first and the least important last.
The feature class encapsulates a single feature including its unique ID, geometry and a list of field...
Definition qgsfeature.h:58
Container of fields for a vector layer.
Definition qgsfields.h:46
Abstract base class for fill symbol layers.
A fill symbol type, for rendering Polygon and MultiPolygon geometries.
static QgsSymbolLayer * create(const QVariantMap &properties)
Creates the symbol layer.
void setSpread(const double spread)
Sets the spread distance for drawing the glow effect.
double spread() const
Returns the spread distance used for drawing the glow effect.
QColor color() const
Returns the color for the glow.
void setBlurLevel(const double level)
Sets blur level (radius) for the glow.
void setSpreadUnit(const Qgis::RenderUnit unit)
Sets the units used for the glow spread distance.
void setColor(const QColor &color)
Sets the color for the glow.
A paint effect which draws a glow outside of a picture.
void setEnabled(bool enabled)
Sets whether the effect is enabled.
bool enabled() const
Returns whether the effect is enabled.
QgsProperty property(int key) const final
Returns a matching property from the collection, if one exists.
static QgsProperty fromExpression(const QString &expression, bool isActive=true)
Returns a new ExpressionBasedProperty created from the specified expression.
bool isActive() const
Returns whether the property is currently active.
void setActive(bool active)
Sets whether the property is currently active.
The class is used as a container of context for various read/write operations on other objects.
Contains information about the context of a rendering operation.
static QgsSymbolLayer * create(const QVariantMap &properties=QVariantMap())
Creates a new QgsSimpleFillSymbolLayer using the specified properties map containing symbol propertie...
An interface for classes which can visit style entity (e.g.
virtual bool visit(const QgsStyleEntityVisitorInterface::StyleLeaf &entity)
Called when the visitor will visit a style entity.
A symbol entity for QgsStyle databases.
Definition qgsstyle.h:1396
static QgsSymbol * loadSymbol(const QDomElement &element, const QgsReadWriteContext &context)
Attempts to load a symbol from a DOM element.
static QDomElement saveSymbol(const QString &symbolName, const QgsSymbol *symbol, QDomDocument &doc, const QgsReadWriteContext &context)
Writes a symbol definition to XML.
virtual QColor fillColor() const
Returns the fill color for the symbol layer.
virtual void setStrokeColor(const QColor &color)
Sets the stroke color for the symbol layer.
void setPaintEffect(QgsPaintEffect *effect)
Sets the current paint effect for the layer.
virtual void setFillColor(const QColor &color)
Sets the fill color for the symbol layer.
virtual void setDataDefinedProperty(Property key, const QgsProperty &property)
Sets a data defined property for the layer.
void setLocked(bool locked)
Sets whether the layer's colors are locked.
QgsPropertyCollection & dataDefinedProperties()
Returns a reference to the symbol layer's property collection, used for data defined overrides.
Abstract base class for all rendered symbols.
Definition qgssymbol.h:231
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
#define WALL_SHADING_EXPRESSION
#define ORDER_BY_EXPRESSION
#define WALL_EXPRESSION
#define ROOF_EXPRESSION
#define RENDERER_TAG_NAME
Definition qgsrenderer.h:53
QList< QgsSymbol * > QgsSymbolList
Definition qgsrenderer.h:47
Contains information relating to the style entity currently being visited.