QGIS API Documentation 3.99.0-Master (26c88405ac0)
Loading...
Searching...
No Matches
qgsmarkersymbol.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgsmarkersymbol.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 "qgsmarkersymbol.h"
17
18#include "qgsfillsymbol.h"
22#include "qgspainteffect.h"
23#include "qgspainting.h"
24#include "qgssymbollayerutils.h"
25
26std::unique_ptr< QgsMarkerSymbol > QgsMarkerSymbol::createSimple( const QVariantMap &properties )
27{
29 if ( !sl )
30 return nullptr;
31
32 QgsSymbolLayerList layers;
33 layers.append( sl );
34 return std::make_unique< QgsMarkerSymbol >( layers );
35}
36
38 : QgsSymbol( Qgis::SymbolType::Marker, layers )
39{
40 if ( mLayers.isEmpty() )
41 mLayers.append( new QgsSimpleMarkerSymbolLayer() );
42}
43
44void QgsMarkerSymbol::setAngle( double symbolAngle ) const
45{
46 double origAngle = angle();
47 double angleDiff = symbolAngle - origAngle;
48 const auto constMLayers = mLayers;
49 for ( QgsSymbolLayer *layer : constMLayers )
50 {
51 QgsMarkerSymbolLayer *markerLayer = dynamic_cast<QgsMarkerSymbolLayer *>( layer );
52 if ( markerLayer )
53 markerLayer->setAngle( markerLayer->angle() + angleDiff );
54 }
55}
56
58{
59 for ( QgsSymbolLayer *layer : std::as_const( mLayers ) )
60 {
61 if ( layer->type() != Qgis::SymbolType::Marker )
62 continue;
63 const QgsMarkerSymbolLayer *markerLayer = static_cast<const QgsMarkerSymbolLayer *>( layer );
64 return markerLayer->angle();
65 }
66 return 0;
67}
68
69void QgsMarkerSymbol::setLineAngle( double lineAng ) const
70{
71 const auto constMLayers = mLayers;
72 for ( QgsSymbolLayer *layer : constMLayers )
73 {
74 if ( layer->type() != Qgis::SymbolType::Marker )
75 continue;
76 QgsMarkerSymbolLayer *markerLayer = static_cast<QgsMarkerSymbolLayer *>( layer );
77 markerLayer->setLineAngle( lineAng );
78 }
79}
80
82{
83 const double symbolRotation = angle();
84
85
86 for ( QgsSymbolLayer *layer : std::as_const( mLayers ) )
87 {
88 if ( layer->type() != Qgis::SymbolType::Marker )
89 continue;
90 const QgsMarkerSymbolLayer *markerLayer = static_cast<const QgsMarkerSymbolLayer *>( layer );
91 if ( !property )
92 {
93 layer->setDataDefinedProperty( QgsSymbolLayer::Property::Angle, QgsProperty() );
94 }
95 else
96 {
97 if ( qgsDoubleNear( markerLayer->angle(), symbolRotation ) )
98 {
99 layer->setDataDefinedProperty( QgsSymbolLayer::Property::Angle, property );
100 }
101 else
102 {
103 QgsProperty rotatedDD = QgsSymbolLayerUtils::rotateWholeSymbol( markerLayer->angle() - symbolRotation, property );
104 layer->setDataDefinedProperty( QgsSymbolLayer::Property::Angle, rotatedDD );
105 }
106 }
107 }
108}
109
111{
112 const double symbolRotation = angle();
113 QgsProperty symbolDD;
114
115 // find the base of the "en masse" pattern
116 const auto layers = mLayers;
117 for ( QgsSymbolLayer *layer : layers )
118 {
119 if ( layer->type() != Qgis::SymbolType::Marker )
120 continue;
121 const QgsMarkerSymbolLayer *markerLayer = static_cast<const QgsMarkerSymbolLayer *>( layer );
122 if ( qgsDoubleNear( markerLayer->angle(), symbolRotation ) && markerLayer->dataDefinedProperties().isActive( QgsSymbolLayer::Property::Angle ) )
123 {
125 break;
126 }
127 }
128
129 if ( !symbolDD )
130 return QgsProperty();
131
132 // check that all layer's angle expressions match the "en masse" pattern
133 for ( QgsSymbolLayer *layer : layers )
134 {
135 if ( layer->type() != Qgis::SymbolType::Marker )
136 continue;
137 const QgsMarkerSymbolLayer *markerLayer = static_cast<const QgsMarkerSymbolLayer *>( layer );
138
140
141 if ( qgsDoubleNear( markerLayer->angle(), symbolRotation ) )
142 {
143 if ( !layerAngleDD || layerAngleDD != symbolDD )
144 return QgsProperty();
145 }
146 else
147 {
148 QgsProperty rotatedDD( QgsSymbolLayerUtils::rotateWholeSymbol( markerLayer->angle() - symbolRotation, symbolDD ) );
149 if ( !layerAngleDD || layerAngleDD != rotatedDD )
150 return QgsProperty();
151 }
152 }
153 return symbolDD;
154}
155
156
157void QgsMarkerSymbol::setSize( double s ) const
158{
159 double origSize = size();
160
161 const auto constMLayers = mLayers;
162 for ( QgsSymbolLayer *layer : constMLayers )
163 {
164 QgsMarkerSymbolLayer *markerLayer = dynamic_cast<QgsMarkerSymbolLayer *>( layer );
165 if ( markerLayer )
166 {
167 if ( qgsDoubleNear( markerLayer->size(), origSize ) )
168 {
169 markerLayer->setSize( s );
170 }
171 else if ( !qgsDoubleNear( origSize, 0.0 ) )
172 {
173 // proportionally scale size
174 markerLayer->setSize( markerLayer->size() * s / origSize );
175 }
176 // also scale offset to maintain relative position
177 if ( !qgsDoubleNear( origSize, 0.0 ) && ( !qgsDoubleNear( markerLayer->offset().x(), 0.0 ) || !qgsDoubleNear( markerLayer->offset().y(), 0.0 ) ) )
178 markerLayer->setOffset( QPointF( markerLayer->offset().x() * s / origSize,
179 markerLayer->offset().y() * s / origSize ) );
180 }
181 else
182 {
183 QgsGeometryGeneratorSymbolLayer *geomGeneratorLayer = dynamic_cast<QgsGeometryGeneratorSymbolLayer *>( layer );
184 if ( geomGeneratorLayer && geomGeneratorLayer->symbolType() == Qgis::SymbolType::Marker )
185 {
186 QgsMarkerSymbol *markerSymbol = qgis::down_cast<QgsMarkerSymbol *>( geomGeneratorLayer->subSymbol() );
187 if ( qgsDoubleNear( markerSymbol->size(), origSize ) )
188 {
189 markerSymbol->setSize( s );
190 }
191 else if ( !qgsDoubleNear( origSize, 0.0 ) )
192 {
193 // proportionally scale the width
194 markerSymbol->setSize( markerSymbol->size() * s / origSize );
195 }
196 }
197 }
198 }
199}
200
202{
203 // return size of the largest symbol
204 double maxSize = 0;
205 const auto constMLayers = mLayers;
206 for ( QgsSymbolLayer *layer : constMLayers )
207 {
208 const QgsMarkerSymbolLayer *markerLayer = dynamic_cast<QgsMarkerSymbolLayer *>( layer );
209 if ( markerLayer )
210 {
211 const double lsize = markerLayer->size();
212 if ( lsize > maxSize )
213 maxSize = lsize;
214 }
215 else
216 {
217 QgsGeometryGeneratorSymbolLayer *geomGeneratorLayer = dynamic_cast<QgsGeometryGeneratorSymbolLayer *>( layer );
218 if ( geomGeneratorLayer && geomGeneratorLayer->symbolType() == Qgis::SymbolType::Marker )
219 {
220 QgsMarkerSymbol *markerSymbol = qgis::down_cast<QgsMarkerSymbol *>( geomGeneratorLayer->subSymbol() );
221 const double lsize = markerSymbol->size();
222 if ( lsize > maxSize )
223 maxSize = lsize;
224 }
225 }
226 }
227 return maxSize;
228}
229
230double QgsMarkerSymbol::size( const QgsRenderContext &context ) const
231{
232 // return size of the largest symbol
233 double maxSize = 0;
234 for ( QgsSymbolLayer *layer : mLayers )
235 {
236 if ( layer->type() != Qgis::SymbolType::Marker )
237 continue;
238 const QgsMarkerSymbolLayer *markerLayer = static_cast<const QgsMarkerSymbolLayer *>( layer );
239 const double layerSize = context.convertToPainterUnits( markerLayer->size(), markerLayer->sizeUnit(), markerLayer->sizeMapUnitScale() );
240 maxSize = std::max( maxSize, layerSize );
241 }
242 return maxSize;
243}
244
246{
247 const auto constMLayers = mLayers;
248 for ( QgsSymbolLayer *layer : constMLayers )
249 {
250 if ( layer->type() != Qgis::SymbolType::Marker )
251 continue;
252
253 QgsMarkerSymbolLayer *markerLayer = static_cast<QgsMarkerSymbolLayer *>( layer );
254 markerLayer->setSizeUnit( unit );
255 }
256}
257
259{
260 bool first = true;
262
263 const auto constMLayers = mLayers;
264 for ( QgsSymbolLayer *layer : constMLayers )
265 {
266 if ( layer->type() != Qgis::SymbolType::Marker )
267 continue;
268 const QgsMarkerSymbolLayer *markerLayer = static_cast<const QgsMarkerSymbolLayer *>( layer );
269
270 if ( first )
271 unit = markerLayer->sizeUnit();
272 else
273 {
274 if ( unit != markerLayer->sizeUnit() )
276 }
277
278 first = false;
279 }
280 return unit;
281}
282
284{
285 const auto constMLayers = mLayers;
286 for ( QgsSymbolLayer *layer : constMLayers )
287 {
288 if ( layer->type() != Qgis::SymbolType::Marker )
289 continue;
290
291 QgsMarkerSymbolLayer *markerLayer = static_cast<QgsMarkerSymbolLayer *>( layer );
292 markerLayer->setSizeMapUnitScale( scale );
293 }
294}
295
297{
298 const auto constMLayers = mLayers;
299 for ( QgsSymbolLayer *layer : constMLayers )
300 {
301 if ( layer->type() != Qgis::SymbolType::Marker )
302 continue;
303
304 QgsMarkerSymbolLayer *markerLayer = static_cast<QgsMarkerSymbolLayer *>( layer );
305 return markerLayer->sizeMapUnitScale();
306 }
307 return QgsMapUnitScale();
308}
309
311{
312 const double symbolSize = size();
313
314 const auto constMLayers = mLayers;
315 for ( QgsSymbolLayer *layer : constMLayers )
316 {
317 if ( layer->type() != Qgis::SymbolType::Marker )
318 continue;
319 QgsMarkerSymbolLayer *markerLayer = static_cast<QgsMarkerSymbolLayer *>( layer );
320
321 if ( !property )
322 {
325 }
326 else
327 {
328 if ( qgsDoubleNear( symbolSize, 0.0 ) || qgsDoubleNear( markerLayer->size(), symbolSize ) )
329 {
331 }
332 else
333 {
334 markerLayer->setDataDefinedProperty( QgsSymbolLayer::Property::Size, QgsSymbolLayerUtils::scaleWholeSymbol( markerLayer->size() / symbolSize, property ) );
335 }
336
337 if ( !qgsDoubleNear( markerLayer->offset().x(), 0.0 ) || !qgsDoubleNear( markerLayer->offset().y(), 0.0 ) )
338 {
339 markerLayer->setDataDefinedProperty( QgsSymbolLayer::Property::Offset, QgsSymbolLayerUtils::scaleWholeSymbol(
340 markerLayer->offset().x() / symbolSize,
341 markerLayer->offset().y() / symbolSize, property ) );
342 }
343 }
344 }
345}
346
348{
349 const double symbolSize = size();
350
351 QgsProperty symbolDD;
352
353 // find the base of the "en masse" pattern
354 const auto layers = mLayers;
355 for ( QgsSymbolLayer *layer : layers )
356 {
357 if ( layer->type() != Qgis::SymbolType::Marker )
358 continue;
359 const QgsMarkerSymbolLayer *markerLayer = static_cast<const QgsMarkerSymbolLayer *>( layer );
360 if ( qgsDoubleNear( markerLayer->size(), symbolSize ) && markerLayer->dataDefinedProperties().isActive( QgsSymbolLayer::Property::Size ) )
361 {
363 break;
364 }
365 }
366
367 if ( !symbolDD )
368 return QgsProperty();
369
370 // check that all layers size expressions match the "en masse" pattern
371 for ( QgsSymbolLayer *layer : layers )
372 {
373 if ( layer->type() != Qgis::SymbolType::Marker )
374 continue;
375 const QgsMarkerSymbolLayer *markerLayer = static_cast<const QgsMarkerSymbolLayer *>( layer );
376
379
380 if ( qgsDoubleNear( markerLayer->size(), symbolSize ) )
381 {
382 if ( !layerSizeDD || layerSizeDD != symbolDD )
383 return QgsProperty();
384 }
385 else
386 {
387 if ( qgsDoubleNear( symbolSize, 0.0 ) )
388 return QgsProperty();
389
390 QgsProperty scaledDD( QgsSymbolLayerUtils::scaleWholeSymbol( markerLayer->size() / symbolSize, symbolDD ) );
391 if ( !layerSizeDD || layerSizeDD != scaledDD )
392 return QgsProperty();
393 }
394
395 QgsProperty scaledOffsetDD( QgsSymbolLayerUtils::scaleWholeSymbol( markerLayer->offset().x() / symbolSize, markerLayer->offset().y() / symbolSize, symbolDD ) );
396 if ( layerOffsetDD && layerOffsetDD != scaledOffsetDD )
397 return QgsProperty();
398 }
399
400 return symbolDD;
401}
402
404{
405 const auto constMLayers = mLayers;
406 for ( QgsSymbolLayer *layer : constMLayers )
407 {
408 if ( layer->type() != Qgis::SymbolType::Marker )
409 continue;
410 QgsMarkerSymbolLayer *markerLayer = static_cast<QgsMarkerSymbolLayer *>( layer );
411 markerLayer->setScaleMethod( scaleMethod );
412 }
413}
414
416{
417 const auto constMLayers = mLayers;
418 for ( QgsSymbolLayer *layer : constMLayers )
419 {
420 if ( layer->type() != Qgis::SymbolType::Marker )
421 continue;
422 const QgsMarkerSymbolLayer *markerLayer = static_cast<const QgsMarkerSymbolLayer *>( layer );
423 // return scale method of the first symbol layer
424 return markerLayer->scaleMethod();
425 }
426
428}
429
430void QgsMarkerSymbol::renderPointUsingLayer( QgsMarkerSymbolLayer *layer, QPointF point, QgsSymbolRenderContext &context )
431{
432 static QPointF nullPoint( 0, 0 );
433
434 if ( layer->dataDefinedProperties().hasActiveProperties() && !layer->dataDefinedProperties().valueAsBool( QgsSymbolLayer::Property::LayerEnabled, context.renderContext().expressionContext(), true ) )
435 return;
436
437 QgsPaintEffect *effect = layer->paintEffect();
438 if ( effect && effect->enabled() )
439 {
440 QgsEffectPainter p( context.renderContext() );
441 p->translate( point );
442 p.setEffect( effect );
443 layer->renderPoint( nullPoint, context );
444 }
445 else
446 {
447 layer->renderPoint( point, context );
448 }
449}
450
451void QgsMarkerSymbol::renderPoint( QPointF point, const QgsFeature *f, QgsRenderContext &context, int layerIdx, bool selected )
452{
454 : mOpacity;
455
456 QgsSymbolRenderContext symbolContext( context, Qgis::RenderUnit::Unknown, opacity, selected, renderHints(), f );
457 symbolContext.setGeometryPartCount( symbolRenderContext()->geometryPartCount() );
458 symbolContext.setGeometryPartNum( symbolRenderContext()->geometryPartNum() );
459
460 // If we're drawing using symbol levels, we only draw buffers for the bottom most level
461 const bool usingBuffer = ( layerIdx == -1 || layerIdx == 0 ) && mBufferSettings && mBufferSettings->enabled() && mBufferSettings->fillSymbol()
463
464 if ( layerIdx != -1 && !usingBuffer )
465 {
466 QgsSymbolLayer *symbolLayer = mLayers.value( layerIdx );
467 if ( symbolLayer && symbolLayer->enabled() && context.isSymbolLayerEnabled( symbolLayer ) )
468 {
469 if ( symbolLayer->type() == Qgis::SymbolType::Marker )
470 {
471 QgsMarkerSymbolLayer *markerLayer = static_cast<QgsMarkerSymbolLayer *>( symbolLayer );
472 renderPointUsingLayer( markerLayer, point, symbolContext );
473 }
474 else
475 {
476 QPolygonF points;
477 points.append( point );
478 renderUsingLayer( symbolLayer, symbolContext, Qgis::GeometryType::Point, &points );
479 }
480 }
481 return;
482 }
483
484 // handle symbol buffers -- we do this by deferring the rendering of the symbol and redirecting
485 // to QPictures, and then using the actual rendered shape from the QPictures to determine the buffer shape.
486 QPainter *originalTargetPainter = nullptr;
487 // this is an array, we need to separate out the symbol layers if we're drawing only one symbol level
488 std::vector< QPicture > picturesForDeferredRendering;
489 std::unique_ptr< QPainter > deferredRenderingPainter;
490 if ( usingBuffer )
491 {
492 originalTargetPainter = context.painter();
493 picturesForDeferredRendering.emplace_back( QPicture() );
494 deferredRenderingPainter = std::make_unique< QPainter >( &picturesForDeferredRendering.front() );
495 context.setPainter( deferredRenderingPainter.get() );
496 }
497
498 int symbolLayerIndex = -1;
499 for ( QgsSymbolLayer *symbolLayer : std::as_const( mLayers ) )
500 {
501 symbolLayerIndex++;
502 if ( context.renderingStopped() )
503 break;
504
505 if ( deferredRenderingPainter && layerIdx != -1 && symbolLayerIndex != 0 )
506 {
507 // if we're using deferred rendering along with symbol level drawing, we
508 // start a new picture for each symbol layer drawn
509 deferredRenderingPainter->end();
510 picturesForDeferredRendering.emplace_back( QPicture() );
511 deferredRenderingPainter->begin( &picturesForDeferredRendering.back() );
512 }
513
514 if ( !symbolLayer->enabled() || !context.isSymbolLayerEnabled( symbolLayer ) )
515 continue;
516
517 if ( symbolLayer->type() == Qgis::SymbolType::Marker )
518 {
519 QgsMarkerSymbolLayer *markerLayer = static_cast<QgsMarkerSymbolLayer *>( symbolLayer );
520 renderPointUsingLayer( markerLayer, point, symbolContext );
521 }
522 else
523 {
524 QPolygonF points;
525 points.append( point );
526 renderUsingLayer( symbolLayer, symbolContext, Qgis::GeometryType::Point, &points );
527 }
528 }
529
530 // if required, render the calculated buffer below the symbol
531 if ( usingBuffer )
532 {
533 deferredRenderingPainter->end();
534 deferredRenderingPainter.reset();
535
536 QgsGeometryPaintDevice geometryPaintDevice;
537 QPainter geometryPainter( &geometryPaintDevice );
538 // render all the symbol layers onto the geometry painter, so we can calculate a single
539 // buffer for ALL of them
540 for ( const auto &deferredPicture : picturesForDeferredRendering )
541 {
542 QgsPainting::drawPicture( &geometryPainter, QPointF( 0, 0 ), deferredPicture );
543 }
544 geometryPainter.end();
545
546 // retrieve the shape of the rendered symbol
547 const QgsGeometry renderedShape( geometryPaintDevice.geometry().clone() );
548
549 context.setPainter( originalTargetPainter );
550
551 // next, buffer out the rendered shape, and draw!
552 const double bufferSize = context.convertToPainterUnits( mBufferSettings->size(), mBufferSettings->sizeUnit(), mBufferSettings->sizeMapUnitScale() );
554 switch ( mBufferSettings->joinStyle() )
555 {
556 case Qt::MiterJoin:
557 case Qt::SvgMiterJoin:
558 joinStyle = Qgis::JoinStyle::Miter;
559 break;
560 case Qt::BevelJoin:
561 joinStyle = Qgis::JoinStyle::Bevel;
562 break;
563 case Qt::RoundJoin:
564 joinStyle = Qgis::JoinStyle::Round;
565 break;
566
567 case Qt::MPenJoinStyle:
568 break;
569 }
570
571 const QgsGeometry bufferedGeometry = renderedShape.buffer( bufferSize, 8, Qgis::EndCapStyle::Round, joinStyle, 2 );
572 const QList<QList<QPolygonF> > polygons = QgsSymbolLayerUtils::toQPolygonF( bufferedGeometry, Qgis::SymbolType::Fill );
573 for ( const QList< QPolygonF > &polygon : polygons )
574 {
575 QVector< QPolygonF > rings;
576 for ( int i = 1; i < polygon.size(); ++i )
577 rings << polygon.at( i );
578 mBufferSettings->fillSymbol()->renderPolygon( polygon.value( 0 ), &rings, nullptr, context );
579 }
580
581 // finally, draw the actual rendered symbol on top. If symbol levels are at play then this will ONLY
582 // be the target symbol level, not all of them.
583 QgsPainting::drawPicture( context.painter(), QPointF( 0, 0 ), picturesForDeferredRendering.front() );
584 }
585}
586
587QRectF QgsMarkerSymbol::bounds( QPointF point, QgsRenderContext &context, const QgsFeature &feature ) const
588{
589 QgsSymbolRenderContext symbolContext( context, Qgis::RenderUnit::Unknown, mOpacity, false, renderHints(), &feature, feature.fields() );
590
591 QRectF bound;
592 const auto constMLayers = mLayers;
593 for ( QgsSymbolLayer *layer : constMLayers )
594 {
595 if ( layer->type() == Qgis::SymbolType::Marker )
596 {
597 if ( !layer->enabled()
598 || ( layer->dataDefinedProperties().hasActiveProperties() && !layer->dataDefinedProperties().valueAsBool( QgsSymbolLayer::Property::LayerEnabled, context.expressionContext(), true ) ) )
599 continue;
600
602 if ( bound.isNull() )
603 bound = symbolLayer->bounds( point, symbolContext );
604 else
605 bound = bound.united( symbolLayer->bounds( point, symbolContext ) );
606 }
607 }
608 return bound;
609}
610
612{
613 QgsMarkerSymbol *cloneSymbol = new QgsMarkerSymbol( cloneLayers() );
614 cloneSymbol->copyCommonProperties( this );
615 return cloneSymbol;
616}
Provides global constants and enumerations for use throughout the application.
Definition qgis.h:56
@ ExcludeSymbolBuffers
Do not render symbol buffers.
Definition qgis.h:773
ScaleMethod
Scale methods.
Definition qgis.h:624
@ Point
Points.
Definition qgis.h:359
JoinStyle
Join styles for buffers.
Definition qgis.h:2121
@ Bevel
Use beveled joins.
Definition qgis.h:2124
@ Round
Use rounded joins.
Definition qgis.h:2122
@ Miter
Use mitered joins.
Definition qgis.h:2123
RenderUnit
Rendering size units.
Definition qgis.h:5183
@ Unknown
Mixed or unknown units.
Definition qgis.h:5190
@ Round
Round cap.
Definition qgis.h:2109
@ Marker
Marker symbol.
Definition qgis.h:611
@ Fill
Fill symbol.
Definition qgis.h:613
virtual QgsAbstractGeometry * clone() const =0
Clones the geometry by performing a deep copy.
double valueAsDouble(int key, const QgsExpressionContext &context, double defaultValue=0.0, bool *ok=nullptr) const
Calculates the current value of the property with the specified key and interprets it as a double.
Manages painter saving and restoring required for effect drawing.
The feature class encapsulates a single feature including its unique ID, geometry and a list of field...
Definition qgsfeature.h:58
QgsFields fields
Definition qgsfeature.h:68
A symbol layer subclass which alters rendered feature shapes through the use of QGIS expressions.
Qgis::SymbolType symbolType() const
Access the symbol type.
QgsSymbol * subSymbol() override
Returns the symbol's sub symbol, if present.
A paint device which converts everything renderer to a QgsGeometry representation of the rendered sha...
const QgsAbstractGeometry & geometry() const
Returns the rendered geometry.
A geometry is the spatial representation of a feature.
QgsGeometry buffer(double distance, int segments) const
Returns a buffer region around this geometry having the given width and with a specified number of se...
Struct for storing maximum and minimum scales for measurements in map units.
Abstract base class for marker symbol layers.
virtual void setSize(double size)
Sets the symbol size.
QPointF offset() const
Returns the marker's offset, which is the horizontal and vertical displacement which the rendered mar...
void setAngle(double angle)
Sets the rotation angle for the marker.
Qgis::ScaleMethod scaleMethod() const
Returns the method to use for scaling the marker's size.
const QgsMapUnitScale & sizeMapUnitScale() const
Returns the map unit scale for the symbol's size.
void setOffset(QPointF offset)
Sets the marker's offset, which is the horizontal and vertical displacement which the rendered marker...
void setSizeMapUnitScale(const QgsMapUnitScale &scale)
Sets the map unit scale for the symbol's size.
void setLineAngle(double lineAngle)
Sets the line angle modification for the symbol's angle.
double size() const
Returns the symbol size.
void setScaleMethod(Qgis::ScaleMethod scaleMethod)
Sets the method to use for scaling the marker's size.
Qgis::RenderUnit sizeUnit() const
Returns the units for the symbol's size.
void setSizeUnit(Qgis::RenderUnit unit)
Sets the units for the symbol's size.
double angle() const
Returns the rotation angle for the marker, in degrees clockwise from north.
void setScaleMethod(Qgis::ScaleMethod scaleMethod) const
Sets the method to use for scaling the marker's size.
void setAngle(double symbolAngle) const
Sets the angle for the whole symbol.
void setSize(double size) const
Sets the size for the whole symbol.
QgsProperty dataDefinedAngle() const
Returns data defined angle for whole symbol (including all symbol layers).
static std::unique_ptr< QgsMarkerSymbol > createSimple(const QVariantMap &properties)
Create a marker symbol with one symbol layer: SimpleMarker with specified properties.
QgsMarkerSymbol(const QgsSymbolLayerList &layers=QgsSymbolLayerList())
Constructor for QgsMarkerSymbol, with the specified list of initial symbol layers.
double size() const
Returns the estimated size for the whole symbol, which is the maximum size of all marker symbol layer...
double angle() const
Returns the marker angle for the whole symbol.
QgsMapUnitScale sizeMapUnitScale() const
Returns the size map unit scale for the whole symbol.
void setLineAngle(double lineAngle) const
Sets the line angle modification for the symbol's angle.
QgsProperty dataDefinedSize() const
Returns data defined size for whole symbol (including all symbol layers).
void setDataDefinedSize(const QgsProperty &property) const
Set data defined size for whole symbol (including all symbol layers).
QgsMarkerSymbol * clone() const override
Returns a deep copy of this symbol.
void setSizeMapUnitScale(const QgsMapUnitScale &scale) const
Sets the size map unit scale for the whole symbol (including all symbol layers).
Qgis::ScaleMethod scaleMethod() const
Returns the method to use for scaling the marker's size.
void renderPoint(QPointF point, const QgsFeature *f, QgsRenderContext &context, int layer=-1, bool selected=false)
Renders the symbol at the specified point, using the given render context.
Qgis::RenderUnit sizeUnit() const
Returns the size units for the whole symbol (including all symbol layers).
void setDataDefinedAngle(const QgsProperty &property)
Set data defined angle for whole symbol (including all symbol layers).
QRectF bounds(QPointF point, QgsRenderContext &context, const QgsFeature &feature=QgsFeature()) const
Returns the approximate bounding box of the marker symbol, which includes the bounding box of all sym...
void setSizeUnit(Qgis::RenderUnit unit) const
Sets the size units for the whole symbol (including all symbol layers).
Base class for visual effects which can be applied to QPicture drawings.
bool enabled() const
Returns whether the effect is enabled.
static void drawPicture(QPainter *painter, const QPointF &point, const QPicture &picture)
Draws a picture onto a painter, correctly applying workarounds to avoid issues with incorrect scaling...
bool isActive(int key) const final
Returns true if the collection contains an active property with the specified key.
bool hasActiveProperties() const final
Returns true if the collection has any active properties, or false if all properties within the colle...
QgsProperty property(int key) const final
Returns a matching property from the collection, if one exists.
A store for object 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 setPainter(QPainter *p)
Sets the destination QPainter for the render operation.
bool isSymbolLayerEnabled(const QgsSymbolLayer *layer) const
When rendering a map layer in a second pass (for selective masking), some symbol layers may be disabl...
bool renderingStopped() const
Returns true if the rendering operation has been stopped and any ongoing rendering should be canceled...
Simple marker symbol layer, consisting of a rendered shape with solid fill color and a stroke.
static QgsSymbolLayer * create(const QVariantMap &properties=QVariantMap())
Creates a new QgsSimpleMarkerSymbolLayer.
static QList< QList< QPolygonF > > toQPolygonF(const QgsGeometry &geometry, Qgis::SymbolType type)
Converts a geometry to a set of QPolygonF objects representing how the geometry should be drawn for a...
Abstract base class for symbol layers.
@ LayerEnabled
Whether symbol layer is enabled.
virtual void setDataDefinedProperty(Property key, const QgsProperty &property)
Sets a data defined property for the layer.
QgsPropertyCollection & dataDefinedProperties()
Returns a reference to the symbol layer's property collection, used for data defined overrides.
Encapsulates the context in which a symbol is being rendered.
Qgis::SymbolRenderHints renderHints() const
Returns the rendering hint flags for the symbol.
void setGeometryPartCount(int count)
Sets the part count of current geometry.
void setGeometryPartNum(int num)
Sets the part number of current geometry.
QgsRenderContext & renderContext()
Returns a reference to the context's render context.
void renderUsingLayer(QgsSymbolLayer *layer, QgsSymbolRenderContext &context, Qgis::GeometryType geometryType=Qgis::GeometryType::Unknown, const QPolygonF *points=nullptr, const QVector< QPolygonF > *rings=nullptr)
Renders a context using a particular symbol layer without passing in a geometry.
QgsSymbolLayerList cloneLayers() const
Retrieve a cloned list of all layers that make up this symbol.
QgsSymbolRenderContext * symbolRenderContext()
Returns the symbol render context.
QgsSymbolLayer * symbolLayer(int layer)
Returns the symbol layer at the specified index.
Qgis::SymbolRenderHints renderHints() const
Returns the rendering hint flags for the symbol.
void copyCommonProperties(const QgsSymbol *other)
Copies common properties from an other symbol to this symbol.
QgsPropertyCollection & dataDefinedProperties()
Returns a reference to the symbol's property collection, used for data defined overrides.
Definition qgssymbol.h:814
qreal mOpacity
Symbol opacity (in the range 0 - 1).
Definition qgssymbol.h:1028
qreal opacity() const
Returns the opacity for the symbol.
Definition qgssymbol.h:659
std::unique_ptr< QgsSymbolBufferSettings > mBufferSettings
Definition qgssymbol.h:1042
QgsSymbolLayerList mLayers
Definition qgssymbol.h:1022
Q_DECL_DEPRECATED const QgsVectorLayer * layer() const
QgsSymbol(Qgis::SymbolType type, const QgsSymbolLayerList &layers)
Constructor for a QgsSymbol of the specified type.
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference).
Definition qgis.h:6607
QList< QgsSymbolLayer * > QgsSymbolLayerList
Definition qgssymbol.h:30
#define DEFAULT_SCALE_METHOD