QGIS API Documentation 3.37.0-Master (fdefdf9c27f)
qgssymbollayer.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgssymbollayer.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 "qgssymbollayer.h"
17#include "qgsrendercontext.h"
18#include "qgsdxfexport.h"
20#include "qgspainteffect.h"
22#include "qgsproperty.h"
24#include "qgssymbollayerutils.h"
25#include "qgslegendpatchshape.h"
26#include "qgsstyle.h"
28#include "qgssymbol.h"
30
31#include <QSize>
32#include <QPainter>
33#include <QPointF>
34#include <QPolygonF>
35#include <QUuid>
36
37QgsPropertiesDefinition QgsSymbolLayer::sPropertyDefinitions;
38
39void QgsSymbolLayer::initPropertyDefinitions()
40{
41 if ( !sPropertyDefinitions.isEmpty() )
42 return;
43
44 QString origin = QStringLiteral( "symbol" );
45
46 sPropertyDefinitions = QgsPropertiesDefinition
47 {
48 { static_cast< int >( QgsSymbolLayer::Property::Size ), QgsPropertyDefinition( "size", QObject::tr( "Symbol size" ), QgsPropertyDefinition::Size, origin ) },
49 { static_cast< int >( QgsSymbolLayer::Property::Angle ), QgsPropertyDefinition( "angle", QObject::tr( "Rotation angle" ), QgsPropertyDefinition::Rotation, origin ) },
50 { static_cast< int >( QgsSymbolLayer::Property::Name ), QgsPropertyDefinition( "name", QObject::tr( "Symbol name" ), QgsPropertyDefinition::String, origin ) },
51 { static_cast< int >( QgsSymbolLayer::Property::FillColor ), QgsPropertyDefinition( "fillColor", QObject::tr( "Symbol fill color" ), QgsPropertyDefinition::ColorWithAlpha, origin ) },
52 { static_cast< int >( QgsSymbolLayer::Property::StrokeColor ), QgsPropertyDefinition( "outlineColor", QObject::tr( "Symbol stroke color" ), QgsPropertyDefinition::ColorWithAlpha, origin ) },
53 { static_cast< int >( QgsSymbolLayer::Property::StrokeWidth ), QgsPropertyDefinition( "outlineWidth", QObject::tr( "Symbol stroke width" ), QgsPropertyDefinition::StrokeWidth, origin ) },
54 { static_cast< int >( QgsSymbolLayer::Property::StrokeStyle ), QgsPropertyDefinition( "outlineStyle", QObject::tr( "Symbol stroke style" ), QgsPropertyDefinition::LineStyle, origin )},
55 { static_cast< int >( QgsSymbolLayer::Property::Offset ), QgsPropertyDefinition( "offset", QObject::tr( "Symbol offset" ), QgsPropertyDefinition::Offset, origin )},
56 { static_cast< int >( QgsSymbolLayer::Property::Character ), QgsPropertyDefinition( "char", QObject::tr( "Marker character(s)" ), QgsPropertyDefinition::String, origin )},
57 { static_cast< int >( QgsSymbolLayer::Property::FontFamily ), QgsPropertyDefinition( "fontFamily", QObject::tr( "Font family" ), QgsPropertyDefinition::String, origin )},
58 { static_cast< int >( QgsSymbolLayer::Property::FontStyle ), QgsPropertyDefinition( "fontStyle", QObject::tr( "Font style" ), QgsPropertyDefinition::String, origin )},
59 { static_cast< int >( QgsSymbolLayer::Property::Width ), QgsPropertyDefinition( "width", QObject::tr( "Symbol width" ), QgsPropertyDefinition::DoublePositive, origin )},
60 { static_cast< int >( QgsSymbolLayer::Property::Height ), QgsPropertyDefinition( "height", QObject::tr( "Symbol height" ), QgsPropertyDefinition::DoublePositive, origin )},
61 { static_cast< int >( QgsSymbolLayer::Property::PreserveAspectRatio ), QgsPropertyDefinition( "preserveAspectRatio", QObject::tr( "Preserve aspect ratio between width and height" ), QgsPropertyDefinition::Boolean, origin )},
62 { static_cast< int >( QgsSymbolLayer::Property::FillStyle ), QgsPropertyDefinition( "fillStyle", QObject::tr( "Symbol fill style" ), QgsPropertyDefinition::FillStyle, origin )},
63 { static_cast< int >( QgsSymbolLayer::Property::JoinStyle ), QgsPropertyDefinition( "joinStyle", QObject::tr( "Outline join style" ), QgsPropertyDefinition::PenJoinStyle, origin )},
64 { static_cast< int >( QgsSymbolLayer::Property::SecondaryColor ), QgsPropertyDefinition( "color2", QObject::tr( "Secondary fill color" ), QgsPropertyDefinition::ColorWithAlpha, origin )},
65 { static_cast< int >( QgsSymbolLayer::Property::LineAngle ), QgsPropertyDefinition( "lineAngle", QObject::tr( "Angle for line fills" ), QgsPropertyDefinition::Rotation, origin )},
66 { static_cast< int >( QgsSymbolLayer::Property::GradientType ), QgsPropertyDefinition( "gradientType", QgsPropertyDefinition::DataTypeString, QObject::tr( "Gradient type" ), QObject::tr( "string " ) + QLatin1String( "[<b>linear</b>|<b>radial</b>|<b>conical</b>]" ), origin )},
67 { static_cast< int >( QgsSymbolLayer::Property::CoordinateMode ), QgsPropertyDefinition( "gradientMode", QgsPropertyDefinition::DataTypeString, QObject::tr( "Gradient mode" ), QObject::tr( "string " ) + QLatin1String( "[<b>feature</b>|<b>viewport</b>]" ), origin )},
68 { static_cast< int >( QgsSymbolLayer::Property::GradientSpread ), QgsPropertyDefinition( "gradientSpread", QgsPropertyDefinition::DataTypeString, QObject::tr( "Gradient spread" ), QObject::tr( "string " ) + QLatin1String( "[<b>pad</b>|<b>repeat</b>|<b>reflect</b>]" ), origin )},
69 { static_cast< int >( QgsSymbolLayer::Property::GradientReference1X ), QgsPropertyDefinition( "gradientRef1X", QObject::tr( "Reference point 1 (X)" ), QgsPropertyDefinition::Double0To1, origin )},
70 { static_cast< int >( QgsSymbolLayer::Property::GradientReference1Y ), QgsPropertyDefinition( "gradientRef1Y", QObject::tr( "Reference point 1 (Y)" ), QgsPropertyDefinition::Double0To1, origin )},
71 { static_cast< int >( QgsSymbolLayer::Property::GradientReference2X ), QgsPropertyDefinition( "gradientRef2X", QObject::tr( "Reference point 2 (X)" ), QgsPropertyDefinition::Double0To1, origin )},
72 { static_cast< int >( QgsSymbolLayer::Property::GradientReference2Y ), QgsPropertyDefinition( "gradientRef2Y", QObject::tr( "Reference point 2 (Y)" ), QgsPropertyDefinition::Double0To1, origin )},
73 { static_cast< int >( QgsSymbolLayer::Property::GradientReference1IsCentroid ), QgsPropertyDefinition( "gradientRef1Centroid", QObject::tr( "Reference point 1 follows feature centroid" ), QgsPropertyDefinition::Boolean, origin )},
74 { static_cast< int >( QgsSymbolLayer::Property::GradientReference2IsCentroid ), QgsPropertyDefinition( "gradientRef2Centroid", QObject::tr( "Reference point 2 follows feature centroid" ), QgsPropertyDefinition::Boolean, origin )},
75 { static_cast< int >( QgsSymbolLayer::Property::BlurRadius ), QgsPropertyDefinition( "blurRadius", QgsPropertyDefinition::DataTypeNumeric, QObject::tr( "Blur radius" ), QObject::tr( "Integer between 0 and 18" ), origin )},
76 { static_cast< int >( QgsSymbolLayer::Property::LineDistance ), QgsPropertyDefinition( "lineDistance", QObject::tr( "Distance between lines" ), QgsPropertyDefinition::DoublePositive, origin )},
77 { static_cast< int >( QgsSymbolLayer::Property::ShapeburstUseWholeShape ), QgsPropertyDefinition( "shapeburstWholeShape", QObject::tr( "Shade whole shape" ), QgsPropertyDefinition::Boolean, origin )},
78 { static_cast< int >( QgsSymbolLayer::Property::ShapeburstMaxDistance ), QgsPropertyDefinition( "shapeburstMaxDist", QObject::tr( "Maximum distance for shapeburst fill" ), QgsPropertyDefinition::DoublePositive, origin )},
79 { static_cast< int >( QgsSymbolLayer::Property::ShapeburstIgnoreRings ), QgsPropertyDefinition( "shapeburstIgnoreRings", QObject::tr( "Ignore rings in feature" ), QgsPropertyDefinition::Boolean, origin )},
80 { static_cast< int >( QgsSymbolLayer::Property::File ), QgsPropertyDefinition( "file", QObject::tr( "Symbol file path" ), QgsPropertyDefinition::String, origin )},
81 { static_cast< int >( QgsSymbolLayer::Property::DistanceX ), QgsPropertyDefinition( "distanceX", QObject::tr( "Horizontal distance between markers" ), QgsPropertyDefinition::DoublePositive, origin )},
82 { static_cast< int >( QgsSymbolLayer::Property::DistanceY ), QgsPropertyDefinition( "distanceY", QObject::tr( "Vertical distance between markers" ), QgsPropertyDefinition::DoublePositive, origin )},
83 { static_cast< int >( QgsSymbolLayer::Property::DisplacementX ), QgsPropertyDefinition( "displacementX", QObject::tr( "Horizontal displacement between rows" ), QgsPropertyDefinition::DoublePositive, origin )},
84 { static_cast< int >( QgsSymbolLayer::Property::DisplacementY ), QgsPropertyDefinition( "displacementY", QObject::tr( "Vertical displacement between columns" ), QgsPropertyDefinition::DoublePositive, origin )},
85 { static_cast< int >( QgsSymbolLayer::Property::OffsetX ), QgsPropertyDefinition( "offsetX", QObject::tr( "Horizontal offset" ), QgsPropertyDefinition::Double, origin )},
86 { static_cast< int >( QgsSymbolLayer::Property::OffsetY ), QgsPropertyDefinition( "offsetY", QObject::tr( "Vertical offset" ), QgsPropertyDefinition::Double, origin )},
87 { static_cast< int >( QgsSymbolLayer::Property::Opacity ), QgsPropertyDefinition( "alpha", QObject::tr( "Opacity" ), QgsPropertyDefinition::Opacity, origin )},
88 { static_cast< int >( QgsSymbolLayer::Property::CustomDash ), QgsPropertyDefinition( "customDash", QgsPropertyDefinition::DataTypeString, QObject::tr( "Custom dash pattern" ), QObject::tr( "[<b><dash>;<space></b>] e.g. '8;2;1;2'" ), origin )},
89 { static_cast< int >( QgsSymbolLayer::Property::CapStyle ), QgsPropertyDefinition( "capStyle", QObject::tr( "Line cap style" ), QgsPropertyDefinition::CapStyle, origin )},
90 { static_cast< int >( QgsSymbolLayer::Property::Placement ), QgsPropertyDefinition( "placement", QgsPropertyDefinition::DataTypeString, QObject::tr( "Marker placement" ), QObject::tr( "string " ) + "[<b>interval</b>|<b>innervertices</b>|<b>vertex</b>|<b>lastvertex</b>|<b>firstvertex</b>|<b>centerpoint</b>|<b>curvepoint</b>|<b>segmentcenter</b>]", origin )},
91 { static_cast< int >( QgsSymbolLayer::Property::Interval ), QgsPropertyDefinition( "interval", QObject::tr( "Marker interval" ), QgsPropertyDefinition::DoublePositive, origin )},
92 { static_cast< int >( QgsSymbolLayer::Property::OffsetAlongLine ), QgsPropertyDefinition( "offsetAlongLine", QObject::tr( "Offset along line" ), QgsPropertyDefinition::Double, origin )},
93 { static_cast< int >( QgsSymbolLayer::Property::AverageAngleLength ), QgsPropertyDefinition( "averageAngleLength", QObject::tr( "Average line angles over" ), QgsPropertyDefinition::DoublePositive, origin )},
94 { static_cast< int >( QgsSymbolLayer::Property::HorizontalAnchor ), QgsPropertyDefinition( "hAnchor", QObject::tr( "Horizontal anchor point" ), QgsPropertyDefinition::HorizontalAnchor, origin )},
95 { static_cast< int >( QgsSymbolLayer::Property::VerticalAnchor ), QgsPropertyDefinition( "vAnchor", QObject::tr( "Vertical anchor point" ), QgsPropertyDefinition::VerticalAnchor, origin )},
96 { static_cast< int >( QgsSymbolLayer::Property::LayerEnabled ), QgsPropertyDefinition( "enabled", QObject::tr( "Layer enabled" ), QgsPropertyDefinition::Boolean, origin )},
97 { static_cast< int >( QgsSymbolLayer::Property::ArrowWidth ), QgsPropertyDefinition( "arrowWidth", QObject::tr( "Arrow line width" ), QgsPropertyDefinition::StrokeWidth, origin )},
98 { static_cast< int >( QgsSymbolLayer::Property::ArrowStartWidth ), QgsPropertyDefinition( "arrowStartWidth", QObject::tr( "Arrow line start width" ), QgsPropertyDefinition::StrokeWidth, origin )},
99 { static_cast< int >( QgsSymbolLayer::Property::ArrowHeadLength ), QgsPropertyDefinition( "arrowHeadLength", QObject::tr( "Arrow head length" ), QgsPropertyDefinition::DoublePositive, origin )},
100 { static_cast< int >( QgsSymbolLayer::Property::ArrowHeadThickness ), QgsPropertyDefinition( "arrowHeadThickness", QObject::tr( "Arrow head thickness" ), QgsPropertyDefinition::DoublePositive, origin )},
101 { static_cast< int >( QgsSymbolLayer::Property::ArrowHeadType ), QgsPropertyDefinition( "arrowHeadType", QgsPropertyDefinition::DataTypeString, QObject::tr( "Arrow head type" ), QObject::tr( "string " ) + QLatin1String( "[<b>single</b>|<b>reversed</b>|<b>double</b>]" ), origin )},
102 { static_cast< int >( QgsSymbolLayer::Property::ArrowType ), QgsPropertyDefinition( "arrowType", QgsPropertyDefinition::DataTypeString, QObject::tr( "Arrow type" ), QObject::tr( "string " ) + QLatin1String( "[<b>plain</b>|<b>lefthalf</b>|<b>righthalf</b>]" ), origin )},
103 { static_cast< int >( QgsSymbolLayer::Property::PointCount ), QgsPropertyDefinition( "pointCount", QObject::tr( "Point count" ), QgsPropertyDefinition::IntegerPositive, origin )},
104 { static_cast< int >( QgsSymbolLayer::Property::RandomSeed ), QgsPropertyDefinition( "randomSeed", QgsPropertyDefinition::DataTypeNumeric, QObject::tr( "Random number seed" ), QObject::tr( "integer > 0, or 0 for completely random sequence" ), origin )},
105 { static_cast< int >( QgsSymbolLayer::Property::ClipPoints ), QgsPropertyDefinition( "clipPoints", QObject::tr( "Clip markers" ), QgsPropertyDefinition::Boolean, origin )},
106 { static_cast< int >( QgsSymbolLayer::Property::ClipPoints ), QgsPropertyDefinition( "densityArea", QObject::tr( "Density area" ), QgsPropertyDefinition::DoublePositive, origin )},
107 { static_cast< int >( QgsSymbolLayer::Property::DashPatternOffset ), QgsPropertyDefinition( "dashPatternOffset", QObject::tr( "Dash pattern offset" ), QgsPropertyDefinition::DoublePositive, origin )},
108 { static_cast< int >( QgsSymbolLayer::Property::TrimStart ), QgsPropertyDefinition( "trimStart", QObject::tr( "Start trim distance" ), QgsPropertyDefinition::DoublePositive, origin )},
109 { static_cast< int >( QgsSymbolLayer::Property::TrimEnd ), QgsPropertyDefinition( "trimEnd", QObject::tr( "End trim distance" ), QgsPropertyDefinition::DoublePositive, origin )},
110 { static_cast< int >( QgsSymbolLayer::Property::LineStartWidthValue ), QgsPropertyDefinition( "lineStartWidthValue", QObject::tr( "Line start width value" ), QgsPropertyDefinition::Double, origin )},
111 { static_cast< int >( QgsSymbolLayer::Property::LineEndWidthValue ), QgsPropertyDefinition( "lineEndWidthValue", QObject::tr( "Line end width value" ), QgsPropertyDefinition::Double, origin )},
112 { static_cast< int >( QgsSymbolLayer::Property::LineStartColorValue ), QgsPropertyDefinition( "lineStartColorValue", QObject::tr( "Line start color value" ), QgsPropertyDefinition::Double, origin )},
113 { static_cast< int >( QgsSymbolLayer::Property::LineEndColorValue ), QgsPropertyDefinition( "lineEndColorValue", QObject::tr( "Line end color value" ), QgsPropertyDefinition::Double, origin )},
114 { static_cast< int >( QgsSymbolLayer::Property::MarkerClipping ), QgsPropertyDefinition( "markerClipping", QgsPropertyDefinition::DataTypeString, QObject::tr( "Marker clipping mode" ), QObject::tr( "string " ) + QLatin1String( "[<b>no</b>|<b>shape</b>|<b>centroid_within</b>|<b>completely_within</b>]" ), origin )},
115 { static_cast< int >( QgsSymbolLayer::Property::RandomOffsetX ), QgsPropertyDefinition( "randomOffsetX", QObject::tr( "Horizontal random offset" ), QgsPropertyDefinition::Double, origin )},
116 { static_cast< int >( QgsSymbolLayer::Property::RandomOffsetY ), QgsPropertyDefinition( "randomOffsetY", QObject::tr( "Vertical random offset" ), QgsPropertyDefinition::Double, origin )},
117 { static_cast< int >( QgsSymbolLayer::Property::LineClipping ), QgsPropertyDefinition( "lineClipping", QgsPropertyDefinition::DataTypeString, QObject::tr( "Line clipping mode" ), QObject::tr( "string " ) + QLatin1String( "[<b>no</b>|<b>during_render</b>|<b>before_render</b>]" ), origin )},
118 };
119}
120
122{
123 dataDefinedProperties().setProperty( key, property );
124}
125
127{
128 installMasks( context, false );
129
130 if ( QgsSymbol *lSubSymbol = subSymbol() )
131 lSubSymbol->startFeatureRender( feature, context );
132}
133
135{
136 if ( QgsSymbol *lSubSymbol = subSymbol() )
137 lSubSymbol->stopFeatureRender( feature, context );
138
139 removeMasks( context, false );
140}
141
143{
144 return nullptr;
145}
146
148{
149 delete symbol;
150 return false;
151}
152
153bool QgsSymbolLayer::writeDxf( QgsDxfExport &e, double mmMapUnitScaleFactor, const QString &layerName, QgsSymbolRenderContext &context, QPointF shift ) const
154{
155 Q_UNUSED( e )
156 Q_UNUSED( mmMapUnitScaleFactor )
157 Q_UNUSED( layerName )
158 Q_UNUSED( context )
159 Q_UNUSED( shift )
160 return false;
161}
162
164{
165 Q_UNUSED( e )
166 Q_UNUSED( context )
167 return 1.0;
168}
169
171{
172 Q_UNUSED( e )
173 Q_UNUSED( context )
174 return 1.0;
175}
176
178{
179 Q_UNUSED( e )
180 Q_UNUSED( context )
181 return 0.0;
182}
183
185{
186 Q_UNUSED( context )
187 return color();
188}
189
191{
192 Q_UNUSED( context )
193 return 0.0;
194}
195
197{
198 Q_UNUSED( unit )
199 return QVector<qreal>();
200}
201
202Qt::PenStyle QgsSymbolLayer::dxfPenStyle() const
203{
204 return Qt::SolidLine;
205}
206
208{
209 Q_UNUSED( context )
210 return color();
211}
212
213Qt::BrushStyle QgsSymbolLayer::dxfBrushStyle() const
214{
215 return Qt::NoBrush;
216}
217
219{
220 return mPaintEffect.get();
221}
222
224{
225 if ( effect == mPaintEffect.get() )
226 return;
227
228 mPaintEffect.reset( effect );
229}
230
232 : mType( type )
233 , mLocked( locked )
234 , mId( QUuid::createUuid().toString() )
235{
236}
237
239{
240 return Qgis::SymbolLayerFlags();
241}
242
244{
245 return mUserFlags;
246}
247
249{
251}
252
254{
255 return mColor;
256}
257
258void QgsSymbolLayer::setColor( const QColor &color )
259{
260 mColor = color;
261}
262
263void QgsSymbolLayer::setStrokeColor( const QColor & )
264{
265
266}
267
269{
270 return QColor();
271}
272
273void QgsSymbolLayer::setFillColor( const QColor & )
274{
275}
276
278{
279 return QColor();
280}
281
283{
285
286 if ( !context.fields().isEmpty() )
287 {
288 //QgsFields is implicitly shared, so it's cheap to make a copy
289 mFields = context.fields();
290 }
291}
292
294{
296}
297
299{
300 QgsSymbolLayer::initPropertyDefinitions();
301 return sPropertyDefinitions;
302}
303
305
307{
309 return true;
310
311 return symbol->type() == mType;
312}
313
315{
316 return false;
317}
318
320{
321 return false;
322}
323
324void QgsSymbolLayer::setRenderingPass( int renderingPass )
325{
327}
328
330{
331 return mRenderingPass;
332}
333
334QSet<QString> QgsSymbolLayer::usedAttributes( const QgsRenderContext &context ) const
335{
336 // calling referencedFields() with ignoreContext=true because in our expression context
337 // we do not have valid QgsFields yet - because of that the field names from expressions
338 // wouldn't get reported
339 QSet<QString> columns = mDataDefinedProperties.referencedFields( context.expressionContext(), true );
340 return columns;
341}
342
343QgsProperty propertyFromMap( const QVariantMap &map, const QString &baseName )
344{
345 QString prefix;
346 if ( !baseName.isEmpty() )
347 {
348 prefix.append( QStringLiteral( "%1_dd_" ).arg( baseName ) );
349 }
350
351 if ( !map.contains( QStringLiteral( "%1expression" ).arg( prefix ) ) )
352 {
353 //requires at least the expression value
354 return QgsProperty();
355 }
356
357 bool active = ( map.value( QStringLiteral( "%1active" ).arg( prefix ), QStringLiteral( "1" ) ) != QLatin1String( "0" ) );
358 QString expression = map.value( QStringLiteral( "%1expression" ).arg( prefix ) ).toString();
359 bool useExpression = ( map.value( QStringLiteral( "%1useexpr" ).arg( prefix ), QStringLiteral( "1" ) ) != QLatin1String( "0" ) );
360 QString field = map.value( QStringLiteral( "%1field" ).arg( prefix ), QString() ).toString();
361
362 if ( useExpression )
363 return QgsProperty::fromExpression( expression, active );
364 else
365 return QgsProperty::fromField( field, active );
366}
367
368void QgsSymbolLayer::restoreOldDataDefinedProperties( const QVariantMap &stringMap )
369{
370 // property string to type upgrade map
371 static const QMap < QString, int > OLD_PROPS
372 {
373 { "color", static_cast< int >( QgsSymbolLayer::Property::FillColor ) },
374 { "arrow_width", static_cast< int >( QgsSymbolLayer::Property::ArrowWidth ) },
375 { "arrow_start_width", static_cast< int >( QgsSymbolLayer::Property::ArrowStartWidth ) },
376 { "head_length", static_cast< int >( QgsSymbolLayer::Property::ArrowHeadLength ) },
377 { "head_thickness", static_cast< int >( QgsSymbolLayer::Property::ArrowHeadThickness ) },
378 { "offset", static_cast< int >( QgsSymbolLayer::Property::Offset ) },
379 { "head_type", static_cast< int >( QgsSymbolLayer::Property::ArrowHeadType ) },
380 { "arrow_type", static_cast< int >( QgsSymbolLayer::Property::ArrowType ) },
381 { "width_field", static_cast< int >( QgsSymbolLayer::Property::Width ) },
382 { "height_field", static_cast< int >( QgsSymbolLayer::Property::Height ) },
383 { "rotation_field", static_cast< int >( QgsSymbolLayer::Property::Angle ) },
384 { "outline_width_field", static_cast< int >( QgsSymbolLayer::Property::StrokeWidth ) },
385 { "fill_color_field", static_cast< int >( QgsSymbolLayer::Property::FillColor ) },
386 { "outline_color_field", static_cast< int >( QgsSymbolLayer::Property::StrokeColor ) },
387 { "symbol_name_field", static_cast< int >( QgsSymbolLayer::Property::Name ) },
388 { "outline_width", static_cast< int >( QgsSymbolLayer::Property::StrokeWidth ) },
389 { "outline_style", static_cast< int >( QgsSymbolLayer::Property::StrokeStyle ) },
390 { "join_style", static_cast< int >( QgsSymbolLayer::Property::JoinStyle ) },
391 { "fill_color", static_cast< int >( QgsSymbolLayer::Property::FillColor ) },
392 { "outline_color", static_cast< int >( QgsSymbolLayer::Property::StrokeColor ) },
393 { "width", static_cast< int >( QgsSymbolLayer::Property::Width ) },
394 { "height", static_cast< int >( QgsSymbolLayer::Property::Height ) },
395 { "symbol_name", static_cast< int >( QgsSymbolLayer::Property::Name ) },
396 { "angle", static_cast< int >( QgsSymbolLayer::Property::Angle ) },
397 { "fill_style", static_cast< int >( QgsSymbolLayer::Property::FillStyle ) },
398 { "color_border", static_cast< int >( QgsSymbolLayer::Property::StrokeColor ) },
399 { "width_border", static_cast< int >( QgsSymbolLayer::Property::StrokeWidth ) },
400 { "border_color", static_cast< int >( QgsSymbolLayer::Property::StrokeColor ) },
401 { "border_style", static_cast< int >( QgsSymbolLayer::Property::StrokeStyle ) },
402 { "color2", static_cast< int >( QgsSymbolLayer::Property::SecondaryColor ) },
403 { "gradient_type", static_cast< int >( QgsSymbolLayer::Property::GradientType ) },
404 { "coordinate_mode", static_cast< int >( QgsSymbolLayer::Property::CoordinateMode )},
405 { "spread", static_cast< int >( QgsSymbolLayer::Property::GradientSpread ) },
406 { "reference1_x", static_cast< int >( QgsSymbolLayer::Property::GradientReference1X ) },
407 { "reference1_y", static_cast< int >( QgsSymbolLayer::Property::GradientReference1Y ) },
408 { "reference2_x", static_cast< int >( QgsSymbolLayer::Property::GradientReference2X ) },
409 { "reference2_y", static_cast< int >( QgsSymbolLayer::Property::GradientReference2Y )},
410 { "reference1_iscentroid", static_cast< int >( QgsSymbolLayer::Property::GradientReference1IsCentroid )},
411 { "reference2_iscentroid", static_cast< int >( QgsSymbolLayer::Property::GradientReference2IsCentroid )},
412 { "blur_radius", static_cast< int >( QgsSymbolLayer::Property::BlurRadius ) },
413 { "use_whole_shape", static_cast< int >( QgsSymbolLayer::Property::ShapeburstUseWholeShape ) },
414 { "max_distance", static_cast< int >( QgsSymbolLayer::Property::ShapeburstMaxDistance ) },
415 { "ignore_rings", static_cast< int >( QgsSymbolLayer::Property::ShapeburstIgnoreRings ) },
416 { "svgFillColor", static_cast< int >( QgsSymbolLayer::Property::FillColor ) },
417 { "svgOutlineColor", static_cast< int >( QgsSymbolLayer::Property::StrokeColor ) },
418 { "svgOutlineWidth", static_cast< int >( QgsSymbolLayer::Property::StrokeWidth ) },
419 { "svgFile", static_cast< int >( QgsSymbolLayer::Property::File ) },
420 { "lineangle", static_cast< int >( QgsSymbolLayer::Property::LineAngle ) },
421 { "distance", static_cast< int >( QgsSymbolLayer::Property::LineDistance )},
422 { "distance_x", static_cast< int >( QgsSymbolLayer::Property::DistanceX )},
423 { "distance_y", static_cast< int >( QgsSymbolLayer::Property::DistanceY ) },
424 { "displacement_x", static_cast< int >( QgsSymbolLayer::Property::DisplacementX )},
425 { "displacement_y", static_cast< int >( QgsSymbolLayer::Property::DisplacementY ) },
426 { "file", static_cast< int >( QgsSymbolLayer::Property::File ) },
427 { "alpha", static_cast< int >( QgsSymbolLayer::Property::Opacity )},
428 { "customdash", static_cast< int >( QgsSymbolLayer::Property::CustomDash ) },
429 { "line_style", static_cast< int >( QgsSymbolLayer::Property::StrokeStyle ) },
430 { "joinstyle", static_cast< int >( QgsSymbolLayer::Property::JoinStyle ) },
431 { "capstyle", static_cast< int >( QgsSymbolLayer::Property::CapStyle ) },
432 { "placement", static_cast< int >( QgsSymbolLayer::Property::Placement ) },
433 { "interval", static_cast< int >( QgsSymbolLayer::Property::Interval ) },
434 { "offset_along_line", static_cast< int >( QgsSymbolLayer::Property::OffsetAlongLine ) },
435 { "name", static_cast< int >( QgsSymbolLayer::Property::Name ) },
436 { "size", static_cast< int >( QgsSymbolLayer::Property::Size ) },
437 { "fill", static_cast< int >( QgsSymbolLayer::Property::FillColor ) },
438 { "outline", static_cast< int >( QgsSymbolLayer::Property::StrokeColor )},
439 { "char", static_cast< int >( QgsSymbolLayer::Property::Character )},
440 { "enabled", static_cast< int >( QgsSymbolLayer::Property::LayerEnabled ) },
441 { "rotation", static_cast< int >( QgsSymbolLayer::Property::Angle )},
442 { "horizontal_anchor_point", static_cast< int >( QgsSymbolLayer::Property::HorizontalAnchor ) },
443 { "vertical_anchor_point", static_cast< int >( QgsSymbolLayer::Property::VerticalAnchor ) },
444 };
445
446 QVariantMap::const_iterator propIt = stringMap.constBegin();
447 for ( ; propIt != stringMap.constEnd(); ++propIt )
448 {
449 std::unique_ptr<QgsProperty> prop;
450 QString propertyName;
451
452 if ( propIt.key().endsWith( QLatin1String( "_dd_expression" ) ) )
453 {
454 //found a data defined property
455
456 //get data defined property name by stripping "_dd_expression" from property key
457 propertyName = propIt.key().left( propIt.key().length() - 14 );
458
459 prop = std::make_unique<QgsProperty>( propertyFromMap( stringMap, propertyName ) );
460 }
461 else if ( propIt.key().endsWith( QLatin1String( "_expression" ) ) )
462 {
463 //old style data defined property, upgrade
464
465 //get data defined property name by stripping "_expression" from property key
466 propertyName = propIt.key().left( propIt.key().length() - 11 );
467
468 prop = std::make_unique<QgsProperty>( QgsProperty::fromExpression( propIt.value().toString() ) );
469 }
470
471 if ( !prop || !OLD_PROPS.contains( propertyName ) )
472 continue;
473
474 int key = OLD_PROPS.value( propertyName );
475
476 if ( type() == Qgis::SymbolType::Line )
477 {
478 //these keys had different meaning for line symbol layers
479 if ( propertyName == QLatin1String( "width" ) )
480 key = static_cast< int >( QgsSymbolLayer::Property::StrokeWidth );
481 else if ( propertyName == QLatin1String( "color" ) )
482 key = static_cast< int >( QgsSymbolLayer::Property::StrokeColor );
483 }
484
485 setDataDefinedProperty( static_cast< QgsSymbolLayer::Property >( key ), QgsProperty( *prop.get() ) );
486 }
487}
488
490{
491 if ( !destLayer )
492 return;
493
495}
496
498{
499 if ( !destLayer || !mPaintEffect )
500 return;
501
503 destLayer->setPaintEffect( mPaintEffect->clone() );
504 else
505 destLayer->setPaintEffect( nullptr );
506}
507
509 : QgsSymbolLayer( Qgis::SymbolType::Marker, locked )
510{
511
512}
513
515 : QgsSymbolLayer( Qgis::SymbolType::Line, locked )
516{
517}
518
520{
521 return mRingFilter;
522}
523
525{
526 mRingFilter = filter;
527}
528
530 : QgsSymbolLayer( Qgis::SymbolType::Fill, locked )
531{
532}
533
535{
536 Q_UNUSED( context )
537}
538
540{
541 Q_UNUSED( context )
542}
543
545{
546 startRender( context );
547 QgsPaintEffect *effect = paintEffect();
548
549 QPolygonF points = context.patchShape() ? context.patchShape()->toQPolygonF( Qgis::SymbolType::Marker, size ).value( 0 ).value( 0 )
551
552 std::unique_ptr< QgsEffectPainter > effectPainter;
553 if ( effect && effect->enabled() )
554 effectPainter = std::make_unique< QgsEffectPainter >( context.renderContext(), effect );
555
556 for ( QPointF point : std::as_const( points ) )
557 renderPoint( point, context );
558
559 effectPainter.reset();
560
561 stopRender( context );
562}
563
564void QgsMarkerSymbolLayer::markerOffset( QgsSymbolRenderContext &context, double &offsetX, double &offsetY ) const
565{
567}
568
569void QgsMarkerSymbolLayer::markerOffset( QgsSymbolRenderContext &context, double width, double height, double &offsetX, double &offsetY ) const
570{
571 markerOffset( context, width, height, mSizeUnit, mSizeUnit, offsetX, offsetY, mSizeMapUnitScale, mSizeMapUnitScale );
572}
573
574void QgsMarkerSymbolLayer::markerOffset( QgsSymbolRenderContext &context, double width, double height,
575 Qgis::RenderUnit widthUnit, Qgis::RenderUnit heightUnit,
576 double &offsetX, double &offsetY, const QgsMapUnitScale &widthMapUnitScale, const QgsMapUnitScale &heightMapUnitScale ) const
577{
578 offsetX = mOffset.x();
579 offsetY = mOffset.y();
580
582 {
585 bool ok = false;
586 const QPointF offset = QgsSymbolLayerUtils::toPoint( exprVal, &ok );
587 if ( ok )
588 {
589 offsetX = offset.x();
590 offsetY = offset.y();
591 }
592 }
593
596
600 {
602 if ( !QgsVariantUtils::isNull( exprVal ) )
603 {
604 horizontalAnchorPoint = decodeHorizontalAnchorPoint( exprVal.toString() );
605 }
606 }
608 {
610 if ( !QgsVariantUtils::isNull( exprVal ) )
611 {
612 verticalAnchorPoint = decodeVerticalAnchorPoint( exprVal.toString() );
613 }
614 }
615
616 //correct horizontal position according to anchor point
618 {
619 return;
620 }
621
622 double anchorPointCorrectionX = context.renderContext().convertToPainterUnits( width, widthUnit, widthMapUnitScale ) / 2.0;
624 {
625 // rendering for symbol previews -- an size in meters in map units can't be calculated, so treat the size as millimeters
626 // and clamp it to a reasonable range. It's the best we can do in this situation!
627 anchorPointCorrectionX = std::min( std::max( context.renderContext().convertToPainterUnits( width, Qgis::RenderUnit::Millimeters ), 3.0 ), 100.0 ) / 2.0;
628 }
629
630 double anchorPointCorrectionY = context.renderContext().convertToPainterUnits( height, heightUnit, heightMapUnitScale ) / 2.0;
632 {
633 // rendering for symbol previews -- an size in meters in map units can't be calculated, so treat the size as millimeters
634 // and clamp it to a reasonable range. It's the best we can do in this situation!
635 anchorPointCorrectionY = std::min( std::max( context.renderContext().convertToPainterUnits( height, Qgis::RenderUnit::Millimeters ), 3.0 ), 100.0 ) / 2.0;
636 }
637
639 {
640 offsetX += anchorPointCorrectionX;
641 }
642 else if ( horizontalAnchorPoint == Right )
643 {
644 offsetX -= anchorPointCorrectionX;
645 }
646
647//correct vertical position according to anchor point
648 if ( verticalAnchorPoint == Top )
649 {
650 offsetY += anchorPointCorrectionY;
651 }
652 else if ( verticalAnchorPoint == Bottom )
653 {
654 offsetY -= anchorPointCorrectionY;
655 }
656}
657
658QPointF QgsMarkerSymbolLayer::_rotatedOffset( QPointF offset, double angle )
659{
660 angle = DEG2RAD( angle );
661 double c = std::cos( angle ), s = std::sin( angle );
662 return QPointF( offset.x() * c - offset.y() * s, offset.x() * s + offset.y() * c );
663}
664
665QgsMarkerSymbolLayer::HorizontalAnchorPoint QgsMarkerSymbolLayer::decodeHorizontalAnchorPoint( const QString &str )
666{
667 if ( str.compare( QLatin1String( "left" ), Qt::CaseInsensitive ) == 0 )
668 {
670 }
671 else if ( str.compare( QLatin1String( "right" ), Qt::CaseInsensitive ) == 0 )
672 {
674 }
675 else
676 {
678 }
679}
680
681QgsMarkerSymbolLayer::VerticalAnchorPoint QgsMarkerSymbolLayer::decodeVerticalAnchorPoint( const QString &str )
682{
683 if ( str.compare( QLatin1String( "top" ), Qt::CaseInsensitive ) == 0 )
684 {
686 }
687 else if ( str.compare( QLatin1String( "bottom" ), Qt::CaseInsensitive ) == 0 )
688 {
690 }
691 else
692 {
694 }
695}
696
698{
699 mSizeUnit = unit;
700 mOffsetUnit = unit;
701}
702
704{
705 if ( mOffsetUnit != mSizeUnit )
706 {
708 }
709 return mOffsetUnit;
710}
711
713{
714 mSizeMapUnitScale = scale;
715 mOffsetMapUnitScale = scale;
716}
717
719{
721 {
722 return mSizeMapUnitScale;
723 }
724 return QgsMapUnitScale();
725}
726
728{
729 mWidthUnit = unit;
730 mOffsetUnit = unit;
731}
732
734{
735 return mWidthUnit;
736}
737
739{
740 mWidthMapUnitScale = scale;
741}
742
744{
745 return mWidthMapUnitScale;
746}
747
748
750{
751 const QList< QList< QPolygonF > > points = context.patchShape() ? context.patchShape()->toQPolygonF( Qgis::SymbolType::Line, size )
753 startRender( context );
754 QgsPaintEffect *effect = paintEffect();
755
756 std::unique_ptr< QgsEffectPainter > effectPainter;
757 if ( effect && effect->enabled() )
758 effectPainter = std::make_unique< QgsEffectPainter >( context.renderContext(), effect );
759
760 for ( const QList< QPolygonF > &line : points )
761 renderPolyline( line.value( 0 ), context );
762
763 effectPainter.reset();
764
765 stopRender( context );
766}
767
768void QgsLineSymbolLayer::renderPolygonStroke( const QPolygonF &points, const QVector<QPolygonF> *rings, QgsSymbolRenderContext &context )
769{
770 QgsExpressionContextScope *scope = nullptr;
771 std::unique_ptr< QgsExpressionContextScopePopper > scopePopper;
773 {
774 scope = new QgsExpressionContextScope();
775 scopePopper = std::make_unique< QgsExpressionContextScopePopper >( context.renderContext().expressionContext(), scope );
776 }
777
778 switch ( mRingFilter )
779 {
780 case AllRings:
781 case ExteriorRingOnly:
782 {
783 if ( scope )
785 renderPolyline( points, context );
786 break;
787 }
789 break;
790 }
791
792 if ( rings )
793 {
794 switch ( mRingFilter )
795 {
796 case AllRings:
798 {
799 int ringIndex = 1;
800 for ( const QPolygonF &ring : std::as_const( *rings ) )
801 {
802 if ( scope )
804
805 renderPolyline( ring, context );
806 ringIndex++;
807 }
808 }
809 break;
810 case ExteriorRingOnly:
811 break;
812 }
813 }
814}
815
816double QgsLineSymbolLayer::width( const QgsRenderContext &context ) const
817{
819}
820
822{
823 Q_UNUSED( context )
825}
826
827
829{
830 const QList< QList< QPolygonF > > polys = context.patchShape() ? context.patchShape()->toQPolygonF( Qgis::SymbolType::Fill, size )
832
833 startRender( context );
834 QgsPaintEffect *effect = paintEffect();
835
836 std::unique_ptr< QgsEffectPainter > effectPainter;
837 if ( effect && effect->enabled() )
838 effectPainter = std::make_unique< QgsEffectPainter >( context.renderContext(), effect );
839
840 for ( const QList< QPolygonF > &poly : polys )
841 {
842 QVector< QPolygonF > rings;
843 for ( int i = 1; i < poly.size(); ++i )
844 rings << poly.at( i );
845 renderPolygon( poly.value( 0 ), &rings, context );
846 }
847
848 effectPainter.reset();
849
850 stopRender( context );
851}
852
854{
855 return QImage();
856}
857
858void QgsFillSymbolLayer::_renderPolygon( QPainter *p, const QPolygonF &points, const QVector<QPolygonF> *rings, QgsSymbolRenderContext &context )
859{
860 if ( !p )
861 {
862 return;
863 }
864
865 // Disable 'Antialiasing' if the geometry was generalized in the current RenderContext (We known that it must have least #5 points).
866 if ( points.size() <= 5 &&
869 ( p->renderHints() & QPainter::Antialiasing ) )
870 {
871 p->setRenderHint( QPainter::Antialiasing, false );
872 p->drawRect( points.boundingRect() );
873 p->setRenderHint( QPainter::Antialiasing, true );
874 return;
875 }
876
877 // polygons outlines are sometimes rendered wrongly with drawPolygon, when
878 // clipped (see #13343), so use drawPath instead.
879 if ( !rings && p->pen().style() == Qt::NoPen )
880 {
881 // simple polygon without holes
882 p->drawPolygon( points );
883 }
884 else
885 {
886 // polygon with holes must be drawn using painter path
887 QPainterPath path;
888 path.addPolygon( points );
889
890 if ( rings )
891 {
892 for ( auto it = rings->constBegin(); it != rings->constEnd(); ++it )
893 {
894 QPolygonF ring = *it;
895 path.addPolygon( ring );
896 }
897 }
898
899 p->drawPath( path );
900 }
901}
902
903void QgsMarkerSymbolLayer::toSld( QDomDocument &doc, QDomElement &element, const QVariantMap &props ) const
904{
905 QDomElement symbolizerElem = doc.createElement( QStringLiteral( "se:PointSymbolizer" ) );
906 if ( !props.value( QStringLiteral( "uom" ), QString() ).toString().isEmpty() )
907 symbolizerElem.setAttribute( QStringLiteral( "uom" ), props.value( QStringLiteral( "uom" ), QString() ).toString() );
908 element.appendChild( symbolizerElem );
909
910 // <Geometry>
911 QgsSymbolLayerUtils::createGeometryElement( doc, symbolizerElem, props.value( QStringLiteral( "geom" ), QString() ).toString() );
912
913 writeSldMarker( doc, symbolizerElem, props );
914}
915
916QList<QgsSymbolLayerReference> QgsSymbolLayer::masks() const
917{
918 return {};
919}
920
922{
923 double size = mSize;
925 {
926 bool ok = false;
928
929 if ( ok )
930 {
931 switch ( mScaleMethod )
932 {
934 size = std::sqrt( size );
935 break;
937 break;
938 }
939 }
940 }
942}
943
945{
946 double angle = mAngle;
948 {
951 }
952 return angle;
953}
954
956{
957 mClipPath.clear();
958
959 const QgsRenderContext &renderContext = context.renderContext();
960 const QList<QPainterPath> clipPaths = renderContext.symbolLayerClipPaths( id() );
961 if ( !clipPaths.isEmpty() )
962 {
963 QPainterPath mergedPaths;
964 mergedPaths.setFillRule( Qt::WindingFill );
965 for ( const QPainterPath &path : clipPaths )
966 {
967 mergedPaths.addPath( path );
968 }
969
970 if ( !mergedPaths.isEmpty() )
971 {
972 mClipPath.addRect( 0, 0, renderContext.outputSize().width(),
973 renderContext.outputSize().height() );
974 mClipPath = mClipPath.subtracted( mergedPaths );
975 }
976 }
977}
978
979void QgsSymbolLayer::installMasks( QgsRenderContext &context, bool recursive )
980{
981 if ( !mClipPath.isEmpty() )
982 {
983 context.painter()->save();
984 context.painter()->setClipPath( mClipPath, Qt::IntersectClip );
985 }
986
987 if ( QgsSymbol *lSubSymbol = recursive ? subSymbol() : nullptr )
988 {
989 const QList<QgsSymbolLayer *> layers = lSubSymbol->symbolLayers();
990 for ( QgsSymbolLayer *sl : layers )
991 sl->installMasks( context, true );
992 }
993}
994
995void QgsSymbolLayer::removeMasks( QgsRenderContext &context, bool recursive )
996{
997 if ( !mClipPath.isEmpty() )
998 {
999 context.painter()->restore();
1000 }
1001
1002 if ( QgsSymbol *lSubSymbol = recursive ? subSymbol() : nullptr )
1003 {
1004 const QList<QgsSymbolLayer *> layers = lSubSymbol->symbolLayers();
1005 for ( QgsSymbolLayer *sl : layers )
1006 sl->removeMasks( context, true );
1007 }
1008}
1009
1011{
1013}
1014
1015void QgsSymbolLayer::setId( const QString &id )
1016{
1017 mId = id;
1018}
1019
1020QString QgsSymbolLayer::id() const
1021{
1022 return mId;
1023}
The Qgis class provides global constants for use throughout the application.
Definition: qgis.h:54
@ ScaleDiameter
Calculate scale by the diameter.
@ ScaleArea
Calculate scale by the area.
QFlags< SymbolLayerFlag > SymbolLayerFlags
Symbol layer flags.
Definition: qgis.h:623
QFlags< SymbolLayerUserFlag > SymbolLayerUserFlags
Symbol layer user flags.
Definition: qgis.h:646
RenderUnit
Rendering size units.
Definition: qgis.h:4255
@ Millimeters
Millimeters.
@ Unknown
Mixed or unknown units.
@ MetersInMapUnits
Meters value as Map units.
@ RenderSymbolPreview
The render is for a symbol preview only and map based properties may not be available,...
@ DisableSelectionRecoloring
If present, indicates that the symbol layer should not be recolored when rendering selected features.
SymbolType
Symbol types.
Definition: qgis.h:401
@ Marker
Marker symbol.
@ Line
Line symbol.
@ Fill
Fill symbol.
static bool isGeneralizableByDeviceBoundingBox(const QgsRectangle &envelope, float mapToPixelTol=1.0f)
Returns whether the device-envelope can be replaced by its BBOX when is applied the specified toleran...
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.
Exports QGIS layers to the DXF format.
Definition: qgsdxfexport.h:66
static double mapUnitScaleFactor(double scale, Qgis::RenderUnit symbolUnits, Qgis::DistanceUnit mapUnits, double mapUnitsPerPixel=1.0)
Returns scale factor for conversion to map units.
Qgis::DistanceUnit mapUnits() const
Retrieve map units.
double symbologyScale() const
Returns the reference scale for output.
Definition: qgsdxfexport.h:252
Single scope for storing variables and functions for use within a QgsExpressionContext.
void addVariable(const QgsExpressionContextScope::StaticVariable &variable)
Adds a variable into the context scope.
static const QString EXPR_GEOMETRY_RING_NUM
Inbuilt variable name for geometry ring number variable.
The feature class encapsulates a single feature including its unique ID, geometry and a list of field...
Definition: qgsfeature.h:56
bool isEmpty() const
Checks whether the container is empty.
Definition: qgsfields.cpp:128
virtual void renderPolygon(const QPolygonF &points, const QVector< QPolygonF > *rings, QgsSymbolRenderContext &context)=0
Renders the fill symbol layer for the polygon whose outer ring is defined by points,...
void _renderPolygon(QPainter *p, const QPolygonF &points, const QVector< QPolygonF > *rings, QgsSymbolRenderContext &context)
Default method to render polygon.
virtual QImage toTiledPatternImage() const
Renders the symbol layer as an image that can be used as a seamless pattern fill for polygons,...
void drawPreviewIcon(QgsSymbolRenderContext &context, QSize size) override
QgsFillSymbolLayer(const QgsFillSymbolLayer &other)=delete
QgsFillSymbolLayer cannot be copied.
QList< QList< QPolygonF > > toQPolygonF(Qgis::SymbolType type, QSizeF size) const
Converts the patch shape to a set of QPolygonF objects representing how the patch should be drawn for...
Qgis::RenderUnit mOffsetUnit
RenderRingFilter
Options for filtering rings when the line symbol layer is being used to render a polygon's rings.
@ ExteriorRingOnly
Render the exterior ring only.
@ InteriorRingsOnly
Render the interior rings only.
@ AllRings
Render both exterior and interior rings.
QgsMapUnitScale mWidthMapUnitScale
RenderRingFilter ringFilter() const
Returns the line symbol layer's ring filter, which controls which rings are rendered when the line sy...
void drawPreviewIcon(QgsSymbolRenderContext &context, QSize size) override
QgsLineSymbolLayer(const QgsLineSymbolLayer &other)=delete
QgsLineSymbolLayer cannot be copied.
void setOutputUnit(Qgis::RenderUnit unit) override
Sets the units to use for sizes and widths within the symbol layer.
Qgis::RenderUnit outputUnit() const override
Returns the units to use for sizes and widths within the symbol layer.
virtual void renderPolygonStroke(const QPolygonF &points, const QVector< QPolygonF > *rings, QgsSymbolRenderContext &context)
Renders the line symbol layer along the outline of polygon, using the given render context.
Qgis::RenderUnit mWidthUnit
virtual void renderPolyline(const QPolygonF &points, QgsSymbolRenderContext &context)=0
Renders the line symbol layer along the line joining points, using the given render context.
RenderRingFilter mRingFilter
virtual double width() const
Returns the estimated width for the line symbol layer.
double dxfWidth(const QgsDxfExport &e, QgsSymbolRenderContext &context) const override
Gets line width.
QgsMapUnitScale mapUnitScale() const override
void setRingFilter(QgsLineSymbolLayer::RenderRingFilter filter)
Sets the line symbol layer's ring filter, which controls which rings are rendered when the line symbo...
void setMapUnitScale(const QgsMapUnitScale &scale) override
Qgis::RenderUnit widthUnit() const
Returns the units for the line's width.
double mapUnitsPerPixel() const
Returns the current map units per pixel.
Struct for storing maximum and minimum scales for measurements in map units.
double mSize
Marker size.
void drawPreviewIcon(QgsSymbolRenderContext &context, QSize size) override
Qgis::RenderUnit mOffsetUnit
Offset units.
QPointF offset() const
Returns the marker's offset, which is the horizontal and vertical displacement which the rendered mar...
HorizontalAnchorPoint
Symbol horizontal anchor points.
@ Right
Align to right side of symbol.
@ HCenter
Align to horizontal center of symbol.
@ Left
Align to left side of symbol.
Qgis::RenderUnit outputUnit() const override
Returns the units to use for sizes and widths within the symbol layer.
virtual void renderPoint(QPointF point, QgsSymbolRenderContext &context)=0
Renders a marker at the specified point.
QPointF mOffset
Marker offset.
QgsMapUnitScale mapUnitScale() const override
double size() const
Returns the symbol size.
QgsMapUnitScale mOffsetMapUnitScale
Offset map unit scale.
HorizontalAnchorPoint mHorizontalAnchorPoint
Horizontal anchor point.
QgsMarkerSymbolLayer(const QgsMarkerSymbolLayer &other)=delete
QgsMarkerSymbolLayer cannot be copied.
static QPointF _rotatedOffset(QPointF offset, double angle)
Adjusts a marker offset to account for rotation.
virtual double dxfAngle(QgsSymbolRenderContext &context) const override
Gets angle.
Qgis::ScaleMethod mScaleMethod
Marker size scaling method.
virtual double dxfSize(const QgsDxfExport &e, QgsSymbolRenderContext &context) const override
Gets marker size.
void stopRender(QgsSymbolRenderContext &context) override
Called after a set of rendering operations has finished on the supplied render context.
VerticalAnchorPoint verticalAnchorPoint() const
Returns the vertical anchor point for positioning the symbol.
QgsMapUnitScale mSizeMapUnitScale
Marker size map unit scale.
Qgis::RenderUnit mSizeUnit
Marker size unit.
void setOutputUnit(Qgis::RenderUnit unit) override
Sets the units to use for sizes and widths within the symbol layer.
HorizontalAnchorPoint horizontalAnchorPoint() const
Returns the horizontal anchor point for positioning the symbol.
VerticalAnchorPoint
Symbol vertical anchor points.
@ VCenter
Align to vertical center of symbol.
@ Bottom
Align to bottom of symbol.
@ Top
Align to top of symbol.
void markerOffset(QgsSymbolRenderContext &context, double &offsetX, double &offsetY) const
Calculates the required marker offset, including both the symbol offset and any displacement required...
VerticalAnchorPoint mVerticalAnchorPoint
Vertical anchor point.
void toSld(QDomDocument &doc, QDomElement &element, const QVariantMap &props) const override
Saves the symbol layer as SLD.
virtual void writeSldMarker(QDomDocument &doc, QDomElement &element, const QVariantMap &props) const
Writes the symbol layer definition as a SLD XML element.
double mAngle
Marker rotation angle, in degrees clockwise from north.
void startRender(QgsSymbolRenderContext &context) override
Called before a set of rendering operations commences on the supplied render context.
double angle() const
Returns the rotation angle for the marker, in degrees clockwise from north.
void setMapUnitScale(const QgsMapUnitScale &scale) override
static bool isDefaultStack(QgsPaintEffect *effect)
Tests whether a paint effect matches the default effects stack.
Base class for visual effects which can be applied to QPicture drawings.
bool enabled() const
Returns whether the effect is enabled.
QVariant value(int key, const QgsExpressionContext &context, const QVariant &defaultValue=QVariant()) const final
Returns the calculated value of the property with the specified key from within the collection.
void setProperty(int key, const QgsProperty &property)
Adds a property to the collection and takes ownership of it.
bool isActive(int key) const final
Returns true if the collection contains an active property with the specified key.
bool prepare(const QgsExpressionContext &context=QgsExpressionContext()) const final
Prepares the collection against a specified expression context.
bool hasActiveProperties() const final
Returns true if the collection has any active properties, or false if all properties within the colle...
QSet< QString > referencedFields(const QgsExpressionContext &context=QgsExpressionContext(), bool ignoreContext=false) const final
Returns the set of any fields referenced by the active properties from the collection.
Definition for a property.
Definition: qgsproperty.h:45
@ HorizontalAnchor
Horizontal anchor point.
Definition: qgsproperty.h:73
@ Double
Double value (including negative values)
Definition: qgsproperty.h:55
@ VerticalAnchor
Vertical anchor point.
Definition: qgsproperty.h:74
@ Double0To1
Double value between 0-1 (inclusive)
Definition: qgsproperty.h:57
@ FillStyle
Fill style (eg solid, lines)
Definition: qgsproperty.h:71
@ StrokeWidth
Line stroke width.
Definition: qgsproperty.h:70
@ LineStyle
Line style (eg solid/dashed)
Definition: qgsproperty.h:69
@ String
Any string value.
Definition: qgsproperty.h:59
@ Boolean
Boolean value.
Definition: qgsproperty.h:51
@ PenJoinStyle
Pen join style.
Definition: qgsproperty.h:64
@ IntegerPositive
Positive integer values (including 0)
Definition: qgsproperty.h:53
@ Opacity
Opacity (0-100)
Definition: qgsproperty.h:60
@ CapStyle
Line cap style (eg round)
Definition: qgsproperty.h:72
@ Rotation
Rotation (value between 0-360 degrees)
Definition: qgsproperty.h:58
@ Size
1D size (eg marker radius, or square marker height/width)
Definition: qgsproperty.h:67
@ ColorWithAlpha
Color with alpha channel.
Definition: qgsproperty.h:62
@ DoublePositive
Positive double value (including 0)
Definition: qgsproperty.h:56
@ DataTypeString
Property requires a string value.
Definition: qgsproperty.h:90
@ DataTypeNumeric
Property requires a numeric value.
Definition: qgsproperty.h:97
A store for object properties.
Definition: qgsproperty.h:228
static QgsProperty fromExpression(const QString &expression, bool isActive=true)
Returns a new ExpressionBasedProperty created from the specified expression.
static QgsProperty fromField(const QString &fieldName, bool isActive=true)
Returns a new FieldBasedProperty created from the specified field name.
Contains information about the context of a rendering operation.
double convertToPainterUnits(double size, Qgis::RenderUnit unit, const QgsMapUnitScale &scale=QgsMapUnitScale(), Qgis::RenderSubcomponentProperty property=Qgis::RenderSubcomponentProperty::Generic) const
Converts a size from the specified units to painter units (pixels).
QPainter * painter()
Returns the destination QPainter for the render operation.
QgsExpressionContext & expressionContext()
Gets the expression context.
QSize outputSize() const
Returns the size of the resulting rendered image, in pixels.
const QgsVectorSimplifyMethod & vectorSimplifyMethod() const
Returns the simplification settings to use when rendering vector layers.
const QgsMapToPixel & mapToPixel() const
Returns the context's map to pixel transform, which transforms between map coordinates and device coo...
Qgis::RenderContextFlags flags() const
Returns combination of flags used for rendering.
QList< QPainterPath > symbolLayerClipPaths(const QString &symbolLayerId) const
Returns clip paths to be applied to the symbolLayer before rendering.
static QgsStyle * defaultStyle(bool initialize=true)
Returns the default application-wide style.
Definition: qgsstyle.cpp:145
QList< QList< QPolygonF > > defaultPatchAsQPolygonF(Qgis::SymbolType type, QSizeF size) const
Returns the default patch geometry for the given symbol type and size as a set of QPolygonF objects (...
Definition: qgsstyle.cpp:1231
static QPointF toPoint(const QVariant &value, bool *ok=nullptr)
Converts a value to a point.
static void createGeometryElement(QDomDocument &doc, QDomElement &element, const QString &geomFunc)
static QString encodePoint(QPointF point)
Encodes a QPointF to a string.
QgsFields mFields
virtual bool setSubSymbol(QgsSymbol *symbol)
Sets layer's subsymbol. takes ownership of the passed symbol.
bool shouldRenderUsingSelectionColor(const QgsSymbolRenderContext &context) const
Returns true if the symbol layer should be rendered using the selection color from the render context...
Qgis::SymbolType type() const
virtual void startFeatureRender(const QgsFeature &feature, QgsRenderContext &context)
Called before the layer will be rendered for a particular feature.
virtual QColor fillColor() const
Returns the fill color for the symbol layer.
void setId(const QString &id)
Set symbol layer identifier This id has to be unique in the whole project.
virtual void setStrokeColor(const QColor &color)
Sets the stroke color for the symbol layer.
QPainterPath mClipPath
virtual double dxfSize(const QgsDxfExport &e, QgsSymbolRenderContext &context) const
Gets marker size.
virtual double dxfOffset(const QgsDxfExport &e, QgsSymbolRenderContext &context) const
Gets offset.
virtual QColor dxfBrushColor(QgsSymbolRenderContext &context) const
Gets brush/fill color.
Qgis::SymbolType mType
void removeMasks(QgsRenderContext &context, bool recursive)
When rendering, remove previously installed masks from context painter if recursive is true masks are...
virtual QSet< QString > usedAttributes(const QgsRenderContext &context) const
Returns the set of attributes referenced by the layer.
void copyDataDefinedProperties(QgsSymbolLayer *destLayer) const
Copies all data defined properties of this layer to another symbol layer.
Property
Data definable properties.
@ ArrowHeadLength
Arrow head length.
@ GradientType
Gradient fill type.
@ SecondaryColor
Secondary color (eg for gradient fills)
@ File
Filename, eg for svg files.
@ VerticalAnchor
Vertical anchor point.
@ GradientReference2Y
Gradient reference point 2 y.
@ GradientReference1X
Gradient reference point 1 x.
@ OffsetY
Vertical offset.
@ OffsetX
Horizontal offset.
@ GradientReference1Y
Gradient reference point 1 y.
@ ArrowWidth
Arrow tail width.
@ PointCount
Point count.
@ DashPatternOffset
Dash pattern offset,.
@ GradientSpread
Gradient spread mode.
@ OffsetAlongLine
Offset along line.
@ ArrowHeadType
Arrow head type.
@ CustomDash
Custom dash pattern.
@ ShapeburstMaxDistance
Shapeburst fill from edge distance.
@ HorizontalAnchor
Horizontal anchor point.
@ StrokeStyle
Stroke style (eg solid, dashed)
@ Name
Name, eg shape name for simple markers.
@ DistanceY
Vertical distance between points.
@ LineEndColorValue
End line color for interpolated line renderer (since QGIS 3.22)
@ ClipPoints
Whether markers should be clipped to polygon boundaries.
@ ArrowHeadThickness
Arrow head thickness.
@ LineClipping
Line clipping mode (since QGIS 3.24)
@ ShapeburstIgnoreRings
Shapeburst ignore rings.
@ Character
Character, eg for font marker symbol layers.
@ ShapeburstUseWholeShape
Shapeburst use whole shape.
@ DisplacementX
Horizontal displacement.
@ CoordinateMode
Gradient coordinate mode.
@ FillStyle
Fill style (eg solid, dots)
@ GradientReference2X
Gradient reference point 2 x.
@ StrokeColor
Stroke color.
@ TrimStart
Trim distance from start of line (since QGIS 3.20)
@ ArrowStartWidth
Arrow tail start width.
@ CapStyle
Line cap style.
@ BlurRadius
Shapeburst blur radius.
@ Placement
Line marker placement.
@ MarkerClipping
Marker clipping mode (since QGIS 3.24)
@ RandomSeed
Random number seed.
@ LineAngle
Line angle, or angle of hash lines for hash line symbols.
@ JoinStyle
Line join style.
@ RandomOffsetY
Random offset Y (since QGIS 3.24)
@ DisplacementY
Vertical displacement.
@ PreserveAspectRatio
Preserve aspect ratio between width and height.
@ LineStartColorValue
Start line color for interpolated line renderer (since QGIS 3.22)
@ DistanceX
Horizontal distance between points.
@ AverageAngleLength
Length to average symbol angles over.
@ LineEndWidthValue
End line width for interpolated line renderer (since QGIS 3.22)
@ GradientReference1IsCentroid
Gradient reference point 1 is centroid.
@ Interval
Line marker interval.
@ StrokeWidth
Stroke width.
@ FontFamily
Font family.
@ GradientReference2IsCentroid
Gradient reference point 2 is centroid.
@ LineStartWidthValue
Start line width for interpolated line renderer (since QGIS 3.22)
@ LineDistance
Distance between lines, or length of lines for hash line symbols.
@ Offset
Symbol offset.
@ RandomOffsetX
Random offset X (since QGIS 3.24)
@ TrimEnd
Trim distance from end of line (since QGIS 3.20)
@ Height
Symbol height.
@ LayerEnabled
Whether symbol layer is enabled.
void installMasks(QgsRenderContext &context, bool recursive)
When rendering, install masks on context painter if recursive is true masks are installed recursively...
void restoreOldDataDefinedProperties(const QVariantMap &stringMap)
Restores older data defined properties from string map.
void setPaintEffect(QgsPaintEffect *effect)
Sets the current paint effect for the layer.
void setRenderingPass(int renderingPass)
Specifies the rendering pass in which this symbol layer should be rendered.
QgsPaintEffect * paintEffect() const
Returns the current paint effect for the layer.
virtual void startRender(QgsSymbolRenderContext &context)=0
Called before a set of rendering operations commences on the supplied render context.
QgsSymbolLayer(const QgsSymbolLayer &other)=delete
QgsSymbolLayer cannot be copied.
std::unique_ptr< QgsPaintEffect > mPaintEffect
virtual Qt::PenStyle dxfPenStyle() const
Gets pen style.
virtual void setFillColor(const QColor &color)
Sets the fill color for the symbol layer.
virtual void prepareExpressions(const QgsSymbolRenderContext &context)
Prepares all data defined property expressions for evaluation.
void setUserFlags(Qgis::SymbolLayerUserFlags flags)
Sets user-controlled flags which control the symbol layer's behavior.
virtual QColor dxfColor(QgsSymbolRenderContext &context) const
Gets color.
int renderingPass() const
Specifies the rendering pass in which this symbol layer should be rendered.
virtual void stopRender(QgsSymbolRenderContext &context)=0
Called after a set of rendering operations has finished on the supplied render context.
virtual bool isCompatibleWithSymbol(QgsSymbol *symbol) const
Returns if the layer can be used below the specified symbol.
QString id() const
Returns symbol layer identifier This id is unique in the whole project.
virtual void setDataDefinedProperty(Property key, const QgsProperty &property)
Sets a data defined property for the layer.
virtual void setColor(const QColor &color)
Sets the "representative" color for the symbol layer.
virtual QgsSymbol * subSymbol()
Returns the symbol's sub symbol, if present.
Qgis::SymbolLayerUserFlags userFlags() const
Returns user-controlled flags which control the symbol layer's behavior.
virtual QColor color() const
Returns the "representative" color of the symbol layer.
virtual void prepareMasks(const QgsSymbolRenderContext &context)
Prepares all mask internal objects according to what is defined in context This should be called prio...
virtual void stopFeatureRender(const QgsFeature &feature, QgsRenderContext &context)
Called after the layer has been rendered for a particular feature.
static const QgsPropertiesDefinition & propertyDefinitions()
Returns the symbol layer property definitions.
virtual double dxfWidth(const QgsDxfExport &e, QgsSymbolRenderContext &context) const
Gets line width.
virtual QColor strokeColor() const
Returns the stroke color for the symbol layer.
virtual double dxfAngle(QgsSymbolRenderContext &context) const
Gets angle.
Qgis::SymbolLayerUserFlags mUserFlags
User controlled flags.
virtual bool canCauseArtifactsBetweenAdjacentTiles() const
Returns true if the symbol layer rendering can cause visible artifacts across a single feature when t...
virtual ~QgsSymbolLayer()
virtual bool usesMapUnits() const
Returns true if the symbol layer has any components which use map unit based sizes.
virtual bool writeDxf(QgsDxfExport &e, double mmMapUnitScaleFactor, const QString &layerName, QgsSymbolRenderContext &context, QPointF shift=QPointF(0.0, 0.0)) const
write as DXF
void copyPaintEffect(QgsSymbolLayer *destLayer) const
Copies paint effect of this layer to another symbol layer.
virtual Qgis::SymbolLayerFlags flags() const
Returns flags which control the symbol layer's behavior.
QgsPropertyCollection mDataDefinedProperties
virtual QList< QgsSymbolLayerReference > masks() const
Returns masks defined by this symbol layer.
QgsPropertyCollection & dataDefinedProperties()
Returns a reference to the symbol layer's property collection, used for data defined overrides.
virtual Qt::BrushStyle dxfBrushStyle() const
Gets brush/fill style.
virtual QVector< qreal > dxfCustomDashPattern(Qgis::RenderUnit &unit) const
Gets dash pattern.
virtual bool hasDataDefinedProperties() const
Returns true if the symbol layer (or any of its sub-symbols) contains data defined properties.
void setDataDefinedProperties(const QgsPropertyCollection &collection)
Sets the symbol layer's property collection, used for data defined overrides.
QgsFields fields() const
Fields of the layer.
bool selected() const
Returns true if symbols should be rendered using the selected symbol coloring and style.
void setOriginalValueVariable(const QVariant &value)
Sets the original value variable value for data defined symbology.
const QgsLegendPatchShape * patchShape() const
Returns the symbol patch shape, to use if rendering symbol preview icons.
QgsRenderContext & renderContext()
Returns a reference to the context's render context.
Abstract base class for all rendered symbols.
Definition: qgssymbol.h:94
Qgis::SymbolType type() const
Returns the symbol's type.
Definition: qgssymbol.h:156
static bool isNull(const QVariant &variant, bool silenceNullWarnings=false)
Returns true if the specified variant should be considered a NULL value.
SimplifyHints simplifyHints() const
Gets the simplification hints of the vector layer managed.
float threshold() const
Gets the simplification threshold of the vector layer managed.
@ AntialiasingSimplification
The geometries can be rendered with 'AntiAliasing' disabled because of it is '1-pixel size'.
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:716
As part of the API refactoring and improvements which landed in the Processing API was substantially reworked from the x version This was done in order to allow much of the underlying Processing framework to be ported into c
#define str(x)
Definition: qgis.cpp:38
#define DEG2RAD(x)
QMap< int, QgsPropertyDefinition > QgsPropertiesDefinition
Definition of available properties.
QgsProperty propertyFromMap(const QVariantMap &map, const QString &baseName)
Single variable definition for use within a QgsExpressionContextScope.