QGIS API Documentation  2.14.0-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").
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
SymbolType type() const
Definition: qgssymbolv2.h:104
QSet< QString > usedAttributes() const
Return a list of attributes required to render this feature.
QgsSymbolV2::SymbolType symbolType() const
Access the symbol type.
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
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)
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:384
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)
virtual Q_DECL_DEPRECATED QgsExpression * expression(const QString &property) const
Returns the data defined expression associated with a property.
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
const QgsFeature * feature() const
Current feature being rendered - may be null.
Definition: qgssymbolv2.h:374
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
QgsFeature feature() const
Convenience function for retrieving the feature for the context, if set.
virtual QColor color() const
The fill color.
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 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:345
Fill symbol.
Definition: qgssymbolv2.h:80
bool selected() const
Definition: qgssymbolv2.h:366
iterator insert(const Key &key, const T &value)
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