QGIS API Documentation  3.27.0-Master (0e23467727)
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 "qgsclipper.h"
18 #include "qgsexpression.h"
19 #include "qgsrendercontext.h"
20 #include "qgsvectorlayer.h"
21 #include "qgsdxfexport.h"
22 #include "qgsgeometrysimplifier.h"
23 #include "qgspainteffect.h"
24 #include "qgseffectstack.h"
25 #include "qgspainteffectregistry.h"
26 #include "qgsproperty.h"
27 #include "qgsexpressioncontext.h"
28 #include "qgssymbollayerutils.h"
29 #include "qgsapplication.h"
30 #include "qgsmultipoint.h"
31 #include "qgslegendpatchshape.h"
32 #include "qgsstyle.h"
34 #include "qgssymbol.h"
36 
37 #include <QSize>
38 #include <QPainter>
39 #include <QPointF>
40 #include <QPolygonF>
41 
42 QgsPropertiesDefinition QgsSymbolLayer::sPropertyDefinitions;
43 
44 void QgsSymbolLayer::initPropertyDefinitions()
45 {
46  if ( !sPropertyDefinitions.isEmpty() )
47  return;
48 
49  QString origin = QStringLiteral( "symbol" );
50 
51  sPropertyDefinitions = QgsPropertiesDefinition
52  {
53  { QgsSymbolLayer::PropertySize, QgsPropertyDefinition( "size", QObject::tr( "Symbol size" ), QgsPropertyDefinition::Size, origin ) },
54  { QgsSymbolLayer::PropertyAngle, QgsPropertyDefinition( "angle", QObject::tr( "Rotation angle" ), QgsPropertyDefinition::Rotation, origin ) },
55  { QgsSymbolLayer::PropertyName, QgsPropertyDefinition( "name", QObject::tr( "Symbol name" ), QgsPropertyDefinition::String, origin ) },
56  { QgsSymbolLayer::PropertyFillColor, QgsPropertyDefinition( "fillColor", QObject::tr( "Symbol fill color" ), QgsPropertyDefinition::ColorWithAlpha, origin ) },
57  { QgsSymbolLayer::PropertyStrokeColor, QgsPropertyDefinition( "outlineColor", QObject::tr( "Symbol stroke color" ), QgsPropertyDefinition::ColorWithAlpha, origin ) },
58  { QgsSymbolLayer::PropertyStrokeWidth, QgsPropertyDefinition( "outlineWidth", QObject::tr( "Symbol stroke width" ), QgsPropertyDefinition::StrokeWidth, origin ) },
59  { QgsSymbolLayer::PropertyStrokeStyle, QgsPropertyDefinition( "outlineStyle", QObject::tr( "Symbol stroke style" ), QgsPropertyDefinition::LineStyle, origin )},
60  { QgsSymbolLayer::PropertyOffset, QgsPropertyDefinition( "offset", QObject::tr( "Symbol offset" ), QgsPropertyDefinition::Offset, origin )},
61  { QgsSymbolLayer::PropertyCharacter, QgsPropertyDefinition( "char", QObject::tr( "Marker character(s)" ), QgsPropertyDefinition::String, origin )},
62  { QgsSymbolLayer::PropertyFontFamily, QgsPropertyDefinition( "fontFamily", QObject::tr( "Font family" ), QgsPropertyDefinition::String, origin )},
63  { QgsSymbolLayer::PropertyFontStyle, QgsPropertyDefinition( "fontStyle", QObject::tr( "Font style" ), QgsPropertyDefinition::String, origin )},
64  { QgsSymbolLayer::PropertyWidth, QgsPropertyDefinition( "width", QObject::tr( "Symbol width" ), QgsPropertyDefinition::DoublePositive, origin )},
65  { QgsSymbolLayer::PropertyHeight, QgsPropertyDefinition( "height", QObject::tr( "Symbol height" ), QgsPropertyDefinition::DoublePositive, origin )},
66  { QgsSymbolLayer::PropertyPreserveAspectRatio, QgsPropertyDefinition( "preserveAspectRatio", QObject::tr( "Preserve aspect ratio between width and height" ), QgsPropertyDefinition::Boolean, origin )},
67  { QgsSymbolLayer::PropertyFillStyle, QgsPropertyDefinition( "fillStyle", QObject::tr( "Symbol fill style" ), QgsPropertyDefinition::FillStyle, origin )},
68  { QgsSymbolLayer::PropertyJoinStyle, QgsPropertyDefinition( "joinStyle", QObject::tr( "Outline join style" ), QgsPropertyDefinition::PenJoinStyle, origin )},
69  { QgsSymbolLayer::PropertySecondaryColor, QgsPropertyDefinition( "color2", QObject::tr( "Secondary fill color" ), QgsPropertyDefinition::ColorWithAlpha, origin )},
70  { QgsSymbolLayer::PropertyLineAngle, QgsPropertyDefinition( "lineAngle", QObject::tr( "Angle for line fills" ), QgsPropertyDefinition::Rotation, origin )},
71  { QgsSymbolLayer::PropertyGradientType, QgsPropertyDefinition( "gradientType", QgsPropertyDefinition::DataTypeString, QObject::tr( "Gradient type" ), QObject::tr( "string " ) + QLatin1String( "[<b>linear</b>|<b>radial</b>|<b>conical</b>]" ), origin )},
72  { QgsSymbolLayer::PropertyCoordinateMode, QgsPropertyDefinition( "gradientMode", QgsPropertyDefinition::DataTypeString, QObject::tr( "Gradient mode" ), QObject::tr( "string " ) + QLatin1String( "[<b>feature</b>|<b>viewport</b>]" ), origin )},
73  { QgsSymbolLayer::PropertyGradientSpread, QgsPropertyDefinition( "gradientSpread", QgsPropertyDefinition::DataTypeString, QObject::tr( "Gradient spread" ), QObject::tr( "string " ) + QLatin1String( "[<b>pad</b>|<b>repeat</b>|<b>reflect</b>]" ), origin )},
74  { QgsSymbolLayer::PropertyGradientReference1X, QgsPropertyDefinition( "gradientRef1X", QObject::tr( "Reference point 1 (X)" ), QgsPropertyDefinition::Double0To1, origin )},
75  { QgsSymbolLayer::PropertyGradientReference1Y, QgsPropertyDefinition( "gradientRef1Y", QObject::tr( "Reference point 1 (Y)" ), QgsPropertyDefinition::Double0To1, origin )},
76  { QgsSymbolLayer::PropertyGradientReference2X, QgsPropertyDefinition( "gradientRef2X", QObject::tr( "Reference point 2 (X)" ), QgsPropertyDefinition::Double0To1, origin )},
77  { QgsSymbolLayer::PropertyGradientReference2Y, QgsPropertyDefinition( "gradientRef2Y", QObject::tr( "Reference point 2 (Y)" ), QgsPropertyDefinition::Double0To1, origin )},
78  { QgsSymbolLayer::PropertyGradientReference1IsCentroid, QgsPropertyDefinition( "gradientRef1Centroid", QObject::tr( "Reference point 1 follows feature centroid" ), QgsPropertyDefinition::Boolean, origin )},
79  { QgsSymbolLayer::PropertyGradientReference2IsCentroid, QgsPropertyDefinition( "gradientRef2Centroid", QObject::tr( "Reference point 2 follows feature centroid" ), QgsPropertyDefinition::Boolean, origin )},
80  { QgsSymbolLayer::PropertyBlurRadius, QgsPropertyDefinition( "blurRadius", QgsPropertyDefinition::DataTypeNumeric, QObject::tr( "Blur radius" ), QObject::tr( "Integer between 0 and 18" ), origin )},
81  { QgsSymbolLayer::PropertyLineDistance, QgsPropertyDefinition( "lineDistance", QObject::tr( "Distance between lines" ), QgsPropertyDefinition::DoublePositive, origin )},
82  { QgsSymbolLayer::PropertyShapeburstUseWholeShape, QgsPropertyDefinition( "shapeburstWholeShape", QObject::tr( "Shade whole shape" ), QgsPropertyDefinition::Boolean, origin )},
83  { QgsSymbolLayer::PropertyShapeburstMaxDistance, QgsPropertyDefinition( "shapeburstMaxDist", QObject::tr( "Maximum distance for shapeburst fill" ), QgsPropertyDefinition::DoublePositive, origin )},
84  { QgsSymbolLayer::PropertyShapeburstIgnoreRings, QgsPropertyDefinition( "shapeburstIgnoreRings", QObject::tr( "Ignore rings in feature" ), QgsPropertyDefinition::Boolean, origin )},
85  { QgsSymbolLayer::PropertyFile, QgsPropertyDefinition( "file", QObject::tr( "Symbol file path" ), QgsPropertyDefinition::String, origin )},
86  { QgsSymbolLayer::PropertyDistanceX, QgsPropertyDefinition( "distanceX", QObject::tr( "Horizontal distance between markers" ), QgsPropertyDefinition::DoublePositive, origin )},
87  { QgsSymbolLayer::PropertyDistanceY, QgsPropertyDefinition( "distanceY", QObject::tr( "Vertical distance between markers" ), QgsPropertyDefinition::DoublePositive, origin )},
88  { QgsSymbolLayer::PropertyDisplacementX, QgsPropertyDefinition( "displacementX", QObject::tr( "Horizontal displacement between rows" ), QgsPropertyDefinition::DoublePositive, origin )},
89  { QgsSymbolLayer::PropertyDisplacementY, QgsPropertyDefinition( "displacementY", QObject::tr( "Vertical displacement between columns" ), QgsPropertyDefinition::DoublePositive, origin )},
90  { QgsSymbolLayer::PropertyOffsetX, QgsPropertyDefinition( "offsetX", QObject::tr( "Horizontal offset" ), QgsPropertyDefinition::Double, origin )},
91  { QgsSymbolLayer::PropertyOffsetY, QgsPropertyDefinition( "offsetY", QObject::tr( "Vertical offset" ), QgsPropertyDefinition::Double, origin )},
92  { QgsSymbolLayer::PropertyOpacity, QgsPropertyDefinition( "alpha", QObject::tr( "Opacity" ), QgsPropertyDefinition::Opacity, origin )},
93  { QgsSymbolLayer::PropertyCustomDash, QgsPropertyDefinition( "customDash", QgsPropertyDefinition::DataTypeString, QObject::tr( "Custom dash pattern" ), QObject::tr( "[<b><dash>;<space></b>] e.g. '8;2;1;2'" ), origin )},
94  { QgsSymbolLayer::PropertyCapStyle, QgsPropertyDefinition( "capStyle", QObject::tr( "Line cap style" ), QgsPropertyDefinition::CapStyle, origin )},
95  { QgsSymbolLayer::PropertyPlacement, 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 )},
96  { QgsSymbolLayer::PropertyInterval, QgsPropertyDefinition( "interval", QObject::tr( "Marker interval" ), QgsPropertyDefinition::DoublePositive, origin )},
97  { QgsSymbolLayer::PropertyOffsetAlongLine, QgsPropertyDefinition( "offsetAlongLine", QObject::tr( "Offset along line" ), QgsPropertyDefinition::Double, origin )},
98  { QgsSymbolLayer::PropertyAverageAngleLength, QgsPropertyDefinition( "averageAngleLength", QObject::tr( "Average line angles over" ), QgsPropertyDefinition::DoublePositive, origin )},
99  { QgsSymbolLayer::PropertyHorizontalAnchor, QgsPropertyDefinition( "hAnchor", QObject::tr( "Horizontal anchor point" ), QgsPropertyDefinition::HorizontalAnchor, origin )},
100  { QgsSymbolLayer::PropertyVerticalAnchor, QgsPropertyDefinition( "vAnchor", QObject::tr( "Vertical anchor point" ), QgsPropertyDefinition::VerticalAnchor, origin )},
101  { QgsSymbolLayer::PropertyLayerEnabled, QgsPropertyDefinition( "enabled", QObject::tr( "Layer enabled" ), QgsPropertyDefinition::Boolean, origin )},
102  { QgsSymbolLayer::PropertyArrowWidth, QgsPropertyDefinition( "arrowWidth", QObject::tr( "Arrow line width" ), QgsPropertyDefinition::StrokeWidth, origin )},
103  { QgsSymbolLayer::PropertyArrowStartWidth, QgsPropertyDefinition( "arrowStartWidth", QObject::tr( "Arrow line start width" ), QgsPropertyDefinition::StrokeWidth, origin )},
104  { QgsSymbolLayer::PropertyArrowHeadLength, QgsPropertyDefinition( "arrowHeadLength", QObject::tr( "Arrow head length" ), QgsPropertyDefinition::DoublePositive, origin )},
105  { QgsSymbolLayer::PropertyArrowHeadThickness, QgsPropertyDefinition( "arrowHeadThickness", QObject::tr( "Arrow head thickness" ), QgsPropertyDefinition::DoublePositive, origin )},
106  { QgsSymbolLayer::PropertyArrowHeadType, QgsPropertyDefinition( "arrowHeadType", QgsPropertyDefinition::DataTypeString, QObject::tr( "Arrow head type" ), QObject::tr( "string " ) + QLatin1String( "[<b>single</b>|<b>reversed</b>|<b>double</b>]" ), origin )},
107  { QgsSymbolLayer::PropertyArrowType, QgsPropertyDefinition( "arrowType", QgsPropertyDefinition::DataTypeString, QObject::tr( "Arrow type" ), QObject::tr( "string " ) + QLatin1String( "[<b>plain</b>|<b>lefthalf</b>|<b>righthalf</b>]" ), origin )},
108  { QgsSymbolLayer::PropertyPointCount, QgsPropertyDefinition( "pointCount", QObject::tr( "Point count" ), QgsPropertyDefinition::IntegerPositive, origin )},
109  { QgsSymbolLayer::PropertyRandomSeed, QgsPropertyDefinition( "randomSeed", QgsPropertyDefinition::DataTypeNumeric, QObject::tr( "Random number seed" ), QObject::tr( "integer > 0, or 0 for completely random sequence" ), origin )},
110  { QgsSymbolLayer::PropertyClipPoints, QgsPropertyDefinition( "clipPoints", QObject::tr( "Clip markers" ), QgsPropertyDefinition::Boolean, origin )},
111  { QgsSymbolLayer::PropertyClipPoints, QgsPropertyDefinition( "densityArea", QObject::tr( "Density area" ), QgsPropertyDefinition::DoublePositive, origin )},
112  { QgsSymbolLayer::PropertyDashPatternOffset, QgsPropertyDefinition( "dashPatternOffset", QObject::tr( "Dash pattern offset" ), QgsPropertyDefinition::DoublePositive, origin )},
113  { QgsSymbolLayer::PropertyTrimStart, QgsPropertyDefinition( "trimStart", QObject::tr( "Start trim distance" ), QgsPropertyDefinition::DoublePositive, origin )},
114  { QgsSymbolLayer::PropertyTrimEnd, QgsPropertyDefinition( "trimEnd", QObject::tr( "End trim distance" ), QgsPropertyDefinition::DoublePositive, origin )},
115  { QgsSymbolLayer::PropertyLineStartWidthValue, QgsPropertyDefinition( "lineStartWidthValue", QObject::tr( "Line start width value" ), QgsPropertyDefinition::Double, origin )},
116  { QgsSymbolLayer::PropertyLineEndWidthValue, QgsPropertyDefinition( "lineEndWidthValue", QObject::tr( "Line end width value" ), QgsPropertyDefinition::Double, origin )},
117  { QgsSymbolLayer::PropertyLineStartColorValue, QgsPropertyDefinition( "lineStartColorValue", QObject::tr( "Line start color value" ), QgsPropertyDefinition::Double, origin )},
118  { QgsSymbolLayer::PropertyLineEndColorValue, QgsPropertyDefinition( "lineEndColorValue", QObject::tr( "Line end color value" ), QgsPropertyDefinition::Double, origin )},
119  { QgsSymbolLayer::PropertyMarkerClipping, 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 )},
120  { QgsSymbolLayer::PropertyRandomOffsetX, QgsPropertyDefinition( "randomOffsetX", QObject::tr( "Horizontal random offset" ), QgsPropertyDefinition::Double, origin )},
121  { QgsSymbolLayer::PropertyRandomOffsetY, QgsPropertyDefinition( "randomOffsetY", QObject::tr( "Vertical random offset" ), QgsPropertyDefinition::Double, origin )},
122  { QgsSymbolLayer::PropertyLineClipping, 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 )},
123  };
124 }
125 
127 {
128  dataDefinedProperties().setProperty( key, property );
129 }
130 
132 {
133  if ( QgsSymbol *lSubSymbol = subSymbol() )
134  lSubSymbol->startFeatureRender( feature, context );
135 
136  if ( !mClipPath.isEmpty() )
137  {
138  context.painter()->save();
139  context.painter()->setClipPath( mClipPath, Qt::IntersectClip );
140  }
141 }
142 
144 {
145  if ( QgsSymbol *lSubSymbol = subSymbol() )
146  lSubSymbol->stopFeatureRender( feature, context );
147 
148  if ( !mClipPath.isEmpty() )
149  {
150  context.painter()->restore();
151  }
152 }
153 
155 {
156  return nullptr;
157 }
158 
160 {
161  delete symbol;
162  return false;
163 }
164 
165 bool QgsSymbolLayer::writeDxf( QgsDxfExport &e, double mmMapUnitScaleFactor, const QString &layerName, QgsSymbolRenderContext &context, QPointF shift ) const
166 {
167  Q_UNUSED( e )
168  Q_UNUSED( mmMapUnitScaleFactor )
169  Q_UNUSED( layerName )
170  Q_UNUSED( context )
171  Q_UNUSED( shift )
172  return false;
173 }
174 
176 {
177  Q_UNUSED( e )
178  Q_UNUSED( context )
179  return 1.0;
180 }
181 
183 {
184  Q_UNUSED( e )
185  Q_UNUSED( context )
186  return 0.0;
187 }
188 
190 {
191  Q_UNUSED( context )
192  return color();
193 }
194 
196 {
197  Q_UNUSED( context )
198  return 0.0;
199 }
200 
202 {
203  Q_UNUSED( unit )
204  return QVector<qreal>();
205 }
206 
207 Qt::PenStyle QgsSymbolLayer::dxfPenStyle() const
208 {
209  return Qt::SolidLine;
210 }
211 
213 {
214  Q_UNUSED( context )
215  return color();
216 }
217 
218 Qt::BrushStyle QgsSymbolLayer::dxfBrushStyle() const
219 {
220  return Qt::NoBrush;
221 }
222 
224 {
225  return mPaintEffect.get();
226 }
227 
229 {
230  if ( effect == mPaintEffect.get() )
231  return;
232 
233  mPaintEffect.reset( effect );
234 }
235 
237  : mType( type )
238  , mLocked( locked )
239 {
240 }
241 
242 Qgis::SymbolLayerFlags QgsSymbolLayer::flags() const
243 {
244  return Qgis::SymbolLayerFlags();
245 }
246 
247 QColor QgsSymbolLayer::color() const
248 {
249  return mColor;
250 }
251 
252 void QgsSymbolLayer::setColor( const QColor &color )
253 {
254  mColor = color;
255 }
256 
257 void QgsSymbolLayer::setStrokeColor( const QColor & )
258 {
259 
260 }
261 
263 {
264  return QColor();
265 }
266 
267 void QgsSymbolLayer::setFillColor( const QColor & )
268 {
269 }
270 
272 {
273  return QColor();
274 }
275 
277 {
279 
280  if ( !context.fields().isEmpty() )
281  {
282  //QgsFields is implicitly shared, so it's cheap to make a copy
283  mFields = context.fields();
284  }
285 }
286 
288 {
290 }
291 
293 {
294  QgsSymbolLayer::initPropertyDefinitions();
295  return sPropertyDefinitions;
296 }
297 
299 
301 {
302  if ( symbol->type() == Qgis::SymbolType::Fill && mType == Qgis::SymbolType::Line )
303  return true;
304 
305  return symbol->type() == mType;
306 }
307 
309 {
310  return false;
311 }
312 
314 {
315  return false;
316 }
317 
318 void QgsSymbolLayer::setRenderingPass( int renderingPass )
319 {
321 }
322 
324 {
325  return mRenderingPass;
326 }
327 
328 QSet<QString> QgsSymbolLayer::usedAttributes( const QgsRenderContext &context ) const
329 {
330  // calling referencedFields() with ignoreContext=true because in our expression context
331  // we do not have valid QgsFields yet - because of that the field names from expressions
332  // wouldn't get reported
333  QSet<QString> columns = mDataDefinedProperties.referencedFields( context.expressionContext(), true );
334  return columns;
335 }
336 
337 QgsProperty propertyFromMap( const QVariantMap &map, const QString &baseName )
338 {
339  QString prefix;
340  if ( !baseName.isEmpty() )
341  {
342  prefix.append( QStringLiteral( "%1_dd_" ).arg( baseName ) );
343  }
344 
345  if ( !map.contains( QStringLiteral( "%1expression" ).arg( prefix ) ) )
346  {
347  //requires at least the expression value
348  return QgsProperty();
349  }
350 
351  bool active = ( map.value( QStringLiteral( "%1active" ).arg( prefix ), QStringLiteral( "1" ) ) != QLatin1String( "0" ) );
352  QString expression = map.value( QStringLiteral( "%1expression" ).arg( prefix ) ).toString();
353  bool useExpression = ( map.value( QStringLiteral( "%1useexpr" ).arg( prefix ), QStringLiteral( "1" ) ) != QLatin1String( "0" ) );
354  QString field = map.value( QStringLiteral( "%1field" ).arg( prefix ), QString() ).toString();
355 
356  if ( useExpression )
357  return QgsProperty::fromExpression( expression, active );
358  else
359  return QgsProperty::fromField( field, active );
360 }
361 
362 void QgsSymbolLayer::restoreOldDataDefinedProperties( const QVariantMap &stringMap )
363 {
364  // property string to type upgrade map
365  static const QMap< QString, QgsSymbolLayer::Property > OLD_PROPS
366  {
368  { "arrow_width", QgsSymbolLayer::PropertyArrowWidth },
369  { "arrow_start_width", QgsSymbolLayer::PropertyArrowStartWidth },
370  { "head_length", QgsSymbolLayer::PropertyArrowHeadLength },
371  { "head_thickness", QgsSymbolLayer::PropertyArrowHeadThickness },
372  { "offset", QgsSymbolLayer::PropertyOffset },
373  { "head_type", QgsSymbolLayer::PropertyArrowHeadType },
374  { "arrow_type", QgsSymbolLayer::PropertyArrowType },
375  { "width_field", QgsSymbolLayer::PropertyWidth },
376  { "height_field", QgsSymbolLayer::PropertyHeight },
377  { "rotation_field", QgsSymbolLayer::PropertyAngle },
378  { "outline_width_field", QgsSymbolLayer::PropertyStrokeWidth },
379  { "fill_color_field", QgsSymbolLayer::PropertyFillColor },
380  { "outline_color_field", QgsSymbolLayer::PropertyStrokeColor },
381  { "symbol_name_field", QgsSymbolLayer::PropertyName },
382  { "outline_width", QgsSymbolLayer::PropertyStrokeWidth },
383  { "outline_style", QgsSymbolLayer::PropertyStrokeStyle },
384  { "join_style", QgsSymbolLayer::PropertyJoinStyle },
385  { "fill_color", QgsSymbolLayer::PropertyFillColor },
386  { "outline_color", QgsSymbolLayer::PropertyStrokeColor },
387  { "width", QgsSymbolLayer::PropertyWidth },
388  { "height", QgsSymbolLayer::PropertyHeight },
389  { "symbol_name", QgsSymbolLayer::PropertyName },
390  { "angle", QgsSymbolLayer::PropertyAngle },
391  { "fill_style", QgsSymbolLayer::PropertyFillStyle },
392  { "color_border", QgsSymbolLayer::PropertyStrokeColor },
393  { "width_border", QgsSymbolLayer::PropertyStrokeWidth },
394  { "border_color", QgsSymbolLayer::PropertyStrokeColor },
395  { "border_style", QgsSymbolLayer::PropertyStrokeStyle },
397  { "gradient_type", QgsSymbolLayer::PropertyGradientType },
398  { "coordinate_mode", QgsSymbolLayer::PropertyCoordinateMode },
404  { "reference1_iscentroid", QgsSymbolLayer::PropertyGradientReference1IsCentroid },
405  { "reference2_iscentroid", QgsSymbolLayer::PropertyGradientReference2IsCentroid },
406  { "blur_radius", QgsSymbolLayer::PropertyBlurRadius },
410  { "svgFillColor", QgsSymbolLayer::PropertyFillColor },
411  { "svgOutlineColor", QgsSymbolLayer::PropertyStrokeColor },
412  { "svgOutlineWidth", QgsSymbolLayer::PropertyStrokeWidth },
413  { "svgFile", QgsSymbolLayer::PropertyFile },
414  { "lineangle", QgsSymbolLayer::PropertyLineAngle },
415  { "distance", QgsSymbolLayer::PropertyLineDistance },
416  { "distance_x", QgsSymbolLayer::PropertyDistanceX },
417  { "distance_y", QgsSymbolLayer::PropertyDistanceY },
418  { "displacement_x", QgsSymbolLayer::PropertyDisplacementX },
419  { "displacement_y", QgsSymbolLayer::PropertyDisplacementY },
420  { "file", QgsSymbolLayer::PropertyFile },
421  { "alpha", QgsSymbolLayer::PropertyOpacity },
422  { "customdash", QgsSymbolLayer::PropertyCustomDash },
423  { "line_style", QgsSymbolLayer::PropertyStrokeStyle },
424  { "joinstyle", QgsSymbolLayer::PropertyJoinStyle },
425  { "capstyle", QgsSymbolLayer::PropertyCapStyle },
426  { "placement", QgsSymbolLayer::PropertyPlacement },
427  { "interval", QgsSymbolLayer::PropertyInterval },
428  { "offset_along_line", QgsSymbolLayer::PropertyOffsetAlongLine },
429  { "name", QgsSymbolLayer::PropertyName },
430  { "size", QgsSymbolLayer::PropertySize },
435  { "rotation", QgsSymbolLayer::PropertyAngle },
436  { "horizontal_anchor_point", QgsSymbolLayer::PropertyHorizontalAnchor },
437  { "vertical_anchor_point", QgsSymbolLayer::PropertyVerticalAnchor },
438  };
439 
440  QVariantMap::const_iterator propIt = stringMap.constBegin();
441  for ( ; propIt != stringMap.constEnd(); ++propIt )
442  {
443  std::unique_ptr<QgsProperty> prop;
444  QString propertyName;
445 
446  if ( propIt.key().endsWith( QLatin1String( "_dd_expression" ) ) )
447  {
448  //found a data defined property
449 
450  //get data defined property name by stripping "_dd_expression" from property key
451  propertyName = propIt.key().left( propIt.key().length() - 14 );
452 
453  prop = std::make_unique<QgsProperty>( propertyFromMap( stringMap, propertyName ) );
454  }
455  else if ( propIt.key().endsWith( QLatin1String( "_expression" ) ) )
456  {
457  //old style data defined property, upgrade
458 
459  //get data defined property name by stripping "_expression" from property key
460  propertyName = propIt.key().left( propIt.key().length() - 11 );
461 
462  prop = std::make_unique<QgsProperty>( QgsProperty::fromExpression( propIt.value().toString() ) );
463  }
464 
465  if ( !prop || !OLD_PROPS.contains( propertyName ) )
466  continue;
467 
468  QgsSymbolLayer::Property key = static_cast< QgsSymbolLayer::Property >( OLD_PROPS.value( propertyName ) );
469 
470  if ( type() == Qgis::SymbolType::Line )
471  {
472  //these keys had different meaning for line symbol layers
473  if ( propertyName == QLatin1String( "width" ) )
475  else if ( propertyName == QLatin1String( "color" ) )
477  }
478 
479  setDataDefinedProperty( key, QgsProperty( *prop.get() ) );
480  }
481 }
482 
484 {
485  if ( !destLayer )
486  return;
487 
489 }
490 
492 {
493  if ( !destLayer || !mPaintEffect )
494  return;
495 
497  destLayer->setPaintEffect( mPaintEffect->clone() );
498  else
499  destLayer->setPaintEffect( nullptr );
500 }
501 
503  : QgsSymbolLayer( Qgis::SymbolType::Marker, locked )
504 {
505 
506 }
507 
509  : QgsSymbolLayer( Qgis::SymbolType::Line, locked )
510 {
511 }
512 
514 {
515  return mRingFilter;
516 }
517 
519 {
520  mRingFilter = filter;
521 }
522 
524  : QgsSymbolLayer( Qgis::SymbolType::Fill, locked )
525 {
526 }
527 
529 {
530  Q_UNUSED( context )
531 }
532 
534 {
535  Q_UNUSED( context )
536 }
537 
539 {
540  startRender( context );
541  QgsPaintEffect *effect = paintEffect();
542 
543  QPolygonF points = context.patchShape() ? context.patchShape()->toQPolygonF( Qgis::SymbolType::Marker, size ).value( 0 ).value( 0 )
545 
546  std::unique_ptr< QgsEffectPainter > effectPainter;
547  if ( effect && effect->enabled() )
548  effectPainter = std::make_unique< QgsEffectPainter >( context.renderContext(), effect );
549 
550  for ( QPointF point : std::as_const( points ) )
551  renderPoint( point, context );
552 
553  effectPainter.reset();
554 
555  stopRender( context );
556 }
557 
558 void QgsMarkerSymbolLayer::markerOffset( QgsSymbolRenderContext &context, double &offsetX, double &offsetY ) const
559 {
561 }
562 
563 void QgsMarkerSymbolLayer::markerOffset( QgsSymbolRenderContext &context, double width, double height, double &offsetX, double &offsetY ) const
564 {
565  markerOffset( context, width, height, mSizeUnit, mSizeUnit, offsetX, offsetY, mSizeMapUnitScale, mSizeMapUnitScale );
566 }
567 
568 void QgsMarkerSymbolLayer::markerOffset( QgsSymbolRenderContext &context, double width, double height,
570  double &offsetX, double &offsetY, const QgsMapUnitScale &widthMapUnitScale, const QgsMapUnitScale &heightMapUnitScale ) const
571 {
572  offsetX = mOffset.x();
573  offsetY = mOffset.y();
574 
576  {
579  bool ok = false;
580  const QPointF offset = QgsSymbolLayerUtils::toPoint( exprVal, &ok );
581  if ( ok )
582  {
583  offsetX = offset.x();
584  offsetY = offset.y();
585  }
586  }
587 
588  offsetX = context.renderContext().convertToPainterUnits( offsetX, mOffsetUnit, mOffsetMapUnitScale );
589  offsetY = context.renderContext().convertToPainterUnits( offsetY, mOffsetUnit, mOffsetMapUnitScale );
590 
594  {
596  if ( !exprVal.isNull() )
597  {
598  horizontalAnchorPoint = decodeHorizontalAnchorPoint( exprVal.toString() );
599  }
600  }
602  {
604  if ( !exprVal.isNull() )
605  {
606  verticalAnchorPoint = decodeVerticalAnchorPoint( exprVal.toString() );
607  }
608  }
609 
610  //correct horizontal position according to anchor point
612  {
613  return;
614  }
615 
616  double anchorPointCorrectionX = context.renderContext().convertToPainterUnits( width, widthUnit, widthMapUnitScale ) / 2.0;
618  {
619  // rendering for symbol previews -- an size in meters in map units can't be calculated, so treat the size as millimeters
620  // and clamp it to a reasonable range. It's the best we can do in this situation!
621  anchorPointCorrectionX = std::min( std::max( context.renderContext().convertToPainterUnits( width, QgsUnitTypes::RenderMillimeters ), 3.0 ), 100.0 ) / 2.0;
622  }
623 
624  double anchorPointCorrectionY = context.renderContext().convertToPainterUnits( height, heightUnit, heightMapUnitScale ) / 2.0;
626  {
627  // rendering for symbol previews -- an size in meters in map units can't be calculated, so treat the size as millimeters
628  // and clamp it to a reasonable range. It's the best we can do in this situation!
629  anchorPointCorrectionY = std::min( std::max( context.renderContext().convertToPainterUnits( height, QgsUnitTypes::RenderMillimeters ), 3.0 ), 100.0 ) / 2.0;
630  }
631 
632  if ( horizontalAnchorPoint == Left )
633  {
634  offsetX += anchorPointCorrectionX;
635  }
636  else if ( horizontalAnchorPoint == Right )
637  {
638  offsetX -= anchorPointCorrectionX;
639  }
640 
641  //correct vertical position according to anchor point
642  if ( verticalAnchorPoint == Top )
643  {
644  offsetY += anchorPointCorrectionY;
645  }
646  else if ( verticalAnchorPoint == Bottom )
647  {
648  offsetY -= anchorPointCorrectionY;
649  }
650 }
651 
652 QPointF QgsMarkerSymbolLayer::_rotatedOffset( QPointF offset, double angle )
653 {
654  angle = DEG2RAD( angle );
655  double c = std::cos( angle ), s = std::sin( angle );
656  return QPointF( offset.x() * c - offset.y() * s, offset.x() * s + offset.y() * c );
657 }
658 
659 QgsMarkerSymbolLayer::HorizontalAnchorPoint QgsMarkerSymbolLayer::decodeHorizontalAnchorPoint( const QString &str )
660 {
661  if ( str.compare( QLatin1String( "left" ), Qt::CaseInsensitive ) == 0 )
662  {
664  }
665  else if ( str.compare( QLatin1String( "right" ), Qt::CaseInsensitive ) == 0 )
666  {
668  }
669  else
670  {
672  }
673 }
674 
675 QgsMarkerSymbolLayer::VerticalAnchorPoint QgsMarkerSymbolLayer::decodeVerticalAnchorPoint( const QString &str )
676 {
677  if ( str.compare( QLatin1String( "top" ), Qt::CaseInsensitive ) == 0 )
678  {
680  }
681  else if ( str.compare( QLatin1String( "bottom" ), Qt::CaseInsensitive ) == 0 )
682  {
684  }
685  else
686  {
688  }
689 }
690 
692 {
693  mSizeUnit = unit;
694  mOffsetUnit = unit;
695 }
696 
698 {
699  if ( mOffsetUnit != mSizeUnit )
700  {
702  }
703  return mOffsetUnit;
704 }
705 
707 {
708  mSizeMapUnitScale = scale;
709  mOffsetMapUnitScale = scale;
710 }
711 
713 {
715  {
716  return mSizeMapUnitScale;
717  }
718  return QgsMapUnitScale();
719 }
720 
722 {
723  mWidthUnit = unit;
724  mOffsetUnit = unit;
725 }
726 
728 {
729  return mWidthUnit;
730 }
731 
733 {
734  mWidthMapUnitScale = scale;
735 }
736 
738 {
739  return mWidthMapUnitScale;
740 }
741 
742 
744 {
745  const QList< QList< QPolygonF > > points = context.patchShape() ? context.patchShape()->toQPolygonF( Qgis::SymbolType::Line, size )
747  startRender( context );
748  QgsPaintEffect *effect = paintEffect();
749 
750  std::unique_ptr< QgsEffectPainter > effectPainter;
751  if ( effect && effect->enabled() )
752  effectPainter = std::make_unique< QgsEffectPainter >( context.renderContext(), effect );
753 
754  for ( const QList< QPolygonF > &line : points )
755  renderPolyline( line.value( 0 ), context );
756 
757  effectPainter.reset();
758 
759  stopRender( context );
760 }
761 
762 void QgsLineSymbolLayer::renderPolygonStroke( const QPolygonF &points, const QVector<QPolygonF> *rings, QgsSymbolRenderContext &context )
763 {
764  QgsExpressionContextScope *scope = nullptr;
765  std::unique_ptr< QgsExpressionContextScopePopper > scopePopper;
766  if ( hasDataDefinedProperties() )
767  {
768  scope = new QgsExpressionContextScope();
769  scopePopper = std::make_unique< QgsExpressionContextScopePopper >( context.renderContext().expressionContext(), scope );
770  }
771 
772  switch ( mRingFilter )
773  {
774  case AllRings:
775  case ExteriorRingOnly:
776  {
777  if ( scope )
779  renderPolyline( points, context );
780  break;
781  }
782  case InteriorRingsOnly:
783  break;
784  }
785 
786  if ( rings )
787  {
788  switch ( mRingFilter )
789  {
790  case AllRings:
791  case InteriorRingsOnly:
792  {
793  int ringIndex = 1;
794  for ( const QPolygonF &ring : std::as_const( *rings ) )
795  {
796  if ( scope )
798 
799  renderPolyline( ring, context );
800  ringIndex++;
801  }
802  }
803  break;
804  case ExteriorRingOnly:
805  break;
806  }
807  }
808 }
809 
810 double QgsLineSymbolLayer::width( const QgsRenderContext &context ) const
811 {
813 }
814 
816 {
817  Q_UNUSED( context )
819 }
820 
821 
823 {
824  const QList< QList< QPolygonF > > polys = context.patchShape() ? context.patchShape()->toQPolygonF( Qgis::SymbolType::Fill, size )
826 
827  startRender( context );
828  QgsPaintEffect *effect = paintEffect();
829 
830  std::unique_ptr< QgsEffectPainter > effectPainter;
831  if ( effect && effect->enabled() )
832  effectPainter = std::make_unique< QgsEffectPainter >( context.renderContext(), effect );
833 
834  for ( const QList< QPolygonF > &poly : polys )
835  {
836  QVector< QPolygonF > rings;
837  for ( int i = 1; i < poly.size(); ++i )
838  rings << poly.at( i );
839  renderPolygon( poly.value( 0 ), &rings, context );
840  }
841 
842  effectPainter.reset();
843 
844  stopRender( context );
845 }
846 
847 void QgsFillSymbolLayer::_renderPolygon( QPainter *p, const QPolygonF &points, const QVector<QPolygonF> *rings, QgsSymbolRenderContext &context )
848 {
849  if ( !p )
850  {
851  return;
852  }
853 
854  // Disable 'Antialiasing' if the geometry was generalized in the current RenderContext (We known that it must have least #5 points).
855  if ( points.size() <= 5 &&
858  ( p->renderHints() & QPainter::Antialiasing ) )
859  {
860  p->setRenderHint( QPainter::Antialiasing, false );
861  p->drawRect( points.boundingRect() );
862  p->setRenderHint( QPainter::Antialiasing, true );
863  return;
864  }
865 
866  // polygons outlines are sometimes rendered wrongly with drawPolygon, when
867  // clipped (see #13343), so use drawPath instead.
868  if ( !rings && p->pen().style() == Qt::NoPen )
869  {
870  // simple polygon without holes
871  p->drawPolygon( points );
872  }
873  else
874  {
875  // polygon with holes must be drawn using painter path
876  QPainterPath path;
877  path.addPolygon( points );
878 
879  if ( rings )
880  {
881  for ( auto it = rings->constBegin(); it != rings->constEnd(); ++it )
882  {
883  QPolygonF ring = *it;
884  path.addPolygon( ring );
885  }
886  }
887 
888  p->drawPath( path );
889  }
890 }
891 
892 void QgsMarkerSymbolLayer::toSld( QDomDocument &doc, QDomElement &element, const QVariantMap &props ) const
893 {
894  QDomElement symbolizerElem = doc.createElement( QStringLiteral( "se:PointSymbolizer" ) );
895  if ( !props.value( QStringLiteral( "uom" ), QString() ).toString().isEmpty() )
896  symbolizerElem.setAttribute( QStringLiteral( "uom" ), props.value( QStringLiteral( "uom" ), QString() ).toString() );
897  element.appendChild( symbolizerElem );
898 
899  // <Geometry>
900  QgsSymbolLayerUtils::createGeometryElement( doc, symbolizerElem, props.value( QStringLiteral( "geom" ), QString() ).toString() );
901 
902  writeSldMarker( doc, symbolizerElem, props );
903 }
904 
905 QList<QgsSymbolLayerReference> QgsSymbolLayer::masks() const
906 {
907  return {};
908 }
909 
911 {
912 #if QT_VERSION < QT_VERSION_CHECK(5, 13, 0)
913  mClipPath = QPainterPath();
914 #else
915  mClipPath.clear();
916 #endif
917 
918  const QgsRenderContext &renderContext = context.renderContext();
919  const QList<QPainterPath> clipPaths = renderContext.symbolLayerClipPaths( this );
920  if ( !clipPaths.isEmpty() )
921  {
922  QPainterPath mergedPaths;
923  mergedPaths.setFillRule( Qt::WindingFill );
924  for ( QPainterPath path : clipPaths )
925  {
926  mergedPaths.addPath( path );
927  }
928 
929  if ( !mergedPaths.isEmpty() )
930  {
931  mClipPath.addRect( 0, 0, renderContext.outputSize().width(),
932  renderContext.outputSize().height() );
933  mClipPath = mClipPath.subtracted( mergedPaths );
934  }
935  }
936 }
The Qgis class provides global constants for use throughout the application.
Definition: qgis.h:72
@ RenderSymbolPreview
The render is for a symbol preview only and map based properties may not be available,...
SymbolType
Symbol types.
Definition: qgis.h:206
@ 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...
Exports QGIS layers to the DXF format.
Definition: qgsdxfexport.h:65
static double mapUnitScaleFactor(double scale, QgsUnitTypes::RenderUnit symbolUnits, QgsUnitTypes::DistanceUnit mapUnits, double mapUnitsPerPixel=1.0)
Returns scale factor for conversion to map units.
QgsUnitTypes::DistanceUnit mapUnits() const
Retrieve map units.
double symbologyScale() const
Returns the reference scale for output.
Definition: qgsdxfexport.h:229
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.
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...
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
void setOutputUnit(QgsUnitTypes::RenderUnit unit) override
Sets the units to use for sizes and widths within the symbol layer.
QgsUnitTypes::RenderUnit mWidthUnit
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.
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.
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
QgsUnitTypes::RenderUnit outputUnit() const override
Returns the units to use for sizes and widths within the symbol layer.
QgsUnitTypes::RenderUnit widthUnit() const
Returns the units for the line's width.
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
QgsUnitTypes::RenderUnit mOffsetUnit
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
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.
QgsUnitTypes::RenderUnit mOffsetUnit
Offset units.
void setOutputUnit(QgsUnitTypes::RenderUnit unit) override
Sets 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.
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.
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.
QgsUnitTypes::RenderUnit mSizeUnit
Marker size unit.
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.
QgsUnitTypes::RenderUnit outputUnit() const override
Returns the units to use for sizes and widths within the symbol layer.
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 override
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.
QSet< QString > referencedFields(const QgsExpressionContext &context=QgsExpressionContext(), bool ignoreContext=false) const override
Returns the set of any fields referenced by the active properties from the collection.
bool isActive(int key) const override
Returns true if the collection contains an active property with the specified key.
bool hasActiveProperties() const override
Returns true if the collection has any active properties, or false if all properties within the colle...
bool prepare(const QgsExpressionContext &context=QgsExpressionContext()) const override
Prepares the collection against a specified expression context.
Definition for a property.
Definition: qgsproperty.h:47
@ HorizontalAnchor
Horizontal anchor point.
Definition: qgsproperty.h:75
@ Double
Double value (including negative values)
Definition: qgsproperty.h:57
@ VerticalAnchor
Vertical anchor point.
Definition: qgsproperty.h:76
@ Double0To1
Double value between 0-1 (inclusive)
Definition: qgsproperty.h:59
@ FillStyle
Fill style (eg solid, lines)
Definition: qgsproperty.h:73
@ StrokeWidth
Line stroke width.
Definition: qgsproperty.h:72
@ LineStyle
Line style (eg solid/dashed)
Definition: qgsproperty.h:71
@ String
Any string value.
Definition: qgsproperty.h:61
@ Boolean
Boolean value.
Definition: qgsproperty.h:53
@ PenJoinStyle
Pen join style.
Definition: qgsproperty.h:66
@ IntegerPositive
Positive integer values (including 0)
Definition: qgsproperty.h:55
@ Opacity
Opacity (0-100)
Definition: qgsproperty.h:62
@ CapStyle
Line cap style (eg round)
Definition: qgsproperty.h:74
@ Rotation
Rotation (value between 0-360 degrees)
Definition: qgsproperty.h:60
@ Size
1D size (eg marker radius, or square marker height/width)
Definition: qgsproperty.h:69
@ ColorWithAlpha
Color with alpha channel.
Definition: qgsproperty.h:64
@ DoublePositive
Positive double value (including 0)
Definition: qgsproperty.h:58
@ DataTypeString
Property requires a string value.
Definition: qgsproperty.h:92
@ DataTypeNumeric
Property requires a numeric value.
Definition: qgsproperty.h:99
A store for object properties.
Definition: qgsproperty.h:231
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.
QPainter * painter()
Returns the destination QPainter for the render operation.
QgsExpressionContext & expressionContext()
Gets the expression context.
const QgsMapToPixel & mapToPixel() const
Returns the context's map to pixel transform, which transforms between map coordinates and device coo...
double convertToPainterUnits(double size, QgsUnitTypes::RenderUnit unit, const QgsMapUnitScale &scale=QgsMapUnitScale(), Qgis::RenderSubcomponentProperty property=Qgis::RenderSubcomponentProperty::Generic) const
Converts a size from the specified units to painter units (pixels).
QSize outputSize() const
Returns the size of the resulting rendered image, in pixels.
QList< QPainterPath > symbolLayerClipPaths(const QgsSymbolLayer *symbolLayer) const
Returns clip paths to be applied to the symbolLayer before rendering.
Qgis::RenderContextFlags flags() const
Returns combination of flags used for rendering.
const QgsVectorSimplifyMethod & vectorSimplifyMethod() const
Returns the simplification settings to use when rendering vector layers.
static QgsStyle * defaultStyle()
Returns 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:1199
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.
Property
Data definable properties.
@ PropertyGradientReference1X
Gradient reference point 1 x.
@ PropertyShapeburstIgnoreRings
Shapeburst ignore rings.
@ PropertyGradientReference2X
Gradient reference point 2 x.
@ PropertyStrokeStyle
Stroke style (eg solid, dashed)
@ PropertyPlacement
Line marker placement.
@ PropertyHorizontalAnchor
Horizontal anchor point.
@ PropertyPreserveAspectRatio
Preserve aspect ratio between width and height.
@ PropertyDistanceX
Horizontal distance between points.
@ PropertyFile
Filename, eg for svg files.
@ PropertyGradientType
Gradient fill type.
@ PropertyCapStyle
Line cap style.
@ PropertyLineEndWidthValue
End line width for interpolated line renderer (since QGIS 3.22)
@ PropertyLineEndColorValue
End line color for interpolated line renderer (since QGIS 3.22)
@ PropertyAngle
Symbol angle.
@ PropertyLineClipping
Line clipping mode (since QGIS 3.24)
@ PropertyDistanceY
Vertical distance between points.
@ PropertyDisplacementX
Horizontal displacement.
@ PropertyVerticalAnchor
Vertical anchor point.
@ PropertyGradientSpread
Gradient spread mode.
@ PropertyOffsetY
Vertical offset.
@ PropertyGradientReference1Y
Gradient reference point 1 y.
@ PropertyLineDistance
Distance between lines, or length of lines for hash line symbols.
@ PropertyOffsetAlongLine
Offset along line.
@ PropertyLineStartColorValue
Start line color for interpolated line renderer (since QGIS 3.22)
@ PropertyArrowStartWidth
Arrow tail start width.
@ PropertyBlurRadius
Shapeburst blur radius.
@ PropertyGradientReference2Y
Gradient reference point 2 y.
@ PropertyMarkerClipping
Marker clipping mode (since QGIS 3.24)
@ PropertyArrowHeadLength
Arrow head length.
@ PropertyGradientReference1IsCentroid
Gradient reference point 1 is centroid.
@ PropertyCustomDash
Custom dash pattern.
@ PropertyShapeburstUseWholeShape
Shapeburst use whole shape.
@ PropertySize
Symbol size.
@ PropertyArrowHeadThickness
Arrow head thickness.
@ PropertyOffsetX
Horizontal offset.
@ PropertyJoinStyle
Line join style.
@ PropertyLineStartWidthValue
Start line width for interpolated line renderer (since QGIS 3.22)
@ PropertyTrimEnd
Trim distance from end of line (since QGIS 3.20)
@ PropertyOpacity
Opacity.
@ PropertySecondaryColor
Secondary color (eg for gradient fills)
@ PropertyCharacter
Character, eg for font marker symbol layers.
@ PropertyCoordinateMode
Gradient coordinate mode.
@ PropertyRandomOffsetY
Random offset Y (since QGIS 3.24)
@ PropertyLineAngle
Line angle, or angle of hash lines for hash line symbols.
@ PropertyShapeburstMaxDistance
Shapeburst fill from edge distance.
@ PropertyTrimStart
Trim distance from start of line (since QGIS 3.20)
@ PropertyOffset
Symbol offset.
@ PropertyStrokeWidth
Stroke width.
@ PropertyDashPatternOffset
Dash pattern offset,.
@ PropertyFillColor
Fill color.
@ PropertyArrowHeadType
Arrow head type.
@ PropertyFontStyle
Font style.
@ PropertyHeight
Symbol height.
@ PropertyClipPoints
Whether markers should be clipped to polygon boundaries.
@ PropertyFontFamily
Font family.
@ PropertyPointCount
Point count.
@ PropertyRandomSeed
Random number seed.
@ PropertyLayerEnabled
Whether symbol layer is enabled.
@ PropertyName
Name, eg shape name for simple markers.
@ PropertyAverageAngleLength
Length to average symbol angles over.
@ PropertyInterval
Line marker interval.
@ PropertyRandomOffsetX
Random offset X (since QGIS 3.24)
@ PropertyFillStyle
Fill style (eg solid, dots)
@ PropertyArrowType
Arrow type.
@ PropertyDisplacementY
Vertical displacement.
@ PropertyStrokeColor
Stroke color.
@ PropertyGradientReference2IsCentroid
Gradient reference point 2 is centroid.
@ PropertyArrowWidth
Arrow tail width.
@ PropertyWidth
Symbol width.
QgsFields mFields
virtual bool setSubSymbol(QgsSymbol *symbol)
Sets layer's subsymbol. takes ownership of the passed symbol.
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.
virtual void setStrokeColor(const QColor &color)
Sets the stroke color for the symbol layer.
QPainterPath mClipPath
virtual double dxfOffset(const QgsDxfExport &e, QgsSymbolRenderContext &context) const
Gets offset.
virtual QColor dxfBrushColor(QgsSymbolRenderContext &context) const
Gets brush/fill color.
Qgis::SymbolType mType
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.
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.
virtual QVector< qreal > dxfCustomDashPattern(QgsUnitTypes::RenderUnit &unit) const
Gets dash pattern.
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.
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.
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.
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.
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
QgsPropertyCollection & dataDefinedProperties()
Returns a reference to the symbol layer's property collection, used for data defined overrides.
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.
virtual Qt::BrushStyle dxfBrushStyle() const
Gets brush/fill style.
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.
QgsRenderContext & renderContext()
Returns a reference to the context's render context.
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.
Abstract base class for all rendered symbols.
Definition: qgssymbol.h:93
Qgis::SymbolType type() const
Returns the symbol's type.
Definition: qgssymbol.h:152
RenderUnit
Rendering size units.
Definition: qgsunittypes.h:168
@ RenderUnknownUnit
Mixed or unknown units.
Definition: qgsunittypes.h:175
@ RenderMetersInMapUnits
Meters value as Map units.
Definition: qgsunittypes.h:176
@ RenderMillimeters
Millimeters.
Definition: qgsunittypes.h:169
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:786
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:37
#define DEG2RAD(x)
const QgsField & field
Definition: qgsfield.h:463
QMap< int, QgsPropertyDefinition > QgsPropertiesDefinition
Definition of available properties.
QgsProperty propertyFromMap(const QVariantMap &map, const QString &baseName)
Single variable definition for use within a QgsExpressionContextScope.