QGIS API Documentation  3.4.15-Madeira (e83d02e274)
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"
24 
25 #define ROOF_EXPRESSION \
26  "translate(" \
27  " $geometry," \
28  " cos( radians( eval( @qgis_25d_angle ) ) ) * eval( @qgis_25d_height )," \
29  " sin( radians( eval( @qgis_25d_angle ) ) ) * eval( @qgis_25d_height )" \
30  ")"
31 
32 #define WALL_EXPRESSION \
33  "order_parts( "\
34  " extrude(" \
35  " segments_to_lines( $geometry )," \
36  " cos( radians( eval( @qgis_25d_angle ) ) ) * eval( @qgis_25d_height )," \
37  " sin( radians( eval( @qgis_25d_angle ) ) ) * eval( @qgis_25d_height )" \
38  " )," \
39  " '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 ) ) ))'," \
40  " False" \
41  ")"
42 
43 #define ORDER_BY_EXPRESSION \
44  "distance(" \
45  " $geometry," \
46  " translate(" \
47  " @map_extent_center," \
48  " 1000 * @map_extent_width * cos( radians( @qgis_25d_angle + 180 ) )," \
49  " 1000 * @map_extent_width * sin( radians( @qgis_25d_angle + 180 ) )" \
50  " )" \
51  ")"
52 
53 #define WALL_SHADING_EXPRESSION \
54  "set_color_part( " \
55  " @symbol_color," \
56  " 'value'," \
57  " 40 + 19 * abs( $pi - azimuth( " \
58  " point_n( geometry_n($geometry, @geometry_part_num) , 1 ), " \
59  " point_n( geometry_n($geometry, @geometry_part_num) , 2 )" \
60  " ) ) " \
61  ")"
62 
64  : QgsFeatureRenderer( QStringLiteral( "25dRenderer" ) )
65 {
66  mSymbol.reset( new QgsFillSymbol() );
67 
68  mSymbol->deleteSymbolLayer( 0 ); // We never asked for the default layer
69 
71 
72  QgsStringMap wallProperties;
73  wallProperties.insert( QStringLiteral( "geometryModifier" ), WALL_EXPRESSION );
74  wallProperties.insert( QStringLiteral( "symbolType" ), QStringLiteral( "Fill" ) );
76 
77  QgsStringMap roofProperties;
78  roofProperties.insert( QStringLiteral( "geometryModifier" ), ROOF_EXPRESSION );
79  roofProperties.insert( QStringLiteral( "symbolType" ), QStringLiteral( "Fill" ) );
81 
82  floor->setLocked( true );
83 
84  mSymbol->appendSymbolLayer( floor );
85  mSymbol->appendSymbolLayer( walls );
86  mSymbol->appendSymbolLayer( roof );
87 
88  QgsEffectStack *effectStack = new QgsEffectStack();
89  QgsOuterGlowEffect *glowEffect = new QgsOuterGlowEffect();
90  glowEffect->setBlurLevel( 5 );
92  effectStack->appendEffect( glowEffect );
93  floor->setPaintEffect( effectStack );
94 
95  // These methods must only be used after the above initialization!
96 
97  setRoofColor( QColor( 177, 169, 124 ) );
98  setWallColor( QColor( 119, 119, 119 ) );
99 
101 
102  setShadowSpread( 4 );
103  setShadowColor( QColor( 17, 17, 17 ) );
104 
108  false );
109 
110  setOrderBy( orderBy );
111  setOrderByEnabled( true );
112 }
113 
114 QDomElement Qgs25DRenderer::save( QDomDocument &doc, const QgsReadWriteContext &context )
115 {
116  QDomElement rendererElem = doc.createElement( RENDERER_TAG_NAME );
117 
118  rendererElem.setAttribute( QStringLiteral( "type" ), QStringLiteral( "25dRenderer" ) );
119 
120  QDomElement symbolElem = QgsSymbolLayerUtils::saveSymbol( QStringLiteral( "symbol" ), mSymbol.get(), doc, context );
121 
122  rendererElem.appendChild( symbolElem );
123 
124  return rendererElem;
125 }
126 
127 QgsFeatureRenderer *Qgs25DRenderer::create( QDomElement &element, const QgsReadWriteContext &context )
128 {
129  Qgs25DRenderer *renderer = new Qgs25DRenderer();
130 
131  QDomNodeList symbols = element.elementsByTagName( QStringLiteral( "symbol" ) );
132  if ( symbols.size() )
133  {
134  renderer->mSymbol.reset( QgsSymbolLayerUtils::loadSymbol( symbols.at( 0 ).toElement(), context ) );
135  }
136 
137  return renderer;
138 }
139 
141 {
142  QgsFeatureRenderer::startRender( context, fields );
143 
144  mSymbol->startRender( context, fields );
145 }
146 
148 {
150 
151  mSymbol->stopRender( context );
152 }
153 
154 QSet<QString> Qgs25DRenderer::usedAttributes( const QgsRenderContext &context ) const
155 {
156  return mSymbol->usedAttributes( context );
157 }
158 
160 {
162  c->mSymbol.reset( mSymbol->clone() );
163  return c;
164 }
165 
167 {
168  Q_UNUSED( feature )
169  Q_UNUSED( context )
170  return mSymbol.get();
171 }
172 
174 {
175  Q_UNUSED( context );
176  QgsSymbolList lst;
177  lst.append( mSymbol.get() );
178  return lst;
179 }
180 
181 QgsFillSymbolLayer *Qgs25DRenderer::roofLayer() const
182 {
183  return static_cast<QgsFillSymbolLayer *>( mSymbol->symbolLayer( 2 )->subSymbol()->symbolLayer( 0 ) );
184 }
185 
186 QgsFillSymbolLayer *Qgs25DRenderer::wallLayer() const
187 {
188  return static_cast<QgsFillSymbolLayer *>( mSymbol->symbolLayer( 1 )->subSymbol()->symbolLayer( 0 ) );
189 }
190 
191 QgsOuterGlowEffect *Qgs25DRenderer::glowEffect() const
192 {
193  QgsEffectStack *stack = static_cast<QgsEffectStack *>( mSymbol->symbolLayer( 0 )->paintEffect() );
194  return static_cast<QgsOuterGlowEffect *>( stack->effect( 0 ) );
195 }
196 
198 {
199  return glowEffect()->enabled();
200 }
201 
203 {
204  glowEffect()->setEnabled( value );
205 }
206 
208 {
209  return glowEffect()->color();
210 }
211 
213 {
214  glowEffect()->setColor( shadowColor );
215 }
216 
218 {
219  return glowEffect()->spread();
220 }
221 
222 void Qgs25DRenderer::setShadowSpread( double spread )
223 {
224  glowEffect()->setSpread( spread );
225 }
226 
228 {
229  return wallLayer()->fillColor();
230 }
231 
233 {
234  wallLayer()->setFillColor( wallColor );
235  wallLayer()->setStrokeColor( wallColor );
236 }
237 
239 {
241 }
242 
244 {
246 }
247 
249 {
250  return roofLayer()->fillColor();
251 }
252 
254 {
255  roofLayer()->setFillColor( roofColor );
256  roofLayer()->setStrokeColor( roofColor );
257 }
258 
260 {
261  if ( renderer->type() == QLatin1String( "25dRenderer" ) )
262  {
263  return static_cast<Qgs25DRenderer *>( renderer->clone() );
264  }
265  else
266  {
267  return new Qgs25DRenderer();
268  }
269 }
270 
QColor shadowColor() const
Gets the shadow&#39;s color.
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.
QString type() const
Definition: qgsrenderer.h:129
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.
bool isActive() const
Returns whether the property is currently active.
QgsSymbolList symbols(QgsRenderContext &context) const override
Returns list of symbols used by the renderer.
QgsFeatureRenderer * clone() const override
Create a deep copy of this renderer.
bool enabled() const
Returns whether the effect is enabled.
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:577
QColor wallColor() const
Gets the wall color.
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 setEnabled(bool enabled)
Sets whether the effect is enabled.
QList< QgsSymbol * > QgsSymbolList
Definition: qgsrenderer.h:43
double spread() const
Returns the spread distance used for drawing the glow effect.
Definition: qgsgloweffect.h:73
void setShadowSpread(double shadowSpread)
Set the shadow&#39;s spread distance in map units.
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...
void setBlurLevel(const double level)
Sets blur level (radius) for the glow.
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.
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.
virtual QColor fillColor() const
Gets fill color.
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.
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:92
QColor roofColor() const
Gets the roof color.
#define WALL_EXPRESSION
void setRoofColor(const QColor &roofColor)
Set the roof color.
bool wallShadingEnabled() const
Gets wall shading enabled.
QColor color() const
Returns the color for the glow.
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.
QgsFeatureRequest::OrderBy orderBy() const
Gets the order in which features shall be processed by this renderer.
A fill symbol type, for rendering Polygon and MultiPolygon geometries.
Definition: qgssymbol.h:1003
QgsPaintEffect * effect(int index) const
Returns a pointer to the effect at a specified index within the stack.
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.
double shadowSpread() const
Gets the shadow&#39;s spread distance in map units.
void setOrderByEnabled(bool enabled)
Sets whether custom ordering should be applied before features are processed by this renderer...
bool shadowEnabled() const
Is the shadow enabled.
virtual QgsFeatureRenderer * clone() const =0
Create a deep copy of this renderer.
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...