QGIS API Documentation  3.26.3-Buenos Aires (65e4edfdad)
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 ) const
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 );
156  return cloneSymbol;
157 }
158 
159 void QgsFillSymbol::setAngle( double angle ) const
160 {
161  const auto constMLayers = mLayers;
162  for ( QgsSymbolLayer *layer : constMLayers )
163  {
164  if ( layer->type() != Qgis::SymbolType::Fill )
165  continue;
166 
167  QgsFillSymbolLayer *fillLayer = static_cast<QgsFillSymbolLayer *>( layer );
168 
169  if ( fillLayer )
170  fillLayer->setAngle( angle );
171  }
172 }
173 
174 
QgsLineSymbolLayer
Definition: qgssymbollayer.h:1024
QgsSymbol::setLayer
Q_DECL_DEPRECATED void setLayer(const QgsVectorLayer *layer)
Definition: qgssymbol.cpp:1196
QgsSymbol::cloneLayers
QgsSymbolLayerList cloneLayers() const
Retrieve a cloned list of all layers that make up this symbol.
Definition: qgssymbol.cpp:1116
QgsSymbolLayer::enabled
bool enabled() const
Returns true if symbol layer is enabled and will be drawn.
Definition: qgssymbollayer.h:242
QgsSymbol::mLayer
const Q_DECL_DEPRECATED QgsVectorLayer * mLayer
Definition: qgssymbol.h:805
QgsFillSymbol::QgsFillSymbol
QgsFillSymbol(const QgsSymbolLayerList &layers=QgsSymbolLayerList())
Constructor for QgsFillSymbol, with the specified list of initial symbol layers.
Definition: qgsfillsymbol.cpp:32
QgsAbstractPropertyCollection::valueAsDouble
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.
Definition: qgspropertycollection.cpp:66
QgsSimpleFillSymbolLayer::create
static QgsSymbolLayer * create(const QVariantMap &properties=QVariantMap())
Creates a new QgsSimpleFillSymbolLayer using the specified properties map containing symbol propertie...
Definition: qgsfillsymbollayer.cpp:171
Qgis::SymbolType::Fill
@ Fill
Fill symbol.
Qgis::SymbolType::Line
@ Line
Line symbol.
QgsRenderContext::expressionContext
QgsExpressionContext & expressionContext()
Gets the expression context.
Definition: qgsrendercontext.h:625
QgsEffectPainter
A class to manager painter saving and restoring required for effect drawing.
Definition: qgspainteffect.h:395
QgsSymbol::layer
const Q_DECL_DEPRECATED QgsVectorLayer * layer() const
Definition: qgssymbol.cpp:1203
QgsSymbolRenderContext::setGeometryPartNum
void setGeometryPartNum(int num)
Sets the part number of current geometry.
Definition: qgssymbolrendercontext.h:192
QgsSymbol::setDataDefinedProperties
void setDataDefinedProperties(const QgsPropertyCollection &collection)
Sets the symbol's property collection, used for data defined overrides.
Definition: qgssymbol.h:637
QgsRenderContext
Contains information about the context of a rendering operation.
Definition: qgsrendercontext.h:59
QgsSymbol
Abstract base class for all rendered symbols.
Definition: qgssymbol.h:92
qgspainteffect.h
QgsSymbol::dataDefinedProperties
QgsPropertyCollection & dataDefinedProperties()
Returns a reference to the symbol's property collection, used for data defined overrides.
Definition: qgssymbol.h:622
QgsFillSymbol::setAngle
void setAngle(double angle) const
Definition: qgsfillsymbol.cpp:159
QgsSymbol::symbolLayer
QgsSymbolLayer * symbolLayer(int layer)
Returns the symbol layer at the specified index.
Definition: qgssymbol.cpp:725
QgsWkbTypes::PolygonGeometry
@ PolygonGeometry
Definition: qgswkbtypes.h:144
QgsSymbol::PropertyOpacity
@ PropertyOpacity
Opacity.
Definition: qgssymbol.h:131
QgsRenderContext::isSymbolLayerEnabled
bool isSymbolLayerEnabled(const QgsSymbolLayer *layer) const
When rendering a map layer in a second pass (for selective masking), some symbol layers may be disabl...
Definition: qgsrendercontext.h:166
QgsSymbolRenderContext
Definition: qgssymbolrendercontext.h:35
QgsSymbol::setOpacity
void setOpacity(qreal opacity)
Sets the opacity for the symbol.
Definition: qgssymbol.h:502
Q_NOWARN_DEPRECATED_POP
#define Q_NOWARN_DEPRECATED_POP
Definition: qgis.h:2820
QgsRenderContext::renderingStopped
bool renderingStopped() const
Returns true if the rendering operation has been stopped and any ongoing rendering should be canceled...
Definition: qgsrendercontext.h:285
QgsSymbol::setClipFeaturesToExtent
void setClipFeaturesToExtent(bool clipFeaturesToExtent)
Sets whether features drawn by the symbol should be clipped to the render context's extent.
Definition: qgssymbol.h:541
QgsSymbol::opacity
qreal opacity() const
Returns the opacity for the symbol.
Definition: qgssymbol.h:495
QgsSymbolLayer
Definition: qgssymbollayer.h:54
QgsSymbol::setAnimationSettings
void setAnimationSettings(const QgsSymbolAnimationSettings &settings)
Sets a the symbol animation settings.
Definition: qgssymbol.cpp:668
Qgis::SymbolType
SymbolType
Symbol types.
Definition: qgis.h:205
QgsSymbol::mRenderHints
Qgis::SymbolRenderHints mRenderHints
Definition: qgssymbol.h:791
QgsSymbol::mLayers
QgsSymbolLayerList mLayers
Definition: qgssymbol.h:786
QgsPropertyCollection::hasActiveProperties
bool hasActiveProperties() const override
Returns true if the collection has any active properties, or false if all properties within the colle...
Definition: qgspropertycollection.cpp:304
QgsSymbolRenderContext::setGeometryPartCount
void setGeometryPartCount(int count)
Sets the part count of current geometry.
Definition: qgssymbolrendercontext.h:180
QgsSymbol::renderUsingLayer
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:1130
qgsfillsymbollayer.h
QgsFillSymbol::renderPolygon
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.
Definition: qgsfillsymbol.cpp:39
QgsFillSymbol::createSimple
static QgsFillSymbol * createSimple(const QVariantMap &properties)
Create a fill symbol with one symbol layer: SimpleFill with specified properties.
Definition: qgsfillsymbol.cpp:20
QgsSymbol::symbolRenderContext
QgsSymbolRenderContext * symbolRenderContext()
Returns the symbol render context.
Definition: qgssymbol.cpp:1793
QgsSymbol::setForceRHR
void setForceRHR(bool force)
Sets whether polygon features drawn by the symbol should be reoriented to follow the standard right-h...
Definition: qgssymbol.h:563
QgsSymbolLayer::PropertyLayerEnabled
@ PropertyLayerEnabled
Whether symbol layer is enabled.
Definition: qgssymbollayer.h:188
QgsSymbol::mOpacity
qreal mOpacity
Symbol opacity (in the range 0 - 1)
Definition: qgssymbol.h:789
QgsSymbolRenderContext::setOriginalGeometryType
void setOriginalGeometryType(QgsWkbTypes::GeometryType type)
Sets the geometry type for the original feature geometry being rendered.
Definition: qgssymbolrendercontext.h:150
QgsSymbolLayer::type
Qgis::SymbolType type() const
Definition: qgssymbollayer.h:437
QgsSymbolLayerList
QList< QgsSymbolLayer * > QgsSymbolLayerList
Definition: qgssymbol.h:27
QgsFillSymbolLayer
Definition: qgssymbollayer.h:1222
QgsPaintEffect
Base class for visual effects which can be applied to QPicture drawings.
Definition: qgspainteffect.h:52
QgsSimpleFillSymbolLayer
Definition: qgsfillsymbollayer.h:43
QgsSymbol::setFlags
void setFlags(Qgis::SymbolFlags flags)
Sets flags for the symbol.
Definition: qgssymbol.h:522
QgsFillSymbol::clone
QgsFillSymbol * clone() const override
Returns a deep copy of this symbol.
Definition: qgsfillsymbol.cpp:144
QgsFillSymbol
A fill symbol type, for rendering Polygon and MultiPolygon geometries.
Definition: qgsfillsymbol.h:29
QgsUnitTypes::RenderUnknownUnit
@ RenderUnknownUnit
Mixed or unknown units.
Definition: qgsunittypes.h:175
Qgis
The Qgis class provides global constants for use throughout the application.
Definition: qgis.h:71
QgsFeature
The feature class encapsulates a single feature including its unique ID, geometry and a list of field...
Definition: qgsfeature.h:55
QgsSymbolRenderContext::renderContext
QgsRenderContext & renderContext()
Returns a reference to the context's render context.
Definition: qgssymbolrendercontext.h:62
QgsPaintEffect::enabled
bool enabled() const
Returns whether the effect is enabled.
Definition: qgspainteffect.h:197
QgsSymbol::mForceRHR
bool mForceRHR
Definition: qgssymbol.h:801
QgsSymbol::mAnimationSettings
QgsSymbolAnimationSettings mAnimationSettings
Definition: qgssymbol.h:803
Q_NOWARN_DEPRECATED_PUSH
#define Q_NOWARN_DEPRECATED_PUSH
Definition: qgis.h:2819
MathUtils::angle
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
QgsSymbol::mSymbolFlags
Qgis::SymbolFlags mSymbolFlags
Symbol flags.
Definition: qgssymbol.h:798
QgsFillSymbolLayer::setAngle
void setAngle(double angle)
Definition: qgssymbollayer.h:1241
qgsfillsymbol.h
QgsSymbol::mClipFeaturesToExtent
bool mClipFeaturesToExtent
Definition: qgssymbol.h:800
QgsMapLayer::type
QgsMapLayerType type
Definition: qgsmaplayer.h:80