QGIS API Documentation  3.22.4-Białowieża (ce8e65e95e)
qgsfillsymbol.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsfillsymbol.cpp
3  ---------------------
4  begin : November 2009
5  copyright : (C) 2009 by Martin Dobias
6  email : wonder dot sk at gmail dot com
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 
16 #include "qgsfillsymbol.h"
17 #include "qgsfillsymbollayer.h"
18 #include "qgspainteffect.h"
19 
20 QgsFillSymbol *QgsFillSymbol::createSimple( const QVariantMap &properties )
21 {
23  if ( !sl )
24  return nullptr;
25 
26  QgsSymbolLayerList layers;
27  layers.append( sl );
28  return new QgsFillSymbol( layers );
29 }
30 
31 
33  : QgsSymbol( Qgis::SymbolType::Fill, layers )
34 {
35  if ( mLayers.isEmpty() )
36  mLayers.append( new QgsSimpleFillSymbolLayer() );
37 }
38 
39 void QgsFillSymbol::renderPolygon( const QPolygonF &points, const QVector<QPolygonF> *rings, const QgsFeature *f, QgsRenderContext &context, int layerIdx, bool selected )
40 {
42  : mOpacity;
43 
44  QgsSymbolRenderContext symbolContext( context, QgsUnitTypes::RenderUnknownUnit, opacity, selected, mRenderHints, f );
46  symbolContext.setGeometryPartCount( symbolRenderContext()->geometryPartCount() );
47  symbolContext.setGeometryPartNum( symbolRenderContext()->geometryPartNum() );
48 
49  if ( layerIdx != -1 )
50  {
51  QgsSymbolLayer *symbolLayer = mLayers.value( layerIdx );
53  {
55  renderPolygonUsingLayer( symbolLayer, points, rings, symbolContext );
56  else
57  renderUsingLayer( symbolLayer, symbolContext, QgsWkbTypes::PolygonGeometry, &points, rings );
58  }
59  return;
60  }
61 
62  const auto constMLayers = mLayers;
63  for ( QgsSymbolLayer *symbolLayer : constMLayers )
64  {
65  if ( context.renderingStopped() )
66  break;
67 
68  if ( !symbolLayer->enabled() || !context.isSymbolLayerEnabled( symbolLayer ) )
69  continue;
70 
72  renderPolygonUsingLayer( symbolLayer, points, rings, symbolContext );
73  else
74  renderUsingLayer( symbolLayer, symbolContext, QgsWkbTypes::PolygonGeometry, &points, rings );
75  }
76 }
77 
78 void QgsFillSymbol::renderPolygonUsingLayer( QgsSymbolLayer *layer, const QPolygonF &points, const QVector<QPolygonF> *rings, QgsSymbolRenderContext &context )
79 {
80  if ( layer->dataDefinedProperties().hasActiveProperties() && !layer->dataDefinedProperties().valueAsBool( QgsSymbolLayer::PropertyLayerEnabled, context.renderContext().expressionContext(), true ) )
81  return;
82 
83  const Qgis::SymbolType layertype = layer->type();
84 
85  QgsPaintEffect *effect = layer->paintEffect();
86  if ( effect && effect->enabled() )
87  {
88  const QRectF bounds = polygonBounds( points, rings );
89  QVector<QPolygonF> *translatedRings = translateRings( rings, -bounds.left(), -bounds.top() );
90 
91  QgsEffectPainter p( context.renderContext() );
92  p->translate( bounds.topLeft() );
93  p.setEffect( effect );
94  if ( layertype == Qgis::SymbolType::Fill )
95  {
96  ( static_cast<QgsFillSymbolLayer *>( layer ) )->renderPolygon( points.translated( -bounds.topLeft() ), translatedRings, context );
97  }
98  else if ( layertype == Qgis::SymbolType::Line )
99  {
100  ( static_cast<QgsLineSymbolLayer *>( layer ) )->renderPolygonStroke( points.translated( -bounds.topLeft() ), translatedRings, context );
101  }
102  delete translatedRings;
103  }
104  else
105  {
106  if ( layertype == Qgis::SymbolType::Fill )
107  {
108  ( static_cast<QgsFillSymbolLayer *>( layer ) )->renderPolygon( points, rings, context );
109  }
110  else if ( layertype == Qgis::SymbolType::Line )
111  {
112  ( static_cast<QgsLineSymbolLayer *>( layer ) )->renderPolygonStroke( points, rings, context );
113  }
114  }
115 }
116 
117 QRectF QgsFillSymbol::polygonBounds( const QPolygonF &points, const QVector<QPolygonF> *rings ) const
118 {
119  QRectF bounds = points.boundingRect();
120  if ( rings )
121  {
122  for ( auto it = rings->constBegin(); it != rings->constEnd(); ++it )
123  {
124  bounds = bounds.united( ( *it ).boundingRect() );
125  }
126  }
127  return bounds;
128 }
129 
130 QVector<QPolygonF> *QgsFillSymbol::translateRings( const QVector<QPolygonF> *rings, double dx, double dy ) const
131 {
132  if ( !rings )
133  return nullptr;
134 
135  QVector<QPolygonF> *translatedRings = new QVector<QPolygonF>;
136  translatedRings->reserve( rings->size() );
137  for ( auto it = rings->constBegin(); it != rings->constEnd(); ++it )
138  {
139  translatedRings->append( ( *it ).translated( dx, dy ) );
140  }
141  return translatedRings;
142 }
143 
145 {
146  QgsFillSymbol *cloneSymbol = new QgsFillSymbol( cloneLayers() );
147  cloneSymbol->setOpacity( mOpacity );
149  cloneSymbol->setLayer( mLayer );
152  cloneSymbol->setForceRHR( mForceRHR );
154  cloneSymbol->setFlags( mSymbolFlags );
155  return cloneSymbol;
156 }
157 
159 {
160  const auto constMLayers = mLayers;
161  for ( QgsSymbolLayer *layer : constMLayers )
162  {
163  if ( layer->type() != Qgis::SymbolType::Fill )
164  continue;
165 
166  QgsFillSymbolLayer *fillLayer = static_cast<QgsFillSymbolLayer *>( layer );
167 
168  if ( fillLayer )
169  fillLayer->setAngle( angle );
170  }
171 }
172 
173 
The Qgis class provides global constants for use throughout the application.
Definition: qgis.h:63
SymbolType
Symbol types.
Definition: qgis.h:169
@ Line
Line symbol.
@ Fill
Fill symbol.
double valueAsDouble(int key, const QgsExpressionContext &context, double defaultValue=0.0, bool *ok=nullptr) const
Calculates the current value of the property with the specified key and interprets it as a double.
A class to manager painter saving and restoring required for effect drawing.
The feature class encapsulates a single feature including its unique ID, geometry and a list of field...
Definition: qgsfeature.h:56
void setAngle(double angle)
A fill symbol type, for rendering Polygon and MultiPolygon geometries.
Definition: qgsfillsymbol.h:30
QgsFillSymbol(const QgsSymbolLayerList &layers=QgsSymbolLayerList())
Constructor for QgsFillSymbol, with the specified list of initial symbol layers.
static QgsFillSymbol * createSimple(const QVariantMap &properties)
Create a fill symbol with one symbol layer: SimpleFill with specified properties.
void setAngle(double angle)
void renderPolygon(const QPolygonF &points, const QVector< QPolygonF > *rings, const QgsFeature *f, QgsRenderContext &context, int layer=-1, bool selected=false)
Renders the symbol using the given render context.
QgsFillSymbol * clone() const override
Returns a deep copy of this symbol.
QgsMapLayerType type
Definition: qgsmaplayer.h:80
Base class for visual effects which can be applied to QPicture drawings.
bool enabled() const
Returns whether the effect is enabled.
bool hasActiveProperties() const override
Returns true if the collection has any active properties, or false if all properties within the colle...
Contains information about the context of a rendering operation.
QgsExpressionContext & expressionContext()
Gets the expression context.
bool isSymbolLayerEnabled(const QgsSymbolLayer *layer) const
When rendering a map layer in a second pass (for selective masking), some symbol layers may be disabl...
bool renderingStopped() const
Returns true if the rendering operation has been stopped and any ongoing rendering should be canceled...
static QgsSymbolLayer * create(const QVariantMap &properties=QVariantMap())
Creates a new QgsSimpleFillSymbolLayer using the specified properties map containing symbol propertie...
@ PropertyLayerEnabled
Whether symbol layer is enabled.
Qgis::SymbolType type() const
bool enabled() const
Returns true if symbol layer is enabled and will be drawn.
QgsRenderContext & renderContext()
Returns a reference to the context's render context.
void setGeometryPartCount(int count)
Sets the part count of current geometry.
void setGeometryPartNum(int num)
Sets the part number of current geometry.
void setOriginalGeometryType(QgsWkbTypes::GeometryType type)
Sets the geometry type for the original feature geometry being rendered.
Abstract base class for all rendered symbols.
Definition: qgssymbol.h:38
void setDataDefinedProperties(const QgsPropertyCollection &collection)
Sets the symbol's property collection, used for data defined overrides.
Definition: qgssymbol.h:558
Qgis::SymbolFlags mSymbolFlags
Symbol flags.
Definition: qgssymbol.h:719
QgsSymbolLayerList cloneLayers() const
Retrieve a cloned list of all layers that make up this symbol.
Definition: qgssymbol.cpp:782
QgsSymbolRenderContext * symbolRenderContext()
Returns the symbol render context.
Definition: qgssymbol.cpp:1459
QgsSymbolLayer * symbolLayer(int layer)
Returns the symbol layer at the specified index.
Definition: qgssymbol.cpp:420
@ PropertyOpacity
Opacity.
Definition: qgssymbol.h:76
void renderUsingLayer(QgsSymbolLayer *layer, QgsSymbolRenderContext &context, QgsWkbTypes::GeometryType geometryType=QgsWkbTypes::GeometryType::UnknownGeometry, const QPolygonF *points=nullptr, const QVector< QPolygonF > *rings=nullptr)
Renders a context using a particular symbol layer without passing in a geometry.
Definition: qgssymbol.cpp:796
qreal mOpacity
Symbol opacity (in the range 0 - 1)
Definition: qgssymbol.h:710
Q_DECL_DEPRECATED const QgsVectorLayer * mLayer
Definition: qgssymbol.h:724
bool mClipFeaturesToExtent
Definition: qgssymbol.h:721
qreal opacity() const
Returns the opacity for the symbol.
Definition: qgssymbol.h:440
void setFlags(Qgis::SymbolFlags flags)
Sets flags for the symbol.
Definition: qgssymbol.h:467
QgsPropertyCollection & dataDefinedProperties()
Returns a reference to the symbol's property collection, used for data defined overrides.
Definition: qgssymbol.h:543
void setOpacity(qreal opacity)
Sets the opacity for the symbol.
Definition: qgssymbol.h:447
Qgis::SymbolRenderHints mRenderHints
Definition: qgssymbol.h:712
bool mForceRHR
Definition: qgssymbol.h:722
QgsSymbolLayerList mLayers
Definition: qgssymbol.h:707
Q_DECL_DEPRECATED const QgsVectorLayer * layer() const
Definition: qgssymbol.cpp:869
Q_DECL_DEPRECATED void setLayer(const QgsVectorLayer *layer)
Definition: qgssymbol.cpp:862
void setClipFeaturesToExtent(bool clipFeaturesToExtent)
Sets whether features drawn by the symbol should be clipped to the render context's extent.
Definition: qgssymbol.h:486
void setForceRHR(bool force)
Sets whether polygon features drawn by the symbol should be reoriented to follow the standard right-h...
Definition: qgssymbol.h:508
@ RenderUnknownUnit
Mixed or unknown units.
Definition: qgsunittypes.h:175
double ANALYSIS_EXPORT angle(QgsPoint *p1, QgsPoint *p2, QgsPoint *p3, QgsPoint *p4)
Calculates the angle between two segments (in 2 dimension, z-values are ignored)
Definition: MathUtils.cpp:786
#define Q_NOWARN_DEPRECATED_POP
Definition: qgis.h:1742
#define Q_NOWARN_DEPRECATED_PUSH
Definition: qgis.h:1741
QList< QgsSymbolLayer * > QgsSymbolLayerList
Definition: qgssymbol.h:27