QGIS API Documentation 3.32.0-Lima (311a8cb8a6)
qgssymbollayer.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgssymbollayer.cpp
3 ---------------------
4 begin : November 2009
5 copyright : (C) 2009 by Martin Dobias
6 email : wonder dot sk at gmail dot com
7 ***************************************************************************
8 * *
9 * This program is free software; you can redistribute it and/or modify *
10 * it under the terms of the GNU General Public License as published by *
11 * the Free Software Foundation; either version 2 of the License, or *
12 * (at your option) any later version. *
13 * *
14 ***************************************************************************/
15
16#include "qgssymbollayer.h"
17#include "qgsrendercontext.h"
18#include "qgsdxfexport.h"
20#include "qgspainteffect.h"
22#include "qgsproperty.h"
24#include "qgssymbollayerutils.h"
25#include "qgslegendpatchshape.h"
26#include "qgsstyle.h"
28#include "qgssymbol.h"
30
31#include <QSize>
32#include <QPainter>
33#include <QPointF>
34#include <QPolygonF>
35#include <QUuid>
36
37QgsPropertiesDefinition QgsSymbolLayer::sPropertyDefinitions;
38
39void QgsSymbolLayer::initPropertyDefinitions()
40{
41 if ( !sPropertyDefinitions.isEmpty() )
42 return;
43
44 QString origin = QStringLiteral( "symbol" );
45
46 sPropertyDefinitions = QgsPropertiesDefinition
47 {
48 { QgsSymbolLayer::PropertySize, QgsPropertyDefinition( "size", QObject::tr( "Symbol size" ), QgsPropertyDefinition::Size, origin ) },
49 { QgsSymbolLayer::PropertyAngle, QgsPropertyDefinition( "angle", QObject::tr( "Rotation angle" ), QgsPropertyDefinition::Rotation, origin ) },
50 { QgsSymbolLayer::PropertyName, QgsPropertyDefinition( "name", QObject::tr( "Symbol name" ), QgsPropertyDefinition::String, origin ) },
51 { QgsSymbolLayer::PropertyFillColor, QgsPropertyDefinition( "fillColor", QObject::tr( "Symbol fill color" ), QgsPropertyDefinition::ColorWithAlpha, origin ) },
52 { QgsSymbolLayer::PropertyStrokeColor, QgsPropertyDefinition( "outlineColor", QObject::tr( "Symbol stroke color" ), QgsPropertyDefinition::ColorWithAlpha, origin ) },
53 { QgsSymbolLayer::PropertyStrokeWidth, QgsPropertyDefinition( "outlineWidth", QObject::tr( "Symbol stroke width" ), QgsPropertyDefinition::StrokeWidth, origin ) },
54 { QgsSymbolLayer::PropertyStrokeStyle, QgsPropertyDefinition( "outlineStyle", QObject::tr( "Symbol stroke style" ), QgsPropertyDefinition::LineStyle, origin )},
55 { QgsSymbolLayer::PropertyOffset, QgsPropertyDefinition( "offset", QObject::tr( "Symbol offset" ), QgsPropertyDefinition::Offset, origin )},
56 { QgsSymbolLayer::PropertyCharacter, QgsPropertyDefinition( "char", QObject::tr( "Marker character(s)" ), QgsPropertyDefinition::String, origin )},
57 { QgsSymbolLayer::PropertyFontFamily, QgsPropertyDefinition( "fontFamily", QObject::tr( "Font family" ), QgsPropertyDefinition::String, origin )},
58 { QgsSymbolLayer::PropertyFontStyle, QgsPropertyDefinition( "fontStyle", QObject::tr( "Font style" ), QgsPropertyDefinition::String, origin )},
59 { QgsSymbolLayer::PropertyWidth, QgsPropertyDefinition( "width", QObject::tr( "Symbol width" ), QgsPropertyDefinition::DoublePositive, origin )},
60 { QgsSymbolLayer::PropertyHeight, QgsPropertyDefinition( "height", QObject::tr( "Symbol height" ), QgsPropertyDefinition::DoublePositive, origin )},
61 { QgsSymbolLayer::PropertyPreserveAspectRatio, QgsPropertyDefinition( "preserveAspectRatio", QObject::tr( "Preserve aspect ratio between width and height" ), QgsPropertyDefinition::Boolean, origin )},
62 { QgsSymbolLayer::PropertyFillStyle, QgsPropertyDefinition( "fillStyle", QObject::tr( "Symbol fill style" ), QgsPropertyDefinition::FillStyle, origin )},
63 { QgsSymbolLayer::PropertyJoinStyle, QgsPropertyDefinition( "joinStyle", QObject::tr( "Outline join style" ), QgsPropertyDefinition::PenJoinStyle, origin )},
64 { QgsSymbolLayer::PropertySecondaryColor, QgsPropertyDefinition( "color2", QObject::tr( "Secondary fill color" ), QgsPropertyDefinition::ColorWithAlpha, origin )},
65 { QgsSymbolLayer::PropertyLineAngle, QgsPropertyDefinition( "lineAngle", QObject::tr( "Angle for line fills" ), QgsPropertyDefinition::Rotation, origin )},
66 { QgsSymbolLayer::PropertyGradientType, QgsPropertyDefinition( "gradientType", QgsPropertyDefinition::DataTypeString, QObject::tr( "Gradient type" ), QObject::tr( "string " ) + QLatin1String( "[<b>linear</b>|<b>radial</b>|<b>conical</b>]" ), origin )},
67 { QgsSymbolLayer::PropertyCoordinateMode, QgsPropertyDefinition( "gradientMode", QgsPropertyDefinition::DataTypeString, QObject::tr( "Gradient mode" ), QObject::tr( "string " ) + QLatin1String( "[<b>feature</b>|<b>viewport</b>]" ), origin )},
68 { QgsSymbolLayer::PropertyGradientSpread, QgsPropertyDefinition( "gradientSpread", QgsPropertyDefinition::DataTypeString, QObject::tr( "Gradient spread" ), QObject::tr( "string " ) + QLatin1String( "[<b>pad</b>|<b>repeat</b>|<b>reflect</b>]" ), origin )},
69 { QgsSymbolLayer::PropertyGradientReference1X, QgsPropertyDefinition( "gradientRef1X", QObject::tr( "Reference point 1 (X)" ), QgsPropertyDefinition::Double0To1, origin )},
70 { QgsSymbolLayer::PropertyGradientReference1Y, QgsPropertyDefinition( "gradientRef1Y", QObject::tr( "Reference point 1 (Y)" ), QgsPropertyDefinition::Double0To1, origin )},
71 { QgsSymbolLayer::PropertyGradientReference2X, QgsPropertyDefinition( "gradientRef2X", QObject::tr( "Reference point 2 (X)" ), QgsPropertyDefinition::Double0To1, origin )},
72 { QgsSymbolLayer::PropertyGradientReference2Y, QgsPropertyDefinition( "gradientRef2Y", QObject::tr( "Reference point 2 (Y)" ), QgsPropertyDefinition::Double0To1, origin )},
73 { QgsSymbolLayer::PropertyGradientReference1IsCentroid, QgsPropertyDefinition( "gradientRef1Centroid", QObject::tr( "Reference point 1 follows feature centroid" ), QgsPropertyDefinition::Boolean, origin )},
74 { QgsSymbolLayer::PropertyGradientReference2IsCentroid, QgsPropertyDefinition( "gradientRef2Centroid", QObject::tr( "Reference point 2 follows feature centroid" ), QgsPropertyDefinition::Boolean, origin )},
75 { QgsSymbolLayer::PropertyBlurRadius, QgsPropertyDefinition( "blurRadius", QgsPropertyDefinition::DataTypeNumeric, QObject::tr( "Blur radius" ), QObject::tr( "Integer between 0 and 18" ), origin )},
76 { QgsSymbolLayer::PropertyLineDistance, QgsPropertyDefinition( "lineDistance", QObject::tr( "Distance between lines" ), QgsPropertyDefinition::DoublePositive, origin )},
77 { QgsSymbolLayer::PropertyShapeburstUseWholeShape, QgsPropertyDefinition( "shapeburstWholeShape", QObject::tr( "Shade whole shape" ), QgsPropertyDefinition::Boolean, origin )},
78 { QgsSymbolLayer::PropertyShapeburstMaxDistance, QgsPropertyDefinition( "shapeburstMaxDist", QObject::tr( "Maximum distance for shapeburst fill" ), QgsPropertyDefinition::DoublePositive, origin )},
79 { QgsSymbolLayer::PropertyShapeburstIgnoreRings, QgsPropertyDefinition( "shapeburstIgnoreRings", QObject::tr( "Ignore rings in feature" ), QgsPropertyDefinition::Boolean, origin )},
80 { QgsSymbolLayer::PropertyFile, QgsPropertyDefinition( "file", QObject::tr( "Symbol file path" ), QgsPropertyDefinition::String, origin )},
81 { QgsSymbolLayer::PropertyDistanceX, QgsPropertyDefinition( "distanceX", QObject::tr( "Horizontal distance between markers" ), QgsPropertyDefinition::DoublePositive, origin )},
82 { QgsSymbolLayer::PropertyDistanceY, QgsPropertyDefinition( "distanceY", QObject::tr( "Vertical distance between markers" ), QgsPropertyDefinition::DoublePositive, origin )},
83 { QgsSymbolLayer::PropertyDisplacementX, QgsPropertyDefinition( "displacementX", QObject::tr( "Horizontal displacement between rows" ), QgsPropertyDefinition::DoublePositive, origin )},
84 { QgsSymbolLayer::PropertyDisplacementY, QgsPropertyDefinition( "displacementY", QObject::tr( "Vertical displacement between columns" ), QgsPropertyDefinition::DoublePositive, origin )},
85 { QgsSymbolLayer::PropertyOffsetX, QgsPropertyDefinition( "offsetX", QObject::tr( "Horizontal offset" ), QgsPropertyDefinition::Double, origin )},
86 { QgsSymbolLayer::PropertyOffsetY, QgsPropertyDefinition( "offsetY", QObject::tr( "Vertical offset" ), QgsPropertyDefinition::Double, origin )},
87 { QgsSymbolLayer::PropertyOpacity, QgsPropertyDefinition( "alpha", QObject::tr( "Opacity" ), QgsPropertyDefinition::Opacity, origin )},
88 { QgsSymbolLayer::PropertyCustomDash, QgsPropertyDefinition( "customDash", QgsPropertyDefinition::DataTypeString, QObject::tr( "Custom dash pattern" ), QObject::tr( "[<b><dash>;<space></b>] e.g. '8;2;1;2'" ), origin )},
89 { QgsSymbolLayer::PropertyCapStyle, QgsPropertyDefinition( "capStyle", QObject::tr( "Line cap style" ), QgsPropertyDefinition::CapStyle, origin )},
90 { 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 )},
91 { QgsSymbolLayer::PropertyInterval, QgsPropertyDefinition( "interval", QObject::tr( "Marker interval" ), QgsPropertyDefinition::DoublePositive, origin )},
92 { QgsSymbolLayer::PropertyOffsetAlongLine, QgsPropertyDefinition( "offsetAlongLine", QObject::tr( "Offset along line" ), QgsPropertyDefinition::Double, origin )},
93 { QgsSymbolLayer::PropertyAverageAngleLength, QgsPropertyDefinition( "averageAngleLength", QObject::tr( "Average line angles over" ), QgsPropertyDefinition::DoublePositive, origin )},
94 { QgsSymbolLayer::PropertyHorizontalAnchor, QgsPropertyDefinition( "hAnchor", QObject::tr( "Horizontal anchor point" ), QgsPropertyDefinition::HorizontalAnchor, origin )},
95 { QgsSymbolLayer::PropertyVerticalAnchor, QgsPropertyDefinition( "vAnchor", QObject::tr( "Vertical anchor point" ), QgsPropertyDefinition::VerticalAnchor, origin )},
96 { QgsSymbolLayer::PropertyLayerEnabled, QgsPropertyDefinition( "enabled", QObject::tr( "Layer enabled" ), QgsPropertyDefinition::Boolean, origin )},
97 { QgsSymbolLayer::PropertyArrowWidth, QgsPropertyDefinition( "arrowWidth", QObject::tr( "Arrow line width" ), QgsPropertyDefinition::StrokeWidth, origin )},
98 { QgsSymbolLayer::PropertyArrowStartWidth, QgsPropertyDefinition( "arrowStartWidth", QObject::tr( "Arrow line start width" ), QgsPropertyDefinition::StrokeWidth, origin )},
99 { QgsSymbolLayer::PropertyArrowHeadLength, QgsPropertyDefinition( "arrowHeadLength", QObject::tr( "Arrow head length" ), QgsPropertyDefinition::DoublePositive, origin )},
100 { QgsSymbolLayer::PropertyArrowHeadThickness, QgsPropertyDefinition( "arrowHeadThickness", QObject::tr( "Arrow head thickness" ), QgsPropertyDefinition::DoublePositive, origin )},
101 { 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 )},
102 { QgsSymbolLayer::PropertyArrowType, QgsPropertyDefinition( "arrowType", QgsPropertyDefinition::DataTypeString, QObject::tr( "Arrow type" ), QObject::tr( "string " ) + QLatin1String( "[<b>plain</b>|<b>lefthalf</b>|<b>righthalf</b>]" ), origin )},
103 { QgsSymbolLayer::PropertyPointCount, QgsPropertyDefinition( "pointCount", QObject::tr( "Point count" ), QgsPropertyDefinition::IntegerPositive, origin )},
104 { QgsSymbolLayer::PropertyRandomSeed, QgsPropertyDefinition( "randomSeed", QgsPropertyDefinition::DataTypeNumeric, QObject::tr( "Random number seed" ), QObject::tr( "integer > 0, or 0 for completely random sequence" ), origin )},
105 { QgsSymbolLayer::PropertyClipPoints, QgsPropertyDefinition( "clipPoints", QObject::tr( "Clip markers" ), QgsPropertyDefinition::Boolean, origin )},
106 { QgsSymbolLayer::PropertyClipPoints, QgsPropertyDefinition( "densityArea", QObject::tr( "Density area" ), QgsPropertyDefinition::DoublePositive, origin )},
107 { QgsSymbolLayer::PropertyDashPatternOffset, QgsPropertyDefinition( "dashPatternOffset", QObject::tr( "Dash pattern offset" ), QgsPropertyDefinition::DoublePositive, origin )},
108 { QgsSymbolLayer::PropertyTrimStart, QgsPropertyDefinition( "trimStart", QObject::tr( "Start trim distance" ), QgsPropertyDefinition::DoublePositive, origin )},
109 { QgsSymbolLayer::PropertyTrimEnd, QgsPropertyDefinition( "trimEnd", QObject::tr( "End trim distance" ), QgsPropertyDefinition::DoublePositive, origin )},
110 { QgsSymbolLayer::PropertyLineStartWidthValue, QgsPropertyDefinition( "lineStartWidthValue", QObject::tr( "Line start width value" ), QgsPropertyDefinition::Double, origin )},
111 { QgsSymbolLayer::PropertyLineEndWidthValue, QgsPropertyDefinition( "lineEndWidthValue", QObject::tr( "Line end width value" ), QgsPropertyDefinition::Double, origin )},
112 { QgsSymbolLayer::PropertyLineStartColorValue, QgsPropertyDefinition( "lineStartColorValue", QObject::tr( "Line start color value" ), QgsPropertyDefinition::Double, origin )},
113 { QgsSymbolLayer::PropertyLineEndColorValue, QgsPropertyDefinition( "lineEndColorValue", QObject::tr( "Line end color value" ), QgsPropertyDefinition::Double, origin )},
114 { 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 )},
115 { QgsSymbolLayer::PropertyRandomOffsetX, QgsPropertyDefinition( "randomOffsetX", QObject::tr( "Horizontal random offset" ), QgsPropertyDefinition::Double, origin )},
116 { QgsSymbolLayer::PropertyRandomOffsetY, QgsPropertyDefinition( "randomOffsetY", QObject::tr( "Vertical random offset" ), QgsPropertyDefinition::Double, origin )},
117 { 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 )},
118 };
119}
120
122{
123 dataDefinedProperties().setProperty( key, property );
124}
125
127{
128 installMasks( context, false );
129
130 if ( QgsSymbol *lSubSymbol = subSymbol() )
131 lSubSymbol->startFeatureRender( feature, context );
132}
133
135{
136 if ( QgsSymbol *lSubSymbol = subSymbol() )
137 lSubSymbol->stopFeatureRender( feature, context );
138
139 removeMasks( context, false );
140}
141
143{
144 return nullptr;
145}
146
148{
149 delete symbol;
150 return false;
151}
152
153bool QgsSymbolLayer::writeDxf( QgsDxfExport &e, double mmMapUnitScaleFactor, const QString &layerName, QgsSymbolRenderContext &context, QPointF shift ) const
154{
155 Q_UNUSED( e )
156 Q_UNUSED( mmMapUnitScaleFactor )
157 Q_UNUSED( layerName )
158 Q_UNUSED( context )
159 Q_UNUSED( shift )
160 return false;
161}
162
164{
165 Q_UNUSED( e )
166 Q_UNUSED( context )
167 return 1.0;
168}
169
171{
172 Q_UNUSED( e )
173 Q_UNUSED( context )
174 return 1.0;
175}
176
178{
179 Q_UNUSED( e )
180 Q_UNUSED( context )
181 return 0.0;
182}
183
185{
186 Q_UNUSED( context )
187 return color();
188}
189
191{
192 Q_UNUSED( context )
193 return 0.0;
194}
195
197{
198 Q_UNUSED( unit )
199 return QVector<qreal>();
200}
201
202Qt::PenStyle QgsSymbolLayer::dxfPenStyle() const
203{
204 return Qt::SolidLine;
205}
206
208{
209 Q_UNUSED( context )
210 return color();
211}
212
213Qt::BrushStyle QgsSymbolLayer::dxfBrushStyle() const
214{
215 return Qt::NoBrush;
216}
217
219{
220 return mPaintEffect.get();
221}
222
224{
225 if ( effect == mPaintEffect.get() )
226 return;
227
228 mPaintEffect.reset( effect );
229}
230
232 : mType( type )
233 , mLocked( locked )
234 , mId( QUuid::createUuid().toString() )
235{
236}
237
238Qgis::SymbolLayerFlags QgsSymbolLayer::flags() const
239{
240 return Qgis::SymbolLayerFlags();
241}
242
244{
245 return mColor;
246}
247
248void QgsSymbolLayer::setColor( const QColor &color )
249{
250 mColor = color;
251}
252
253void QgsSymbolLayer::setStrokeColor( const QColor & )
254{
255
256}
257
259{
260 return QColor();
261}
262
263void QgsSymbolLayer::setFillColor( const QColor & )
264{
265}
266
268{
269 return QColor();
270}
271
273{
275
276 if ( !context.fields().isEmpty() )
277 {
278 //QgsFields is implicitly shared, so it's cheap to make a copy
279 mFields = context.fields();
280 }
281}
282
284{
286}
287
289{
290 QgsSymbolLayer::initPropertyDefinitions();
291 return sPropertyDefinitions;
292}
293
295
297{
299 return true;
300
301 return symbol->type() == mType;
302}
303
305{
306 return false;
307}
308
310{
311 return false;
312}
313
314void QgsSymbolLayer::setRenderingPass( int renderingPass )
315{
317}
318
320{
321 return mRenderingPass;
322}
323
324QSet<QString> QgsSymbolLayer::usedAttributes( const QgsRenderContext &context ) const
325{
326 // calling referencedFields() with ignoreContext=true because in our expression context
327 // we do not have valid QgsFields yet - because of that the field names from expressions
328 // wouldn't get reported
329 QSet<QString> columns = mDataDefinedProperties.referencedFields( context.expressionContext(), true );
330 return columns;
331}
332
333QgsProperty propertyFromMap( const QVariantMap &map, const QString &baseName )
334{
335 QString prefix;
336 if ( !baseName.isEmpty() )
337 {
338 prefix.append( QStringLiteral( "%1_dd_" ).arg( baseName ) );
339 }
340
341 if ( !map.contains( QStringLiteral( "%1expression" ).arg( prefix ) ) )
342 {
343 //requires at least the expression value
344 return QgsProperty();
345 }
346
347 bool active = ( map.value( QStringLiteral( "%1active" ).arg( prefix ), QStringLiteral( "1" ) ) != QLatin1String( "0" ) );
348 QString expression = map.value( QStringLiteral( "%1expression" ).arg( prefix ) ).toString();
349 bool useExpression = ( map.value( QStringLiteral( "%1useexpr" ).arg( prefix ), QStringLiteral( "1" ) ) != QLatin1String( "0" ) );
350 QString field = map.value( QStringLiteral( "%1field" ).arg( prefix ), QString() ).toString();
351
352 if ( useExpression )
353 return QgsProperty::fromExpression( expression, active );
354 else
355 return QgsProperty::fromField( field, active );
356}
357
358void QgsSymbolLayer::restoreOldDataDefinedProperties( const QVariantMap &stringMap )
359{
360 // property string to type upgrade map
361 static const QMap< QString, QgsSymbolLayer::Property > OLD_PROPS
362 {
364 { "arrow_width", QgsSymbolLayer::PropertyArrowWidth },
365 { "arrow_start_width", QgsSymbolLayer::PropertyArrowStartWidth },
367 { "head_thickness", QgsSymbolLayer::PropertyArrowHeadThickness },
368 { "offset", QgsSymbolLayer::PropertyOffset },
370 { "arrow_type", QgsSymbolLayer::PropertyArrowType },
371 { "width_field", QgsSymbolLayer::PropertyWidth },
372 { "height_field", QgsSymbolLayer::PropertyHeight },
373 { "rotation_field", QgsSymbolLayer::PropertyAngle },
374 { "outline_width_field", QgsSymbolLayer::PropertyStrokeWidth },
375 { "fill_color_field", QgsSymbolLayer::PropertyFillColor },
376 { "outline_color_field", QgsSymbolLayer::PropertyStrokeColor },
377 { "symbol_name_field", QgsSymbolLayer::PropertyName },
378 { "outline_width", QgsSymbolLayer::PropertyStrokeWidth },
379 { "outline_style", QgsSymbolLayer::PropertyStrokeStyle },
380 { "join_style", QgsSymbolLayer::PropertyJoinStyle },
381 { "fill_color", QgsSymbolLayer::PropertyFillColor },
382 { "outline_color", QgsSymbolLayer::PropertyStrokeColor },
384 { "height", QgsSymbolLayer::PropertyHeight },
385 { "symbol_name", QgsSymbolLayer::PropertyName },
387 { "fill_style", QgsSymbolLayer::PropertyFillStyle },
388 { "color_border", QgsSymbolLayer::PropertyStrokeColor },
389 { "width_border", QgsSymbolLayer::PropertyStrokeWidth },
390 { "border_color", QgsSymbolLayer::PropertyStrokeColor },
391 { "border_style", QgsSymbolLayer::PropertyStrokeStyle },
393 { "gradient_type", QgsSymbolLayer::PropertyGradientType },
394 { "coordinate_mode", QgsSymbolLayer::PropertyCoordinateMode },
400 { "reference1_iscentroid", QgsSymbolLayer::PropertyGradientReference1IsCentroid },
401 { "reference2_iscentroid", QgsSymbolLayer::PropertyGradientReference2IsCentroid },
402 { "blur_radius", QgsSymbolLayer::PropertyBlurRadius },
406 { "svgFillColor", QgsSymbolLayer::PropertyFillColor },
407 { "svgOutlineColor", QgsSymbolLayer::PropertyStrokeColor },
408 { "svgOutlineWidth", QgsSymbolLayer::PropertyStrokeWidth },
409 { "svgFile", QgsSymbolLayer::PropertyFile },
410 { "lineangle", QgsSymbolLayer::PropertyLineAngle },
412 { "distance_x", QgsSymbolLayer::PropertyDistanceX },
413 { "distance_y", QgsSymbolLayer::PropertyDistanceY },
414 { "displacement_x", QgsSymbolLayer::PropertyDisplacementX },
415 { "displacement_y", QgsSymbolLayer::PropertyDisplacementY },
418 { "customdash", QgsSymbolLayer::PropertyCustomDash },
419 { "line_style", QgsSymbolLayer::PropertyStrokeStyle },
420 { "joinstyle", QgsSymbolLayer::PropertyJoinStyle },
421 { "capstyle", QgsSymbolLayer::PropertyCapStyle },
422 { "placement", QgsSymbolLayer::PropertyPlacement },
423 { "interval", QgsSymbolLayer::PropertyInterval },
424 { "offset_along_line", QgsSymbolLayer::PropertyOffsetAlongLine },
431 { "rotation", QgsSymbolLayer::PropertyAngle },
432 { "horizontal_anchor_point", QgsSymbolLayer::PropertyHorizontalAnchor },
433 { "vertical_anchor_point", QgsSymbolLayer::PropertyVerticalAnchor },
434 };
435
436 QVariantMap::const_iterator propIt = stringMap.constBegin();
437 for ( ; propIt != stringMap.constEnd(); ++propIt )
438 {
439 std::unique_ptr<QgsProperty> prop;
440 QString propertyName;
441
442 if ( propIt.key().endsWith( QLatin1String( "_dd_expression" ) ) )
443 {
444 //found a data defined property
445
446 //get data defined property name by stripping "_dd_expression" from property key
447 propertyName = propIt.key().left( propIt.key().length() - 14 );
448
449 prop = std::make_unique<QgsProperty>( propertyFromMap( stringMap, propertyName ) );
450 }
451 else if ( propIt.key().endsWith( QLatin1String( "_expression" ) ) )
452 {
453 //old style data defined property, upgrade
454
455 //get data defined property name by stripping "_expression" from property key
456 propertyName = propIt.key().left( propIt.key().length() - 11 );
457
458 prop = std::make_unique<QgsProperty>( QgsProperty::fromExpression( propIt.value().toString() ) );
459 }
460
461 if ( !prop || !OLD_PROPS.contains( propertyName ) )
462 continue;
463
464 QgsSymbolLayer::Property key = static_cast< QgsSymbolLayer::Property >( OLD_PROPS.value( propertyName ) );
465
466 if ( type() == Qgis::SymbolType::Line )
467 {
468 //these keys had different meaning for line symbol layers
469 if ( propertyName == QLatin1String( "width" ) )
471 else if ( propertyName == QLatin1String( "color" ) )
473 }
474
475 setDataDefinedProperty( key, QgsProperty( *prop.get() ) );
476 }
477}
478
480{
481 if ( !destLayer )
482 return;
483
485}
486
488{
489 if ( !destLayer || !mPaintEffect )
490 return;
491
493 destLayer->setPaintEffect( mPaintEffect->clone() );
494 else
495 destLayer->setPaintEffect( nullptr );
496}
497
499 : QgsSymbolLayer( Qgis::SymbolType::Marker, locked )
500{
501
502}
503
505 : QgsSymbolLayer( Qgis::SymbolType::Line, locked )
506{
507}
508
510{
511 return mRingFilter;
512}
513
515{
516 mRingFilter = filter;
517}
518
520 : QgsSymbolLayer( Qgis::SymbolType::Fill, locked )
521{
522}
523
525{
526 Q_UNUSED( context )
527}
528
530{
531 Q_UNUSED( context )
532}
533
535{
536 startRender( context );
537 QgsPaintEffect *effect = paintEffect();
538
539 QPolygonF points = context.patchShape() ? context.patchShape()->toQPolygonF( Qgis::SymbolType::Marker, size ).value( 0 ).value( 0 )
541
542 std::unique_ptr< QgsEffectPainter > effectPainter;
543 if ( effect && effect->enabled() )
544 effectPainter = std::make_unique< QgsEffectPainter >( context.renderContext(), effect );
545
546 for ( QPointF point : std::as_const( points ) )
547 renderPoint( point, context );
548
549 effectPainter.reset();
550
551 stopRender( context );
552}
553
554void QgsMarkerSymbolLayer::markerOffset( QgsSymbolRenderContext &context, double &offsetX, double &offsetY ) const
555{
557}
558
559void QgsMarkerSymbolLayer::markerOffset( QgsSymbolRenderContext &context, double width, double height, double &offsetX, double &offsetY ) const
560{
561 markerOffset( context, width, height, mSizeUnit, mSizeUnit, offsetX, offsetY, mSizeMapUnitScale, mSizeMapUnitScale );
562}
563
564void QgsMarkerSymbolLayer::markerOffset( QgsSymbolRenderContext &context, double width, double height,
565 Qgis::RenderUnit widthUnit, Qgis::RenderUnit heightUnit,
566 double &offsetX, double &offsetY, const QgsMapUnitScale &widthMapUnitScale, const QgsMapUnitScale &heightMapUnitScale ) const
567{
568 offsetX = mOffset.x();
569 offsetY = mOffset.y();
570
572 {
575 bool ok = false;
576 const QPointF offset = QgsSymbolLayerUtils::toPoint( exprVal, &ok );
577 if ( ok )
578 {
579 offsetX = offset.x();
580 offsetY = offset.y();
581 }
582 }
583
586
590 {
592 if ( !QgsVariantUtils::isNull( exprVal ) )
593 {
594 horizontalAnchorPoint = decodeHorizontalAnchorPoint( exprVal.toString() );
595 }
596 }
598 {
600 if ( !QgsVariantUtils::isNull( exprVal ) )
601 {
602 verticalAnchorPoint = decodeVerticalAnchorPoint( exprVal.toString() );
603 }
604 }
605
606 //correct horizontal position according to anchor point
608 {
609 return;
610 }
611
612 double anchorPointCorrectionX = context.renderContext().convertToPainterUnits( width, widthUnit, widthMapUnitScale ) / 2.0;
613 if ( widthUnit == Qgis::RenderUnit::MetersInMapUnits && context.renderContext().flags() & Qgis::RenderContextFlag::RenderSymbolPreview )
614 {
615 // rendering for symbol previews -- an size in meters in map units can't be calculated, so treat the size as millimeters
616 // and clamp it to a reasonable range. It's the best we can do in this situation!
617 anchorPointCorrectionX = std::min( std::max( context.renderContext().convertToPainterUnits( width, Qgis::RenderUnit::Millimeters ), 3.0 ), 100.0 ) / 2.0;
618 }
619
620 double anchorPointCorrectionY = context.renderContext().convertToPainterUnits( height, heightUnit, heightMapUnitScale ) / 2.0;
621 if ( heightUnit == Qgis::RenderUnit::MetersInMapUnits && context.renderContext().flags() & Qgis::RenderContextFlag::RenderSymbolPreview )
622 {
623 // rendering for symbol previews -- an size in meters in map units can't be calculated, so treat the size as millimeters
624 // and clamp it to a reasonable range. It's the best we can do in this situation!
625 anchorPointCorrectionY = std::min( std::max( context.renderContext().convertToPainterUnits( height, Qgis::RenderUnit::Millimeters ), 3.0 ), 100.0 ) / 2.0;
626 }
627
629 {
630 offsetX += anchorPointCorrectionX;
631 }
632 else if ( horizontalAnchorPoint == Right )
633 {
634 offsetX -= anchorPointCorrectionX;
635 }
636
637 //correct vertical position according to anchor point
638 if ( verticalAnchorPoint == Top )
639 {
640 offsetY += anchorPointCorrectionY;
641 }
642 else if ( verticalAnchorPoint == Bottom )
643 {
644 offsetY -= anchorPointCorrectionY;
645 }
646}
647
648QPointF QgsMarkerSymbolLayer::_rotatedOffset( QPointF offset, double angle )
649{
650 angle = DEG2RAD( angle );
651 double c = std::cos( angle ), s = std::sin( angle );
652 return QPointF( offset.x() * c - offset.y() * s, offset.x() * s + offset.y() * c );
653}
654
655QgsMarkerSymbolLayer::HorizontalAnchorPoint QgsMarkerSymbolLayer::decodeHorizontalAnchorPoint( const QString &str )
656{
657 if ( str.compare( QLatin1String( "left" ), Qt::CaseInsensitive ) == 0 )
658 {
660 }
661 else if ( str.compare( QLatin1String( "right" ), Qt::CaseInsensitive ) == 0 )
662 {
664 }
665 else
666 {
668 }
669}
670
671QgsMarkerSymbolLayer::VerticalAnchorPoint QgsMarkerSymbolLayer::decodeVerticalAnchorPoint( const QString &str )
672{
673 if ( str.compare( QLatin1String( "top" ), Qt::CaseInsensitive ) == 0 )
674 {
676 }
677 else if ( str.compare( QLatin1String( "bottom" ), Qt::CaseInsensitive ) == 0 )
678 {
680 }
681 else
682 {
684 }
685}
686
688{
689 mSizeUnit = unit;
690 mOffsetUnit = unit;
691}
692
694{
695 if ( mOffsetUnit != mSizeUnit )
696 {
697 return Qgis::RenderUnit::Unknown;
698 }
699 return mOffsetUnit;
700}
701
703{
704 mSizeMapUnitScale = scale;
705 mOffsetMapUnitScale = scale;
706}
707
709{
711 {
712 return mSizeMapUnitScale;
713 }
714 return QgsMapUnitScale();
715}
716
718{
719 mWidthUnit = unit;
720 mOffsetUnit = unit;
721}
722
724{
725 return mWidthUnit;
726}
727
729{
730 mWidthMapUnitScale = scale;
731}
732
734{
735 return mWidthMapUnitScale;
736}
737
738
740{
741 const QList< QList< QPolygonF > > points = context.patchShape() ? context.patchShape()->toQPolygonF( Qgis::SymbolType::Line, size )
743 startRender( context );
744 QgsPaintEffect *effect = paintEffect();
745
746 std::unique_ptr< QgsEffectPainter > effectPainter;
747 if ( effect && effect->enabled() )
748 effectPainter = std::make_unique< QgsEffectPainter >( context.renderContext(), effect );
749
750 for ( const QList< QPolygonF > &line : points )
751 renderPolyline( line.value( 0 ), context );
752
753 effectPainter.reset();
754
755 stopRender( context );
756}
757
758void QgsLineSymbolLayer::renderPolygonStroke( const QPolygonF &points, const QVector<QPolygonF> *rings, QgsSymbolRenderContext &context )
759{
760 QgsExpressionContextScope *scope = nullptr;
761 std::unique_ptr< QgsExpressionContextScopePopper > scopePopper;
763 {
764 scope = new QgsExpressionContextScope();
765 scopePopper = std::make_unique< QgsExpressionContextScopePopper >( context.renderContext().expressionContext(), scope );
766 }
767
768 switch ( mRingFilter )
769 {
770 case AllRings:
771 case ExteriorRingOnly:
772 {
773 if ( scope )
775 renderPolyline( points, context );
776 break;
777 }
779 break;
780 }
781
782 if ( rings )
783 {
784 switch ( mRingFilter )
785 {
786 case AllRings:
788 {
789 int ringIndex = 1;
790 for ( const QPolygonF &ring : std::as_const( *rings ) )
791 {
792 if ( scope )
794
795 renderPolyline( ring, context );
796 ringIndex++;
797 }
798 }
799 break;
800 case ExteriorRingOnly:
801 break;
802 }
803 }
804}
805
806double QgsLineSymbolLayer::width( const QgsRenderContext &context ) const
807{
809}
810
812{
813 Q_UNUSED( context )
815}
816
817
819{
820 const QList< QList< QPolygonF > > polys = context.patchShape() ? context.patchShape()->toQPolygonF( Qgis::SymbolType::Fill, size )
822
823 startRender( context );
824 QgsPaintEffect *effect = paintEffect();
825
826 std::unique_ptr< QgsEffectPainter > effectPainter;
827 if ( effect && effect->enabled() )
828 effectPainter = std::make_unique< QgsEffectPainter >( context.renderContext(), effect );
829
830 for ( const QList< QPolygonF > &poly : polys )
831 {
832 QVector< QPolygonF > rings;
833 for ( int i = 1; i < poly.size(); ++i )
834 rings << poly.at( i );
835 renderPolygon( poly.value( 0 ), &rings, context );
836 }
837
838 effectPainter.reset();
839
840 stopRender( context );
841}
842
844{
845 return QImage();
846}
847
848void QgsFillSymbolLayer::_renderPolygon( QPainter *p, const QPolygonF &points, const QVector<QPolygonF> *rings, QgsSymbolRenderContext &context )
849{
850 if ( !p )
851 {
852 return;
853 }
854
855 // Disable 'Antialiasing' if the geometry was generalized in the current RenderContext (We known that it must have least #5 points).
856 if ( points.size() <= 5 &&
859 ( p->renderHints() & QPainter::Antialiasing ) )
860 {
861 p->setRenderHint( QPainter::Antialiasing, false );
862 p->drawRect( points.boundingRect() );
863 p->setRenderHint( QPainter::Antialiasing, true );
864 return;
865 }
866
867 // polygons outlines are sometimes rendered wrongly with drawPolygon, when
868 // clipped (see #13343), so use drawPath instead.
869 if ( !rings && p->pen().style() == Qt::NoPen )
870 {
871 // simple polygon without holes
872 p->drawPolygon( points );
873 }
874 else
875 {
876 // polygon with holes must be drawn using painter path
877 QPainterPath path;
878 path.addPolygon( points );
879
880 if ( rings )
881 {
882 for ( auto it = rings->constBegin(); it != rings->constEnd(); ++it )
883 {
884 QPolygonF ring = *it;
885 path.addPolygon( ring );
886 }
887 }
888
889 p->drawPath( path );
890 }
891}
892
893void QgsMarkerSymbolLayer::toSld( QDomDocument &doc, QDomElement &element, const QVariantMap &props ) const
894{
895 QDomElement symbolizerElem = doc.createElement( QStringLiteral( "se:PointSymbolizer" ) );
896 if ( !props.value( QStringLiteral( "uom" ), QString() ).toString().isEmpty() )
897 symbolizerElem.setAttribute( QStringLiteral( "uom" ), props.value( QStringLiteral( "uom" ), QString() ).toString() );
898 element.appendChild( symbolizerElem );
899
900 // <Geometry>
901 QgsSymbolLayerUtils::createGeometryElement( doc, symbolizerElem, props.value( QStringLiteral( "geom" ), QString() ).toString() );
902
903 writeSldMarker( doc, symbolizerElem, props );
904}
905
906QList<QgsSymbolLayerReference> QgsSymbolLayer::masks() const
907{
908 return {};
909}
910
912{
913 double size = mSize;
915 {
916 bool ok = false;
918
919 if ( ok )
920 {
921 switch ( mScaleMethod )
922 {
924 size = std::sqrt( size );
925 break;
927 break;
928 }
929 }
930 }
932}
933
935{
936 double angle = mAngle;
938 {
941 }
942 return angle;
943}
944
946{
947 mClipPath.clear();
948
949 const QgsRenderContext &renderContext = context.renderContext();
950 const QList<QPainterPath> clipPaths = renderContext.symbolLayerClipPaths( id() );
951 if ( !clipPaths.isEmpty() )
952 {
953 QPainterPath mergedPaths;
954 mergedPaths.setFillRule( Qt::WindingFill );
955 for ( QPainterPath path : clipPaths )
956 {
957 mergedPaths.addPath( path );
958 }
959
960 if ( !mergedPaths.isEmpty() )
961 {
962 mClipPath.addRect( 0, 0, renderContext.outputSize().width(),
963 renderContext.outputSize().height() );
964 mClipPath = mClipPath.subtracted( mergedPaths );
965 }
966 }
967}
968
969void QgsSymbolLayer::installMasks( QgsRenderContext &context, bool recursive )
970{
971 if ( !mClipPath.isEmpty() )
972 {
973 context.painter()->save();
974 context.painter()->setClipPath( mClipPath, Qt::IntersectClip );
975 }
976
977 if ( QgsSymbol *lSubSymbol = recursive ? subSymbol() : nullptr )
978 {
979 for ( QgsSymbolLayer *sl : lSubSymbol->symbolLayers() )
980 sl->installMasks( context, true );
981 }
982}
983
984void QgsSymbolLayer::removeMasks( QgsRenderContext &context, bool recursive )
985{
986 if ( !mClipPath.isEmpty() )
987 {
988 context.painter()->restore();
989 }
990
991 if ( QgsSymbol *lSubSymbol = recursive ? subSymbol() : nullptr )
992 {
993 for ( QgsSymbolLayer *sl : lSubSymbol->symbolLayers() )
994 sl->removeMasks( context, true );
995 }
996}
997
998
999void QgsSymbolLayer::setId( const QString &id )
1000{
1001 mId = id;
1002}
1003
1004QString QgsSymbolLayer::id() const
1005{
1006 return mId;
1007}
The Qgis class provides global constants for use throughout the application.
Definition: qgis.h:54
@ ScaleDiameter
Calculate scale by the diameter.
@ ScaleArea
Calculate scale by the area.
RenderUnit
Rendering size units.
Definition: qgis.h:3441
@ RenderSymbolPreview
The render is for a symbol preview only and map based properties may not be available,...
SymbolType
Attribute editing capabilities which may be supported by vector data providers.
Definition: qgis.h:340
@ Marker
Marker symbol.
@ Line
Line symbol.
@ Fill
Fill symbol.
static bool isGeneralizableByDeviceBoundingBox(const QgsRectangle &envelope, float mapToPixelTol=1.0f)
Returns whether the device-envelope can be replaced by its BBOX when is applied the specified toleran...
double valueAsDouble(int key, const QgsExpressionContext &context, double defaultValue=0.0, bool *ok=nullptr) const
Calculates the current value of the property with the specified key and interprets it as a double.
Exports QGIS layers to the DXF format.
Definition: qgsdxfexport.h:65
static double mapUnitScaleFactor(double scale, Qgis::RenderUnit symbolUnits, Qgis::DistanceUnit mapUnits, double mapUnitsPerPixel=1.0)
Returns scale factor for conversion to map units.
Qgis::DistanceUnit mapUnits() const
Retrieve map units.
double symbologyScale() const
Returns the reference scale for output.
Definition: qgsdxfexport.h:222
Single scope for storing variables and functions for use within a QgsExpressionContext.
void addVariable(const QgsExpressionContextScope::StaticVariable &variable)
Adds a variable into the context scope.
static const QString EXPR_GEOMETRY_RING_NUM
Inbuilt variable name for geometry ring number variable.
The feature class encapsulates a single feature including its unique ID, geometry and a list of field...
Definition: qgsfeature.h:56
bool isEmpty() const
Checks whether the container is empty.
Definition: qgsfields.cpp:128
virtual void renderPolygon(const QPolygonF &points, const QVector< QPolygonF > *rings, QgsSymbolRenderContext &context)=0
Renders the fill symbol layer for the polygon whose outer ring is defined by points,...
void _renderPolygon(QPainter *p, const QPolygonF &points, const QVector< QPolygonF > *rings, QgsSymbolRenderContext &context)
Default method to render polygon.
virtual QImage toTiledPatternImage() const
Renders the symbol layer as an image that can be used as a seamless pattern fill for polygons,...
void drawPreviewIcon(QgsSymbolRenderContext &context, QSize size) override
QgsFillSymbolLayer(const QgsFillSymbolLayer &other)=delete
QgsFillSymbolLayer cannot be copied.
QList< QList< QPolygonF > > toQPolygonF(Qgis::SymbolType type, QSizeF size) const
Converts the patch shape to a set of QPolygonF objects representing how the patch should be drawn for...
Qgis::RenderUnit mOffsetUnit
RenderRingFilter
Options for filtering rings when the line symbol layer is being used to render a polygon's rings.
@ ExteriorRingOnly
Render the exterior ring only.
@ InteriorRingsOnly
Render the interior rings only.
@ AllRings
Render both exterior and interior rings.
QgsMapUnitScale mWidthMapUnitScale
RenderRingFilter ringFilter() const
Returns the line symbol layer's ring filter, which controls which rings are rendered when the line sy...
void drawPreviewIcon(QgsSymbolRenderContext &context, QSize size) override
QgsLineSymbolLayer(const QgsLineSymbolLayer &other)=delete
QgsLineSymbolLayer cannot be copied.
void setOutputUnit(Qgis::RenderUnit unit) override
Sets the units to use for sizes and widths within the symbol layer.
Qgis::RenderUnit outputUnit() const override
Returns the units to use for sizes and widths within the symbol layer.
virtual void renderPolygonStroke(const QPolygonF &points, const QVector< QPolygonF > *rings, QgsSymbolRenderContext &context)
Renders the line symbol layer along the outline of polygon, using the given render context.
Qgis::RenderUnit mWidthUnit
virtual void renderPolyline(const QPolygonF &points, QgsSymbolRenderContext &context)=0
Renders the line symbol layer along the line joining points, using the given render context.
RenderRingFilter mRingFilter
virtual double width() const
Returns the estimated width for the line symbol layer.
double dxfWidth(const QgsDxfExport &e, QgsSymbolRenderContext &context) const override
Gets line width.
QgsMapUnitScale mapUnitScale() const override
void setRingFilter(QgsLineSymbolLayer::RenderRingFilter filter)
Sets the line symbol layer's ring filter, which controls which rings are rendered when the line symbo...
void setMapUnitScale(const QgsMapUnitScale &scale) override
Qgis::RenderUnit widthUnit() const
Returns the units for the line's width.
double mapUnitsPerPixel() const
Returns the current map units per pixel.
Struct for storing maximum and minimum scales for measurements in map units.
double mSize
Marker size.
void drawPreviewIcon(QgsSymbolRenderContext &context, QSize size) override
Qgis::RenderUnit mOffsetUnit
Offset units.
QPointF offset() const
Returns the marker's offset, which is the horizontal and vertical displacement which the rendered mar...
HorizontalAnchorPoint
Symbol horizontal anchor points.
@ Right
Align to right side of symbol.
@ HCenter
Align to horizontal center of symbol.
@ Left
Align to left side of symbol.
Qgis::RenderUnit outputUnit() const override
Returns the units to use for sizes and widths within the symbol layer.
virtual void renderPoint(QPointF point, QgsSymbolRenderContext &context)=0
Renders a marker at the specified point.
QPointF mOffset
Marker offset.
QgsMapUnitScale mapUnitScale() const override
double size() const
Returns the symbol size.
QgsMapUnitScale mOffsetMapUnitScale
Offset map unit scale.
HorizontalAnchorPoint mHorizontalAnchorPoint
Horizontal anchor point.
QgsMarkerSymbolLayer(const QgsMarkerSymbolLayer &other)=delete
QgsMarkerSymbolLayer cannot be copied.
static QPointF _rotatedOffset(QPointF offset, double angle)
Adjusts a marker offset to account for rotation.
virtual double dxfAngle(QgsSymbolRenderContext &context) const override
Gets angle.
Qgis::ScaleMethod mScaleMethod
Marker size scaling method.
virtual double dxfSize(const QgsDxfExport &e, QgsSymbolRenderContext &context) const override
Gets marker size.
void stopRender(QgsSymbolRenderContext &context) override
Called after a set of rendering operations has finished on the supplied render context.
VerticalAnchorPoint verticalAnchorPoint() const
Returns the vertical anchor point for positioning the symbol.
QgsMapUnitScale mSizeMapUnitScale
Marker size map unit scale.
Qgis::RenderUnit mSizeUnit
Marker size unit.
void setOutputUnit(Qgis::RenderUnit unit) override
Sets the units to use for sizes and widths within the symbol layer.
HorizontalAnchorPoint horizontalAnchorPoint() const
Returns the horizontal anchor point for positioning the symbol.
VerticalAnchorPoint
Symbol vertical anchor points.
@ VCenter
Align to vertical center of symbol.
@ Bottom
Align to bottom of symbol.
@ Top
Align to top of symbol.
void markerOffset(QgsSymbolRenderContext &context, double &offsetX, double &offsetY) const
Calculates the required marker offset, including both the symbol offset and any displacement required...
VerticalAnchorPoint mVerticalAnchorPoint
Vertical anchor point.
void toSld(QDomDocument &doc, QDomElement &element, const QVariantMap &props) const override
Saves the symbol layer as SLD.
virtual void writeSldMarker(QDomDocument &doc, QDomElement &element, const QVariantMap &props) const
Writes the symbol layer definition as a SLD XML element.
double mAngle
Marker rotation angle, in degrees clockwise from north.
void startRender(QgsSymbolRenderContext &context) override
Called before a set of rendering operations commences on the supplied render context.
double angle() const
Returns the rotation angle for the marker, in degrees clockwise from north.
void setMapUnitScale(const QgsMapUnitScale &scale) override
static bool isDefaultStack(QgsPaintEffect *effect)
Tests whether a paint effect matches the default effects stack.
Base class for visual effects which can be applied to QPicture drawings.
bool enabled() const
Returns whether the effect is enabled.
QVariant value(int key, const QgsExpressionContext &context, const QVariant &defaultValue=QVariant()) const 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:46
@ HorizontalAnchor
Horizontal anchor point.
Definition: qgsproperty.h:74
@ Double
Double value (including negative values)
Definition: qgsproperty.h:56
@ VerticalAnchor
Vertical anchor point.
Definition: qgsproperty.h:75
@ Double0To1
Double value between 0-1 (inclusive)
Definition: qgsproperty.h:58
@ FillStyle
Fill style (eg solid, lines)
Definition: qgsproperty.h:72
@ StrokeWidth
Line stroke width.
Definition: qgsproperty.h:71
@ LineStyle
Line style (eg solid/dashed)
Definition: qgsproperty.h:70
@ String
Any string value.
Definition: qgsproperty.h:60
@ Boolean
Boolean value.
Definition: qgsproperty.h:52
@ PenJoinStyle
Pen join style.
Definition: qgsproperty.h:65
@ IntegerPositive
Positive integer values (including 0)
Definition: qgsproperty.h:54
@ Opacity
Opacity (0-100)
Definition: qgsproperty.h:61
@ CapStyle
Line cap style (eg round)
Definition: qgsproperty.h:73
@ Rotation
Rotation (value between 0-360 degrees)
Definition: qgsproperty.h:59
@ Size
1D size (eg marker radius, or square marker height/width)
Definition: qgsproperty.h:68
@ ColorWithAlpha
Color with alpha channel.
Definition: qgsproperty.h:63
@ DoublePositive
Positive double value (including 0)
Definition: qgsproperty.h:57
@ DataTypeString
Property requires a string value.
Definition: qgsproperty.h:91
@ DataTypeNumeric
Property requires a numeric value.
Definition: qgsproperty.h:98
A store for object properties.
Definition: qgsproperty.h:230
static QgsProperty fromExpression(const QString &expression, bool isActive=true)
Returns a new ExpressionBasedProperty created from the specified expression.
static QgsProperty fromField(const QString &fieldName, bool isActive=true)
Returns a new FieldBasedProperty created from the specified field name.
Contains information about the context of a rendering operation.
double convertToPainterUnits(double size, Qgis::RenderUnit unit, const QgsMapUnitScale &scale=QgsMapUnitScale(), Qgis::RenderSubcomponentProperty property=Qgis::RenderSubcomponentProperty::Generic) const
Converts a size from the specified units to painter units (pixels).
QPainter * painter()
Returns the destination QPainter for the render operation.
QgsExpressionContext & expressionContext()
Gets the expression context.
QSize outputSize() const
Returns the size of the resulting rendered image, in pixels.
const QgsVectorSimplifyMethod & vectorSimplifyMethod() const
Returns the simplification settings to use when rendering vector layers.
const QgsMapToPixel & mapToPixel() const
Returns the context's map to pixel transform, which transforms between map coordinates and device coo...
Qgis::RenderContextFlags flags() const
Returns combination of flags used for rendering.
QList< QPainterPath > symbolLayerClipPaths(const QString &symbolLayerId) const
Returns clip paths to be applied to the symbolLayer before rendering.
static QgsStyle * defaultStyle()
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:1205
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.
void setId(const QString &id)
Set symbol layer identifier This id has to be unique in the whole project.
virtual void setStrokeColor(const QColor &color)
Sets the stroke color for the symbol layer.
QPainterPath mClipPath
virtual double dxfSize(const QgsDxfExport &e, QgsSymbolRenderContext &context) const
Gets marker size.
virtual double dxfOffset(const QgsDxfExport &e, QgsSymbolRenderContext &context) const
Gets offset.
virtual QColor dxfBrushColor(QgsSymbolRenderContext &context) const
Gets brush/fill color.
Qgis::SymbolType mType
void removeMasks(QgsRenderContext &context, bool recursive)
When rendering, remove previously installed masks from context painter if recursive is true masks are...
virtual QSet< QString > usedAttributes(const QgsRenderContext &context) const
Returns the set of attributes referenced by the layer.
void copyDataDefinedProperties(QgsSymbolLayer *destLayer) const
Copies all data defined properties of this layer to another symbol layer.
void installMasks(QgsRenderContext &context, bool recursive)
When rendering, install masks on context painter if recursive is true masks are installed recursively...
void restoreOldDataDefinedProperties(const QVariantMap &stringMap)
Restores older data defined properties from string map.
void setPaintEffect(QgsPaintEffect *effect)
Sets the current paint effect for the layer.
void setRenderingPass(int renderingPass)
Specifies the rendering pass in which this symbol layer should be rendered.
QgsPaintEffect * paintEffect() const
Returns the current paint effect for the layer.
virtual void startRender(QgsSymbolRenderContext &context)=0
Called before a set of rendering operations commences on the supplied render context.
QgsSymbolLayer(const QgsSymbolLayer &other)=delete
QgsSymbolLayer cannot be copied.
std::unique_ptr< QgsPaintEffect > mPaintEffect
virtual Qt::PenStyle dxfPenStyle() const
Gets pen style.
virtual void setFillColor(const QColor &color)
Sets the fill color for the symbol layer.
virtual void prepareExpressions(const QgsSymbolRenderContext &context)
Prepares all data defined property expressions for evaluation.
virtual QColor dxfColor(QgsSymbolRenderContext &context) const
Gets color.
int renderingPass() const
Specifies the rendering pass in which this symbol layer should be rendered.
virtual void stopRender(QgsSymbolRenderContext &context)=0
Called after a set of rendering operations has finished on the supplied render context.
virtual bool isCompatibleWithSymbol(QgsSymbol *symbol) const
Returns if the layer can be used below the specified symbol.
QString id() const
Returns symbol layer identifier This id is unique in the whole project.
virtual void setDataDefinedProperty(Property key, const QgsProperty &property)
Sets a data defined property for the layer.
virtual void setColor(const QColor &color)
Sets the "representative" color for the symbol layer.
virtual QgsSymbol * subSymbol()
Returns the symbol's sub symbol, if present.
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
void copyPaintEffect(QgsSymbolLayer *destLayer) const
Copies paint effect of this layer to another symbol layer.
virtual Qgis::SymbolLayerFlags flags() const
Returns flags which control the symbol layer's behavior.
QgsPropertyCollection mDataDefinedProperties
virtual QList< QgsSymbolLayerReference > masks() const
Returns masks defined by this symbol layer.
QgsPropertyCollection & dataDefinedProperties()
Returns a reference to the symbol layer's property collection, used for data defined overrides.
virtual Qt::BrushStyle dxfBrushStyle() const
Gets brush/fill style.
virtual QVector< qreal > dxfCustomDashPattern(Qgis::RenderUnit &unit) const
Gets dash pattern.
virtual bool hasDataDefinedProperties() const
Returns true if the symbol layer (or any of its sub-symbols) contains data defined properties.
void setDataDefinedProperties(const QgsPropertyCollection &collection)
Sets the symbol layer's property collection, used for data defined overrides.
QgsFields fields() const
Fields of the layer.
void setOriginalValueVariable(const QVariant &value)
Sets the original value variable value for data defined symbology.
const QgsLegendPatchShape * patchShape() const
Returns the symbol patch shape, to use if rendering symbol preview icons.
QgsRenderContext & renderContext()
Returns a reference to the context's render context.
Abstract base class for all rendered symbols.
Definition: qgssymbol.h:94
Qgis::SymbolType type() const
Returns the symbol's type.
Definition: qgssymbol.h:153
static bool isNull(const QVariant &variant)
Returns true if the specified variant should be considered a NULL value.
SimplifyHints simplifyHints() const
Gets the simplification hints of the vector layer managed.
float threshold() const
Gets the simplification threshold of the vector layer managed.
@ AntialiasingSimplification
The geometries can be rendered with 'AntiAliasing' disabled because of it is '1-pixel size'.
double ANALYSIS_EXPORT angle(QgsPoint *p1, QgsPoint *p2, QgsPoint *p3, QgsPoint *p4)
Calculates the angle between two segments (in 2 dimension, z-values are ignored)
Definition: MathUtils.cpp: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:38
#define DEG2RAD(x)
const QgsField & field
Definition: qgsfield.h:554
QMap< int, QgsPropertyDefinition > QgsPropertiesDefinition
Definition of available properties.
QgsProperty propertyFromMap(const QVariantMap &map, const QString &baseName)
Single variable definition for use within a QgsExpressionContextScope.