QGIS API Documentation  3.14.0-Pi (9f7028fd23)
qgsgeometrygeneratorsymbollayer.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsgeometrygeneratorsymbollayer.cpp
3  ---------------------
4  begin : November 2015
5  copyright : (C) 2015 by Matthias Kuhn
6  email : matthias at opengis dot ch
7  ***************************************************************************
8  * *
9  * This program is free software; you can redistribute it and/or modify *
10  * it under the terms of the GNU General Public License as published by *
11  * the Free Software Foundation; either version 2 of the License, or *
12  * (at your option) any later version. *
13  * *
14  ***************************************************************************/
15 
17 #include "qgsgeometry.h"
18 
20 
22 {
23  QString expression = properties.value( QStringLiteral( "geometryModifier" ) );
24  if ( expression.isEmpty() )
25  {
26  expression = QStringLiteral( "$geometry" );
27  }
29 
30  if ( properties.value( QStringLiteral( "SymbolType" ) ) == QLatin1String( "Marker" ) )
31  {
33  }
34  else if ( properties.value( QStringLiteral( "SymbolType" ) ) == QLatin1String( "Line" ) )
35  {
37  }
38  else
39  {
41  }
43 
44  return symbolLayer;
45 }
46 
47 QgsGeometryGeneratorSymbolLayer::QgsGeometryGeneratorSymbolLayer( const QString &expression )
48  : QgsSymbolLayer( QgsSymbol::Hybrid )
49  , mExpression( new QgsExpression( expression ) )
50  , mSymbolType( QgsSymbol::Marker )
51 {
52 
53 }
54 
56 {
57  return QStringLiteral( "GeometryGenerator" );
58 }
59 
61 {
62  if ( symbolType == QgsSymbol::Fill )
63  {
64  if ( !mFillSymbol )
65  mFillSymbol.reset( QgsFillSymbol::createSimple( QgsStringMap() ) );
66  mSymbol = mFillSymbol.get();
67  }
68  else if ( symbolType == QgsSymbol::Line )
69  {
70  if ( !mLineSymbol )
71  mLineSymbol.reset( QgsLineSymbol::createSimple( QgsStringMap() ) );
72  mSymbol = mLineSymbol.get();
73  }
74  else if ( symbolType == QgsSymbol::Marker )
75  {
76  if ( !mMarkerSymbol )
77  mMarkerSymbol.reset( QgsMarkerSymbol::createSimple( QgsStringMap() ) );
78  mSymbol = mMarkerSymbol.get();
79  }
80  else
81  Q_ASSERT( false );
82 
83  mSymbolType = symbolType;
84 }
85 
87 {
88  mExpression->prepare( &context.renderContext().expressionContext() );
89 
90  subSymbol()->startRender( context.renderContext() );
91 }
92 
94 {
95  if ( mSymbol )
96  mSymbol->stopRender( context.renderContext() );
97 }
98 
100 {
101  mRenderingFeature = true;
102  mHasRenderedFeature = false;
103 }
104 
106 {
107  mRenderingFeature = false;
108 }
109 
111 {
112  QgsGeometryGeneratorSymbolLayer *clone = new QgsGeometryGeneratorSymbolLayer( mExpression->expression() );
113 
114  if ( mFillSymbol )
115  clone->mFillSymbol.reset( mFillSymbol->clone() );
116  if ( mLineSymbol )
117  clone->mLineSymbol.reset( mLineSymbol->clone() );
118  if ( mMarkerSymbol )
119  clone->mMarkerSymbol.reset( mMarkerSymbol->clone() );
120 
121  clone->setSymbolType( mSymbolType );
122 
125 
126  return clone;
127 }
128 
130 {
131  QgsStringMap props;
132  props.insert( QStringLiteral( "geometryModifier" ), mExpression->expression() );
133  switch ( mSymbolType )
134  {
135  case QgsSymbol::Marker:
136  props.insert( QStringLiteral( "SymbolType" ), QStringLiteral( "Marker" ) );
137  break;
138  case QgsSymbol::Line:
139  props.insert( QStringLiteral( "SymbolType" ), QStringLiteral( "Line" ) );
140  break;
141  default:
142  props.insert( QStringLiteral( "SymbolType" ), QStringLiteral( "Fill" ) );
143  break;
144  }
145  return props;
146 }
147 
149 {
150  if ( mSymbol )
151  mSymbol->drawPreviewIcon( context.renderContext().painter(), size, nullptr, false, nullptr, context.patchShape() );
152 }
153 
155 {
156  mExpression.reset( new QgsExpression( exp ) );
157 }
158 
160 {
161  switch ( symbol->type() )
162  {
163  case QgsSymbol::Marker:
164  mMarkerSymbol.reset( static_cast<QgsMarkerSymbol *>( symbol ) );
165  break;
166 
167  case QgsSymbol::Line:
168  mLineSymbol.reset( static_cast<QgsLineSymbol *>( symbol ) );
169  break;
170 
171  case QgsSymbol::Fill:
172  mFillSymbol.reset( static_cast<QgsFillSymbol *>( symbol ) );
173  break;
174 
175  default:
176  break;
177  }
178 
179  setSymbolType( symbol->type() );
180 
181  return true;
182 }
183 
185 {
186  return QgsSymbolLayer::usedAttributes( context )
187  + mSymbol->usedAttributes( context )
188  + mExpression->referencedColumns();
189 }
190 
192 {
193  // we treat geometry generator layers like they have data defined properties,
194  // since the WHOLE layer is based on expressions and requires the full expression
195  // context
196  return true;
197 }
198 
200 {
201  Q_UNUSED( symbol )
202  return true;
203 }
205 {
206  if ( mRenderingFeature && mHasRenderedFeature )
207  return;
208 
209  if ( context.feature() )
210  {
211  QgsExpressionContext &expressionContext = context.renderContext().expressionContext();
212 
213  QgsFeature f = expressionContext.feature();
214  QgsGeometry geom = mExpression->evaluate( &expressionContext ).value<QgsGeometry>();
215  f.setGeometry( geom );
216 
217  QgsExpressionContextScope *subSymbolExpressionContextScope = mSymbol->symbolRenderContext()->expressionContextScope();
218 
219  subSymbolExpressionContextScope->setFeature( f );
220 
221  mSymbol->renderFeature( f, context.renderContext(), -1, context.selected() );
222 
223  if ( mRenderingFeature )
224  mHasRenderedFeature = true;
225  }
226 }
227 
228 void QgsGeometryGeneratorSymbolLayer::setColor( const QColor &color )
229 {
230  mSymbol->setColor( color );
231 }
QgsExpressionContext
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
Definition: qgsexpressioncontext.h:369
QgsExpressionContextScope::setFeature
void setFeature(const QgsFeature &feature)
Convenience function for setting a feature for the scope.
Definition: qgsexpressioncontext.h:317
QgsGeometryGeneratorSymbolLayer::usedAttributes
QSet< QString > usedAttributes(const QgsRenderContext &context) const override
Returns the set of attributes referenced by the layer.
Definition: qgsgeometrygeneratorsymbollayer.cpp:184
QgsGeometryGeneratorSymbolLayer::layerType
QString layerType() const override
Returns a string that represents this layer type.
Definition: qgsgeometrygeneratorsymbollayer.cpp:55
QgsRenderContext::expressionContext
QgsExpressionContext & expressionContext()
Gets the expression context.
Definition: qgsrendercontext.h:580
QgsSymbolRenderContext::feature
const QgsFeature * feature() const
Returns the current feature being rendered.
Definition: qgssymbol.h:789
QgsGeometryGeneratorSymbolLayer::subSymbol
QgsSymbol * subSymbol() override
Returns the symbol's sub symbol, if present.
Definition: qgsgeometrygeneratorsymbollayer.h:72
QgsSymbolLayer::color
virtual QColor color() const
The fill color.
Definition: qgssymbollayer.h:226
QgsMarkerSymbol::createSimple
static QgsMarkerSymbol * createSimple(const QgsStringMap &properties)
Create a marker symbol with one symbol layer: SimpleMarker with specified properties.
Definition: qgssymbol.cpp:1418
QgsRenderContext
Definition: qgsrendercontext.h:57
QgsGeometryGeneratorSymbolLayer::setSymbolType
void setSymbolType(QgsSymbol::SymbolType symbolType)
Set the type of symbol which should be created.
Definition: qgsgeometrygeneratorsymbollayer.cpp:60
QgsGeometryGeneratorSymbolLayer::setColor
void setColor(const QColor &color) override
The fill color.
Definition: qgsgeometrygeneratorsymbollayer.cpp:228
QgsSymbol
Definition: qgssymbol.h:63
QgsSymbolRenderContext::patchShape
const QgsLegendPatchShape * patchShape() const
Returns the symbol patch shape, to use if rendering symbol preview icons.
Definition: qgssymbol.cpp:1406
QgsGeometryGeneratorSymbolLayer::startFeatureRender
void startFeatureRender(const QgsFeature &feature, QgsRenderContext &context) override
Called before the layer will be rendered for a particular feature.
Definition: qgsgeometrygeneratorsymbollayer.cpp:99
QgsSymbolRenderContext::selected
bool selected() const
Returns true if symbols should be rendered using the selected symbol coloring and style.
Definition: qgssymbol.h:764
QgsSymbolRenderContext
Definition: qgssymbol.h:681
QgsSymbolRenderContext::expressionContextScope
QgsExpressionContextScope * expressionContextScope()
This scope is always available when a symbol of this type is being rendered.
Definition: qgssymbol.cpp:1396
QgsSymbolLayer
Definition: qgssymbollayer.h:52
QgsSymbol::stopRender
void stopRender(QgsRenderContext &context)
Ends the rendering process.
Definition: qgssymbol.cpp:460
QgsFeature::setGeometry
void setGeometry(const QgsGeometry &geometry)
Set the feature's geometry.
Definition: qgsfeature.cpp:137
QgsGeometryGeneratorSymbolLayer::clone
QgsSymbolLayer * clone() const override
Shall be reimplemented by subclasses to create a deep copy of the instance.
Definition: qgsgeometrygeneratorsymbollayer.cpp:110
QgsMarkerSymbol
Definition: qgssymbol.h:917
QgsSymbol::renderFeature
void renderFeature(const QgsFeature &feature, QgsRenderContext &context, int layer=-1, bool selected=false, bool drawVertexMarker=false, int currentVertexMarkerType=0, double currentVertexMarkerSize=0.0) SIP_THROW(QgsCsException)
Render a feature.
Definition: qgssymbol.cpp:819
QgsSymbolLayer::copyPaintEffect
void copyPaintEffect(QgsSymbolLayer *destLayer) const
Copies paint effect of this layer to another symbol layer.
Definition: qgssymbollayer.cpp:406
QgsGeometryGeneratorSymbolLayer
Definition: qgsgeometrygeneratorsymbollayer.h:26
QgsGeometryGeneratorSymbolLayer::~QgsGeometryGeneratorSymbolLayer
~QgsGeometryGeneratorSymbolLayer() override
QgsLineSymbol
Definition: qgssymbol.h:1117
QgsSymbol::Fill
@ Fill
Fill symbol.
Definition: qgssymbol.h:89
QgsSymbol::startRender
void startRender(QgsRenderContext &context, const QgsFields &fields=QgsFields())
Begins the rendering process for the symbol.
Definition: qgssymbol.cpp:435
QgsGeometryGeneratorSymbolLayer::hasDataDefinedProperties
bool hasDataDefinedProperties() const override
Returns true if the symbol layer (or any of its sub-symbols) contains data defined properties.
Definition: qgsgeometrygeneratorsymbollayer.cpp:191
QgsSymbol::symbolRenderContext
QgsSymbolRenderContext * symbolRenderContext()
Returns the symbol render context.
Definition: qgssymbol.cpp:1292
QgsGeometryGeneratorSymbolLayer::isCompatibleWithSymbol
bool isCompatibleWithSymbol(QgsSymbol *symbol) const override
Will always return true.
Definition: qgsgeometrygeneratorsymbollayer.cpp:199
QgsGeometryGeneratorSymbolLayer::properties
QgsStringMap properties() const override
Should be reimplemented by subclasses to return a string map that contains the configuration informat...
Definition: qgsgeometrygeneratorsymbollayer.cpp:129
QgsExpressionContextScope
Single scope for storing variables and functions for use within a QgsExpressionContext....
Definition: qgsexpressioncontext.h:111
QgsSymbolLayer::usedAttributes
virtual QSet< QString > usedAttributes(const QgsRenderContext &context) const
Returns the set of attributes referenced by the layer.
Definition: qgssymbollayer.cpp:246
QgsGeometryGeneratorSymbolLayer::setGeometryExpression
void setGeometryExpression(const QString &exp)
Set the expression to generate this geometry.
Definition: qgsgeometrygeneratorsymbollayer.cpp:154
QgsGeometryGeneratorSymbolLayer::startRender
void startRender(QgsSymbolRenderContext &context) override
Called before a set of rendering operations commences on the supplied render context.
Definition: qgsgeometrygeneratorsymbollayer.cpp:86
QgsGeometryGeneratorSymbolLayer::stopFeatureRender
void stopFeatureRender(const QgsFeature &feature, QgsRenderContext &context) override
Called after the layer has been rendered for a particular feature.
Definition: qgsgeometrygeneratorsymbollayer.cpp:105
QgsStringMap
QMap< QString, QString > QgsStringMap
Definition: qgis.h:714
qgsgeometry.h
QgsGeometry
Definition: qgsgeometry.h:122
QgsSymbol::setColor
void setColor(const QColor &color)
Sets the color for the symbol.
Definition: qgssymbol.cpp:485
QgsGeometryGeneratorSymbolLayer::render
virtual void render(QgsSymbolRenderContext &context)
Will render this symbol layer using the context.
Definition: qgsgeometrygeneratorsymbollayer.cpp:204
QgsSymbol::drawPreviewIcon
void drawPreviewIcon(QPainter *painter, QSize size, QgsRenderContext *customContext=nullptr, bool selected=false, const QgsExpressionContext *expressionContext=nullptr, const QgsLegendPatchShape *patchShape=nullptr)
Draws an icon of the symbol that occupies an area given by size using the specified painter.
Definition: qgssymbol.cpp:506
QgsGeometryGeneratorSymbolLayer::stopRender
void stopRender(QgsSymbolRenderContext &context) override
Called after a set of rendering operations has finished on the supplied render context.
Definition: qgsgeometrygeneratorsymbollayer.cpp:93
QgsLineSymbol::createSimple
static QgsLineSymbol * createSimple(const QgsStringMap &properties)
Create a line symbol with one symbol layer: SimpleLine with specified properties.
Definition: qgssymbol.cpp:1429
QgsExpressionContext::feature
QgsFeature feature() const
Convenience function for retrieving the feature for the context, if set.
Definition: qgsexpressioncontext.cpp:540
QgsSymbol::usedAttributes
QSet< QString > usedAttributes(const QgsRenderContext &context) const
Returns a list of attributes required to render this feature.
Definition: qgssymbol.cpp:738
QgsGeometryGeneratorSymbolLayer::drawPreviewIcon
void drawPreviewIcon(QgsSymbolRenderContext &context, QSize size) override
Definition: qgsgeometrygeneratorsymbollayer.cpp:148
QgsFillSymbol
Definition: qgssymbol.h:1212
QgsSymbol::Line
@ Line
Line symbol.
Definition: qgssymbol.h:88
QgsGeometryGeneratorSymbolLayer::setSubSymbol
bool setSubSymbol(QgsSymbol *symbol) override
Sets layer's subsymbol. takes ownership of the passed symbol.
Definition: qgsgeometrygeneratorsymbollayer.cpp:159
QgsSymbol::type
SymbolType type() const
Returns the symbol's type.
Definition: qgssymbol.h:122
QgsSymbol::Marker
@ Marker
Marker symbol.
Definition: qgssymbol.h:87
QgsSymbolLayer::restoreOldDataDefinedProperties
void restoreOldDataDefinedProperties(const QgsStringMap &stringMap)
Restores older data defined properties from string map.
Definition: qgssymbollayer.cpp:277
QgsFeature
Definition: qgsfeature.h:55
QgsFillSymbol::createSimple
static QgsFillSymbol * createSimple(const QgsStringMap &properties)
Create a fill symbol with one symbol layer: SimpleFill with specified properties.
Definition: qgssymbol.cpp:1440
QgsSymbolRenderContext::renderContext
QgsRenderContext & renderContext()
Returns a reference to the context's render context.
Definition: qgssymbol.h:708
QgsSymbol::SymbolType
SymbolType
Type of the symbol.
Definition: qgssymbol.h:85
QgsGeometryGeneratorSymbolLayer::create
static QgsSymbolLayer * create(const QgsStringMap &properties)
Definition: qgsgeometrygeneratorsymbollayer.cpp:21
qgsgeometrygeneratorsymbollayer.h
QgsRenderContext::painter
QPainter * painter()
Returns the destination QPainter for the render operation.
Definition: qgsrendercontext.h:174
QgsExpression
Definition: qgsexpression.h:113
QgsGeometryGeneratorSymbolLayer::symbolType
QgsSymbol::SymbolType symbolType() const
Access the symbol type.
Definition: qgsgeometrygeneratorsymbollayer.h:49
QgsSymbolLayer::copyDataDefinedProperties
void copyDataDefinedProperties(QgsSymbolLayer *destLayer) const
Copies all data defined properties of this layer to another symbol layer.
Definition: qgssymbollayer.cpp:398