QGIS API Documentation 4.0.0-Norrköping (1ddcee3d0e4)
Loading...
Searching...
No Matches
qgsgeometrygeneratorsymbollayer.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgsgeometrygeneratorsymbollayer.cpp
3 ---------------------
4 begin : November 2015
5 copyright : (C) 2015 by Matthias Kuhn
6 email : matthias at opengis dot ch
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
17
18#include <memory>
19
21#include "qgsexpressionutils.h"
22#include "qgsfillsymbol.h"
23#include "qgsgeometry.h"
24#include "qgslegendpatchshape.h"
25#include "qgslinesymbol.h"
26#include "qgsmarkersymbol.h"
27#include "qgspolygon.h"
28#include "qgsstyle.h"
29#include "qgsunittypes.h"
30
31#include <QString>
32
33using namespace Qt::StringLiterals;
34
36
38{
39 QString expression = properties.value( u"geometryModifier"_s ).toString();
40 if ( expression.isEmpty() )
41 {
42 expression = u"@geometry"_s;
43 }
44 QgsGeometryGeneratorSymbolLayer *symbolLayer = new QgsGeometryGeneratorSymbolLayer( expression );
45
46 if ( properties.value( u"SymbolType"_s ) == "Marker"_L1 )
47 {
48 symbolLayer->setSubSymbol( QgsMarkerSymbol::createSimple( properties ).release() );
49 }
50 else if ( properties.value( u"SymbolType"_s ) == "Line"_L1 )
51 {
52 symbolLayer->setSubSymbol( QgsLineSymbol::createSimple( properties ).release() );
53 }
54 else
55 {
56 symbolLayer->setSubSymbol( QgsFillSymbol::createSimple( properties ).release() );
57 }
58 symbolLayer->setUnits( QgsUnitTypes::decodeRenderUnit( properties.value( u"units"_s, u"mapunits"_s ).toString() ) );
59
61
62 return symbolLayer;
63}
64
65QgsGeometryGeneratorSymbolLayer::QgsGeometryGeneratorSymbolLayer( const QString &expression )
66 : QgsSymbolLayer( Qgis::SymbolType::Hybrid )
67 , mExpression( new QgsExpression( expression ) )
68{}
69
71{
72 return u"GeometryGenerator"_s;
73}
74
76{
78 {
79 if ( !mFillSymbol )
80 mFillSymbol = QgsFillSymbol::createSimple( QVariantMap() );
81 mSymbol = mFillSymbol.get();
82 }
84 {
85 if ( !mLineSymbol )
86 mLineSymbol = QgsLineSymbol::createSimple( QVariantMap() );
87 mSymbol = mLineSymbol.get();
88 }
90 {
91 if ( !mMarkerSymbol )
92 mMarkerSymbol = QgsMarkerSymbol::createSimple( QVariantMap() );
93 mSymbol = mMarkerSymbol.get();
94 }
95 else
96 Q_ASSERT( false );
97
98 mSymbolType = symbolType;
99}
100
102{
103 mExpression->prepare( &context.renderContext().expressionContext() );
104
106
107 subSymbol()->startRender( context.renderContext(), context.fields() );
108}
109
111{
112 if ( mSymbol )
113 mSymbol->stopRender( context.renderContext() );
114}
115
117{
119 return;
120
121 mRenderingFeature = true;
122 mHasRenderedFeature = false;
123}
124
126{
127 mRenderingFeature = false;
128}
129
131{
132 if ( mFillSymbol )
133 return mFillSymbol->usesMapUnits();
134 else if ( mLineSymbol )
135 return mLineSymbol->usesMapUnits();
136 else if ( mMarkerSymbol )
137 return mMarkerSymbol->usesMapUnits();
138 return false;
139}
140
142{
143 if ( mFillSymbol )
144 return mFillSymbol->color();
145 else if ( mLineSymbol )
146 return mLineSymbol->color();
147 else if ( mMarkerSymbol )
148 return mMarkerSymbol->color();
149 return QColor();
150}
151
153{
154 if ( mFillSymbol )
155 return mFillSymbol->outputUnit();
156 else if ( mLineSymbol )
157 return mLineSymbol->outputUnit();
158 else if ( mMarkerSymbol )
159 return mMarkerSymbol->outputUnit();
161}
162
164{
165 if ( mFillSymbol )
166 mFillSymbol->setOutputUnit( unit );
167 else if ( mLineSymbol )
168 mLineSymbol->setOutputUnit( unit );
169 else if ( mMarkerSymbol )
170 mMarkerSymbol->setOutputUnit( unit );
171}
172
174{
175 if ( mFillSymbol )
176 return mFillSymbol->mapUnitScale();
177 else if ( mLineSymbol )
178 return mLineSymbol->mapUnitScale();
179 else if ( mMarkerSymbol )
180 return mMarkerSymbol->mapUnitScale();
181 return QgsMapUnitScale();
182}
183
185{
186 // since rendersIdenticallyTo must be pessimistic, we always return FALSE here as it's
187 // non-trivial to determine if a QGIS expression will always return the same result
188 // TODO: we could potentially investigate the actual expression and catch cases where we
189 // are CERTAIN that the result will always be the same
190 return false;
191}
192
194{
195 QgsGeometryGeneratorSymbolLayer *clone = new QgsGeometryGeneratorSymbolLayer( mExpression->expression() );
196
197 if ( mFillSymbol )
198 clone->mFillSymbol.reset( mFillSymbol->clone() );
199 if ( mLineSymbol )
200 clone->mLineSymbol.reset( mLineSymbol->clone() );
201 if ( mMarkerSymbol )
202 clone->mMarkerSymbol.reset( mMarkerSymbol->clone() );
203
204 clone->setSymbolType( mSymbolType );
205 clone->setUnits( mUnits );
206
208
209 return clone;
210}
211
213{
214 QVariantMap props;
215 props.insert( u"geometryModifier"_s, mExpression->expression() );
216 switch ( mSymbolType )
217 {
219 props.insert( u"SymbolType"_s, u"Marker"_s );
220 break;
222 props.insert( u"SymbolType"_s, u"Line"_s );
223 break;
224 default:
225 props.insert( u"SymbolType"_s, u"Fill"_s );
226 break;
227 }
228 props.insert( u"units"_s, QgsUnitTypes::encodeUnit( mUnits ) );
229
230 return props;
231}
232
234{
235 if ( mSymbol )
236 {
237 // evaluate expression
238 QgsGeometry patchShapeGeometry;
239
240 if ( context.patchShape() && !context.patchShape()->isNull() )
241 {
242 patchShapeGeometry = context.patchShape()->scaledGeometry( size );
243 }
244 if ( patchShapeGeometry.isEmpty() )
245 {
246 Qgis::SymbolType originalSymbolType = Qgis::SymbolType::Hybrid;
247 switch ( context.originalGeometryType() )
248 {
250 originalSymbolType = Qgis::SymbolType::Marker;
251 break;
253 originalSymbolType = Qgis::SymbolType::Line;
254 break;
256 originalSymbolType = Qgis::SymbolType::Fill;
257 break;
260 originalSymbolType = mSymbol->type();
261 break;
262 }
263 patchShapeGeometry = QgsStyle::defaultStyle()->defaultPatch( originalSymbolType, size ).scaledGeometry( size );
264 }
265
266 // evaluate geometry expression
267 QgsFeature feature;
268 if ( context.feature() )
269 feature = *context.feature();
270 else
271 feature.setGeometry( patchShapeGeometry );
272 const QgsGeometry iconGeometry = evaluateGeometryInPainterUnits( patchShapeGeometry, feature, context.renderContext(), context.renderContext().expressionContext() );
273
274 QgsLegendPatchShape evaluatedPatchShape( mSymbol->type(), coerceToExpectedType( iconGeometry ) );
275 // we don't want to rescale the patch shape to fit the legend symbol size -- we've already considered that here,
276 // and we don't want to undo the effects of a geometry generator which modifies the symbol bounds
277 evaluatedPatchShape.setScaleToOutputSize( false );
278 mSymbol->drawPreviewIcon( context.renderContext().painter(), size, &context.renderContext(), false, &context.renderContext().expressionContext(), &evaluatedPatchShape );
279 }
280}
281
283{
284 mExpression = std::make_unique<QgsExpression>( exp );
285}
286
288{
289 return mExpression->expression();
290}
291
293{
294 switch ( symbol->type() )
295 {
297 mMarkerSymbol.reset( static_cast<QgsMarkerSymbol *>( symbol ) );
298 break;
299
301 mLineSymbol.reset( static_cast<QgsLineSymbol *>( symbol ) );
302 break;
303
305 mFillSymbol.reset( static_cast<QgsFillSymbol *>( symbol ) );
306 break;
307
308 default:
309 break;
310 }
311
312 setSymbolType( symbol->type() );
313
314 return true;
315}
316
318{
319 return QgsSymbolLayer::usedAttributes( context ) + mSymbol->usedAttributes( context ) + mExpression->referencedColumns();
320}
321
323{
324 // we treat geometry generator layers like they have data defined properties,
325 // since the WHOLE layer is based on expressions and requires the full expression
326 // context
327 return true;
328}
329
331{
332 Q_UNUSED( symbol )
333 return true;
334}
335
336QgsGeometry QgsGeometryGeneratorSymbolLayer::evaluateGeometryInPainterUnits( const QgsGeometry &input, const QgsFeature &, const QgsRenderContext &renderContext, QgsExpressionContext &expressionContext ) const
337{
338 QgsGeometry drawGeometry( input );
339 // step 1 - scale the draw geometry from PAINTER units to target units (e.g. millimeters)
340 const double scale = 1 / renderContext.convertToPainterUnits( 1, mUnits );
341 const QTransform painterToTargetUnits = QTransform::fromScale( scale, scale );
342 drawGeometry.transform( painterToTargetUnits );
343
344 // step 2 - set the feature to use the new scaled geometry, and inject it into the expression context
346 QgsExpressionContextScopePopper popper( expressionContext, generatorScope );
347 generatorScope->setGeometry( drawGeometry );
348
349 // step 3 - evaluate the new generated geometry.
350 QVariant value = mExpression->evaluate( &expressionContext );
351 QgsGeometry geom = QgsExpressionUtils::getGeometry( value, mExpression.get() );
352
353 // step 4 - transform geometry back from target units to painter units
354 geom.transform( painterToTargetUnits.inverted() );
355
356 return geom;
357}
358
359QgsGeometry QgsGeometryGeneratorSymbolLayer::coerceToExpectedType( const QgsGeometry &geometry ) const
360{
361 switch ( mSymbolType )
362 {
364 if ( geometry.type() != Qgis::GeometryType::Point )
365 {
366 QVector< QgsGeometry > geoms = geometry.coerceToType( Qgis::WkbType::MultiPoint );
367 if ( !geoms.empty() )
368 return geoms.at( 0 );
369 }
370 break;
372 if ( geometry.type() != Qgis::GeometryType::Line )
373 {
374 QVector< QgsGeometry > geoms = geometry.coerceToType( Qgis::WkbType::MultiLineString );
375 if ( !geoms.empty() )
376 return geoms.at( 0 );
377 }
378 break;
380 if ( geometry.type() != Qgis::GeometryType::Polygon )
381 {
382 QVector< QgsGeometry > geoms = geometry.coerceToType( Qgis::WkbType::MultiPolygon );
383 if ( !geoms.empty() )
384 return geoms.at( 0 );
385 }
386 break;
388 break;
389 }
390 return geometry;
391}
392
393void QgsGeometryGeneratorSymbolLayer::render( QgsSymbolRenderContext &context, Qgis::GeometryType geometryType, const QPolygonF *points, const QVector<QPolygonF> *rings )
394{
395 if ( mRenderingFeature && mHasRenderedFeature )
396 return;
397
398 QgsExpressionContext &expressionContext = context.renderContext().expressionContext();
399 QgsFeature f = expressionContext.feature();
400
401 if ( ( !context.feature() || context.renderContext().flags() & Qgis::RenderContextFlag::RenderingSubSymbol ) && points )
402 {
403 // oh dear, we don't have a feature to work from... but that's ok, we are probably being rendered as a plain old symbol!
404 // in this case we need to build up a feature which represents the points being rendered.
405 // note that we also do this same logic when we are rendering a subsymbol. In that case the $geometry part of the
406 // expression should refer to the shape of the subsymbol being rendered, NOT the feature's original geometry
407 QgsGeometry drawGeometry;
408
409 // step 1 - convert points and rings to geometry
410 switch ( geometryType )
411 {
413 {
414 Q_ASSERT( points->size() == 1 );
415 drawGeometry = QgsGeometry::fromPointXY( points->at( 0 ) );
416 break;
417 }
419 {
420 Q_ASSERT( !rings );
421 std::unique_ptr< QgsLineString > ring( QgsLineString::fromQPolygonF( *points ) );
422 drawGeometry = QgsGeometry( std::move( ring ) );
423 break;
424 }
426 {
427 std::unique_ptr< QgsLineString > exterior( QgsLineString::fromQPolygonF( *points ) );
428 auto polygon = std::make_unique< QgsPolygon >();
429 polygon->setExteriorRing( exterior.release() );
430 if ( rings )
431 {
432 for ( const QPolygonF &ring : *rings )
433 {
434 std::unique_ptr< QgsLineString > fromRing = QgsLineString::fromQPolygonF( ring );
435 polygon->addInteriorRing( fromRing.release() );
436 }
437 }
438 drawGeometry = QgsGeometry( std::move( polygon ) );
439 break;
440 }
441
444 return; // unreachable
445 }
446
447 // step 2 - evaluate the result
448 QgsGeometry result = evaluateGeometryInPainterUnits( drawGeometry, f, context.renderContext(), expressionContext );
449
450 // We transform back to map units here (from painter units)
451 // as we'll ultimately be calling renderFeature, which excepts the feature has a geometry in map units.
452 // Here we also scale the transform by the target unit to painter units factor to reverse that conversion
453 QTransform mapToPixel = context.renderContext().mapToPixel().transform();
454 result.transform( mapToPixel.inverted() );
455 // also need to apply the coordinate transform from the render context
456 try
457 {
459 }
460 catch ( QgsCsException & )
461 {
462 QgsDebugError( u"Could no transform generated geometry to layer CRS"_s );
463 }
464
465 f.setGeometry( coerceToExpectedType( result ) );
466 }
467 else if ( context.feature() )
468 {
469 switch ( mUnits )
470 {
472 case Qgis::RenderUnit::Unknown: // unsupported, not exposed as an option
473 case Qgis::RenderUnit::MetersInMapUnits: // unsupported, not exposed as an option
474 case Qgis::RenderUnit::Percentage: // unsupported, not exposed as an option
475 {
476 QVariant value = mExpression->evaluate( &expressionContext );
477 f.setGeometry( coerceToExpectedType( QgsExpressionUtils::getGeometry( value, mExpression.get() ) ) );
478 break;
479 }
480
485 {
486 // convert feature geometry to painter units
487 QgsGeometry transformed = f.geometry();
488
489 try
490 {
491 transformed.transform( context.renderContext().coordinateTransform() );
492 }
493 catch ( QgsCsException & )
494 {
495 QgsDebugError( u"Could no transform generated geometry to layer CRS"_s );
496 }
497 const QTransform mapToPixel = context.renderContext().mapToPixel().transform();
498 transformed.transform( mapToPixel );
499
500 QgsGeometry result = evaluateGeometryInPainterUnits( transformed, f, context.renderContext(), expressionContext );
501
502 // We transform back to map units here (from painter units)
503 // as we'll ultimately be calling renderFeature, which excepts the feature has a geometry in map units.
504 // Here we also scale the transform by the target unit to painter units factor to reverse that conversion
505 result.transform( mapToPixel.inverted() );
506 // also need to apply the coordinate transform from the render context
507 try
508 {
510 }
511 catch ( QgsCsException & )
512 {
513 QgsDebugError( u"Could no transform generated geometry to layer CRS"_s );
514 }
515 f.setGeometry( coerceToExpectedType( result ) );
516 break;
517 }
518 }
519 }
520
521 QgsExpressionContextScope *subSymbolExpressionContextScope = mSymbol->symbolRenderContext()->expressionContextScope();
522 // override the $geometry value for all subsymbols -- this should be the generated geometry
523 subSymbolExpressionContextScope->setGeometry( f.geometry() );
524
525 const bool prevIsSubsymbol = context.renderContext().flags() & Qgis::RenderContextFlag::RenderingSubSymbol;
527
528 const bool useSelectedColor = shouldRenderUsingSelectionColor( context );
529 mSymbol->renderFeature( f, context.renderContext(), -1, useSelectedColor );
530
532
533 if ( mRenderingFeature )
534 mHasRenderedFeature = true;
535}
536
538{
539 mSymbol->setColor( color );
540}
Provides global constants and enumerations for use throughout the application.
Definition qgis.h:62
@ IsSymbolLayerSubSymbol
Symbol is being rendered as a sub-symbol of a QgsSymbolLayer.
Definition qgis.h:797
GeometryType
The geometry types are used to group Qgis::WkbType in a coarse way.
Definition qgis.h:379
@ Point
Points.
Definition qgis.h:380
@ Line
Lines.
Definition qgis.h:381
@ Polygon
Polygons.
Definition qgis.h:382
@ Unknown
Unknown types.
Definition qgis.h:383
@ Null
No geometry.
Definition qgis.h:384
RenderUnit
Rendering size units.
Definition qgis.h:5340
@ Percentage
Percentage of another measurement (e.g., canvas size, feature size).
Definition qgis.h:5344
@ Millimeters
Millimeters.
Definition qgis.h:5341
@ Points
Points (e.g., for font sizes).
Definition qgis.h:5345
@ Unknown
Mixed or unknown units.
Definition qgis.h:5347
@ MapUnits
Map units.
Definition qgis.h:5342
@ Pixels
Pixels.
Definition qgis.h:5343
@ Inches
Inches.
Definition qgis.h:5346
@ MetersInMapUnits
Meters value as Map units.
Definition qgis.h:5348
@ RenderingSubSymbol
Set whenever a sub-symbol of a parent symbol is currently being rendered. Can be used during symbol a...
Definition qgis.h:2862
SymbolType
Symbol types.
Definition qgis.h:636
@ Marker
Marker symbol.
Definition qgis.h:637
@ Line
Line symbol.
Definition qgis.h:638
@ Fill
Fill symbol.
Definition qgis.h:639
@ Hybrid
Hybrid symbol.
Definition qgis.h:640
@ MultiPoint
MultiPoint.
Definition qgis.h:300
@ MultiPolygon
MultiPolygon.
Definition qgis.h:302
@ MultiLineString
MultiLineString.
Definition qgis.h:301
@ Reverse
Reverse/inverse transform (from destination to source).
Definition qgis.h:2766
Custom exception class for Coordinate Reference System related exceptions.
RAII class to pop scope from an expression context on destruction.
Single scope for storing variables and functions for use within a QgsExpressionContext.
void setGeometry(const QgsGeometry &geometry)
Convenience function for setting a geometry for the scope.
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
QgsFeature feature() const
Convenience function for retrieving the feature for the context, if set.
Handles parsing and evaluation of expressions (formerly called "search strings").
The feature class encapsulates a single feature including its unique ID, geometry and a list of field...
Definition qgsfeature.h:60
QgsGeometry geometry
Definition qgsfeature.h:71
void setGeometry(const QgsGeometry &geometry)
Set the feature's geometry.
A fill symbol type, for rendering Polygon and MultiPolygon geometries.
static std::unique_ptr< QgsFillSymbol > createSimple(const QVariantMap &properties)
Create a fill symbol with one symbol layer: SimpleFill with specified properties.
bool usesMapUnits() const override
Returns true if the symbol layer has any components which use map unit based sizes.
QgsMapUnitScale mapUnitScale() const override
void drawPreviewIcon(QgsSymbolRenderContext &context, QSize size) override
QString geometryExpression() const
Gets the expression to generate this geometry.
bool hasDataDefinedProperties() const override
Returns true if the symbol layer (or any of its sub-symbols) contains data defined properties.
void setUnits(Qgis::RenderUnit units)
Sets the units for the geometry expression.
void setGeometryExpression(const QString &exp)
Set the expression to generate this geometry.
bool rendersIdenticallyTo(const QgsSymbolLayer *other) const override
Returns true if this symbol layer will always render identically to an other symbol layer.
void setSymbolType(Qgis::SymbolType symbolType)
Set the type of symbol which should be created.
QString layerType() const override
Returns a string that represents this layer type.
bool setSubSymbol(QgsSymbol *symbol) override
Sets layer's subsymbol. takes ownership of the passed symbol.
bool isCompatibleWithSymbol(QgsSymbol *symbol) const override
Will always return true.
Qgis::SymbolType symbolType() const
Access the symbol type.
QVariantMap properties() const override
Should be reimplemented by subclasses to return a string map that contains the configuration informat...
void startRender(QgsSymbolRenderContext &context) override
Called before a set of rendering operations commences on the supplied render context.
QgsSymbol * subSymbol() override
Returns the symbol's sub symbol, if present.
QSet< QString > usedAttributes(const QgsRenderContext &context) const override
Returns the set of attributes referenced by the layer.
void setColor(const QColor &color) override
Sets the "representative" color for the symbol layer.
static QgsSymbolLayer * create(const QVariantMap &properties)
Creates the symbol layer.
void setOutputUnit(Qgis::RenderUnit unit) override
Sets the units to use for sizes and widths within the symbol layer.
void stopFeatureRender(const QgsFeature &feature, QgsRenderContext &context) override
Called after the layer has been rendered for a particular feature.
QgsSymbolLayer * clone() const override
Shall be reimplemented by subclasses to create a deep copy of the instance.
void render(QgsSymbolRenderContext &context, Qgis::GeometryType geometryType=Qgis::GeometryType::Unknown, const QPolygonF *points=nullptr, const QVector< QPolygonF > *rings=nullptr)
Will render this symbol layer using the context.
void stopRender(QgsSymbolRenderContext &context) override
Called after a set of rendering operations has finished on the supplied render context.
QColor color() const override
Returns the "representative" color of the symbol layer.
void startFeatureRender(const QgsFeature &feature, QgsRenderContext &context) override
Called before the layer will be rendered for a particular feature.
Qgis::RenderUnit outputUnit() const override
Returns the units to use for sizes and widths within the symbol layer.
A geometry is the spatial representation of a feature.
Qgis::GeometryOperationResult transform(const QgsCoordinateTransform &ct, Qgis::TransformDirection direction=Qgis::TransformDirection::Forward, bool transformZ=false)
Transforms this geometry as described by the coordinate transform ct.
static QgsGeometry fromPointXY(const QgsPointXY &point)
Creates a new geometry from a QgsPointXY object.
Qgis::GeometryType type
QVector< QgsGeometry > coerceToType(Qgis::WkbType type, double defaultZ=0, double defaultM=0, bool avoidDuplicates=true) const
Attempts to coerce this geometry into the specified destination type.
bool isEmpty() const
Returns true if the geometry is empty (eg a linestring with no vertices, or a collection with no geom...
Represents a patch shape for use in map legends.
QgsGeometry scaledGeometry(QSizeF size) const
Returns the patch shape's geometry, scaled to the given size.
bool isNull() const
Returns true if the patch shape is a null QgsLegendPatchShape, which indicates that the default legen...
void setScaleToOutputSize(bool scale)
Sets whether the patch shape should by resized to the desired target size when rendering.
static std::unique_ptr< QgsLineString > fromQPolygonF(const QPolygonF &polygon)
Returns a new linestring from a QPolygonF polygon input.
A line symbol type, for rendering LineString and MultiLineString geometries.
static std::unique_ptr< QgsLineSymbol > createSimple(const QVariantMap &properties)
Create a line symbol with one symbol layer: SimpleLine with specified properties.
QgsPointXY transform(const QgsPointXY &p) const
Transforms a point p from map (world) coordinates to device coordinates.
Struct for storing maximum and minimum scales for measurements in map units.
A marker symbol type, for rendering Point and MultiPoint geometries.
static std::unique_ptr< QgsMarkerSymbol > createSimple(const QVariantMap &properties)
Create a marker symbol with one symbol layer: SimpleMarker with specified properties.
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.
void setFlag(Qgis::RenderContextFlag flag, bool on=true)
Enable or disable a particular flag (other flags are not affected).
const QgsMapToPixel & mapToPixel() const
Returns the context's map to pixel transform, which transforms between map coordinates and device coo...
QgsCoordinateTransform coordinateTransform() const
Returns the current coordinate transform for the context.
Qgis::RenderContextFlags flags() const
Returns combination of flags used for rendering.
QgsLegendPatchShape defaultPatch(Qgis::SymbolType type, QSizeF size) const
Returns the default legend patch shape for the given symbol type.
static QgsStyle * defaultStyle(bool initialize=true)
Returns the default application-wide style.
Definition qgsstyle.cpp:148
Abstract base class for symbol layers.
void copyCommonProperties(QgsSymbolLayer *destLayer) const
Copies all common base class properties from this layer to another symbol layer.
bool shouldRenderUsingSelectionColor(const QgsSymbolRenderContext &context) const
Returns true if the symbol layer should be rendered using the selection color from the render context...
virtual QSet< QString > usedAttributes(const QgsRenderContext &context) const
Returns the set of attributes referenced by the layer.
void restoreOldDataDefinedProperties(const QVariantMap &stringMap)
Restores older data defined properties from string map.
QgsSymbolLayer(const QgsSymbolLayer &other)
Encapsulates the context in which a symbol is being rendered.
const QgsFeature * feature() const
Returns the current feature being rendered.
Qgis::GeometryType originalGeometryType() const
Returns the geometry type for the original feature geometry being rendered.
QgsFields fields() const
Fields of the layer.
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:227
void setRenderHints(Qgis::SymbolRenderHints hints)
Sets rendering hint flags for the symbol.
Definition qgssymbol.h:690
Qgis::SymbolType type() const
Returns the symbol's type.
Definition qgssymbol.h:296
void startRender(QgsRenderContext &context, const QgsFields &fields=QgsFields())
Begins the rendering process for the symbol.
static Q_INVOKABLE Qgis::RenderUnit decodeRenderUnit(const QString &string, bool *ok=nullptr)
Decodes a render unit from a string.
static Q_INVOKABLE QString encodeUnit(Qgis::DistanceUnit unit)
Encodes a distance unit to a string.
#define QgsDebugError(str)
Definition qgslogger.h:59