QGIS API Documentation  2.14.11-Essen
qgsgeometrygeneratorsymbollayerv2.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsgeometrygeneratorsymbollayerv2.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 {
21  delete mMarkerSymbol;
22  delete mLineSymbol;
23  delete mFillSymbol;
24 }
25 
27 {
28  QString expression = properties.value( "geometryModifier" );
29  if ( expression.isEmpty() )
30  {
31  expression = "$geometry";
32  }
34 
35  if ( properties.value( "SymbolType" ) == "Marker" )
36  {
37  symbolLayer->setSubSymbol( QgsMarkerSymbolV2::createSimple( properties ) );
38  }
39  else if ( properties.value( "SymbolType" ) == "Line" )
40  {
41  symbolLayer->setSubSymbol( QgsLineSymbolV2::createSimple( properties ) );
42  }
43  else
44  {
45  symbolLayer->setSubSymbol( QgsFillSymbolV2::createSimple( properties ) );
46  }
47 
48  return symbolLayer;
49 }
50 
51 QgsGeometryGeneratorSymbolLayerV2::QgsGeometryGeneratorSymbolLayerV2( const QString& expression )
53  , mExpression( new QgsExpression( expression ) )
54  , mFillSymbol( nullptr )
55  , mLineSymbol( nullptr )
56  , mMarkerSymbol( nullptr )
57  , mSymbol( nullptr )
58  , mSymbolType( QgsSymbolV2::Marker )
59 {
60 
61 }
62 
64 {
65  return "GeometryGenerator";
66 }
67 
69 {
70  if ( symbolType == QgsSymbolV2::Fill )
71  {
72  if ( !mFillSymbol )
74  mSymbol = mFillSymbol;
75  }
76  else if ( symbolType == QgsSymbolV2::Line )
77  {
78  if ( !mLineSymbol )
80  mSymbol = mLineSymbol;
81  }
82  else if ( symbolType == QgsSymbolV2::Marker )
83  {
84  if ( !mMarkerSymbol )
85  mMarkerSymbol = QgsMarkerSymbolV2::createSimple( QgsStringMap() );
86  mSymbol = mMarkerSymbol;
87  }
88  else
89  Q_ASSERT( false );
90 
91  mSymbolType = symbolType;
92 }
93 
95 {
96  mExpression->prepare( &context.renderContext().expressionContext() );
97 
98  subSymbol()->startRender( context.renderContext() );
99 }
100 
102 {
103  if ( mSymbol )
104  mSymbol->stopRender( context.renderContext() );
105 }
106 
108 {
110 
111  if ( mFillSymbol )
112  clone->mFillSymbol = mFillSymbol->clone();
113  if ( mLineSymbol )
114  clone->mLineSymbol = mLineSymbol->clone();
115  if ( mMarkerSymbol )
116  clone->mMarkerSymbol = mMarkerSymbol->clone();
117 
118  clone->setSymbolType( mSymbolType );
119 
120  return clone;
121 }
122 
124 {
125  QgsStringMap props;
126  props.insert( "geometryModifier" , mExpression->expression() );
127  switch ( mSymbolType )
128  {
129  case QgsSymbolV2::Marker:
130  props.insert( "SymbolType", "Marker" );
131  break;
132  case QgsSymbolV2::Line:
133  props.insert( "SymbolType", "Line" );
134  break;
135  default:
136  props.insert( "SymbolType", "Fill" );
137  break;
138  }
139 
140  return props;
141 }
142 
144 {
145  if ( mSymbol )
146  mSymbol->drawPreviewIcon( context.renderContext().painter(), size );
147 }
148 
150 {
151  mExpression.reset( new QgsExpression( exp ) );
152 }
153 
155 {
156  switch ( symbol->type() )
157  {
158  case QgsSymbolV2::Marker:
159  mMarkerSymbol = static_cast<QgsMarkerSymbolV2*>( symbol );
160  break;
161 
162  case QgsSymbolV2::Line:
163  mLineSymbol = static_cast<QgsLineSymbolV2*>( symbol );
164  break;
165 
166  case QgsSymbolV2::Fill:
167  mFillSymbol = static_cast<QgsFillSymbolV2*>( symbol );
168  break;
169 
170  default:
171  break;
172  }
173 
174  setSymbolType( symbol->type() );
175 
176  return true;
177 }
178 
180 {
181  return mSymbol->usedAttributes() + mExpression->referencedColumns().toSet();
182 }
183 
185 {
186  Q_UNUSED( symbol )
187  return true;
188 }
190 {
191  if ( context.feature() )
192  {
193  QgsExpressionContext& expressionContext = context.renderContext().expressionContext();
194 
195  QgsFeature f = expressionContext.feature();
196  QgsGeometry geom = mExpression->evaluate( &expressionContext ).value<QgsGeometry>();
197  f.setGeometry( geom );
198 
199  QgsExpressionContextScope* subSymbolExpressionContextScope = mSymbol->symbolRenderContext()->expressionContextScope();
200 
201  subSymbolExpressionContextScope->setFeature( f );
202 
203  mSymbol->renderFeature( f, context.renderContext(), -1, context.selected() );
204  }
205 }
206 
208 {
209  mSymbol->setColor( color );
210 }
Class for parsing and evaluation of expressions (formerly called "search strings").
QgsSymbolV2::SymbolType symbolType() const
Access the symbol type.
bool isCompatibleWithSymbol(QgsSymbolV2 *symbol) const override
Will always return true.
static QgsMarkerSymbolV2 * createSimple(const QgsStringMap &properties)
Create a marker symbol with one symbol layer: SimpleMarker with specified properties.
QgsSymbolLayerV2 * clone() const override
Shall be reimplemented by subclasses to create a deep copy of the instance.
static QgsSymbolLayerV2 * create(const QgsStringMap &properties)
void setSymbolType(QgsSymbolV2::SymbolType symbolType)
Set the type of symbol which should be created.
virtual QgsLineSymbolV2 * clone() const override
static QgsFillSymbolV2 * createSimple(const QgsStringMap &properties)
Create a fill symbol with one symbol layer: SimpleFill with specified properties. ...
virtual bool setSubSymbol(QgsSymbolV2 *symbol) override
set layer&#39;s subsymbol. takes ownership of the passed symbol
A geometry is the spatial representation of a feature.
Definition: qgsgeometry.h:76
SymbolType type() const
Definition: qgssymbolv2.h:104
Line symbol.
Definition: qgssymbolv2.h:79
QgsStringMap properties() const override
Should be reimplemented by subclasses to return a string map that contains the configuration informat...
QgsSymbolLayerV2(QgsSymbolV2::SymbolType type, bool locked=false)
const QgsFeature * feature() const
Current feature being rendered - may be null.
Definition: qgssymbolv2.h:375
The feature class encapsulates a single feature including its id, geometry and a list of field/values...
Definition: qgsfeature.h:187
void renderFeature(const QgsFeature &feature, QgsRenderContext &context, int layer=-1, bool selected=false, bool drawVertexMarker=false, int currentVertexMarkerType=0, int currentVertexMarkerSize=0)
Render a feature.
QMap< QString, QString > QgsStringMap
Definition: qgis.h:392
void drawPreviewIcon(QPainter *painter, QSize size, QgsRenderContext *customContext=nullptr)
Draw icon of the symbol that occupyies area given by size using the painter.
Marker symbol.
Definition: qgssymbolv2.h:78
void reset(T *other)
void drawPreviewIcon(QgsSymbolV2RenderContext &context, QSize size) override
virtual void render(QgsSymbolV2RenderContext &context)
Will render this symbol layer using the context.
void setColor(const QColor &color)
void setGeometry(const QgsGeometry &geom)
Set this feature&#39;s geometry from another QgsGeometry object.
Definition: qgsfeature.cpp:124
void startRender(QgsSymbolV2RenderContext &context) override
void startRender(QgsRenderContext &context, const QgsFields *fields=nullptr)
static QgsLineSymbolV2 * createSimple(const QgsStringMap &properties)
Create a line symbol with one symbol layer: SimpleLine with specified properties. ...
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
bool isEmpty() const
void setGeometryExpression(const QString &exp)
Set the expression to generate this geometry.
void stopRender(QgsSymbolV2RenderContext &context) override
Single scope for storing variables and functions for use within a QgsExpressionContext.
void setFeature(const QgsFeature &feature)
Convenience function for setting a feature for the scope.
virtual QColor color() const
The fill color.
virtual QSet< QString > usedAttributes() const override
Returns the set of attributes referenced by the layer.
virtual QgsFillSymbolV2 * clone() const override
QgsExpressionContext & expressionContext()
Gets the expression context.
void setColor(const QColor &color) override
The fill color.
SymbolType
Type of the symbol.
Definition: qgssymbolv2.h:76
Hybrid symbol.
Definition: qgssymbolv2.h:81
QgsExpressionContextScope * expressionContextScope()
This scope is always available when a symbol of this type is being rendered.
QPainter * painter()
void stopRender(QgsRenderContext &context)
QgsRenderContext & renderContext()
Definition: qgssymbolv2.h:346
Fill symbol.
Definition: qgssymbolv2.h:80
QgsFeature feature() const
Convenience function for retrieving the feature for the context, if set.
virtual Q_DECL_DEPRECATED QgsExpression * expression(const QString &property) const
Returns the data defined expression associated with a property.
iterator insert(const Key &key, const T &value)
QSet< QString > usedAttributes() const
Return a list of attributes required to render this feature.
QgsSymbolV2RenderContext * symbolRenderContext()
Returns the symbol render context.
virtual QgsMarkerSymbolV2 * clone() const override
QString layerType() const override
Returns a string that represents this layer type.
const T value(const Key &key) const