QGIS API Documentation  3.6.0-Noosa (5873452)
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 
26 #define ROOF_EXPRESSION \
27  "translate(" \
28  " $geometry," \
29  " cos( radians( eval( @qgis_25d_angle ) ) ) * eval( @qgis_25d_height )," \
30  " sin( radians( eval( @qgis_25d_angle ) ) ) * eval( @qgis_25d_height )" \
31  ")"
32 
33 #define WALL_EXPRESSION \
34  "order_parts( "\
35  " extrude(" \
36  " segments_to_lines( $geometry )," \
37  " cos( radians( eval( @qgis_25d_angle ) ) ) * eval( @qgis_25d_height )," \
38  " sin( radians( eval( @qgis_25d_angle ) ) ) * eval( @qgis_25d_height )" \
39  " )," \
40  " '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 ) ) ))'," \
41  " False" \
42  ")"
43 
44 #define ORDER_BY_EXPRESSION \
45  "distance(" \
46  " $geometry," \
47  " translate(" \
48  " @map_extent_center," \
49  " 1000 * @map_extent_width * cos( radians( @qgis_25d_angle + 180 ) )," \
50  " 1000 * @map_extent_width * sin( radians( @qgis_25d_angle + 180 ) )" \
51  " )" \
52  ")"
53 
54 #define WALL_SHADING_EXPRESSION \
55  "set_color_part( " \
56  " @symbol_color," \
57  " 'value'," \
58  " 40 + 19 * abs( $pi - azimuth( " \
59  " point_n( geometry_n($geometry, @geometry_part_num) , 1 ), " \
60  " point_n( geometry_n($geometry, @geometry_part_num) , 2 )" \
61  " ) ) " \
62  ")"
63 
65  : QgsFeatureRenderer( QStringLiteral( "25dRenderer" ) )
66 {
67  mSymbol.reset( new QgsFillSymbol() );
68 
69  mSymbol->deleteSymbolLayer( 0 ); // We never asked for the default layer
70 
72 
73  QgsStringMap wallProperties;
74  wallProperties.insert( QStringLiteral( "geometryModifier" ), WALL_EXPRESSION );
75  wallProperties.insert( QStringLiteral( "symbolType" ), QStringLiteral( "Fill" ) );
77 
78  QgsStringMap roofProperties;
79  roofProperties.insert( QStringLiteral( "geometryModifier" ), ROOF_EXPRESSION );
80  roofProperties.insert( QStringLiteral( "symbolType" ), QStringLiteral( "Fill" ) );
82 
83  floor->setLocked( true );
84 
85  mSymbol->appendSymbolLayer( floor );
86  mSymbol->appendSymbolLayer( walls );
87  mSymbol->appendSymbolLayer( roof );
88 
89  QgsEffectStack *effectStack = new QgsEffectStack();
90  QgsOuterGlowEffect *glowEffect = new QgsOuterGlowEffect();
91  glowEffect->setBlurLevel( 5 );
93  effectStack->appendEffect( glowEffect );
94  floor->setPaintEffect( effectStack );
95 
96  // These methods must only be used after the above initialization!
97 
98  setRoofColor( QColor( 177, 169, 124 ) );
99  setWallColor( QColor( 119, 119, 119 ) );
100 
102 
103  setShadowSpread( 4 );
104  setShadowColor( QColor( 17, 17, 17 ) );
105 
109  false );
110 
111  setOrderBy( orderBy );
112  setOrderByEnabled( true );
113 }
114 
115 QDomElement Qgs25DRenderer::save( QDomDocument &doc, const QgsReadWriteContext &context )
116 {
117  QDomElement rendererElem = doc.createElement( RENDERER_TAG_NAME );
118 
119  rendererElem.setAttribute( QStringLiteral( "type" ), QStringLiteral( "25dRenderer" ) );
120 
121  QDomElement symbolElem = QgsSymbolLayerUtils::saveSymbol( QStringLiteral( "symbol" ), mSymbol.get(), doc, context );
122 
123  rendererElem.appendChild( symbolElem );
124 
125  return rendererElem;
126 }
127 
128 QgsFeatureRenderer *Qgs25DRenderer::create( QDomElement &element, const QgsReadWriteContext &context )
129 {
130  Qgs25DRenderer *renderer = new Qgs25DRenderer();
131 
132  QDomNodeList symbols = element.elementsByTagName( QStringLiteral( "symbol" ) );
133  if ( symbols.size() )
134  {
135  renderer->mSymbol.reset( QgsSymbolLayerUtils::loadSymbol( symbols.at( 0 ).toElement(), context ) );
136  }
137 
138  return renderer;
139 }
140 
142 {
143  QgsFeatureRenderer::startRender( context, fields );
144 
145  mSymbol->startRender( context, fields );
146 }
147 
149 {
151 
152  mSymbol->stopRender( context );
153 }
154 
155 QSet<QString> Qgs25DRenderer::usedAttributes( const QgsRenderContext &context ) const
156 {
157  return mSymbol->usedAttributes( context );
158 }
159 
161 {
163  c->mSymbol.reset( mSymbol->clone() );
164  return c;
165 }
166 
168 {
169  Q_UNUSED( feature )
170  Q_UNUSED( context )
171  return mSymbol.get();
172 }
173 
175 {
176  Q_UNUSED( context );
177  QgsSymbolList lst;
178  lst.append( mSymbol.get() );
179  return lst;
180 }
181 
182 QgsFillSymbolLayer *Qgs25DRenderer::roofLayer() const
183 {
184  return static_cast<QgsFillSymbolLayer *>( mSymbol->symbolLayer( 2 )->subSymbol()->symbolLayer( 0 ) );
185 }
186 
187 QgsFillSymbolLayer *Qgs25DRenderer::wallLayer() const
188 {
189  return static_cast<QgsFillSymbolLayer *>( mSymbol->symbolLayer( 1 )->subSymbol()->symbolLayer( 0 ) );
190 }
191 
192 QgsOuterGlowEffect *Qgs25DRenderer::glowEffect() const
193 {
194  QgsEffectStack *stack = static_cast<QgsEffectStack *>( mSymbol->symbolLayer( 0 )->paintEffect() );
195  return static_cast<QgsOuterGlowEffect *>( stack->effect( 0 ) );
196 }
197 
199 {
200  return glowEffect()->enabled();
201 }
202 
204 {
205  glowEffect()->setEnabled( value );
206 }
207 
209 {
210  return glowEffect()->color();
211 }
212 
214 {
215  glowEffect()->setColor( shadowColor );
216 }
217 
219 {
220  return glowEffect()->spread();
221 }
222 
223 void Qgs25DRenderer::setShadowSpread( double spread )
224 {
225  glowEffect()->setSpread( spread );
226 }
227 
229 {
230  return wallLayer()->fillColor();
231 }
232 
234 {
235  wallLayer()->setFillColor( wallColor );
236  wallLayer()->setStrokeColor( wallColor );
237 }
238 
240 {
242 }
243 
245 {
247 }
248 
250 {
251  return roofLayer()->fillColor();
252 }
253 
255 {
256  roofLayer()->setFillColor( roofColor );
257  roofLayer()->setStrokeColor( roofColor );
258 }
259 
261 {
262  if ( renderer->type() == QLatin1String( "25dRenderer" ) )
263  {
264  return static_cast<Qgs25DRenderer *>( renderer->clone() );
265  }
266  else
267  {
268  return new Qgs25DRenderer();
269  }
270 }
271 
The class is used as a container of context for various read/write operations on other objects...
void stopRender(QgsRenderContext &context) override
Must be called when a render cycle has finished, to allow the renderer to clean up.
QDomElement save(QDomDocument &doc, const QgsReadWriteContext &context) override
store renderer info to XML element
void setLocked(bool locked)
Abstract base class for all rendered symbols.
Definition: qgssymbol.h:61
void startRender(QgsRenderContext &context, const QgsFields &fields) override
Must be called when a new render cycle is started.
QColor wallColor() const
Gets the wall color.
QgsSymbolList symbols(QgsRenderContext &context) const override
Returns list of symbols used by the renderer.
QgsFeatureRequest::OrderBy orderBy() const
Gets the order in which features shall be processed by this renderer.
QgsFeatureRenderer * clone() const override
Create a deep copy of this renderer.
static QgsProperty fromExpression(const QString &expression, bool isActive=true)
Returns a new ExpressionBasedProperty created from the specified expression.
Container of fields for a vector layer.
Definition: qgsfields.h:42
#define RENDERER_TAG_NAME
Definition: qgsrenderer.h:49
#define WALL_SHADING_EXPRESSION
The feature class encapsulates a single feature including its id, geometry and a list of field/values...
Definition: qgsfeature.h:55
static QgsSymbol * loadSymbol(const QDomElement &element, const QgsReadWriteContext &context)
Attempts to load a symbol from a DOM element.
QMap< QString, QString > QgsStringMap
Definition: qgis.h:587
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
void setBlurLevel(const int level)
Sets blur level (strength) for the glow.
void setEnabled(bool enabled)
Sets whether the effect is enabled.
bool shadowEnabled() const
Is the shadow enabled.
QList< QgsSymbol * > QgsSymbolList
Definition: qgsrenderer.h:43
QString type() const
Definition: qgsrenderer.h:129
void setShadowSpread(double shadowSpread)
Set the shadow&#39;s spread distance in map units.
QColor shadowColor() const
Gets the shadow&#39;s color.
QgsPaintEffect * effect(int index) const
Returns a pointer to the effect at a specified index within the stack.
void setSpreadUnit(const QgsUnitTypes::RenderUnit unit)
Sets the units used for the glow spread distance.
Definition: qgsgloweffect.h:82
void setActive(bool active)
Sets whether the property is currently active.
static Qgs25DRenderer * convertFromRenderer(QgsFeatureRenderer *renderer)
Try to convert from an existing renderer.
#define ORDER_BY_EXPRESSION
QgsPropertyCollection & dataDefinedProperties()
Returns a reference to the symbol layer&#39;s property collection, used for data defined overrides...
A paint effect which consists of a stack of other chained paint effects.
void setPaintEffect(QgsPaintEffect *effect)
Sets the current paint effect for the layer.
bool enabled() const
Returns whether the effect is enabled.
void setSpread(const double spread)
Sets the spread distance for drawing the glow effect.
Definition: qgsgloweffect.h:64
void appendEffect(QgsPaintEffect *effect)
Appends an effect to the end of the stack.
#define ROOF_EXPRESSION
virtual void setStrokeColor(const QColor &color)
Set stroke color.
void setOrderBy(const QgsFeatureRequest::OrderBy &orderBy)
Define the order in which features shall be processed by this renderer.
A paint effect which draws a glow outside of a picture.
The OrderByClause class represents an order by clause for a QgsFeatureRequest.
QgsSymbol * symbolForFeature(const QgsFeature &feature, QgsRenderContext &context) const override
To be overridden.
QSet< QString > usedAttributes(const QgsRenderContext &context) const override
Returns a list of attributes required by this renderer.
Contains information about the context of a rendering operation.
virtual void setFillColor(const QColor &color)
Set fill color.
double spread() const
Returns the spread distance used for drawing the glow effect.
Definition: qgsgloweffect.h:73
static QgsFeatureRenderer * create(QDomElement &element, const QgsReadWriteContext &context)
Create a new 2.5D renderer from XML.
static QgsSymbolLayer * create(const QgsStringMap &properties=QgsStringMap())
static QgsSymbolLayer * create(const QgsStringMap &properties)
virtual void startRender(QgsRenderContext &context, const QgsFields &fields)
Must be called when a new render cycle is started.
Definition: qgsrenderer.cpp:93
#define WALL_EXPRESSION
void setRoofColor(const QColor &roofColor)
Set the roof color.
bool wallShadingEnabled() const
Gets wall shading enabled.
virtual void stopRender(QgsRenderContext &context)
Must be called when a render cycle has finished, to allow the renderer to clean up.
void setShadowEnabled(bool value)
Enable or disable the shadow.
void setWallShadingEnabled(bool enabled)
Set wall shading enabled.
static QDomElement saveSymbol(const QString &symbolName, QgsSymbol *symbol, QDomDocument &doc, const QgsReadWriteContext &context)
Writes a symbol definition to XML.
QColor roofColor() const
Gets the roof color.
A fill symbol type, for rendering Polygon and MultiPolygon geometries.
Definition: qgssymbol.h:1003
double shadowSpread() const
Gets the shadow&#39;s spread distance in map units.
virtual QColor fillColor() const
Gets fill color.
void setShadowColor(const QColor &shadowColor)
Set the shadow&#39;s color.
void setColor(const QColor &color)
Sets the color for the glow.
void setWallColor(const QColor &wallColor)
Set the wall color.
void setOrderByEnabled(bool enabled)
Sets whether custom ordering should be applied before features are processed by this renderer...
virtual QgsFeatureRenderer * clone() const =0
Create a deep copy of this renderer.
bool isActive() const
Returns whether the property is currently active.
QgsProperty property(int key) const override
Returns a matching property from the collection, if one exists.
virtual void setDataDefinedProperty(Property key, const QgsProperty &property)
Sets a data defined property for the layer.
Represents a list of OrderByClauses, with the most important first and the least important last...
QColor color() const
Returns the color for the glow.