QGIS API Documentation 4.3.0-Master (96c7fa699b4)
Loading...
Searching...
No Matches
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
18#include "qgsdxfexport.h"
22#include "qgsgeos.h"
23#include "qgslegendpatchshape.h"
24#include "qgspainteffect.h"
26#include "qgsproperty.h"
27#include "qgsrendercontext.h"
28#include "qgssldexportcontext.h"
29#include "qgsstyle.h"
30#include "qgssymbol.h"
32#include "qgssymbollayerutils.h"
33
34#include <QPainter>
35#include <QPointF>
36#include <QPolygonF>
37#include <QSize>
38#include <QString>
39#include <QUuid>
40
41using namespace Qt::StringLiterals;
42
43QgsPropertiesDefinition QgsSymbolLayer::sPropertyDefinitions;
44
45void QgsSymbolLayer::initPropertyDefinitions()
46{
47 if ( !sPropertyDefinitions.isEmpty() )
48 return;
49
50 QString origin = u"symbol"_s;
51
52 sPropertyDefinitions = QgsPropertiesDefinition {
53 { static_cast< int >( QgsSymbolLayer::Property::Size ), QgsPropertyDefinition( "size", QObject::tr( "Symbol size" ), QgsPropertyDefinition::Size, origin ) },
54 { static_cast< int >( QgsSymbolLayer::Property::Angle ), QgsPropertyDefinition( "angle", QObject::tr( "Rotation angle" ), QgsPropertyDefinition::Rotation, origin ) },
55 { static_cast< int >( QgsSymbolLayer::Property::Name ), QgsPropertyDefinition( "name", QObject::tr( "Symbol name" ), QgsPropertyDefinition::String, origin ) },
56 { static_cast< int >( QgsSymbolLayer::Property::FillColor ), QgsPropertyDefinition( "fillColor", QObject::tr( "Symbol fill color" ), QgsPropertyDefinition::ColorWithAlpha, origin ) },
57 { static_cast< int >( QgsSymbolLayer::Property::StrokeColor ), QgsPropertyDefinition( "outlineColor", QObject::tr( "Symbol stroke color" ), QgsPropertyDefinition::ColorWithAlpha, origin ) },
58 { static_cast< int >( QgsSymbolLayer::Property::StrokeWidth ), QgsPropertyDefinition( "outlineWidth", QObject::tr( "Symbol stroke width" ), QgsPropertyDefinition::StrokeWidth, origin ) },
59 { static_cast< int >( QgsSymbolLayer::Property::StrokeStyle ), QgsPropertyDefinition( "outlineStyle", QObject::tr( "Symbol stroke style" ), QgsPropertyDefinition::LineStyle, origin ) },
60 { static_cast< int >( QgsSymbolLayer::Property::Offset ), QgsPropertyDefinition( "offset", QObject::tr( "Symbol offset" ), QgsPropertyDefinition::Offset, origin ) },
61 { static_cast< int >( QgsSymbolLayer::Property::Character ), QgsPropertyDefinition( "char", QObject::tr( "Marker character(s)" ), QgsPropertyDefinition::String, origin ) },
62 { static_cast< int >( QgsSymbolLayer::Property::FontFamily ), QgsPropertyDefinition( "fontFamily", QObject::tr( "Font family" ), QgsPropertyDefinition::String, origin ) },
63 { static_cast< int >( QgsSymbolLayer::Property::FontStyle ), QgsPropertyDefinition( "fontStyle", QObject::tr( "Font style" ), QgsPropertyDefinition::String, origin ) },
64 { static_cast< int >( QgsSymbolLayer::Property::Width ), QgsPropertyDefinition( "width", QObject::tr( "Symbol width" ), QgsPropertyDefinition::DoublePositive, origin ) },
65 { static_cast< int >( QgsSymbolLayer::Property::Height ), QgsPropertyDefinition( "height", QObject::tr( "Symbol height" ), QgsPropertyDefinition::DoublePositive, origin ) },
67 QgsPropertyDefinition( "preserveAspectRatio", QObject::tr( "Preserve aspect ratio between width and height" ), QgsPropertyDefinition::Boolean, origin ) },
68 { static_cast< int >( QgsSymbolLayer::Property::FillStyle ), QgsPropertyDefinition( "fillStyle", QObject::tr( "Symbol fill style" ), QgsPropertyDefinition::FillStyle, origin ) },
69 { static_cast< int >( QgsSymbolLayer::Property::JoinStyle ), QgsPropertyDefinition( "joinStyle", QObject::tr( "Outline join style" ), QgsPropertyDefinition::PenJoinStyle, origin ) },
70 { static_cast< int >( QgsSymbolLayer::Property::SecondaryColor ), QgsPropertyDefinition( "color2", QObject::tr( "Secondary fill color" ), QgsPropertyDefinition::ColorWithAlpha, origin ) },
71 { static_cast< int >( QgsSymbolLayer::Property::LineAngle ), QgsPropertyDefinition( "lineAngle", QObject::tr( "Angle for line fills" ), QgsPropertyDefinition::Rotation, origin ) },
72 { static_cast< int >( QgsSymbolLayer::Property::GradientType ),
73 QgsPropertyDefinition( "gradientType", QgsPropertyDefinition::DataTypeString, QObject::tr( "Gradient type" ), QObject::tr( "string " ) + "[<b>linear</b>|<b>radial</b>|<b>conical</b>]"_L1, origin ) },
74 { static_cast< int >( QgsSymbolLayer::Property::CoordinateMode ),
75 QgsPropertyDefinition( "gradientMode", QgsPropertyDefinition::DataTypeString, QObject::tr( "Gradient mode" ), QObject::tr( "string " ) + "[<b>feature</b>|<b>viewport</b>]"_L1, origin ) },
76 { static_cast< int >( QgsSymbolLayer::Property::GradientSpread ),
77 QgsPropertyDefinition( "gradientSpread", QgsPropertyDefinition::DataTypeString, QObject::tr( "Gradient spread" ), QObject::tr( "string " ) + "[<b>pad</b>|<b>repeat</b>|<b>reflect</b>]"_L1, origin ) },
78 { static_cast< int >( QgsSymbolLayer::Property::GradientReference1X ), QgsPropertyDefinition( "gradientRef1X", QObject::tr( "Reference point 1 (X)" ), QgsPropertyDefinition::Double0To1, origin ) },
79 { static_cast< int >( QgsSymbolLayer::Property::GradientReference1Y ), QgsPropertyDefinition( "gradientRef1Y", QObject::tr( "Reference point 1 (Y)" ), QgsPropertyDefinition::Double0To1, origin ) },
80 { static_cast< int >( QgsSymbolLayer::Property::GradientReference2X ), QgsPropertyDefinition( "gradientRef2X", QObject::tr( "Reference point 2 (X)" ), QgsPropertyDefinition::Double0To1, origin ) },
81 { static_cast< int >( QgsSymbolLayer::Property::GradientReference2Y ), QgsPropertyDefinition( "gradientRef2Y", QObject::tr( "Reference point 2 (Y)" ), QgsPropertyDefinition::Double0To1, origin ) },
83 QgsPropertyDefinition( "gradientRef1Centroid", QObject::tr( "Reference point 1 follows feature centroid" ), QgsPropertyDefinition::Boolean, origin ) },
85 QgsPropertyDefinition( "gradientRef2Centroid", QObject::tr( "Reference point 2 follows feature centroid" ), QgsPropertyDefinition::Boolean, origin ) },
86 { static_cast< int >( QgsSymbolLayer::Property::BlurRadius ),
87 QgsPropertyDefinition( "blurRadius", QgsPropertyDefinition::DataTypeNumeric, QObject::tr( "Blur radius" ), QObject::tr( "Integer between 0 and 18" ), origin ) },
88 { static_cast< int >( QgsSymbolLayer::Property::LineDistance ), QgsPropertyDefinition( "lineDistance", QObject::tr( "Distance between lines" ), QgsPropertyDefinition::DoublePositive, origin ) },
90 QgsPropertyDefinition( "shapeburstWholeShape", QObject::tr( "Shade whole shape" ), QgsPropertyDefinition::Boolean, origin ) },
92 QgsPropertyDefinition( "shapeburstMaxDist", QObject::tr( "Maximum distance for shapeburst fill" ), QgsPropertyDefinition::DoublePositive, origin ) },
94 QgsPropertyDefinition( "shapeburstIgnoreRings", QObject::tr( "Ignore rings in feature" ), QgsPropertyDefinition::Boolean, origin ) },
95 { static_cast< int >( QgsSymbolLayer::Property::File ), QgsPropertyDefinition( "file", QObject::tr( "Symbol file path" ), QgsPropertyDefinition::String, origin ) },
96 { static_cast< int >( QgsSymbolLayer::Property::DistanceX ),
97 QgsPropertyDefinition( "distanceX", QObject::tr( "Horizontal distance between markers" ), QgsPropertyDefinition::DoublePositive, origin ) },
98 { static_cast< int >( QgsSymbolLayer::Property::DistanceY ), QgsPropertyDefinition( "distanceY", QObject::tr( "Vertical distance between markers" ), QgsPropertyDefinition::DoublePositive, origin ) },
99 { static_cast< int >( QgsSymbolLayer::Property::DisplacementX ),
100 QgsPropertyDefinition( "displacementX", QObject::tr( "Horizontal displacement between rows" ), QgsPropertyDefinition::DoublePositive, origin ) },
101 { static_cast< int >( QgsSymbolLayer::Property::DisplacementY ),
102 QgsPropertyDefinition( "displacementY", QObject::tr( "Vertical displacement between columns" ), QgsPropertyDefinition::DoublePositive, origin ) },
103 { static_cast< int >( QgsSymbolLayer::Property::OffsetX ), QgsPropertyDefinition( "offsetX", QObject::tr( "Horizontal offset" ), QgsPropertyDefinition::Double, origin ) },
104 { static_cast< int >( QgsSymbolLayer::Property::OffsetY ), QgsPropertyDefinition( "offsetY", QObject::tr( "Vertical offset" ), QgsPropertyDefinition::Double, origin ) },
105 { static_cast< int >( QgsSymbolLayer::Property::Opacity ), QgsPropertyDefinition( "alpha", QObject::tr( "Opacity" ), QgsPropertyDefinition::Opacity, origin ) },
106 { static_cast< int >( QgsSymbolLayer::Property::CustomDash ),
107 QgsPropertyDefinition( "customDash", QgsPropertyDefinition::DataTypeString, QObject::tr( "Custom dash pattern" ), QObject::tr( "[<b><dash>;<space></b>] e.g. '8;2;1;2'" ), origin ) },
108 { static_cast< int >( QgsSymbolLayer::Property::CapStyle ), QgsPropertyDefinition( "capStyle", QObject::tr( "Line cap style" ), QgsPropertyDefinition::CapStyle, origin ) },
109 { static_cast< int >( QgsSymbolLayer::Property::Placement ),
110 QgsPropertyDefinition(
111 "placement",
113 QObject::tr( "Marker placement" ),
114 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>]",
115 origin
116 ) },
117 { static_cast< int >( QgsSymbolLayer::Property::Interval ), QgsPropertyDefinition( "interval", QObject::tr( "Marker interval" ), QgsPropertyDefinition::DoublePositive, origin ) },
118 { static_cast< int >( QgsSymbolLayer::Property::OffsetAlongLine ), QgsPropertyDefinition( "offsetAlongLine", QObject::tr( "Offset along line" ), QgsPropertyDefinition::Double, origin ) },
119 { static_cast< int >( QgsSymbolLayer::Property::AverageAngleLength ),
120 QgsPropertyDefinition( "averageAngleLength", QObject::tr( "Average line angles over" ), QgsPropertyDefinition::DoublePositive, origin ) },
121 { static_cast< int >( QgsSymbolLayer::Property::HorizontalAnchor ), QgsPropertyDefinition( "hAnchor", QObject::tr( "Horizontal anchor point" ), QgsPropertyDefinition::HorizontalAnchor, origin ) },
122 { static_cast< int >( QgsSymbolLayer::Property::VerticalAnchor ), QgsPropertyDefinition( "vAnchor", QObject::tr( "Vertical anchor point" ), QgsPropertyDefinition::VerticalAnchor, origin ) },
123 { static_cast< int >( QgsSymbolLayer::Property::LayerEnabled ), QgsPropertyDefinition( "enabled", QObject::tr( "Layer enabled" ), QgsPropertyDefinition::Boolean, origin ) },
124 { static_cast< int >( QgsSymbolLayer::Property::ArrowWidth ), QgsPropertyDefinition( "arrowWidth", QObject::tr( "Arrow line width" ), QgsPropertyDefinition::StrokeWidth, origin ) },
125 { static_cast< int >( QgsSymbolLayer::Property::ArrowStartWidth ), QgsPropertyDefinition( "arrowStartWidth", QObject::tr( "Arrow line start width" ), QgsPropertyDefinition::StrokeWidth, origin ) },
126 { static_cast< int >( QgsSymbolLayer::Property::ArrowHeadLength ), QgsPropertyDefinition( "arrowHeadLength", QObject::tr( "Arrow head length" ), QgsPropertyDefinition::DoublePositive, origin ) },
127 { static_cast< int >( QgsSymbolLayer::Property::ArrowHeadThickness ),
128 QgsPropertyDefinition( "arrowHeadThickness", QObject::tr( "Arrow head thickness" ), QgsPropertyDefinition::DoublePositive, origin ) },
129 { static_cast< int >( QgsSymbolLayer::Property::ArrowHeadType ),
130 QgsPropertyDefinition( "arrowHeadType", QgsPropertyDefinition::DataTypeString, QObject::tr( "Arrow head type" ), QObject::tr( "string " ) + "[<b>single</b>|<b>reversed</b>|<b>double</b>]"_L1, origin ) },
131 { static_cast< int >( QgsSymbolLayer::Property::ArrowType ),
132 QgsPropertyDefinition( "arrowType", QgsPropertyDefinition::DataTypeString, QObject::tr( "Arrow type" ), QObject::tr( "string " ) + "[<b>plain</b>|<b>lefthalf</b>|<b>righthalf</b>]"_L1, origin ) },
133 { static_cast< int >( QgsSymbolLayer::Property::PointCount ), QgsPropertyDefinition( "pointCount", QObject::tr( "Point count" ), QgsPropertyDefinition::IntegerPositive, origin ) },
134 { static_cast< int >( QgsSymbolLayer::Property::RandomSeed ),
135 QgsPropertyDefinition( "randomSeed", QgsPropertyDefinition::DataTypeNumeric, QObject::tr( "Random number seed" ), QObject::tr( "integer > 0, or 0 for completely random sequence" ), origin ) },
136 { static_cast< int >( QgsSymbolLayer::Property::ClipPoints ), QgsPropertyDefinition( "clipPoints", QObject::tr( "Clip markers" ), QgsPropertyDefinition::Boolean, origin ) },
137 { static_cast< int >( QgsSymbolLayer::Property::DensityArea ), QgsPropertyDefinition( "densityArea", QObject::tr( "Density area" ), QgsPropertyDefinition::DoublePositive, origin ) },
138 { static_cast< int >( QgsSymbolLayer::Property::DashPatternOffset ),
139 QgsPropertyDefinition( "dashPatternOffset", QObject::tr( "Dash pattern offset" ), QgsPropertyDefinition::DoublePositive, origin ) },
140 { static_cast< int >( QgsSymbolLayer::Property::TrimStart ), QgsPropertyDefinition( "trimStart", QObject::tr( "Start trim distance" ), QgsPropertyDefinition::DoublePositive, origin ) },
141 { static_cast< int >( QgsSymbolLayer::Property::TrimEnd ), QgsPropertyDefinition( "trimEnd", QObject::tr( "End trim distance" ), QgsPropertyDefinition::DoublePositive, origin ) },
142 { static_cast< int >( QgsSymbolLayer::Property::LineStartWidthValue ),
143 QgsPropertyDefinition( "lineStartWidthValue", QObject::tr( "Line start width value" ), QgsPropertyDefinition::Double, origin ) },
144 { static_cast< int >( QgsSymbolLayer::Property::LineEndWidthValue ), QgsPropertyDefinition( "lineEndWidthValue", QObject::tr( "Line end width value" ), QgsPropertyDefinition::Double, origin ) },
145 { static_cast< int >( QgsSymbolLayer::Property::LineStartColorValue ),
146 QgsPropertyDefinition( "lineStartColorValue", QObject::tr( "Line start color value" ), QgsPropertyDefinition::Double, origin ) },
147 { static_cast< int >( QgsSymbolLayer::Property::LineEndColorValue ), QgsPropertyDefinition( "lineEndColorValue", QObject::tr( "Line end color value" ), QgsPropertyDefinition::Double, origin ) },
148 { static_cast< int >( QgsSymbolLayer::Property::MarkerClipping ),
149 QgsPropertyDefinition( "markerClipping", QgsPropertyDefinition::DataTypeString, QObject::tr( "Marker clipping mode" ), QObject::tr( "string " ) + "[<b>no</b>|<b>shape</b>|<b>centroid_within</b>|<b>completely_within</b>]"_L1, origin ) },
150 { static_cast< int >( QgsSymbolLayer::Property::RandomOffsetX ), QgsPropertyDefinition( "randomOffsetX", QObject::tr( "Horizontal random offset" ), QgsPropertyDefinition::Double, origin ) },
151 { static_cast< int >( QgsSymbolLayer::Property::RandomOffsetY ), QgsPropertyDefinition( "randomOffsetY", QObject::tr( "Vertical random offset" ), QgsPropertyDefinition::Double, origin ) },
152 { static_cast< int >( QgsSymbolLayer::Property::LineClipping ),
153 QgsPropertyDefinition( "lineClipping", QgsPropertyDefinition::DataTypeString, QObject::tr( "Line clipping mode" ), QObject::tr( "string " ) + "[<b>no</b>|<b>during_render</b>|<b>before_render</b>]"_L1, origin ) },
154 { static_cast< int >( QgsSymbolLayer::Property::SkipMultiples ), QgsPropertyDefinition( "skipMultiples", QObject::tr( "Skip multiples of" ), QgsPropertyDefinition::DoublePositive, origin ) },
155 { static_cast< int >( QgsSymbolLayer::Property::ShowMarker ), QgsPropertyDefinition( "showMarker", QObject::tr( "Show marker" ), QgsPropertyDefinition::Boolean, origin ) },
156 { static_cast< int >( QgsSymbolLayer::Property::BlankSegments ), QgsPropertyDefinition( "blankSegments", QObject::tr( "Line blank segments" ), QgsPropertyDefinition::String, origin ) },
157 { static_cast< int >( QgsSymbolLayer::Property::ExtraItems ), QgsPropertyDefinition( "extraItems", QObject::tr( "Line extra item" ), QgsPropertyDefinition::String, origin ) },
158 };
159}
160
165
167{
168 installMasks( context, false );
169
170 if ( QgsSymbol *lSubSymbol = subSymbol() )
171 lSubSymbol->startFeatureRender( feature, context );
172}
173
175{
176 if ( QgsSymbol *lSubSymbol = subSymbol() )
177 lSubSymbol->stopFeatureRender( feature, context );
178
179 removeMasks( context, false );
180}
181
183{
184 return nullptr;
185}
186
188{
189 delete symbol;
190 return false;
191}
192
193bool QgsSymbolLayer::writeDxf( QgsDxfExport &e, double mmMapUnitScaleFactor, const QString &layerName, QgsSymbolRenderContext &context, QPointF shift ) const
194{
195 Q_UNUSED( e )
196 Q_UNUSED( mmMapUnitScaleFactor )
197 Q_UNUSED( layerName )
198 Q_UNUSED( context )
199 Q_UNUSED( shift )
200 return false;
201}
202
204{
205 Q_UNUSED( e )
206 return dxfWidth( context );
207}
208
210{
211 Q_UNUSED( context )
212 return 1.0;
213}
214
216{
217 Q_UNUSED( e )
218 return dxfSize( context );
219}
220
222{
223 Q_UNUSED( context )
224 return 1.0;
225}
226
228{
229 Q_UNUSED( e )
230 return dxfOffset( context );
231}
232
234{
235 Q_UNUSED( context )
236 return 0.0;
237}
238
240{
241 Q_UNUSED( context )
242 return color();
243}
244
246{
247 Q_UNUSED( context )
248 return 0.0;
249}
250
252{
253 Q_UNUSED( unit )
254 return QVector<qreal>();
255}
256
257Qt::PenStyle QgsSymbolLayer::dxfPenStyle() const
258{
259 return Qt::SolidLine;
260}
261
263{
264 Q_UNUSED( context )
265 return color();
266}
267
268Qt::BrushStyle QgsSymbolLayer::dxfBrushStyle() const
269{
270 return Qt::NoBrush;
271}
272
274{
275 return mPaintEffect.get();
276}
277
279{
280 if ( effect == mPaintEffect.get() )
281 return;
282
283 mPaintEffect.reset( effect );
284}
285
287 : mType( other.mType )
288 , mEnabled( other.mEnabled )
289 , mUserFlags( other.mUserFlags )
290 , mLocked( other.mLocked )
291 , mColor( other.mColor )
293 , mId( other.mId )
296 , mPaintEffect( other.mPaintEffect ? other.mPaintEffect->clone() : nullptr )
297 , mFields( other.mFields )
298 , mClipPath( other.mClipPath )
299 , mStateBeforeInstallingMaskClipPaths( nullptr ) // we intentionally do not copy this, it will only be set in between start/end render calls of a the same symbol layer instance
300{}
301
303 : mType( type )
304 , mLocked( locked )
305 , mId( QUuid::createUuid().toString() )
306{}
307
309{
310 if ( !other )
311 return false;
312
313 if ( layerType() != other->layerType() )
314 return false;
315
316 // TODO -- we could consider each property individually
318 return false;
319
320 // shortcut now that we know there's no randomness/changing overrides involved
321 if ( other == this )
322 return true;
323
324 if ( mEnabled != other->mEnabled
325 || mColor != other->mColor
326 || mRenderingPass != other->mRenderingPass
327
328 // TODO -- we could consider the actual settings of the paint effect
330 || ( other->mPaintEffect && !QgsPaintEffectRegistry::isDefaultStack( other->mPaintEffect.get() ) ) )
331 return false;
332
333 return properties() == other->properties();
334}
335
340
345
350
352{
353 return mColor;
354}
355
356void QgsSymbolLayer::setColor( const QColor &color )
357{
358 mColor = color;
359}
360
361void QgsSymbolLayer::setStrokeColor( const QColor & )
362{}
363
365{
366 return QColor();
367}
368
369void QgsSymbolLayer::setFillColor( const QColor & )
370{}
371
373{
374 return QColor();
375}
376
378{
380
381 if ( !context.fields().isEmpty() )
382 {
383 //QgsFields is implicitly shared, so it's cheap to make a copy
384 mFields = context.fields();
385 }
386}
387
389{
390 return mDataDefinedProperties.hasActiveProperties();
391}
392
394{
395 QgsSymbolLayer::initPropertyDefinitions();
396 return sPropertyDefinitions;
397}
398
400
402{
404 return true;
405
406 return symbol->type() == mType;
407}
408
410{
411 return false;
412}
413
415{
416 return false;
417}
418
423
425{
426 return mRenderingPass;
427}
428
429QSet<QString> QgsSymbolLayer::usedAttributes( const QgsRenderContext &context ) const
430{
431 // calling referencedFields() with ignoreContext=true because in our expression context
432 // we do not have valid QgsFields yet - because of that the field names from expressions
433 // wouldn't get reported
434 QSet<QString> columns = mDataDefinedProperties.referencedFields( context.expressionContext(), true );
435 return columns;
436}
437
438QgsProperty propertyFromMap( const QVariantMap &map, const QString &baseName )
439{
440 QString prefix;
441 if ( !baseName.isEmpty() )
442 {
443 prefix.append( u"%1_dd_"_s.arg( baseName ) );
444 }
445
446 if ( !map.contains( u"%1expression"_s.arg( prefix ) ) )
447 {
448 //requires at least the expression value
449 return QgsProperty();
450 }
451
452 bool active = ( map.value( u"%1active"_s.arg( prefix ), u"1"_s ) != "0"_L1 );
453 QString expression = map.value( u"%1expression"_s.arg( prefix ) ).toString();
454 bool useExpression = ( map.value( u"%1useexpr"_s.arg( prefix ), u"1"_s ) != "0"_L1 );
455 QString field = map.value( u"%1field"_s.arg( prefix ), QString() ).toString();
456
457 if ( useExpression )
458 return QgsProperty::fromExpression( expression, active );
459 else
460 return QgsProperty::fromField( field, active );
461}
462
463void QgsSymbolLayer::restoreOldDataDefinedProperties( const QVariantMap &stringMap )
464{
465 // property string to type upgrade map
466 static const QMap< QString, int > OLD_PROPS {
467 { "color", static_cast< int >( QgsSymbolLayer::Property::FillColor ) },
468 { "arrow_width", static_cast< int >( QgsSymbolLayer::Property::ArrowWidth ) },
469 { "arrow_start_width", static_cast< int >( QgsSymbolLayer::Property::ArrowStartWidth ) },
470 { "head_length", static_cast< int >( QgsSymbolLayer::Property::ArrowHeadLength ) },
471 { "head_thickness", static_cast< int >( QgsSymbolLayer::Property::ArrowHeadThickness ) },
472 { "offset", static_cast< int >( QgsSymbolLayer::Property::Offset ) },
473 { "head_type", static_cast< int >( QgsSymbolLayer::Property::ArrowHeadType ) },
474 { "arrow_type", static_cast< int >( QgsSymbolLayer::Property::ArrowType ) },
475 { "width_field", static_cast< int >( QgsSymbolLayer::Property::Width ) },
476 { "height_field", static_cast< int >( QgsSymbolLayer::Property::Height ) },
477 { "rotation_field", static_cast< int >( QgsSymbolLayer::Property::Angle ) },
478 { "outline_width_field", static_cast< int >( QgsSymbolLayer::Property::StrokeWidth ) },
479 { "fill_color_field", static_cast< int >( QgsSymbolLayer::Property::FillColor ) },
480 { "outline_color_field", static_cast< int >( QgsSymbolLayer::Property::StrokeColor ) },
481 { "symbol_name_field", static_cast< int >( QgsSymbolLayer::Property::Name ) },
482 { "outline_width", static_cast< int >( QgsSymbolLayer::Property::StrokeWidth ) },
483 { "outline_style", static_cast< int >( QgsSymbolLayer::Property::StrokeStyle ) },
484 { "join_style", static_cast< int >( QgsSymbolLayer::Property::JoinStyle ) },
485 { "fill_color", static_cast< int >( QgsSymbolLayer::Property::FillColor ) },
486 { "outline_color", static_cast< int >( QgsSymbolLayer::Property::StrokeColor ) },
487 { "width", static_cast< int >( QgsSymbolLayer::Property::Width ) },
488 { "height", static_cast< int >( QgsSymbolLayer::Property::Height ) },
489 { "symbol_name", static_cast< int >( QgsSymbolLayer::Property::Name ) },
490 { "angle", static_cast< int >( QgsSymbolLayer::Property::Angle ) },
491 { "fill_style", static_cast< int >( QgsSymbolLayer::Property::FillStyle ) },
492 { "color_border", static_cast< int >( QgsSymbolLayer::Property::StrokeColor ) },
493 { "width_border", static_cast< int >( QgsSymbolLayer::Property::StrokeWidth ) },
494 { "border_color", static_cast< int >( QgsSymbolLayer::Property::StrokeColor ) },
495 { "border_style", static_cast< int >( QgsSymbolLayer::Property::StrokeStyle ) },
496 { "color2", static_cast< int >( QgsSymbolLayer::Property::SecondaryColor ) },
497 { "gradient_type", static_cast< int >( QgsSymbolLayer::Property::GradientType ) },
498 { "coordinate_mode", static_cast< int >( QgsSymbolLayer::Property::CoordinateMode ) },
499 { "spread", static_cast< int >( QgsSymbolLayer::Property::GradientSpread ) },
500 { "reference1_x", static_cast< int >( QgsSymbolLayer::Property::GradientReference1X ) },
501 { "reference1_y", static_cast< int >( QgsSymbolLayer::Property::GradientReference1Y ) },
502 { "reference2_x", static_cast< int >( QgsSymbolLayer::Property::GradientReference2X ) },
503 { "reference2_y", static_cast< int >( QgsSymbolLayer::Property::GradientReference2Y ) },
504 { "reference1_iscentroid", static_cast< int >( QgsSymbolLayer::Property::GradientReference1IsCentroid ) },
505 { "reference2_iscentroid", static_cast< int >( QgsSymbolLayer::Property::GradientReference2IsCentroid ) },
506 { "blur_radius", static_cast< int >( QgsSymbolLayer::Property::BlurRadius ) },
507 { "use_whole_shape", static_cast< int >( QgsSymbolLayer::Property::ShapeburstUseWholeShape ) },
508 { "max_distance", static_cast< int >( QgsSymbolLayer::Property::ShapeburstMaxDistance ) },
509 { "ignore_rings", static_cast< int >( QgsSymbolLayer::Property::ShapeburstIgnoreRings ) },
510 { "svgFillColor", static_cast< int >( QgsSymbolLayer::Property::FillColor ) },
511 { "svgOutlineColor", static_cast< int >( QgsSymbolLayer::Property::StrokeColor ) },
512 { "svgOutlineWidth", static_cast< int >( QgsSymbolLayer::Property::StrokeWidth ) },
513 { "svgFile", static_cast< int >( QgsSymbolLayer::Property::File ) },
514 { "lineangle", static_cast< int >( QgsSymbolLayer::Property::LineAngle ) },
515 { "distance", static_cast< int >( QgsSymbolLayer::Property::LineDistance ) },
516 { "distance_x", static_cast< int >( QgsSymbolLayer::Property::DistanceX ) },
517 { "distance_y", static_cast< int >( QgsSymbolLayer::Property::DistanceY ) },
518 { "displacement_x", static_cast< int >( QgsSymbolLayer::Property::DisplacementX ) },
519 { "displacement_y", static_cast< int >( QgsSymbolLayer::Property::DisplacementY ) },
520 { "file", static_cast< int >( QgsSymbolLayer::Property::File ) },
521 { "alpha", static_cast< int >( QgsSymbolLayer::Property::Opacity ) },
522 { "customdash", static_cast< int >( QgsSymbolLayer::Property::CustomDash ) },
523 { "line_style", static_cast< int >( QgsSymbolLayer::Property::StrokeStyle ) },
524 { "joinstyle", static_cast< int >( QgsSymbolLayer::Property::JoinStyle ) },
525 { "capstyle", static_cast< int >( QgsSymbolLayer::Property::CapStyle ) },
526 { "placement", static_cast< int >( QgsSymbolLayer::Property::Placement ) },
527 { "interval", static_cast< int >( QgsSymbolLayer::Property::Interval ) },
528 { "offset_along_line", static_cast< int >( QgsSymbolLayer::Property::OffsetAlongLine ) },
529 { "name", static_cast< int >( QgsSymbolLayer::Property::Name ) },
530 { "size", static_cast< int >( QgsSymbolLayer::Property::Size ) },
531 { "fill", static_cast< int >( QgsSymbolLayer::Property::FillColor ) },
532 { "outline", static_cast< int >( QgsSymbolLayer::Property::StrokeColor ) },
533 { "char", static_cast< int >( QgsSymbolLayer::Property::Character ) },
534 { "enabled", static_cast< int >( QgsSymbolLayer::Property::LayerEnabled ) },
535 { "rotation", static_cast< int >( QgsSymbolLayer::Property::Angle ) },
536 { "horizontal_anchor_point", static_cast< int >( QgsSymbolLayer::Property::HorizontalAnchor ) },
537 { "vertical_anchor_point", static_cast< int >( QgsSymbolLayer::Property::VerticalAnchor ) },
538 };
539
540 QVariantMap::const_iterator propIt = stringMap.constBegin();
541 for ( ; propIt != stringMap.constEnd(); ++propIt )
542 {
543 std::unique_ptr<QgsProperty> prop;
544 QString propertyName;
545
546 if ( propIt.key().endsWith( "_dd_expression"_L1 ) )
547 {
548 //found a data defined property
549
550 //get data defined property name by stripping "_dd_expression" from property key
551 propertyName = propIt.key().left( propIt.key().length() - 14 );
552
553 prop = std::make_unique<QgsProperty>( propertyFromMap( stringMap, propertyName ) );
554 }
555 else if ( propIt.key().endsWith( "_expression"_L1 ) )
556 {
557 //old style data defined property, upgrade
558
559 //get data defined property name by stripping "_expression" from property key
560 propertyName = propIt.key().left( propIt.key().length() - 11 );
561
562 prop = std::make_unique<QgsProperty>( QgsProperty::fromExpression( propIt.value().toString() ) );
563 }
564
565 if ( !prop || !OLD_PROPS.contains( propertyName ) )
566 continue;
567
568 int key = OLD_PROPS.value( propertyName );
569
570 if ( type() == Qgis::SymbolType::Line )
571 {
572 //these keys had different meaning for line symbol layers
573 if ( propertyName == "width"_L1 )
574 key = static_cast< int >( QgsSymbolLayer::Property::StrokeWidth );
575 else if ( propertyName == "color"_L1 )
576 key = static_cast< int >( QgsSymbolLayer::Property::StrokeColor );
577 }
578
579 setDataDefinedProperty( static_cast< QgsSymbolLayer::Property >( key ), QgsProperty( *prop.get() ) );
580 }
581}
582
589
591{
592 if ( !destLayer )
593 return;
594
597
599{
600 if ( !destLayer || !mPaintEffect )
601 return;
602
604 destLayer->setPaintEffect( mPaintEffect->clone() );
605 else
606 destLayer->setPaintEffect( nullptr );
607}
610 : QgsSymbolLayer( Qgis::SymbolType::Marker, locked )
611{}
612
614 : QgsSymbolLayer( Qgis::SymbolType::Line, locked )
615{}
616
621
623{
624 mRingFilter = filter;
625}
626
628 : QgsSymbolLayer( Qgis::SymbolType::Fill, locked )
629{}
630
645
647{
648 Q_UNUSED( context )
649}
650
652{
653 Q_UNUSED( context )
654}
655
657{
658 startRender( context );
659 QgsPaintEffect *effect = paintEffect();
660
661 QPolygonF points = context.patchShape() ? context.patchShape()->toQPolygonF( Qgis::SymbolType::Marker, size ).value( 0 ).value( 0 )
663
664 std::unique_ptr< QgsEffectPainter > effectPainter;
665 if ( effect && effect->enabled() )
666 effectPainter = std::make_unique< QgsEffectPainter >( context.renderContext(), effect );
667
668 for ( QPointF point : std::as_const( points ) )
669 renderPoint( point, context );
670
671 effectPainter.reset();
672
673 stopRender( context );
674}
675
676void QgsMarkerSymbolLayer::markerOffset( QgsSymbolRenderContext &context, double &offsetX, double &offsetY ) const
677{
679}
680
681void QgsMarkerSymbolLayer::markerOffset( QgsSymbolRenderContext &context, double width, double height, double &offsetX, double &offsetY ) const
682{
683 markerOffset( context, width, height, mSizeUnit, mSizeUnit, offsetX, offsetY, mSizeMapUnitScale, mSizeMapUnitScale );
684}
685
687 QgsSymbolRenderContext &context,
688 double width,
689 double height,
690 Qgis::RenderUnit widthUnit,
691 Qgis::RenderUnit heightUnit,
692 double &offsetX,
693 double &offsetY,
694 const QgsMapUnitScale &widthMapUnitScale,
695 const QgsMapUnitScale &heightMapUnitScale
696) const
697{
698 offsetX = mOffset.x();
699 offsetY = mOffset.y();
700
702 {
705 bool ok = false;
706 const QPointF offset = QgsSymbolLayerUtils::toPoint( exprVal, &ok );
707 if ( ok )
708 {
709 offsetX = offset.x();
710 offsetY = offset.y();
711 }
712 }
713
716
720 {
722 if ( !QgsVariantUtils::isNull( exprVal ) )
723 {
724 horizontalAnchorPoint = decodeHorizontalAnchorPoint( exprVal.toString() );
725 }
726 }
728 {
730 if ( !QgsVariantUtils::isNull( exprVal ) )
731 {
732 verticalAnchorPoint = decodeVerticalAnchorPoint( exprVal.toString() );
733 }
734 }
735
736 //correct horizontal position according to anchor point
738 {
739 return;
740 }
741
742 double anchorPointCorrectionX = context.renderContext().convertToPainterUnits( width, widthUnit, widthMapUnitScale ) / 2.0;
743 if ( widthUnit == Qgis::RenderUnit::MetersInMapUnits
745 {
746 // rendering for symbol previews -- an size in meters in map units can't be calculated, so treat the size as millimeters
747 // and clamp it to a reasonable range. It's the best we can do in this situation!
748 anchorPointCorrectionX = std::min( std::max( context.renderContext().convertToPainterUnits( width, Qgis::RenderUnit::Millimeters ), 3.0 ), 100.0 ) / 2.0;
749 }
750
751 double anchorPointCorrectionY = context.renderContext().convertToPainterUnits( height, heightUnit, heightMapUnitScale ) / 2.0;
752 if ( heightUnit == Qgis::RenderUnit::MetersInMapUnits
754 {
755 // rendering for symbol previews -- an size in meters in map units can't be calculated, so treat the size as millimeters
756 // and clamp it to a reasonable range. It's the best we can do in this situation!
757 anchorPointCorrectionY = std::min( std::max( context.renderContext().convertToPainterUnits( height, Qgis::RenderUnit::Millimeters ), 3.0 ), 100.0 ) / 2.0;
758 }
759
760 switch ( horizontalAnchorPoint )
761 {
763 offsetX += anchorPointCorrectionX;
764 break;
766 offsetX -= anchorPointCorrectionX;
767 break;
769 break;
770 }
771
772 //correct vertical position according to anchor point
773 switch ( verticalAnchorPoint )
774 {
776 offsetY += anchorPointCorrectionY;
777 break;
780 offsetY -= anchorPointCorrectionY;
781 break;
783 break;
784 }
785}
786
788{
789 angle = DEG2RAD( angle );
790 double c = std::cos( angle ), s = std::sin( angle );
791 return QPointF( offset.x() * c - offset.y() * s, offset.x() * s + offset.y() * c );
792}
793
794Qgis::HorizontalAnchorPoint QgsMarkerSymbolLayer::decodeHorizontalAnchorPoint( const QString &str )
795{
796 if ( str.compare( "left"_L1, Qt::CaseInsensitive ) == 0 )
797 {
799 }
800 else if ( str.compare( "right"_L1, Qt::CaseInsensitive ) == 0 )
801 {
803 }
804 else
805 {
807 }
808}
809
810Qgis::VerticalAnchorPoint QgsMarkerSymbolLayer::decodeVerticalAnchorPoint( const QString &str )
811{
812 if ( str.compare( "top"_L1, Qt::CaseInsensitive ) == 0 )
813 {
815 }
816 else if ( str.compare( "bottom"_L1, Qt::CaseInsensitive ) == 0 )
817 {
819 }
820 else
821 {
823 }
824}
825
827{
828 mSizeUnit = unit;
829 mOffsetUnit = unit;
830}
831
833{
834 if ( mOffsetUnit != mSizeUnit )
835 {
837 }
838 return mOffsetUnit;
839}
840
846
855
857{
858 mWidthUnit = unit;
859 mOffsetUnit = unit;
860}
861
866
871
876
877
879{
880 const QList< QList< QPolygonF > > points = context.patchShape() ? context.patchShape()->toQPolygonF( Qgis::SymbolType::Line, size )
882 startRender( context );
883 QgsPaintEffect *effect = paintEffect();
884
885 std::unique_ptr< QgsEffectPainter > effectPainter;
886 if ( effect && effect->enabled() )
887 effectPainter = std::make_unique< QgsEffectPainter >( context.renderContext(), effect );
888
889 for ( const QList< QPolygonF > &line : points )
890 renderPolyline( line.value( 0 ), context );
891
892 effectPainter.reset();
893
894 stopRender( context );
895}
896
897void QgsLineSymbolLayer::renderPolygonStroke( const QPolygonF &points, const QVector<QPolygonF> *rings, QgsSymbolRenderContext &context )
898{
899 QgsExpressionContextScope *scope = nullptr;
900 std::unique_ptr< QgsExpressionContextScopePopper > scopePopper;
902 {
903 scope = new QgsExpressionContextScope();
904 scopePopper = std::make_unique< QgsExpressionContextScopePopper >( context.renderContext().expressionContext(), scope );
905 }
906
907 switch ( mRingFilter )
908 {
909 case AllRings:
910 case ExteriorRingOnly:
911 {
912 if ( scope )
914 renderPolyline( points, context );
915 break;
916 }
918 break;
919 }
920
921 if ( rings )
922 {
923 switch ( mRingFilter )
924 {
925 case AllRings:
927 {
928 int ringIndex = 1;
929 for ( const QPolygonF &ring : std::as_const( *rings ) )
930 {
931 if ( scope )
933
934 renderPolyline( ring, context );
935 ringIndex++;
936 }
937 }
938 break;
939 case ExteriorRingOnly:
940 break;
941 }
942 }
943}
944
945double QgsLineSymbolLayer::width( const QgsRenderContext &context ) const
946{
948}
949
954
955
957{
958 const QList< QList< QPolygonF > > polys = context.patchShape() ? context.patchShape()->toQPolygonF( Qgis::SymbolType::Fill, size )
960
961 startRender( context );
962 QgsPaintEffect *effect = paintEffect();
963
964 std::unique_ptr< QgsEffectPainter > effectPainter;
965 if ( effect && effect->enabled() )
966 effectPainter = std::make_unique< QgsEffectPainter >( context.renderContext(), effect );
967
968 for ( const QList< QPolygonF > &poly : polys )
969 {
970 QVector< QPolygonF > rings;
971 for ( int i = 1; i < poly.size(); ++i )
972 rings << poly.at( i );
973 renderPolygon( poly.value( 0 ), &rings, context );
974 }
975
976 effectPainter.reset();
977
978 stopRender( context );
979}
980
982{
983 return QImage();
984}
985
986void QgsFillSymbolLayer::_renderPolygon( QPainter *p, const QPolygonF &points, const QVector<QPolygonF> *rings, QgsSymbolRenderContext &context )
987{
988 if ( !p )
989 {
990 return;
991 }
992
993 // Disable 'Antialiasing' if the geometry was generalized in the current RenderContext (We known that it must have least #5 points).
994 if ( points.size() <= 5
997 && ( p->renderHints() & QPainter::Antialiasing ) )
998 {
999 p->setRenderHint( QPainter::Antialiasing, false );
1000 p->drawRect( points.boundingRect() );
1001 p->setRenderHint( QPainter::Antialiasing, true );
1002 return;
1003 }
1004
1005 // polygons outlines are sometimes rendered wrongly with drawPolygon, when
1006 // clipped (see #13343), so use drawPath instead.
1007 if ( !rings && p->pen().style() == Qt::NoPen )
1008 {
1009 // simple polygon without holes
1010 p->drawPolygon( points );
1011 }
1012 else
1013 {
1014 // polygon with holes must be drawn using painter path
1015 QPainterPath path;
1016 path.addPolygon( points );
1017
1018 if ( rings )
1019 {
1020 for ( auto it = rings->constBegin(); it != rings->constEnd(); ++it )
1021 {
1022 QPolygonF ring = *it;
1023 path.addPolygon( ring );
1024 }
1025 }
1026
1027 p->drawPath( path );
1028 }
1029}
1030
1031bool QgsMarkerSymbolLayer::toSld( QDomDocument &doc, QDomElement &element, QgsSldExportContext &context ) const
1032{
1033 QDomElement symbolizerElem = doc.createElement( u"se:PointSymbolizer"_s );
1034 const QVariantMap props = context.extraProperties();
1035 if ( !props.value( u"uom"_s, QString() ).toString().isEmpty() )
1036 symbolizerElem.setAttribute( u"uom"_s, props.value( u"uom"_s, QString() ).toString() );
1037 element.appendChild( symbolizerElem );
1038
1039 // <Geometry>
1040 QgsSymbolLayerUtils::createGeometryElement( doc, symbolizerElem, props.value( u"geom"_s, QString() ).toString(), context );
1041
1042 return writeSldMarker( doc, symbolizerElem, context );
1043}
1044
1045void QgsMarkerSymbolLayer::writeSldMarker( QDomDocument &doc, QDomElement &element, const QVariantMap &props ) const
1046{
1047 QgsSldExportContext context;
1048 context.setExtraProperties( props );
1049 writeSldMarker( doc, element, context );
1050}
1051
1052bool QgsMarkerSymbolLayer::writeSldMarker( QDomDocument &, QDomElement &, QgsSldExportContext &context ) const
1053{
1054 context.pushError( QObject::tr( "Marker symbol layer %1 cannot be converted to SLD" ).arg( layerType() ) );
1055 return false;
1056}
1057
1058QList<QgsSymbolLayerReference> QgsSymbolLayer::masks() const
1059{
1060 return {};
1061}
1062
1067
1072
1074{
1075 double size = mSize;
1077 {
1078 bool ok = false;
1080
1081 if ( ok )
1082 {
1083 switch ( mScaleMethod )
1084 {
1086 size = std::sqrt( size );
1087 break;
1089 break;
1090 }
1091 }
1092 }
1094}
1095
1097{
1098 double angle = mAngle;
1100 {
1103 }
1104 return angle;
1105}
1106
1107QPainterPath generateClipPath( const QgsRenderContext &renderContext, const QString &id, const QRectF *rect, bool &foundGeometries )
1108{
1109 foundGeometries = false;
1110 const QVector<QgsGeometry> clipGeometries = rect ? QgsSymbolLayerUtils::collectSymbolLayerClipGeometries( renderContext, id, *rect ) : renderContext.symbolLayerClipGeometries( id );
1111 if ( !clipGeometries.empty() )
1112 {
1113 foundGeometries = true;
1114 QgsGeometry mergedGeom = QgsGeometry::unaryUnion( clipGeometries, QgsGeometryParameters(), renderContext.feedback() );
1115 if ( renderContext.maskSettings().simplifyTolerance() > 0 )
1116 {
1117 QgsGeos geos( mergedGeom.constGet() );
1118 mergedGeom = QgsGeometry( geos.simplify( renderContext.maskSettings().simplifyTolerance(), nullptr, renderContext.feedback() ) );
1119 }
1120#if GEOS_VERSION_MAJOR == 3 && GEOS_VERSION_MINOR < 10
1121 // structure would be better, but too old GEOS
1122 mergedGeom = mergedGeom.makeValid( Qgis::MakeValidMethod::Linework, false, renderContext.feedback() );
1123#else
1124 mergedGeom = mergedGeom.makeValid( Qgis::MakeValidMethod::Structure, false, renderContext.feedback() );
1125#endif
1126 if ( !mergedGeom.isEmpty() )
1127 {
1128 QgsGeometry exterior;
1129 const QgsRectangle contextBounds( 0, 0, renderContext.outputSize().width(), renderContext.outputSize().height() );
1130 if ( rect )
1131 {
1132 exterior = QgsGeometry::fromRect( QgsRectangle( *rect ).intersect( contextBounds ) );
1133 }
1134 else
1135 {
1136 exterior = QgsGeometry::fromRect( contextBounds );
1137 }
1138 const QgsGeometry maskGeom = exterior.difference( mergedGeom, QgsGeometryParameters(), renderContext.feedback() );
1139 if ( !maskGeom.isNull() )
1140 {
1141 return maskGeom.constGet()->asQPainterPath();
1142 }
1143 }
1144 }
1145 return QPainterPath();
1146}
1147
1149{
1150 const QgsRenderContext &renderContext = context.renderContext();
1151
1152 bool foundGeometries = false;
1153 mClipPath = generateClipPath( renderContext, id(), nullptr, foundGeometries );
1154}
1155
1156bool QgsSymbolLayer::installMasks( QgsRenderContext &context, bool recursive, const QRectF &rect )
1157{
1158 bool res = false;
1159 if ( !mClipPath.isEmpty() )
1160 {
1161 mStateBeforeInstallingMaskClipPaths = std::make_unique< QgsScopedQPainterState >( context.painter() );
1162 context.painter()->setClipPath( mClipPath, Qt::IntersectClip );
1163 res = true;
1164 }
1165 else if ( rect.isValid() )
1166 {
1167 // find just the clip geometries within the area the symbol layer will be drawn over
1168 bool foundGeometries = false;
1169 const QPainterPath clipPath = generateClipPath( context, id(), &rect, foundGeometries );
1170 if ( !clipPath.isEmpty() )
1171 {
1172 mStateBeforeInstallingMaskClipPaths = std::make_unique< QgsScopedQPainterState >( context.painter() );
1173 context.painter()->setClipPath( clipPath, context.painter()->clipPath().isEmpty() ? Qt::ReplaceClip : Qt::IntersectClip );
1174 res = true;
1175 }
1176 }
1177
1178 if ( QgsSymbol *lSubSymbol = recursive ? subSymbol() : nullptr )
1179 {
1180 const QList<QgsSymbolLayer *> layers = lSubSymbol->symbolLayers();
1181 for ( QgsSymbolLayer *sl : layers )
1182 res = sl->installMasks( context, true ) || res;
1183 }
1184
1185 return res;
1186}
1187
1188void QgsSymbolLayer::removeMasks( QgsRenderContext &context, bool recursive )
1189{
1190 // restore painter state to before the clip paths were installed
1192
1193 if ( QgsSymbol *lSubSymbol = recursive ? subSymbol() : nullptr )
1194 {
1195 const QList<QgsSymbolLayer *> layers = lSubSymbol->symbolLayers();
1196 for ( QgsSymbolLayer *sl : layers )
1197 sl->removeMasks( context, true );
1198 }
1199}
1200
1205
1206void QgsSymbolLayer::setId( const QString &id )
1207{
1208 mId = id;
1209}
1210
1211QString QgsSymbolLayer::id() const
1212{
1213 return mId;
1214}
1215
1216void QgsSymbolLayer::toSld( QDomDocument &doc, QDomElement &element, const QVariantMap &props ) const
1217{
1218 QgsSldExportContext context;
1219 context.setExtraProperties( props );
1220 toSld( doc, element, context );
1221}
1222
1223bool QgsSymbolLayer::toSld( QDomDocument &, QDomElement &, QgsSldExportContext &context ) const
1224{
1225 context.pushError( QObject::tr( "Symbol layer %1 cannot be converted to SLD" ).arg( layerType() ) );
1226 return false;
1227}
Provides global constants and enumerations for use throughout the application.
Definition qgis.h:62
@ AntialiasingSimplification
The geometries can be rendered with 'AntiAliasing' disabled because of it is '1-pixel size'.
Definition qgis.h:3257
@ ScaleDiameter
Calculate scale by the diameter.
Definition qgis.h:687
@ ScaleArea
Calculate scale by the area.
Definition qgis.h:686
QFlags< SymbolLayerFlag > SymbolLayerFlags
Symbol layer flags.
Definition qgis.h:969
QFlags< SymbolLayerUserFlag > SymbolLayerUserFlags
Symbol layer user flags.
Definition qgis.h:992
VerticalAnchorPoint
Marker symbol vertical anchor points.
Definition qgis.h:896
@ Bottom
Align to bottom of symbol.
Definition qgis.h:899
@ Center
Align to vertical center of symbol.
Definition qgis.h:898
@ Baseline
Align to baseline of symbol, e.g. font baseline for font marker symbol layers. Treated as Bottom if n...
Definition qgis.h:900
@ Top
Align to top of symbol.
Definition qgis.h:897
RenderUnit
Rendering size units.
Definition qgis.h:5758
@ Millimeters
Millimeters.
Definition qgis.h:5759
@ Unknown
Mixed or unknown units.
Definition qgis.h:5765
@ MetersInMapUnits
Meters value as Map units.
Definition qgis.h:5766
@ RenderSymbolPreview
The render is for a symbol preview only and map based properties may not be available,...
Definition qgis.h:2976
@ RenderLayerTree
The render is for a layer tree display where map based properties are not available and where avoidan...
Definition qgis.h:2987
@ Linework
Combines all rings into a set of noded lines and then extracts valid polygons from that linework.
Definition qgis.h:2365
@ Structure
Structured method, first makes all rings valid and then merges shells and subtracts holes from shells...
Definition qgis.h:2366
@ DisableSelectionRecoloring
If present, indicates that the symbol layer should not be recolored when rendering selected features.
Definition qgis.h:983
SymbolType
Symbol types.
Definition qgis.h:671
@ Marker
Marker symbol.
Definition qgis.h:672
@ Line
Line symbol.
Definition qgis.h:673
@ Fill
Fill symbol.
Definition qgis.h:674
HorizontalAnchorPoint
Marker symbol horizontal anchor points.
Definition qgis.h:882
@ Center
Align to horizontal center of symbol.
Definition qgis.h:884
@ Right
Align to right side of symbol.
Definition qgis.h:885
@ Left
Align to left side of symbol.
Definition qgis.h:883
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...
virtual QPainterPath asQPainterPath() const =0
Returns the geometry represented as a QPainterPath.
Exports QGIS layers to the DXF format.
static Q_DECL_DEPRECATED double mapUnitScaleFactor(double scale, Qgis::RenderUnit symbolUnits, Qgis::DistanceUnit mapUnits, double mapUnitsPerPixel=1.0)
Returns scale factor for conversion to map units.
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:60
bool isEmpty
Definition qgsfields.h:48
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
Encapsulates parameters under which a geometry operation is performed.
A geometry is the spatial representation of a feature.
static QgsGeometry fromRect(const QgsRectangle &rect)
Creates a new geometry from a QgsRectangle.
const QgsAbstractGeometry * constGet() const
Returns a non-modifiable (const) reference to the underlying abstract geometry primitive.
QgsGeometry makeValid(Qgis::MakeValidMethod method=Qgis::MakeValidMethod::Linework, bool keepCollapsed=false, QgsFeedback *feedback=nullptr) const
Attempts to make an invalid geometry valid without losing vertices.
static QgsGeometry unaryUnion(const QVector< QgsGeometry > &geometries, const QgsGeometryParameters &parameters=QgsGeometryParameters(), QgsFeedback *feedback=nullptr)
Compute the unary union on a list of geometries.
bool isEmpty() const
Returns true if the geometry is empty (eg a linestring with no vertices, or a collection with no geom...
QgsGeometry difference(const QgsGeometry &geometry, const QgsGeometryParameters &parameters=QgsGeometryParameters(), QgsFeedback *feedback=nullptr) const
Returns a geometry representing the points making up this geometry that do not make up other.
Does vector analysis using the GEOS library and handles import, export, and exception handling.
Definition qgsgeos.h:192
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
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
double dxfWidth(QgsSymbolRenderContext &context) const override
Gets line width.
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.
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.
Struct for storing maximum and minimum scales for measurements in map units.
double mSize
Marker size.
QgsMarkerSymbolLayer(const QgsMarkerSymbolLayer &other)
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...
double mLineAngle
Line rotation angle (see setLineAngle() for details).
bool toSld(QDomDocument &doc, QDomElement &element, QgsSldExportContext &context) const override
Saves the symbol layer as SLD.
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.
Qgis::VerticalAnchorPoint verticalAnchorPoint() const
Returns the vertical anchor point for positioning the symbol.
QgsMapUnitScale mOffsetMapUnitScale
Offset map unit scale.
Qgis::VerticalAnchorPoint mVerticalAnchorPoint
Vertical anchor point.
static QPointF _rotatedOffset(QPointF offset, double angle)
Adjusts a marker offset to account for rotation.
double dxfSize(QgsSymbolRenderContext &context) const override
Gets marker size.
double dxfAngle(QgsSymbolRenderContext &context) const override
Gets angle.
Qgis::ScaleMethod mScaleMethod
Marker size scaling method.
Qgis::HorizontalAnchorPoint horizontalAnchorPoint() const
Returns the horizontal anchor point for positioning the symbol.
void stopRender(QgsSymbolRenderContext &context) override
Called after a set of rendering operations has finished on the supplied render context.
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.
virtual Q_DECL_DEPRECATED void writeSldMarker(QDomDocument &doc, QDomElement &element, const QVariantMap &props) const
Writes the symbol layer definition as a SLD XML element.
void markerOffset(QgsSymbolRenderContext &context, double &offsetX, double &offsetY) const
Calculates the required marker offset, including both the symbol offset and any displacement required...
Qgis::HorizontalAnchorPoint mHorizontalAnchorPoint
Horizontal anchor point.
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
double simplifyTolerance() const
Returns the simplification tolerance (in painter units) to use for on-the-fly simplification of mask ...
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.
void setProperty(int key, const QgsProperty &property)
Adds a property to the collection and takes ownership of it.
@ 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.
QVariant value(const QgsExpressionContext &context, const QVariant &defaultValue=QVariant(), bool *ok=nullptr) const
Calculates the current value of the property, including any transforms which are set for the property...
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.
A rectangle specified with double values.
QgsRectangle intersect(const QgsRectangle &rect) const
Returns the intersection with the given rectangle.
Contains information about the context of a rendering operation.
QgsVectorSimplifyMethod & vectorSimplifyMethod()
Returns the simplification settings to use when rendering vector layers.
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.
QgsFeedback * feedback() const
Returns the feedback object that can be queried regularly during rendering to check if rendering shou...
QVector< QgsGeometry > symbolLayerClipGeometries(const QString &symbolLayerId) const
Returns clipping geometries to be applied to the symbolLayer before rendering.
Qgis::RenderContextFlags flags() const
Returns combination of flags used for rendering.
const QgsMaskRenderSettings & maskSettings() const
Returns a reference to the mask render settings, which control how masks are drawn and behave during ...
Holds SLD export options and other information related to SLD export of a QGIS layer style.
void setExtraProperties(const QVariantMap &properties)
Sets the open ended set of properties that can drive/inform the SLD encoding.
QVariantMap extraProperties() const
Returns the open ended set of properties that can drive/inform the SLD encoding.
void pushError(const QString &error)
Pushes a error message generated during the conversion.
static QgsStyle * defaultStyle(bool initialize=true)
Returns the default application-wide style.
Definition qgsstyle.cpp:164
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 (...
static QPointF toPoint(const QVariant &value, bool *ok=nullptr)
Converts a value to a point.
static QVector< QgsGeometry > collectSymbolLayerClipGeometries(const QgsRenderContext &context, const QString &symbolLayerId, const QRectF &bounds)
Returns a list of the symbol layer clip geometries to be used for the symbol layer with the specified...
static Q_DECL_DEPRECATED void createGeometryElement(QDomDocument &doc, QDomElement &element, const QString &geomFunc)
Creates an SLD geometry element.
static QString encodePoint(QPointF point)
Encodes a QPointF to a string.
void copyCommonProperties(QgsSymbolLayer *destLayer) const
Copies all common base class properties from this layer to another symbol layer.
virtual QgsSymbolLayer * clone() const =0
Shall be reimplemented by subclasses to create a deep copy of the instance.
virtual bool setSubSymbol(QgsSymbol *symbol)
Sets layer's subsymbol. takes ownership of the passed symbol.
bool shouldRenderUsingSelectionColor(const QgsSymbolRenderContext &context) const
Returns true if the symbol layer should be rendered using the selection color from the render context...
Qgis::SymbolType type() const
virtual void startFeatureRender(const QgsFeature &feature, QgsRenderContext &context)
Called before the layer will be rendered for a particular feature.
friend class QgsSymbol
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.
std::unique_ptr< QgsScopedQPainterState > mStateBeforeInstallingMaskClipPaths
virtual void setStrokeColor(const QColor &color)
Sets the stroke color for the symbol layer.
QPainterPath mClipPath
bool installMasks(QgsRenderContext &context, bool recursive, const QRectF &rect=QRectF())
When rendering, install masks on context painter.
virtual Q_DECL_DEPRECATED double dxfSize(const QgsDxfExport &e, QgsSymbolRenderContext &context) const
Gets marker size.
virtual Q_DECL_DEPRECATED double dxfOffset(const QgsDxfExport &e, QgsSymbolRenderContext &context) const
Gets offset.
virtual QColor dxfBrushColor(QgsSymbolRenderContext &context) const
Gets brush/fill color.
Qgis::SymbolType mType
void removeMasks(QgsRenderContext &context, bool recursive)
When rendering, remove previously installed masks from context painter if recursive is true masks are...
virtual QSet< QString > usedAttributes(const QgsRenderContext &context) const
Returns the set of attributes referenced by the layer.
void copyDataDefinedProperties(QgsSymbolLayer *destLayer) const
Copies all data defined properties of this layer to another symbol layer.
Property
Data definable properties.
@ SkipMultiples
Skip multiples of.
@ ArrowHeadLength
Arrow head length.
@ GradientType
Gradient fill type.
@ SecondaryColor
Secondary color (eg for gradient fills).
@ File
Filename, eg for svg files.
@ VerticalAnchor
Vertical anchor point.
@ GradientReference2Y
Gradient reference point 2 y.
@ GradientReference1X
Gradient reference point 1 x.
@ OffsetY
Vertical offset.
@ OffsetX
Horizontal offset.
@ GradientReference1Y
Gradient reference point 1 y.
@ ArrowWidth
Arrow tail width.
@ BlankSegments
String list of distance to define blank segments along line for templated line symbol layers.
@ DashPatternOffset
Dash pattern offset,.
@ GradientSpread
Gradient spread mode.
@ OffsetAlongLine
Offset along line.
@ ArrowHeadType
Arrow head type.
@ CustomDash
Custom dash pattern.
@ ShapeburstMaxDistance
Shapeburst fill from edge distance.
@ HorizontalAnchor
Horizontal anchor point.
@ StrokeStyle
Stroke style (eg solid, dashed).
@ Name
Name, eg shape name for simple markers.
@ DistanceY
Vertical distance between points.
@ LineEndColorValue
End line color for interpolated line renderer.
@ ClipPoints
Whether markers should be clipped to polygon boundaries.
@ ArrowHeadThickness
Arrow head thickness.
@ LineClipping
Line clipping mode.
@ ShapeburstIgnoreRings
Shapeburst ignore rings.
@ Character
Character, eg for font marker symbol layers.
@ ShapeburstUseWholeShape
Shapeburst use whole shape.
@ DisplacementX
Horizontal displacement.
@ CoordinateMode
Gradient coordinate mode.
@ FillStyle
Fill style (eg solid, dots).
@ GradientReference2X
Gradient reference point 2 x.
@ TrimStart
Trim distance from start of line.
@ ArrowStartWidth
Arrow tail start width.
@ CapStyle
Line cap style.
@ BlurRadius
Shapeburst blur radius.
@ Placement
Line marker placement.
@ MarkerClipping
Marker clipping mode.
@ RandomSeed
Random number seed.
@ LineAngle
Line angle, or angle of hash lines for hash line symbols.
@ JoinStyle
Line join style.
@ RandomOffsetY
Random offset Y.
@ DisplacementY
Vertical displacement.
@ PreserveAspectRatio
Preserve aspect ratio between width and height.
@ LineStartColorValue
Start line color for interpolated line renderer.
@ DistanceX
Horizontal distance between points.
@ AverageAngleLength
Length to average symbol angles over.
@ LineEndWidthValue
End line width for interpolated line renderer.
@ GradientReference1IsCentroid
Gradient reference point 1 is centroid.
@ Interval
Line marker interval.
@ GradientReference2IsCentroid
Gradient reference point 2 is centroid.
@ LineStartWidthValue
Start line width for interpolated line renderer.
@ LineDistance
Distance between lines, or length of lines for hash line symbols.
@ RandomOffsetX
Random offset X.
@ ExtraItems
String list of tuple (x, y and rotation angle) to define extra items to be rendered for templated lin...
@ TrimEnd
Trim distance from end of line.
@ LayerEnabled
Whether symbol layer is enabled.
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.
QString selectiveMaskingSourceSetId() const
Returns the selective masking source set ID for this symbol layer.
virtual QVariantMap properties() const =0
Should be reimplemented by subclasses to return a string map that contains the configuration informat...
std::unique_ptr< QgsPaintEffect > mPaintEffect
virtual Qt::PenStyle dxfPenStyle() const
Gets pen style.
QString mSelectiveMaskingSourceSetId
void setSelectiveMaskingSourceSetId(const QString &id)
Sets the selective masking source set id for this symbol layer.
virtual void setFillColor(const QColor &color)
Sets the fill color for the symbol layer.
bool mEnabled
True if layer is enabled and should be drawn.
virtual void prepareExpressions(const QgsSymbolRenderContext &context)
Prepares all data defined property expressions for evaluation.
void setUserFlags(Qgis::SymbolLayerUserFlags flags)
Sets user-controlled flags which control the symbol layer's behavior.
virtual QColor dxfColor(QgsSymbolRenderContext &context) const
Gets color.
virtual bool rendersIdenticallyTo(const QgsSymbolLayer *other) const
Returns true if this symbol layer will always render identically to an other symbol layer.
virtual QString layerType() const =0
Returns a string that represents this layer type.
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 Q_DECL_DEPRECATED void toSld(QDomDocument &doc, QDomElement &element, const QVariantMap &props) const
Saves the symbol layer as SLD.
virtual bool isCompatibleWithSymbol(QgsSymbol *symbol) const
Returns if the layer can be used below the specified symbol.
QString id() const
Returns symbol layer identifier This id is unique in the whole project.
virtual void setDataDefinedProperty(Property key, const QgsProperty &property)
Sets a data defined property for the layer.
virtual void setColor(const QColor &color)
Sets the "representative" color for the symbol layer.
virtual QgsSymbol * subSymbol()
Returns the symbol's sub symbol, if present.
Qgis::SymbolLayerUserFlags userFlags() const
Returns user-controlled flags which control the symbol layer's behavior.
virtual QColor color() const
Returns the "representative" color of the symbol layer.
virtual void prepareMasks(const QgsSymbolRenderContext &context)
Prepares all mask internal objects according to what is defined in context This should be called prio...
virtual void stopFeatureRender(const QgsFeature &feature, QgsRenderContext &context)
Called after the layer has been rendered for a particular feature.
static const QgsPropertiesDefinition & propertyDefinitions()
Returns the symbol layer property definitions.
virtual Q_DECL_DEPRECATED double dxfWidth(const QgsDxfExport &e, QgsSymbolRenderContext &context) const
Gets line width.
virtual QColor strokeColor() const
Returns the stroke color for the symbol layer.
virtual double dxfAngle(QgsSymbolRenderContext &context) const
Gets angle.
Qgis::SymbolLayerUserFlags mUserFlags
User controlled flags.
virtual bool canCauseArtifactsBetweenAdjacentTiles() const
Returns true if the symbol layer rendering can cause visible artifacts across a single feature when t...
virtual ~QgsSymbolLayer()
virtual bool usesMapUnits() const
Returns true if the symbol layer has any components which use map unit based sizes.
virtual bool writeDxf(QgsDxfExport &e, double mmMapUnitScaleFactor, const QString &layerName, QgsSymbolRenderContext &context, QPointF shift=QPointF(0.0, 0.0)) const
write as DXF
void copyPaintEffect(QgsSymbolLayer *destLayer) const
Copies paint effect of this layer to another symbol layer.
virtual Qgis::SymbolLayerFlags flags() const
Returns flags which control the symbol layer's behavior.
QgsPropertyCollection mDataDefinedProperties
virtual QList< QgsSymbolLayerReference > masks() const
Returns masks defined by this symbol layer.
QgsPropertyCollection & dataDefinedProperties()
Returns a reference to the symbol layer's property collection, used for data defined overrides.
virtual Qt::BrushStyle dxfBrushStyle() const
Gets brush/fill style.
virtual QVector< qreal > dxfCustomDashPattern(Qgis::RenderUnit &unit) const
Gets dash pattern.
virtual bool hasDataDefinedProperties() const
Returns true if the symbol layer (or any of its sub-symbols) contains data defined properties.
QgsSymbolLayer(const QgsSymbolLayer &other)
void setDataDefinedProperties(const QgsPropertyCollection &collection)
Sets the symbol layer's property collection, used for data defined overrides.
Encapsulates the context in which a symbol is being rendered.
QgsFields fields() const
Fields of the layer.
bool selected() const
Returns true if symbols should be rendered using the selected symbol coloring and style.
void setOriginalValueVariable(const QVariant &value)
Sets the original value variable value for data defined symbology.
const QgsLegendPatchShape * patchShape() const
Returns the symbol patch shape, to use if rendering symbol preview icons.
QgsRenderContext & renderContext()
Returns a reference to the context's render context.
Qgis::SymbolType type() const
Returns the symbol's type.
Definition qgssymbol.h:296
static bool isNull(const QVariant &variant, bool silenceNullWarnings=false)
Returns true if the specified variant should be considered a NULL value.
Qgis::VectorRenderingSimplificationFlags simplifyHints() const
Gets the simplification hints of the vector layer managed.
float threshold() const
Gets the simplification threshold of the vector layer managed.
Contains geos related utilities and functions.
Definition qgsgeos.h:129
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
QMap< int, QgsPropertyDefinition > QgsPropertiesDefinition
Definition of available properties.
QgsProperty propertyFromMap(const QVariantMap &map, const QString &baseName)
QPainterPath generateClipPath(const QgsRenderContext &renderContext, const QString &id, const QRectF *rect, bool &foundGeometries)
#define DEG2RAD(x)
Single variable definition for use within a QgsExpressionContextScope.