QGIS API Documentation 3.99.0-Master (2fe06baccd8)
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
32
34{
35 QString expression = properties.value( QStringLiteral( "geometryModifier" ) ).toString();
36 if ( expression.isEmpty() )
37 {
38 expression = QStringLiteral( "@geometry" );
39 }
40 QgsGeometryGeneratorSymbolLayer *symbolLayer = new QgsGeometryGeneratorSymbolLayer( expression );
41
42 if ( properties.value( QStringLiteral( "SymbolType" ) ) == QLatin1String( "Marker" ) )
43 {
44 symbolLayer->setSubSymbol( QgsMarkerSymbol::createSimple( properties ).release() );
45 }
46 else if ( properties.value( QStringLiteral( "SymbolType" ) ) == QLatin1String( "Line" ) )
47 {
48 symbolLayer->setSubSymbol( QgsLineSymbol::createSimple( properties ).release() );
49 }
50 else
51 {
52 symbolLayer->setSubSymbol( QgsFillSymbol::createSimple( properties ).release() );
53 }
54 symbolLayer->setUnits( QgsUnitTypes::decodeRenderUnit( properties.value( QStringLiteral( "units" ), QStringLiteral( "mapunits" ) ).toString() ) );
55
57
58 return symbolLayer;
59}
60
61QgsGeometryGeneratorSymbolLayer::QgsGeometryGeneratorSymbolLayer( const QString &expression )
62 : QgsSymbolLayer( Qgis::SymbolType::Hybrid )
63 , mExpression( new QgsExpression( expression ) )
64{
65
66}
67
69{
70 return QStringLiteral( "GeometryGenerator" );
71}
72
74{
76 {
77 if ( !mFillSymbol )
78 mFillSymbol = QgsFillSymbol::createSimple( QVariantMap() );
79 mSymbol = mFillSymbol.get();
80 }
82 {
83 if ( !mLineSymbol )
84 mLineSymbol = QgsLineSymbol::createSimple( QVariantMap() );
85 mSymbol = mLineSymbol.get();
86 }
88 {
89 if ( !mMarkerSymbol )
90 mMarkerSymbol = QgsMarkerSymbol::createSimple( QVariantMap() );
91 mSymbol = mMarkerSymbol.get();
92 }
93 else
94 Q_ASSERT( false );
95
96 mSymbolType = symbolType;
97}
98
100{
101 mExpression->prepare( &context.renderContext().expressionContext() );
102
104
105 subSymbol()->startRender( context.renderContext(), context.fields() );
106}
107
109{
110 if ( mSymbol )
111 mSymbol->stopRender( context.renderContext() );
112}
113
115{
117 return;
118
119 mRenderingFeature = true;
120 mHasRenderedFeature = false;
121}
122
124{
125 mRenderingFeature = false;
126}
127
129{
130 if ( mFillSymbol )
131 return mFillSymbol->usesMapUnits();
132 else if ( mLineSymbol )
133 return mLineSymbol->usesMapUnits();
134 else if ( mMarkerSymbol )
135 return mMarkerSymbol->usesMapUnits();
136 return false;
137}
138
140{
141 if ( mFillSymbol )
142 return mFillSymbol->color();
143 else if ( mLineSymbol )
144 return mLineSymbol->color();
145 else if ( mMarkerSymbol )
146 return mMarkerSymbol->color();
147 return QColor();
148}
149
151{
152 if ( mFillSymbol )
153 return mFillSymbol->outputUnit();
154 else if ( mLineSymbol )
155 return mLineSymbol->outputUnit();
156 else if ( mMarkerSymbol )
157 return mMarkerSymbol->outputUnit();
159}
160
162{
163 if ( mFillSymbol )
164 mFillSymbol->setOutputUnit( unit );
165 else if ( mLineSymbol )
166 mLineSymbol->setOutputUnit( unit );
167 else if ( mMarkerSymbol )
168 mMarkerSymbol->setOutputUnit( unit );
169}
170
172{
173 if ( mFillSymbol )
174 return mFillSymbol->mapUnitScale();
175 else if ( mLineSymbol )
176 return mLineSymbol->mapUnitScale();
177 else if ( mMarkerSymbol )
178 return mMarkerSymbol->mapUnitScale();
179 return QgsMapUnitScale();
180}
181
183{
184 // since rendersIdenticallyTo must be pessimistic, we always return FALSE here as it's
185 // non-trivial to determine if a QGIS expression will always return the same result
186 // TODO: we could potentially investigate the actual expression and catch cases where we
187 // are CERTAIN that the result will always be the same
188 return false;
189}
190
192{
193 QgsGeometryGeneratorSymbolLayer *clone = new QgsGeometryGeneratorSymbolLayer( mExpression->expression() );
194
195 if ( mFillSymbol )
196 clone->mFillSymbol.reset( mFillSymbol->clone() );
197 if ( mLineSymbol )
198 clone->mLineSymbol.reset( mLineSymbol->clone() );
199 if ( mMarkerSymbol )
200 clone->mMarkerSymbol.reset( mMarkerSymbol->clone() );
201
202 clone->setSymbolType( mSymbolType );
203 clone->setUnits( mUnits );
204
207
208 return clone;
209}
210
212{
213 QVariantMap props;
214 props.insert( QStringLiteral( "geometryModifier" ), mExpression->expression() );
215 switch ( mSymbolType )
216 {
218 props.insert( QStringLiteral( "SymbolType" ), QStringLiteral( "Marker" ) );
219 break;
221 props.insert( QStringLiteral( "SymbolType" ), QStringLiteral( "Line" ) );
222 break;
223 default:
224 props.insert( QStringLiteral( "SymbolType" ), QStringLiteral( "Fill" ) );
225 break;
226 }
227 props.insert( QStringLiteral( "units" ), QgsUnitTypes::encodeUnit( mUnits ) );
228
229 return props;
230}
231
233{
234 if ( mSymbol )
235 {
236 // evaluate expression
237 QgsGeometry patchShapeGeometry;
238
239 if ( context.patchShape() && !context.patchShape()->isNull() )
240 {
241 patchShapeGeometry = context.patchShape()->scaledGeometry( size );
242 }
243 if ( patchShapeGeometry.isEmpty() )
244 {
245 Qgis::SymbolType originalSymbolType = Qgis::SymbolType::Hybrid;
246 switch ( context.originalGeometryType() )
247 {
249 originalSymbolType = Qgis::SymbolType::Marker;
250 break;
252 originalSymbolType = Qgis::SymbolType::Line;
253 break;
255 originalSymbolType = Qgis::SymbolType::Fill;
256 break;
259 originalSymbolType = mSymbol->type();
260 break;
261 }
262 patchShapeGeometry = QgsStyle::defaultStyle()->defaultPatch( originalSymbolType, size ).scaledGeometry( size );
263 }
264
265 // evaluate geometry expression
266 QgsFeature feature;
267 if ( context.feature() )
268 feature = *context.feature();
269 else
270 feature.setGeometry( patchShapeGeometry );
271 const QgsGeometry iconGeometry = evaluateGeometryInPainterUnits( patchShapeGeometry, feature, context.renderContext(), context.renderContext().expressionContext() );
272
273 QgsLegendPatchShape evaluatedPatchShape( mSymbol->type(), coerceToExpectedType( iconGeometry ) );
274 // we don't want to rescale the patch shape to fit the legend symbol size -- we've already considered that here,
275 // and we don't want to undo the effects of a geometry generator which modifies the symbol bounds
276 evaluatedPatchShape.setScaleToOutputSize( false );
277 mSymbol->drawPreviewIcon( context.renderContext().painter(), size, &context.renderContext(), false, &context.renderContext().expressionContext(), &evaluatedPatchShape );
278 }
279}
280
282{
283 mExpression = std::make_unique<QgsExpression>( exp );
284}
285
287{
288 return mExpression->expression();
289}
290
292{
293 switch ( symbol->type() )
294 {
296 mMarkerSymbol.reset( static_cast<QgsMarkerSymbol *>( symbol ) );
297 break;
298
300 mLineSymbol.reset( static_cast<QgsLineSymbol *>( symbol ) );
301 break;
302
304 mFillSymbol.reset( static_cast<QgsFillSymbol *>( symbol ) );
305 break;
306
307 default:
308 break;
309 }
310
311 setSymbolType( symbol->type() );
312
313 return true;
314}
315
317{
318 return QgsSymbolLayer::usedAttributes( context )
319 + mSymbol->usedAttributes( context )
320 + mExpression->referencedColumns();
321}
322
324{
325 // we treat geometry generator layers like they have data defined properties,
326 // since the WHOLE layer is based on expressions and requires the full expression
327 // context
328 return true;
329}
330
332{
333 Q_UNUSED( symbol )
334 return true;
335}
336
337QgsGeometry QgsGeometryGeneratorSymbolLayer::evaluateGeometryInPainterUnits( const QgsGeometry &input, const QgsFeature &, const QgsRenderContext &renderContext, QgsExpressionContext &expressionContext ) const
338{
339 QgsGeometry drawGeometry( input );
340 // step 1 - scale the draw geometry from PAINTER units to target units (e.g. millimeters)
341 const double scale = 1 / renderContext.convertToPainterUnits( 1, mUnits );
342 const QTransform painterToTargetUnits = QTransform::fromScale( scale, scale );
343 drawGeometry.transform( painterToTargetUnits );
344
345 // step 2 - set the feature to use the new scaled geometry, and inject it into the expression context
347 QgsExpressionContextScopePopper popper( expressionContext, generatorScope );
348 generatorScope->setGeometry( drawGeometry );
349
350 // step 3 - evaluate the new generated geometry.
351 QVariant value = mExpression->evaluate( &expressionContext );
352 QgsGeometry geom = QgsExpressionUtils::getGeometry( value, mExpression.get() );
353
354 // step 4 - transform geometry back from target units to painter units
355 geom.transform( painterToTargetUnits.inverted( ) );
356
357 return geom;
358}
359
360QgsGeometry QgsGeometryGeneratorSymbolLayer::coerceToExpectedType( const QgsGeometry &geometry ) const
361{
362 switch ( mSymbolType )
363 {
365 if ( geometry.type() != Qgis::GeometryType::Point )
366 {
367 QVector< QgsGeometry > geoms = geometry.coerceToType( Qgis::WkbType::MultiPoint );
368 if ( !geoms.empty() )
369 return geoms.at( 0 );
370 }
371 break;
373 if ( geometry.type() != Qgis::GeometryType::Line )
374 {
375 QVector< QgsGeometry > geoms = geometry.coerceToType( Qgis::WkbType::MultiLineString );
376 if ( !geoms.empty() )
377 return geoms.at( 0 );
378 }
379 break;
381 if ( geometry.type() != Qgis::GeometryType::Polygon )
382 {
383 QVector< QgsGeometry > geoms = geometry.coerceToType( Qgis::WkbType::MultiPolygon );
384 if ( !geoms.empty() )
385 return geoms.at( 0 );
386 }
387 break;
389 break;
390 }
391 return geometry;
392}
393
394void QgsGeometryGeneratorSymbolLayer::render( QgsSymbolRenderContext &context, Qgis::GeometryType geometryType, const QPolygonF *points, const QVector<QPolygonF> *rings )
395{
396 if ( mRenderingFeature && mHasRenderedFeature )
397 return;
398
399 QgsExpressionContext &expressionContext = context.renderContext().expressionContext();
400 QgsFeature f = expressionContext.feature();
401
402 if ( ( !context.feature() || context.renderContext().flags() & Qgis::RenderContextFlag::RenderingSubSymbol ) && points )
403 {
404 // 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!
405 // in this case we need to build up a feature which represents the points being rendered.
406 // note that we also do this same logic when we are rendering a subsymbol. In that case the $geometry part of the
407 // expression should refer to the shape of the subsymbol being rendered, NOT the feature's original geometry
408 QgsGeometry drawGeometry;
409
410 // step 1 - convert points and rings to geometry
411 switch ( geometryType )
412 {
414 {
415 Q_ASSERT( points->size() == 1 );
416 drawGeometry = QgsGeometry::fromPointXY( points->at( 0 ) );
417 break;
418 }
420 {
421 Q_ASSERT( !rings );
422 std::unique_ptr < QgsLineString > ring( QgsLineString::fromQPolygonF( *points ) );
423 drawGeometry = QgsGeometry( std::move( ring ) );
424 break;
425 }
427 {
428 std::unique_ptr < QgsLineString > exterior( QgsLineString::fromQPolygonF( *points ) );
429 auto polygon = std::make_unique< QgsPolygon >();
430 polygon->setExteriorRing( exterior.release() );
431 if ( rings )
432 {
433 for ( const QPolygonF &ring : *rings )
434 {
435 std::unique_ptr< QgsLineString > fromRing = QgsLineString::fromQPolygonF( ring );
436 polygon->addInteriorRing( fromRing.release() );
437 }
438 }
439 drawGeometry = QgsGeometry( std::move( polygon ) );
440 break;
441 }
442
445 return; // unreachable
446 }
447
448 // step 2 - evaluate the result
449 QgsGeometry result = evaluateGeometryInPainterUnits( drawGeometry, f, context.renderContext(), expressionContext );
450
451 // We transform back to map units here (from painter units)
452 // as we'll ultimately be calling renderFeature, which excepts the feature has a geometry in map units.
453 // Here we also scale the transform by the target unit to painter units factor to reverse that conversion
454 QTransform mapToPixel = context.renderContext().mapToPixel().transform();
455 result.transform( mapToPixel.inverted() );
456 // also need to apply the coordinate transform from the render context
457 try
458 {
460 }
461 catch ( QgsCsException & )
462 {
463 QgsDebugError( QStringLiteral( "Could no transform generated geometry to layer CRS" ) );
464 }
465
466 f.setGeometry( coerceToExpectedType( result ) );
467 }
468 else if ( context.feature() )
469 {
470 switch ( mUnits )
471 {
473 case Qgis::RenderUnit::Unknown: // unsupported, not exposed as an option
474 case Qgis::RenderUnit::MetersInMapUnits: // unsupported, not exposed as an option
475 case Qgis::RenderUnit::Percentage: // unsupported, not exposed as an option
476 {
477 QVariant value = mExpression->evaluate( &expressionContext );
478 f.setGeometry( coerceToExpectedType( QgsExpressionUtils::getGeometry( value, mExpression.get() ) ) );
479 break;
480 }
481
486 {
487 // convert feature geometry to painter units
488 QgsGeometry transformed = f.geometry();
489
490 try
491 {
492 transformed.transform( context.renderContext().coordinateTransform() );
493 }
494 catch ( QgsCsException & )
495 {
496 QgsDebugError( QStringLiteral( "Could no transform generated geometry to layer CRS" ) );
497 }
498 const QTransform mapToPixel = context.renderContext().mapToPixel().transform();
499 transformed.transform( mapToPixel );
500
501 QgsGeometry result = evaluateGeometryInPainterUnits( transformed, f, context.renderContext(), expressionContext );
502
503 // We transform back to map units here (from painter units)
504 // as we'll ultimately be calling renderFeature, which excepts the feature has a geometry in map units.
505 // Here we also scale the transform by the target unit to painter units factor to reverse that conversion
506 result.transform( mapToPixel.inverted() );
507 // also need to apply the coordinate transform from the render context
508 try
509 {
511 }
512 catch ( QgsCsException & )
513 {
514 QgsDebugError( QStringLiteral( "Could no transform generated geometry to layer CRS" ) );
515 }
516 f.setGeometry( coerceToExpectedType( result ) );
517 break;
518 }
519 }
520 }
521
522 QgsExpressionContextScope *subSymbolExpressionContextScope = mSymbol->symbolRenderContext()->expressionContextScope();
523 // override the $geometry value for all subsymbols -- this should be the generated geometry
524 subSymbolExpressionContextScope->setGeometry( f.geometry() );
525
526 const bool prevIsSubsymbol = context.renderContext().flags() & Qgis::RenderContextFlag::RenderingSubSymbol;
528
529 const bool useSelectedColor = shouldRenderUsingSelectionColor( context );
530 mSymbol->renderFeature( f, context.renderContext(), -1, useSelectedColor );
531
533
534 if ( mRenderingFeature )
535 mHasRenderedFeature = true;
536}
537
539{
540 mSymbol->setColor( color );
541}
Provides global constants and enumerations for use throughout the application.
Definition qgis.h:56
@ IsSymbolLayerSubSymbol
Symbol is being rendered as a sub-symbol of a QgsSymbolLayer.
Definition qgis.h:771
GeometryType
The geometry types are used to group Qgis::WkbType in a coarse way.
Definition qgis.h:358
@ Point
Points.
Definition qgis.h:359
@ Line
Lines.
Definition qgis.h:360
@ Polygon
Polygons.
Definition qgis.h:361
@ Unknown
Unknown types.
Definition qgis.h:362
@ Null
No geometry.
Definition qgis.h:363
RenderUnit
Rendering size units.
Definition qgis.h:5183
@ Percentage
Percentage of another measurement (e.g., canvas size, feature size).
Definition qgis.h:5187
@ Millimeters
Millimeters.
Definition qgis.h:5184
@ Points
Points (e.g., for font sizes).
Definition qgis.h:5188
@ Unknown
Mixed or unknown units.
Definition qgis.h:5190
@ MapUnits
Map units.
Definition qgis.h:5185
@ Pixels
Pixels.
Definition qgis.h:5186
@ Inches
Inches.
Definition qgis.h:5189
@ MetersInMapUnits
Meters value as Map units.
Definition qgis.h:5191
@ RenderingSubSymbol
Set whenever a sub-symbol of a parent symbol is currently being rendered. Can be used during symbol a...
Definition qgis.h:2765
SymbolType
Symbol types.
Definition qgis.h:610
@ Marker
Marker symbol.
Definition qgis.h:611
@ Line
Line symbol.
Definition qgis.h:612
@ Fill
Fill symbol.
Definition qgis.h:613
@ Hybrid
Hybrid symbol.
Definition qgis.h:614
@ MultiPoint
MultiPoint.
Definition qgis.h:283
@ MultiPolygon
MultiPolygon.
Definition qgis.h:285
@ MultiLineString
MultiLineString.
Definition qgis.h:284
@ Reverse
Reverse/inverse transform (from destination to source).
Definition qgis.h:2673
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:58
QgsGeometry geometry
Definition qgsfeature.h:69
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:147
Abstract base class for symbol layers.
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 copyDataDefinedProperties(QgsSymbolLayer *destLayer) const
Copies all data defined properties of this layer to another symbol layer.
void restoreOldDataDefinedProperties(const QVariantMap &stringMap)
Restores older data defined properties from string map.
void copyPaintEffect(QgsSymbolLayer *destLayer) const
Copies paint effect of this layer to another symbol layer.
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:231
void setRenderHints(Qgis::SymbolRenderHints hints)
Sets rendering hint flags for the symbol.
Definition qgssymbol.h:672
Qgis::SymbolType type() const
Returns the symbol's type.
Definition qgssymbol.h:294
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:57