QGIS API Documentation 3.99.0-Master (2fe06baccd8)
Loading...
Searching...
No Matches
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
18#include "qgsfillsymbollayer.h"
19#include "qgspainteffect.h"
20
21std::unique_ptr< QgsFillSymbol > QgsFillSymbol::createSimple( const QVariantMap &properties )
22{
24 if ( !sl )
25 return nullptr;
26
27 QgsSymbolLayerList layers;
28 layers.append( sl );
29 return std::make_unique< QgsFillSymbol >( layers );
30}
31
32
34 : QgsSymbol( Qgis::SymbolType::Fill, layers )
35{
36 if ( mLayers.isEmpty() )
37 mLayers.append( new QgsSimpleFillSymbolLayer() );
38}
39
40void QgsFillSymbol::renderPolygon( const QPolygonF &points, const QVector<QPolygonF> *rings, const QgsFeature *f, QgsRenderContext &context, int layerIdx, bool selected )
41{
43 : mOpacity;
44
45 QgsSymbolRenderContext symbolContext( context, Qgis::RenderUnit::Unknown, opacity, selected, renderHints(), f );
47 symbolContext.setGeometryPartCount( symbolRenderContext()->geometryPartCount() );
48 symbolContext.setGeometryPartNum( symbolRenderContext()->geometryPartNum() );
49
50 if ( layerIdx != -1 )
51 {
52 QgsSymbolLayer *symbolLayer = mLayers.value( layerIdx );
53 if ( symbolLayer && symbolLayer->enabled() && context.isSymbolLayerEnabled( symbolLayer ) )
54 {
56 renderPolygonUsingLayer( symbolLayer, points, rings, symbolContext );
57 else
58 renderUsingLayer( symbolLayer, symbolContext, Qgis::GeometryType::Polygon, &points, rings );
59 }
60 return;
61 }
62
63 const auto constMLayers = mLayers;
64 for ( QgsSymbolLayer *symbolLayer : constMLayers )
65 {
66 if ( context.renderingStopped() )
67 break;
68
69 if ( !symbolLayer->enabled() || !context.isSymbolLayerEnabled( symbolLayer ) )
70 continue;
71
73 renderPolygonUsingLayer( symbolLayer, points, rings, symbolContext );
74 else
75 renderUsingLayer( symbolLayer, symbolContext, Qgis::GeometryType::Polygon, &points, rings );
76 }
77}
78
79void QgsFillSymbol::renderPolygonUsingLayer( QgsSymbolLayer *layer, const QPolygonF &points, const QVector<QPolygonF> *rings, QgsSymbolRenderContext &context ) const
80{
81 if ( layer->dataDefinedProperties().hasActiveProperties() && !layer->dataDefinedProperties().valueAsBool( QgsSymbolLayer::Property::LayerEnabled, context.renderContext().expressionContext(), true ) )
82 return;
83
84 const Qgis::SymbolType layertype = layer->type();
85
86 QgsPaintEffect *effect = layer->paintEffect();
87 if ( effect && effect->enabled() )
88 {
89 const QRectF bounds = polygonBounds( points, rings );
90 QVector<QPolygonF> *translatedRings = translateRings( rings, -bounds.left(), -bounds.top() );
91
92 QgsEffectPainter p( context.renderContext() );
93 p->translate( bounds.topLeft() );
94 p.setEffect( effect );
95 if ( layertype == Qgis::SymbolType::Fill )
96 {
97 ( static_cast<QgsFillSymbolLayer *>( layer ) )->renderPolygon( points.translated( -bounds.topLeft() ), translatedRings, context );
98 }
99 else if ( layertype == Qgis::SymbolType::Line )
100 {
101 ( static_cast<QgsLineSymbolLayer *>( layer ) )->renderPolygonStroke( points.translated( -bounds.topLeft() ), translatedRings, context );
102 }
103 delete translatedRings;
104 }
105 else
106 {
107 if ( layertype == Qgis::SymbolType::Fill )
108 {
109 ( static_cast<QgsFillSymbolLayer *>( layer ) )->renderPolygon( points, rings, context );
110 }
111 else if ( layertype == Qgis::SymbolType::Line )
112 {
113 ( static_cast<QgsLineSymbolLayer *>( layer ) )->renderPolygonStroke( points, rings, context );
114 }
115 }
116}
117
118QRectF QgsFillSymbol::polygonBounds( const QPolygonF &points, const QVector<QPolygonF> *rings ) const
119{
120 QRectF bounds = points.boundingRect();
121 if ( rings )
122 {
123 for ( auto it = rings->constBegin(); it != rings->constEnd(); ++it )
124 {
125 bounds = bounds.united( ( *it ).boundingRect() );
126 }
127 }
128 return bounds;
129}
130
131QVector<QPolygonF> *QgsFillSymbol::translateRings( const QVector<QPolygonF> *rings, double dx, double dy ) const
132{
133 if ( !rings )
134 return nullptr;
135
136 QVector<QPolygonF> *translatedRings = new QVector<QPolygonF>;
137 translatedRings->reserve( rings->size() );
138 for ( auto it = rings->constBegin(); it != rings->constEnd(); ++it )
139 {
140 translatedRings->append( ( *it ).translated( dx, dy ) );
141 }
142 return translatedRings;
143}
144
146{
147 QgsFillSymbol *cloneSymbol = new QgsFillSymbol( cloneLayers() );
148 cloneSymbol->copyCommonProperties( this );
149 return cloneSymbol;
150}
151
152void QgsFillSymbol::setAngle( double angle ) const
153{
154 const auto constMLayers = mLayers;
155 for ( QgsSymbolLayer *layer : constMLayers )
156 {
157 if ( layer->type() != Qgis::SymbolType::Fill )
158 continue;
159
160 QgsFillSymbolLayer *fillLayer = static_cast<QgsFillSymbolLayer *>( layer );
161
162 if ( fillLayer )
163 fillLayer->setAngle( angle );
164 }
165}
Provides global constants and enumerations for use throughout the application.
Definition qgis.h:56
@ Polygon
Polygons.
Definition qgis.h:361
@ Unknown
Mixed or unknown units.
Definition qgis.h:5190
SymbolType
Symbol types.
Definition qgis.h:610
@ Line
Line symbol.
Definition qgis.h:612
@ Fill
Fill symbol.
Definition qgis.h:613
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.
Manages 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:58
Abstract base class for fill symbol layers.
void setAngle(double angle)
Sets the rotation angle of the pattern, in degrees clockwise.
void setAngle(double angle) const
static std::unique_ptr< QgsFillSymbol > createSimple(const QVariantMap &properties)
Create a fill symbol with one symbol layer: SimpleFill with specified properties.
QgsFillSymbol(const QgsSymbolLayerList &layers=QgsSymbolLayerList())
Constructor for QgsFillSymbol, with the specified list of initial symbol layers.
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.
Qgis::LayerType type
Definition qgsmaplayer.h:90
Base class for visual effects which can be applied to QPicture drawings.
bool enabled() const
Returns whether the effect is enabled.
bool hasActiveProperties() const final
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...
Renders polygons using a single fill and stroke color.
static QgsSymbolLayer * create(const QVariantMap &properties=QVariantMap())
Creates a new QgsSimpleFillSymbolLayer using the specified properties map containing symbol propertie...
Abstract base class for symbol layers.
@ LayerEnabled
Whether symbol layer is enabled.
Encapsulates the context in which a symbol is being rendered.
void setOriginalGeometryType(Qgis::GeometryType type)
Sets the geometry type for the original feature geometry being rendered.
void setGeometryPartCount(int count)
Sets the part count of current geometry.
void setGeometryPartNum(int num)
Sets the part number of current geometry.
QgsRenderContext & renderContext()
Returns a reference to the context's render context.
void renderUsingLayer(QgsSymbolLayer *layer, QgsSymbolRenderContext &context, Qgis::GeometryType geometryType=Qgis::GeometryType::Unknown, const QPolygonF *points=nullptr, const QVector< QPolygonF > *rings=nullptr)
Renders a context using a particular symbol layer without passing in a geometry.
QgsSymbolLayerList cloneLayers() const
Retrieve a cloned list of all layers that make up this symbol.
QgsSymbolRenderContext * symbolRenderContext()
Returns the symbol render context.
QgsSymbolLayer * symbolLayer(int layer)
Returns the symbol layer at the specified index.
Qgis::SymbolRenderHints renderHints() const
Returns the rendering hint flags for the symbol.
void copyCommonProperties(const QgsSymbol *other)
Copies common properties from an other symbol to this symbol.
QgsPropertyCollection & dataDefinedProperties()
Returns a reference to the symbol's property collection, used for data defined overrides.
Definition qgssymbol.h:814
qreal mOpacity
Symbol opacity (in the range 0 - 1).
Definition qgssymbol.h:1028
qreal opacity() const
Returns the opacity for the symbol.
Definition qgssymbol.h:659
QgsSymbolLayerList mLayers
Definition qgssymbol.h:1022
Q_DECL_DEPRECATED const QgsVectorLayer * layer() const
QgsSymbol(Qgis::SymbolType type, const QgsSymbolLayerList &layers)
Constructor for a QgsSymbol of the specified type.
QList< QgsSymbolLayer * > QgsSymbolLayerList
Definition qgssymbol.h:30