QGIS API Documentation  3.18.1-Zürich (202f1bf7e5)
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"
33 
34 #include <QSize>
35 #include <QPainter>
36 #include <QPointF>
37 #include <QPolygonF>
38 
39 QgsPropertiesDefinition QgsSymbolLayer::sPropertyDefinitions;
40 
41 void QgsSymbolLayer::initPropertyDefinitions()
42 {
43  if ( !sPropertyDefinitions.isEmpty() )
44  return;
45 
46  QString origin = QStringLiteral( "symbol" );
47 
48  sPropertyDefinitions = QgsPropertiesDefinition
49  {
50  { QgsSymbolLayer::PropertySize, QgsPropertyDefinition( "size", QObject::tr( "Symbol size" ), QgsPropertyDefinition::Size, origin ) },
51  { QgsSymbolLayer::PropertyAngle, QgsPropertyDefinition( "angle", QObject::tr( "Rotation angle" ), QgsPropertyDefinition::Rotation, origin ) },
52  { QgsSymbolLayer::PropertyName, QgsPropertyDefinition( "name", QObject::tr( "Symbol name" ), QgsPropertyDefinition::String, origin ) },
53  { QgsSymbolLayer::PropertyFillColor, QgsPropertyDefinition( "fillColor", QObject::tr( "Symbol fill color" ), QgsPropertyDefinition::ColorWithAlpha, origin ) },
54  { QgsSymbolLayer::PropertyStrokeColor, QgsPropertyDefinition( "outlineColor", QObject::tr( "Symbol stroke color" ), QgsPropertyDefinition::ColorWithAlpha, origin ) },
55  { QgsSymbolLayer::PropertyStrokeWidth, QgsPropertyDefinition( "outlineWidth", QObject::tr( "Symbol stroke width" ), QgsPropertyDefinition::StrokeWidth, origin ) },
56  { QgsSymbolLayer::PropertyStrokeStyle, QgsPropertyDefinition( "outlineStyle", QObject::tr( "Symbol stroke style" ), QgsPropertyDefinition::LineStyle, origin )},
57  { QgsSymbolLayer::PropertyOffset, QgsPropertyDefinition( "offset", QObject::tr( "Symbol offset" ), QgsPropertyDefinition::Offset, origin )},
58  { QgsSymbolLayer::PropertyCharacter, QgsPropertyDefinition( "char", QObject::tr( "Marker character(s)" ), QgsPropertyDefinition::String, origin )},
59  { QgsSymbolLayer::PropertyFontFamily, QgsPropertyDefinition( "fontFamily", QObject::tr( "Font family" ), QgsPropertyDefinition::String, origin )},
60  { QgsSymbolLayer::PropertyFontStyle, QgsPropertyDefinition( "fontStyle", QObject::tr( "Font style" ), QgsPropertyDefinition::String, origin )},
61  { QgsSymbolLayer::PropertyWidth, QgsPropertyDefinition( "width", QObject::tr( "Symbol width" ), QgsPropertyDefinition::DoublePositive, origin )},
62  { QgsSymbolLayer::PropertyHeight, QgsPropertyDefinition( "height", QObject::tr( "Symbol height" ), QgsPropertyDefinition::DoublePositive, origin )},
63  { QgsSymbolLayer::PropertyPreserveAspectRatio, QgsPropertyDefinition( "preserveAspectRatio", QObject::tr( "Preserve aspect ratio between width and height" ), QgsPropertyDefinition::Boolean, origin )},
64  { QgsSymbolLayer::PropertyFillStyle, QgsPropertyDefinition( "fillStyle", QObject::tr( "Symbol fill style" ), QgsPropertyDefinition::FillStyle, origin )},
65  { QgsSymbolLayer::PropertyJoinStyle, QgsPropertyDefinition( "joinStyle", QObject::tr( "Outline join style" ), QgsPropertyDefinition::PenJoinStyle, origin )},
66  { QgsSymbolLayer::PropertySecondaryColor, QgsPropertyDefinition( "color2", QObject::tr( "Secondary fill color" ), QgsPropertyDefinition::ColorWithAlpha, origin )},
67  { QgsSymbolLayer::PropertyLineAngle, QgsPropertyDefinition( "lineAngle", QObject::tr( "Angle for line fills" ), QgsPropertyDefinition::Rotation, origin )},
68  { QgsSymbolLayer::PropertyGradientType, QgsPropertyDefinition( "gradientType", QgsPropertyDefinition::DataTypeString, QObject::tr( "Gradient type" ), QObject::tr( "string " ) + QLatin1String( "[<b>linear</b>|<b>radial</b>|<b>conical</b>]" ), origin )},
69  { QgsSymbolLayer::PropertyCoordinateMode, QgsPropertyDefinition( "gradientMode", QgsPropertyDefinition::DataTypeString, QObject::tr( "Gradient mode" ), QObject::tr( "string " ) + QLatin1String( "[<b>feature</b>|<b>viewport</b>]" ), origin )},
70  { QgsSymbolLayer::PropertyGradientSpread, QgsPropertyDefinition( "gradientSpread", QgsPropertyDefinition::DataTypeString, QObject::tr( "Gradient spread" ), QObject::tr( "string " ) + QLatin1String( "[<b>pad</b>|<b>repeat</b>|<b>reflect</b>]" ), origin )},
71  { QgsSymbolLayer::PropertyGradientReference1X, QgsPropertyDefinition( "gradientRef1X", QObject::tr( "Reference point 1 (X)" ), QgsPropertyDefinition::Double0To1, origin )},
72  { QgsSymbolLayer::PropertyGradientReference1Y, QgsPropertyDefinition( "gradientRef1Y", QObject::tr( "Reference point 1 (Y)" ), QgsPropertyDefinition::Double0To1, origin )},
73  { QgsSymbolLayer::PropertyGradientReference2X, QgsPropertyDefinition( "gradientRef2X", QObject::tr( "Reference point 2 (X)" ), QgsPropertyDefinition::Double0To1, origin )},
74  { QgsSymbolLayer::PropertyGradientReference2Y, QgsPropertyDefinition( "gradientRef2Y", QObject::tr( "Reference point 2 (Y)" ), QgsPropertyDefinition::Double0To1, origin )},
75  { QgsSymbolLayer::PropertyGradientReference1IsCentroid, QgsPropertyDefinition( "gradientRef1Centroid", QObject::tr( "Reference point 1 follows feature centroid" ), QgsPropertyDefinition::Boolean, origin )},
76  { QgsSymbolLayer::PropertyGradientReference2IsCentroid, QgsPropertyDefinition( "gradientRef2Centroid", QObject::tr( "Reference point 2 follows feature centroid" ), QgsPropertyDefinition::Boolean, origin )},
77  { QgsSymbolLayer::PropertyBlurRadius, QgsPropertyDefinition( "blurRadius", QgsPropertyDefinition::DataTypeNumeric, QObject::tr( "Blur radius" ), QObject::tr( "Integer between 0 and 18" ), origin )},
78  { QgsSymbolLayer::PropertyLineDistance, QgsPropertyDefinition( "lineDistance", QObject::tr( "Distance between lines" ), QgsPropertyDefinition::DoublePositive, origin )},
79  { QgsSymbolLayer::PropertyShapeburstUseWholeShape, QgsPropertyDefinition( "shapeburstWholeShape", QObject::tr( "Shade whole shape" ), QgsPropertyDefinition::Boolean, origin )},
80  { QgsSymbolLayer::PropertyShapeburstMaxDistance, QgsPropertyDefinition( "shapeburstMaxDist", QObject::tr( "Maximum distance for shapeburst fill" ), QgsPropertyDefinition::DoublePositive, origin )},
81  { QgsSymbolLayer::PropertyShapeburstIgnoreRings, QgsPropertyDefinition( "shapeburstIgnoreRings", QObject::tr( "Ignore rings in feature" ), QgsPropertyDefinition::Boolean, origin )},
82  { QgsSymbolLayer::PropertyFile, QgsPropertyDefinition( "file", QObject::tr( "Symbol file path" ), QgsPropertyDefinition::String, origin )},
83  { QgsSymbolLayer::PropertyDistanceX, QgsPropertyDefinition( "distanceX", QObject::tr( "Horizontal distance between markers" ), QgsPropertyDefinition::DoublePositive, origin )},
84  { QgsSymbolLayer::PropertyDistanceY, QgsPropertyDefinition( "distanceY", QObject::tr( "Vertical distance between markers" ), QgsPropertyDefinition::DoublePositive, origin )},
85  { QgsSymbolLayer::PropertyDisplacementX, QgsPropertyDefinition( "displacementX", QObject::tr( "Horizontal displacement between rows" ), QgsPropertyDefinition::DoublePositive, origin )},
86  { QgsSymbolLayer::PropertyDisplacementY, QgsPropertyDefinition( "displacementY", QObject::tr( "Vertical displacement between columns" ), QgsPropertyDefinition::DoublePositive, origin )},
87  { QgsSymbolLayer::PropertyOffsetX, QgsPropertyDefinition( "offsetX", QObject::tr( "Horizontal offset" ), QgsPropertyDefinition::Double, origin )},
88  { QgsSymbolLayer::PropertyOffsetY, QgsPropertyDefinition( "offsetY", QObject::tr( "Vertical offset" ), QgsPropertyDefinition::Double, origin )},
89  { QgsSymbolLayer::PropertyOpacity, QgsPropertyDefinition( "alpha", QObject::tr( "Opacity" ), QgsPropertyDefinition::Opacity, origin )},
90  { QgsSymbolLayer::PropertyCustomDash, QgsPropertyDefinition( "customDash", QgsPropertyDefinition::DataTypeString, QObject::tr( "Custom dash pattern" ), QObject::tr( "[<b><dash>;<space></b>] e.g. '8;2;1;2'" ), origin )},
91  { QgsSymbolLayer::PropertyCapStyle, QgsPropertyDefinition( "capStyle", QObject::tr( "Line cap style" ), QgsPropertyDefinition::CapStyle, origin )},
92  { QgsSymbolLayer::PropertyPlacement, QgsPropertyDefinition( "placement", QgsPropertyDefinition::DataTypeString, QObject::tr( "Marker placement" ), QObject::tr( "string " ) + "[<b>interval</b>|<b>vertex</b>|<b>lastvertex</b>|<b>firstvertex</b>|<b>centerpoint</b>|<b>curvepoint</b>|<b>segmentcenter</b>]", origin )},
93  { QgsSymbolLayer::PropertyInterval, QgsPropertyDefinition( "interval", QObject::tr( "Marker interval" ), QgsPropertyDefinition::DoublePositive, origin )},
94  { QgsSymbolLayer::PropertyOffsetAlongLine, QgsPropertyDefinition( "offsetAlongLine", QObject::tr( "Offset along line" ), QgsPropertyDefinition::DoublePositive, origin )},
95  { QgsSymbolLayer::PropertyAverageAngleLength, QgsPropertyDefinition( "averageAngleLength", QObject::tr( "Average line angles over" ), QgsPropertyDefinition::DoublePositive, origin )},
96  { QgsSymbolLayer::PropertyHorizontalAnchor, QgsPropertyDefinition( "hAnchor", QObject::tr( "Horizontal anchor point" ), QgsPropertyDefinition::HorizontalAnchor, origin )},
97  { QgsSymbolLayer::PropertyVerticalAnchor, QgsPropertyDefinition( "vAnchor", QObject::tr( "Vertical anchor point" ), QgsPropertyDefinition::VerticalAnchor, origin )},
98  { QgsSymbolLayer::PropertyLayerEnabled, QgsPropertyDefinition( "enabled", QObject::tr( "Layer enabled" ), QgsPropertyDefinition::Boolean, origin )},
99  { QgsSymbolLayer::PropertyArrowWidth, QgsPropertyDefinition( "arrowWidth", QObject::tr( "Arrow line width" ), QgsPropertyDefinition::StrokeWidth, origin )},
100  { QgsSymbolLayer::PropertyArrowStartWidth, QgsPropertyDefinition( "arrowStartWidth", QObject::tr( "Arrow line start width" ), QgsPropertyDefinition::StrokeWidth, origin )},
101  { QgsSymbolLayer::PropertyArrowHeadLength, QgsPropertyDefinition( "arrowHeadLength", QObject::tr( "Arrow head length" ), QgsPropertyDefinition::DoublePositive, origin )},
102  { QgsSymbolLayer::PropertyArrowHeadThickness, QgsPropertyDefinition( "arrowHeadThickness", QObject::tr( "Arrow head thickness" ), QgsPropertyDefinition::DoublePositive, origin )},
103  { 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 )},
104  { QgsSymbolLayer::PropertyArrowType, QgsPropertyDefinition( "arrowType", QgsPropertyDefinition::DataTypeString, QObject::tr( "Arrow type" ), QObject::tr( "string " ) + QLatin1String( "[<b>plain</b>|<b>lefthalf</b>|<b>righthalf</b>]" ), origin )},
105  { QgsSymbolLayer::PropertyPointCount, QgsPropertyDefinition( "pointCount", QObject::tr( "Point count" ), QgsPropertyDefinition::IntegerPositive, origin )},
106  { QgsSymbolLayer::PropertyRandomSeed, QgsPropertyDefinition( "randomSeed", QgsPropertyDefinition::DataTypeNumeric, QObject::tr( "Random number seed" ), QObject::tr( "integer > 0, or 0 for completely random sequence" ), origin )},
107  { QgsSymbolLayer::PropertyClipPoints, QgsPropertyDefinition( "clipPoints", QObject::tr( "Clip markers" ), QgsPropertyDefinition::Boolean, origin )},
108  { QgsSymbolLayer::PropertyClipPoints, QgsPropertyDefinition( "densityArea", QObject::tr( "Density area" ), QgsPropertyDefinition::DoublePositive, origin )},
109  { QgsSymbolLayer::PropertyDashPatternOffset, QgsPropertyDefinition( "dashPatternOffset", QObject::tr( "Dash pattern offset" ), QgsPropertyDefinition::DoublePositive, origin )},
110  };
111 }
112 
114 {
115  dataDefinedProperties().setProperty( key, property );
116 }
117 
119 {
120 
121 }
122 
124 {
125 
126 }
127 
128 bool QgsSymbolLayer::writeDxf( QgsDxfExport &e, double mmMapUnitScaleFactor, const QString &layerName, QgsSymbolRenderContext &context, QPointF shift ) const
129 {
130  Q_UNUSED( e )
131  Q_UNUSED( mmMapUnitScaleFactor )
132  Q_UNUSED( layerName )
133  Q_UNUSED( context )
134  Q_UNUSED( shift )
135  return false;
136 }
137 
139 {
140  Q_UNUSED( e )
141  Q_UNUSED( context )
142  return 1.0;
143 }
144 
146 {
147  Q_UNUSED( e )
148  Q_UNUSED( context )
149  return 0.0;
150 }
151 
153 {
154  Q_UNUSED( context )
155  return color();
156 }
157 
159 {
160  Q_UNUSED( context )
161  return 0.0;
162 }
163 
165 {
166  Q_UNUSED( unit )
167  return QVector<qreal>();
168 }
169 
170 Qt::PenStyle QgsSymbolLayer::dxfPenStyle() const
171 {
172  return Qt::SolidLine;
173 }
174 
176 {
177  Q_UNUSED( context )
178  return color();
179 }
180 
181 Qt::BrushStyle QgsSymbolLayer::dxfBrushStyle() const
182 {
183  return Qt::NoBrush;
184 }
185 
187 {
188  return mPaintEffect.get();
189 }
190 
192 {
193  if ( effect == mPaintEffect.get() )
194  return;
195 
196  mPaintEffect.reset( effect );
197 }
198 
200  : mType( type )
201  , mLocked( locked )
202 {
203 }
204 
206 {
208 
209  if ( !context.fields().isEmpty() )
210  {
211  //QgsFields is implicitly shared, so it's cheap to make a copy
212  mFields = context.fields();
213  }
214 }
215 
217 {
219 }
220 
222 {
223  QgsSymbolLayer::initPropertyDefinitions();
224  return sPropertyDefinitions;
225 }
226 
228 
230 {
231  if ( symbol->type() == QgsSymbol::Fill && mType == QgsSymbol::Line )
232  return true;
233 
234  return symbol->type() == mType;
235 }
236 
238 {
239  return false;
240 }
241 
243 {
244  return false;
245 }
246 
247 void QgsSymbolLayer::setRenderingPass( int renderingPass )
248 {
250 }
251 
253 {
254  return mRenderingPass;
255 }
256 
257 QSet<QString> QgsSymbolLayer::usedAttributes( const QgsRenderContext &context ) const
258 {
259  // calling referencedFields() with ignoreContext=true because in our expression context
260  // we do not have valid QgsFields yet - because of that the field names from expressions
261  // wouldn't get reported
262  QSet<QString> columns = mDataDefinedProperties.referencedFields( context.expressionContext(), true );
263  return columns;
264 }
265 
266 QgsProperty propertyFromMap( const QVariantMap &map, const QString &baseName )
267 {
268  QString prefix;
269  if ( !baseName.isEmpty() )
270  {
271  prefix.append( QStringLiteral( "%1_dd_" ).arg( baseName ) );
272  }
273 
274  if ( !map.contains( QStringLiteral( "%1expression" ).arg( prefix ) ) )
275  {
276  //requires at least the expression value
277  return QgsProperty();
278  }
279 
280  bool active = ( map.value( QStringLiteral( "%1active" ).arg( prefix ), QStringLiteral( "1" ) ) != QLatin1String( "0" ) );
281  QString expression = map.value( QStringLiteral( "%1expression" ).arg( prefix ) ).toString();
282  bool useExpression = ( map.value( QStringLiteral( "%1useexpr" ).arg( prefix ), QStringLiteral( "1" ) ) != QLatin1String( "0" ) );
283  QString field = map.value( QStringLiteral( "%1field" ).arg( prefix ), QString() ).toString();
284 
285  if ( useExpression )
286  return QgsProperty::fromExpression( expression, active );
287  else
288  return QgsProperty::fromField( field, active );
289 }
290 
291 void QgsSymbolLayer::restoreOldDataDefinedProperties( const QVariantMap &stringMap )
292 {
293  // property string to type upgrade map
294  static const QMap< QString, QgsSymbolLayer::Property > OLD_PROPS
295  {
297  { "arrow_width", QgsSymbolLayer::PropertyArrowWidth },
298  { "arrow_start_width", QgsSymbolLayer::PropertyArrowStartWidth },
299  { "head_length", QgsSymbolLayer::PropertyArrowHeadLength },
300  { "head_thickness", QgsSymbolLayer::PropertyArrowHeadThickness },
301  { "offset", QgsSymbolLayer::PropertyOffset },
302  { "head_type", QgsSymbolLayer::PropertyArrowHeadType },
303  { "arrow_type", QgsSymbolLayer::PropertyArrowType },
304  { "width_field", QgsSymbolLayer::PropertyWidth },
305  { "height_field", QgsSymbolLayer::PropertyHeight },
306  { "rotation_field", QgsSymbolLayer::PropertyAngle },
307  { "outline_width_field", QgsSymbolLayer::PropertyStrokeWidth },
308  { "fill_color_field", QgsSymbolLayer::PropertyFillColor },
309  { "outline_color_field", QgsSymbolLayer::PropertyStrokeColor },
310  { "symbol_name_field", QgsSymbolLayer::PropertyName },
311  { "outline_width", QgsSymbolLayer::PropertyStrokeWidth },
312  { "outline_style", QgsSymbolLayer::PropertyStrokeStyle },
313  { "join_style", QgsSymbolLayer::PropertyJoinStyle },
314  { "fill_color", QgsSymbolLayer::PropertyFillColor },
315  { "outline_color", QgsSymbolLayer::PropertyStrokeColor },
316  { "width", QgsSymbolLayer::PropertyWidth },
317  { "height", QgsSymbolLayer::PropertyHeight },
318  { "symbol_name", QgsSymbolLayer::PropertyName },
319  { "angle", QgsSymbolLayer::PropertyAngle },
320  { "fill_style", QgsSymbolLayer::PropertyFillStyle },
321  { "color_border", QgsSymbolLayer::PropertyStrokeColor },
322  { "width_border", QgsSymbolLayer::PropertyStrokeWidth },
323  { "border_color", QgsSymbolLayer::PropertyStrokeColor },
324  { "border_style", QgsSymbolLayer::PropertyStrokeStyle },
326  { "gradient_type", QgsSymbolLayer::PropertyGradientType },
327  { "coordinate_mode", QgsSymbolLayer::PropertyCoordinateMode },
333  { "reference1_iscentroid", QgsSymbolLayer::PropertyGradientReference1IsCentroid },
334  { "reference2_iscentroid", QgsSymbolLayer::PropertyGradientReference2IsCentroid },
335  { "blur_radius", QgsSymbolLayer::PropertyBlurRadius },
339  { "svgFillColor", QgsSymbolLayer::PropertyFillColor },
340  { "svgOutlineColor", QgsSymbolLayer::PropertyStrokeColor },
341  { "svgOutlineWidth", QgsSymbolLayer::PropertyStrokeWidth },
342  { "svgFile", QgsSymbolLayer::PropertyFile },
343  { "lineangle", QgsSymbolLayer::PropertyLineAngle },
344  { "distance", QgsSymbolLayer::PropertyLineDistance },
345  { "distance_x", QgsSymbolLayer::PropertyDistanceX },
346  { "distance_y", QgsSymbolLayer::PropertyDistanceY },
347  { "displacement_x", QgsSymbolLayer::PropertyDisplacementX },
348  { "displacement_y", QgsSymbolLayer::PropertyDisplacementY },
349  { "file", QgsSymbolLayer::PropertyFile },
350  { "alpha", QgsSymbolLayer::PropertyOpacity },
351  { "customdash", QgsSymbolLayer::PropertyCustomDash },
352  { "line_style", QgsSymbolLayer::PropertyStrokeStyle },
353  { "joinstyle", QgsSymbolLayer::PropertyJoinStyle },
354  { "capstyle", QgsSymbolLayer::PropertyCapStyle },
355  { "placement", QgsSymbolLayer::PropertyPlacement },
356  { "interval", QgsSymbolLayer::PropertyInterval },
357  { "offset_along_line", QgsSymbolLayer::PropertyOffsetAlongLine },
358  { "name", QgsSymbolLayer::PropertyName },
359  { "size", QgsSymbolLayer::PropertySize },
364  { "rotation", QgsSymbolLayer::PropertyAngle },
365  { "horizontal_anchor_point", QgsSymbolLayer::PropertyHorizontalAnchor },
366  { "vertical_anchor_point", QgsSymbolLayer::PropertyVerticalAnchor },
367  };
368 
369  QVariantMap::const_iterator propIt = stringMap.constBegin();
370  for ( ; propIt != stringMap.constEnd(); ++propIt )
371  {
372  std::unique_ptr<QgsProperty> prop;
373  QString propertyName;
374 
375  if ( propIt.key().endsWith( QLatin1String( "_dd_expression" ) ) )
376  {
377  //found a data defined property
378 
379  //get data defined property name by stripping "_dd_expression" from property key
380  propertyName = propIt.key().left( propIt.key().length() - 14 );
381 
382  prop = qgis::make_unique<QgsProperty>( propertyFromMap( stringMap, propertyName ) );
383  }
384  else if ( propIt.key().endsWith( QLatin1String( "_expression" ) ) )
385  {
386  //old style data defined property, upgrade
387 
388  //get data defined property name by stripping "_expression" from property key
389  propertyName = propIt.key().left( propIt.key().length() - 11 );
390 
391  prop = qgis::make_unique<QgsProperty>( QgsProperty::fromExpression( propIt.value().toString() ) );
392  }
393 
394  if ( !prop || !OLD_PROPS.contains( propertyName ) )
395  continue;
396 
397  QgsSymbolLayer::Property key = static_cast< QgsSymbolLayer::Property >( OLD_PROPS.value( propertyName ) );
398 
399  if ( type() == QgsSymbol::Line )
400  {
401  //these keys had different meaning for line symbol layers
402  if ( propertyName == QLatin1String( "width" ) )
404  else if ( propertyName == QLatin1String( "color" ) )
406  }
407 
408  setDataDefinedProperty( key, QgsProperty( *prop.get() ) );
409  }
410 }
411 
413 {
414  if ( !destLayer )
415  return;
416 
418 }
419 
421 {
422  if ( !destLayer || !mPaintEffect )
423  return;
424 
426  destLayer->setPaintEffect( mPaintEffect->clone() );
427  else
428  destLayer->setPaintEffect( nullptr );
429 }
430 
432  : QgsSymbolLayer( QgsSymbol::Marker, locked )
433 {
434 
435 }
436 
438  : QgsSymbolLayer( QgsSymbol::Line, locked )
439 {
440 }
441 
443 {
444  return mRingFilter;
445 }
446 
448 {
449  mRingFilter = filter;
450 }
451 
453  : QgsSymbolLayer( QgsSymbol::Fill, locked )
454 {
455 }
456 
458 {
459  Q_UNUSED( context )
460 }
461 
463 {
464  Q_UNUSED( context )
465 }
466 
468 {
469  startRender( context );
470  QgsPaintEffect *effect = paintEffect();
471 
472  QPolygonF points = context.patchShape() ? context.patchShape()->toQPolygonF( QgsSymbol::Marker, size ).value( 0 ).value( 0 )
474 
475  std::unique_ptr< QgsEffectPainter > effectPainter;
476  if ( effect && effect->enabled() )
477  effectPainter = qgis::make_unique< QgsEffectPainter >( context.renderContext(), effect );
478 
479  for ( QPointF point : qgis::as_const( points ) )
480  renderPoint( point, context );
481 
482  effectPainter.reset();
483 
484  stopRender( context );
485 }
486 
487 void QgsMarkerSymbolLayer::markerOffset( QgsSymbolRenderContext &context, double &offsetX, double &offsetY ) const
488 {
490 }
491 
492 void QgsMarkerSymbolLayer::markerOffset( QgsSymbolRenderContext &context, double width, double height, double &offsetX, double &offsetY ) const
493 {
494  markerOffset( context, width, height, mSizeUnit, mSizeUnit, offsetX, offsetY, mSizeMapUnitScale, mSizeMapUnitScale );
495 }
496 
497 void QgsMarkerSymbolLayer::markerOffset( QgsSymbolRenderContext &context, double width, double height,
499  double &offsetX, double &offsetY, const QgsMapUnitScale &widthMapUnitScale, const QgsMapUnitScale &heightMapUnitScale ) const
500 {
501  offsetX = mOffset.x();
502  offsetY = mOffset.y();
503 
505  {
508  bool ok = false;
509  const QPointF offset = QgsSymbolLayerUtils::toPoint( exprVal, &ok );
510  if ( ok )
511  {
512  offsetX = offset.x();
513  offsetY = offset.y();
514  }
515  }
516 
517  offsetX = context.renderContext().convertToPainterUnits( offsetX, mOffsetUnit, mOffsetMapUnitScale );
518  offsetY = context.renderContext().convertToPainterUnits( offsetY, mOffsetUnit, mOffsetMapUnitScale );
519 
523  {
525  if ( exprVal.isValid() )
526  {
527  horizontalAnchorPoint = decodeHorizontalAnchorPoint( exprVal.toString() );
528  }
529  }
531  {
533  if ( exprVal.isValid() )
534  {
535  verticalAnchorPoint = decodeVerticalAnchorPoint( exprVal.toString() );
536  }
537  }
538 
539  //correct horizontal position according to anchor point
541  {
542  return;
543  }
544 
545  double anchorPointCorrectionX = context.renderContext().convertToPainterUnits( width, widthUnit, widthMapUnitScale ) / 2.0;
547  {
548  // rendering for symbol previews -- an size in meters in map units can't be calculated, so treat the size as millimeters
549  // and clamp it to a reasonable range. It's the best we can do in this situation!
550  anchorPointCorrectionX = std::min( std::max( context.renderContext().convertToPainterUnits( width, QgsUnitTypes::RenderMillimeters ), 3.0 ), 100.0 ) / 2.0;
551  }
552 
553  double anchorPointCorrectionY = context.renderContext().convertToPainterUnits( height, heightUnit, heightMapUnitScale ) / 2.0;
555  {
556  // rendering for symbol previews -- an size in meters in map units can't be calculated, so treat the size as millimeters
557  // and clamp it to a reasonable range. It's the best we can do in this situation!
558  anchorPointCorrectionY = std::min( std::max( context.renderContext().convertToPainterUnits( height, QgsUnitTypes::RenderMillimeters ), 3.0 ), 100.0 ) / 2.0;
559  }
560 
561  if ( horizontalAnchorPoint == Left )
562  {
563  offsetX += anchorPointCorrectionX;
564  }
565  else if ( horizontalAnchorPoint == Right )
566  {
567  offsetX -= anchorPointCorrectionX;
568  }
569 
570  //correct vertical position according to anchor point
571  if ( verticalAnchorPoint == Top )
572  {
573  offsetY += anchorPointCorrectionY;
574  }
575  else if ( verticalAnchorPoint == Bottom )
576  {
577  offsetY -= anchorPointCorrectionY;
578  }
579 }
580 
581 QPointF QgsMarkerSymbolLayer::_rotatedOffset( QPointF offset, double angle )
582 {
583  angle = DEG2RAD( angle );
584  double c = std::cos( angle ), s = std::sin( angle );
585  return QPointF( offset.x() * c - offset.y() * s, offset.x() * s + offset.y() * c );
586 }
587 
588 QgsMarkerSymbolLayer::HorizontalAnchorPoint QgsMarkerSymbolLayer::decodeHorizontalAnchorPoint( const QString &str )
589 {
590  if ( str.compare( QLatin1String( "left" ), Qt::CaseInsensitive ) == 0 )
591  {
593  }
594  else if ( str.compare( QLatin1String( "right" ), Qt::CaseInsensitive ) == 0 )
595  {
597  }
598  else
599  {
601  }
602 }
603 
604 QgsMarkerSymbolLayer::VerticalAnchorPoint QgsMarkerSymbolLayer::decodeVerticalAnchorPoint( const QString &str )
605 {
606  if ( str.compare( QLatin1String( "top" ), Qt::CaseInsensitive ) == 0 )
607  {
609  }
610  else if ( str.compare( QLatin1String( "bottom" ), Qt::CaseInsensitive ) == 0 )
611  {
613  }
614  else
615  {
617  }
618 }
619 
621 {
622  mSizeUnit = unit;
623  mOffsetUnit = unit;
624 }
625 
627 {
628  if ( mOffsetUnit != mSizeUnit )
629  {
631  }
632  return mOffsetUnit;
633 }
634 
636 {
637  mSizeMapUnitScale = scale;
638  mOffsetMapUnitScale = scale;
639 }
640 
642 {
644  {
645  return mSizeMapUnitScale;
646  }
647  return QgsMapUnitScale();
648 }
649 
651 {
652  mWidthUnit = unit;
653 }
654 
656 {
657  return mWidthUnit;
658 }
659 
661 {
662  mWidthMapUnitScale = scale;
663 }
664 
666 {
667  return mWidthMapUnitScale;
668 }
669 
670 
672 {
673  const QList< QList< QPolygonF > > points = context.patchShape() ? context.patchShape()->toQPolygonF( QgsSymbol::Line, size )
675  startRender( context );
676  QgsPaintEffect *effect = paintEffect();
677 
678  std::unique_ptr< QgsEffectPainter > effectPainter;
679  if ( effect && effect->enabled() )
680  effectPainter = qgis::make_unique< QgsEffectPainter >( context.renderContext(), effect );
681 
682  for ( const QList< QPolygonF > &line : points )
683  renderPolyline( line.value( 0 ), context );
684 
685  effectPainter.reset();
686 
687  stopRender( context );
688 }
689 
690 void QgsLineSymbolLayer::renderPolygonStroke( const QPolygonF &points, const QVector<QPolygonF> *rings, QgsSymbolRenderContext &context )
691 {
692  switch ( mRingFilter )
693  {
694  case AllRings:
695  case ExteriorRingOnly:
696  renderPolyline( points, context );
697  break;
698  case InteriorRingsOnly:
699  break;
700  }
701 
702  if ( rings )
703  {
704  switch ( mRingFilter )
705  {
706  case AllRings:
707  case InteriorRingsOnly:
708  {
709  for ( const QPolygonF &ring : qgis::as_const( *rings ) )
710  renderPolyline( ring, context );
711  }
712  break;
713  case ExteriorRingOnly:
714  break;
715  }
716  }
717 }
718 
719 double QgsLineSymbolLayer::width( const QgsRenderContext &context ) const
720 {
722 }
723 
725 {
726  Q_UNUSED( context )
728 }
729 
730 
732 {
733  const QList< QList< QPolygonF > > polys = context.patchShape() ? context.patchShape()->toQPolygonF( QgsSymbol::Fill, size )
735 
736  startRender( context );
737  QgsPaintEffect *effect = paintEffect();
738 
739  std::unique_ptr< QgsEffectPainter > effectPainter;
740  if ( effect && effect->enabled() )
741  effectPainter = qgis::make_unique< QgsEffectPainter >( context.renderContext(), effect );
742 
743  for ( const QList< QPolygonF > &poly : polys )
744  {
745  QVector< QPolygonF > rings;
746  for ( int i = 1; i < poly.size(); ++i )
747  rings << poly.at( i );
748  renderPolygon( poly.value( 0 ), &rings, context );
749  }
750 
751  effectPainter.reset();
752 
753  stopRender( context );
754 }
755 
756 void QgsFillSymbolLayer::_renderPolygon( QPainter *p, const QPolygonF &points, const QVector<QPolygonF> *rings, QgsSymbolRenderContext &context )
757 {
758  if ( !p )
759  {
760  return;
761  }
762 
763  // Disable 'Antialiasing' if the geometry was generalized in the current RenderContext (We known that it must have least #5 points).
764  if ( points.size() <= 5 &&
767  ( p->renderHints() & QPainter::Antialiasing ) )
768  {
769  p->setRenderHint( QPainter::Antialiasing, false );
770  p->drawRect( points.boundingRect() );
771  p->setRenderHint( QPainter::Antialiasing, true );
772  return;
773  }
774 
775  // polygons outlines are sometimes rendered wrongly with drawPolygon, when
776  // clipped (see #13343), so use drawPath instead.
777  if ( !rings && p->pen().style() == Qt::NoPen )
778  {
779  // simple polygon without holes
780  p->drawPolygon( points );
781  }
782  else
783  {
784  // polygon with holes must be drawn using painter path
785  QPainterPath path;
786  path.addPolygon( points );
787 
788  if ( rings )
789  {
790  for ( auto it = rings->constBegin(); it != rings->constEnd(); ++it )
791  {
792  QPolygonF ring = *it;
793  path.addPolygon( ring );
794  }
795  }
796 
797  p->drawPath( path );
798  }
799 }
800 
801 void QgsMarkerSymbolLayer::toSld( QDomDocument &doc, QDomElement &element, const QVariantMap &props ) const
802 {
803  QDomElement symbolizerElem = doc.createElement( QStringLiteral( "se:PointSymbolizer" ) );
804  if ( !props.value( QStringLiteral( "uom" ), QString() ).toString().isEmpty() )
805  symbolizerElem.setAttribute( QStringLiteral( "uom" ), props.value( QStringLiteral( "uom" ), QString() ).toString() );
806  element.appendChild( symbolizerElem );
807 
808  // <Geometry>
809  QgsSymbolLayerUtils::createGeometryElement( doc, symbolizerElem, props.value( QStringLiteral( "geom" ), QString() ).toString() );
810 
811  writeSldMarker( doc, symbolizerElem, props );
812 }
813 
815 {
816  return {};
817 }
818 
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:64
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:228
The feature class encapsulates a single feature including its id, geometry and a list of field/values...
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(QgsSymbol::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
double mapUnitsPerPixel() const
Returns 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:48
@ HorizontalAnchor
Horizontal anchor point.
Definition: qgsproperty.h:76
@ Double
Double value (including negative values)
Definition: qgsproperty.h:58
@ VerticalAnchor
Vertical anchor point.
Definition: qgsproperty.h:77
@ Double0To1
Double value between 0-1 (inclusive)
Definition: qgsproperty.h:60
@ FillStyle
Fill style (eg solid, lines)
Definition: qgsproperty.h:74
@ StrokeWidth
Line stroke width.
Definition: qgsproperty.h:73
@ LineStyle
Line style (eg solid/dashed)
Definition: qgsproperty.h:72
@ String
Any string value.
Definition: qgsproperty.h:62
@ Boolean
Boolean value.
Definition: qgsproperty.h:54
@ PenJoinStyle
Pen join style.
Definition: qgsproperty.h:67
@ IntegerPositive
Positive integer values (including 0)
Definition: qgsproperty.h:56
@ Opacity
Opacity (0-100)
Definition: qgsproperty.h:63
@ CapStyle
Line cap style (eg round)
Definition: qgsproperty.h:75
@ Rotation
Rotation (value between 0-360 degrees)
Definition: qgsproperty.h:61
@ Size
1D size (eg marker radius, or square marker height/width)
Definition: qgsproperty.h:70
@ ColorWithAlpha
Color with alpha channel.
Definition: qgsproperty.h:65
@ DoublePositive
Positive double value (including 0)
Definition: qgsproperty.h:59
@ DataTypeString
Property requires a string value.
Definition: qgsproperty.h:93
@ DataTypeNumeric
Property requires a numeric value.
Definition: qgsproperty.h:100
A store for object properties.
Definition: qgsproperty.h:232
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.
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...
@ RenderSymbolPreview
The render is for a symbol preview only and map based properties may not be available,...
Flags flags() const
Returns combination of flags used for rendering.
double convertToPainterUnits(double size, QgsUnitTypes::RenderUnit unit, const QgsMapUnitScale &scale=QgsMapUnitScale()) const
Converts a size from the specified units to painter units (pixels).
const QgsVectorSimplifyMethod & vectorSimplifyMethod() const
Returns the simplification settings to use when rendering vector layers.
QList< QList< QPolygonF > > defaultPatchAsQPolygonF(QgsSymbol::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:1202
static QgsStyle * defaultStyle()
Returns default application-wide style.
Definition: qgsstyle.cpp:128
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.
@ PropertyAngle
Symbol angle.
@ 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.
@ PropertyArrowStartWidth
Arrow tail start width.
@ PropertyBlurRadius
Shapeburst blur radius.
@ PropertyGradientReference2Y
Gradient reference point 2 y.
@ 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.
@ PropertyOpacity
Opacity.
@ PropertySecondaryColor
Secondary color (eg for gradient fills)
@ PropertyCharacter
Character, eg for font marker symbol layers.
@ PropertyCoordinateMode
Gradient coordinate mode.
@ PropertyLineAngle
Line angle, or angle of hash lines for hash line symbols.
@ PropertyShapeburstMaxDistance
Shapeburst fill from edge distance.
@ 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.
@ 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 void startFeatureRender(const QgsFeature &feature, QgsRenderContext &context)
Called before the layer will be rendered for a particular feature.
virtual double dxfOffset(const QgsDxfExport &e, QgsSymbolRenderContext &context) const
Gets offset.
virtual QColor color() const
The fill color.
virtual QColor dxfBrushColor(QgsSymbolRenderContext &context) const
Gets brush/fill color.
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.
virtual QgsSymbolLayerReferenceList masks() const
Returns masks defined by this symbol layer.
std::unique_ptr< QgsPaintEffect > mPaintEffect
virtual Qt::PenStyle dxfPenStyle() const
Gets pen style.
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.
QgsSymbol::SymbolType type() const
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 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.
QgsPropertyCollection mDataDefinedProperties
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.
QgsSymbol::SymbolType mType
void setDataDefinedProperties(const QgsPropertyCollection &collection)
Sets the symbol layer's property collection, used for data defined overrides.
QgsFields fields() const
Fields of the layer.
Definition: qgssymbol.h:900
QgsRenderContext & renderContext()
Returns a reference to the context's render context.
Definition: qgssymbol.h:794
void setOriginalValueVariable(const QVariant &value)
Sets the original value variable value for data defined symbology.
Definition: qgssymbol.cpp:1508
const QgsLegendPatchShape * patchShape() const
Returns the symbol patch shape, to use if rendering symbol preview icons.
Definition: qgssymbol.cpp:1544
Abstract base class for all rendered symbols.
Definition: qgssymbol.h:65
SymbolType type() const
Returns the symbol's type.
Definition: qgssymbol.h:138
SymbolType
Type of the symbol.
Definition: qgssymbol.h:87
@ Line
Line symbol.
Definition: qgssymbol.h:89
@ Fill
Fill symbol.
Definition: qgssymbol.h:90
@ Marker
Marker symbol.
Definition: qgssymbol.h:88
RenderUnit
Rendering size units.
Definition: qgsunittypes.h:167
@ RenderUnknownUnit
Mixed or unknown units.
Definition: qgsunittypes.h:174
@ RenderMetersInMapUnits
Meters value as Map units.
Definition: qgsunittypes.h:175
@ RenderMillimeters
Millimeters.
Definition: qgsunittypes.h:168
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 DEG2RAD(x)
const QgsField & field
Definition: qgsfield.h:472
QMap< int, QgsPropertyDefinition > QgsPropertiesDefinition
Definition of available properties.
QgsProperty propertyFromMap(const QVariantMap &map, const QString &baseName)
QList< QgsSymbolLayerReference > QgsSymbolLayerReferenceList