Branch data Line data Source code
1 : : /***************************************************************************
2 : : qgssymbol.h
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 : : #ifndef QGSSYMBOL_H
17 : : #define QGSSYMBOL_H
18 : :
19 : : #include "qgis_core.h"
20 : : #include "qgis.h"
21 : : #include <QList>
22 : : #include <QMap>
23 : : #include "qgsmapunitscale.h"
24 : : #include "qgsfields.h"
25 : : #include "qgsrendercontext.h"
26 : : #include "qgsproperty.h"
27 : : #include "qgssymbollayerreference.h"
28 : : #include "qgspropertycollection.h"
29 : : #include "qgswkbtypes.h"
30 : :
31 : : class QColor;
32 : : class QImage;
33 : : class QPainter;
34 : : class QSize;
35 : : class QPointF;
36 : : class QPolygonF;
37 : : class QDomDocument;
38 : : class QDomElement;
39 : :
40 : : class QgsFields;
41 : : class QgsSymbolLayer;
42 : : class QgsRenderContext;
43 : : class QgsVectorLayer;
44 : : class QgsPaintEffect;
45 : : class QgsMarkerSymbolLayer;
46 : : class QgsLineSymbolLayer;
47 : : class QgsFillSymbolLayer;
48 : : class QgsSymbolRenderContext;
49 : : class QgsFeature;
50 : : class QgsFeatureRenderer;
51 : : class QgsCurve;
52 : : class QgsPolygon;
53 : : class QgsExpressionContext;
54 : : class QgsPoint;
55 : : class QgsLegendPatchShape;
56 : :
57 : : typedef QList<QgsSymbolLayer *> QgsSymbolLayerList;
58 : :
59 : : /**
60 : : * \ingroup core
61 : : * \class QgsSymbol
62 : : *
63 : : * \brief Abstract base class for all rendered symbols.
64 : : */
65 : : class CORE_EXPORT QgsSymbol
66 : : {
67 : :
68 : : #ifdef SIP_RUN
69 : : SIP_CONVERT_TO_SUBCLASS_CODE
70 : : switch ( sipCpp->type() )
71 : : {
72 : : case QgsSymbol::Marker: sipType = sipType_QgsMarkerSymbol; break;
73 : : case QgsSymbol::Line: sipType = sipType_QgsLineSymbol; break;
74 : : case QgsSymbol::Fill: sipType = sipType_QgsFillSymbol; break;
75 : : default: sipType = 0; break;
76 : : }
77 : : SIP_END
78 : : #endif
79 : :
80 : : friend class QgsFeatureRenderer;
81 : :
82 : : public:
83 : :
84 : : /**
85 : : * Type of the symbol
86 : : */
87 : : enum SymbolType
88 : : {
89 : : Marker, //!< Marker symbol
90 : : Line, //!< Line symbol
91 : : Fill, //!< Fill symbol
92 : : Hybrid //!< Hybrid symbol
93 : : };
94 : :
95 : : /**
96 : : * Returns a translated string version of the specified symbol \a type.
97 : : *
98 : : * \since QGIS 3.20
99 : : */
100 : : static QString symbolTypeToString( SymbolType type );
101 : :
102 : : /**
103 : : * Returns the default symbol type required for the specified geometry \a type.
104 : : *
105 : : * \since QGIS 3.20
106 : : */
107 : : static SymbolType symbolTypeForGeometryType( QgsWkbTypes::GeometryType type );
108 : :
109 : : /**
110 : : * Scale method
111 : : */
112 : : enum ScaleMethod
113 : : {
114 : : ScaleArea, //!< Calculate scale by the area
115 : : ScaleDiameter //!< Calculate scale by the diameter
116 : : };
117 : :
118 : :
119 : : //! Flags controlling behavior of symbols during rendering
120 : : enum RenderHint
121 : : {
122 : : DynamicRotation = 2, //!< Rotation of symbol may be changed during rendering and symbol should not be cached
123 : : };
124 : : Q_DECLARE_FLAGS( RenderHints, RenderHint )
125 : :
126 : : /**
127 : : * Data definable properties.
128 : : * \since QGIS 3.18
129 : : */
130 : : enum Property
131 : : {
132 : : PropertyOpacity, //!< Opacity
133 : : };
134 : :
135 : : /**
136 : : * Returns the symbol property definitions.
137 : : * \since QGIS 3.18
138 : : */
139 : : static const QgsPropertiesDefinition &propertyDefinitions();
140 : :
141 : : virtual ~QgsSymbol();
142 : :
143 : : /**
144 : : * Returns a new default symbol for the specified geometry type.
145 : : *
146 : : * The caller takes ownership of the returned object.
147 : : */
148 : : static QgsSymbol *defaultSymbol( QgsWkbTypes::GeometryType geomType ) SIP_FACTORY;
149 : :
150 : : /**
151 : : * Returns the symbol's type.
152 : : */
153 : 2315 : SymbolType type() const { return mType; }
154 : :
155 : : // symbol layers handling
156 : :
157 : : /**
158 : : * Returns the list of symbol layers contained in the symbol.
159 : : * \returns symbol layers list
160 : : * \see symbolLayer
161 : : * \see symbolLayerCount
162 : : * \since QGIS 2.7
163 : : */
164 : 0 : QgsSymbolLayerList symbolLayers() { return mLayers; }
165 : :
166 : : #ifndef SIP_RUN
167 : :
168 : : /**
169 : : * Returns the symbol layer at the specified index
170 : : * \see symbolLayers
171 : : * \see symbolLayerCount
172 : : * \since QGIS 2.7
173 : : */
174 : : QgsSymbolLayer *symbolLayer( int layer );
175 : :
176 : : /**
177 : : * Returns the symbol layer at the specified index, const variant
178 : : * \see symbolLayers
179 : : * \see symbolLayerCount
180 : : * \since QGIS 3.12
181 : : */
182 : : const QgsSymbolLayer *symbolLayer( int layer ) const;
183 : : #else
184 : :
185 : : /**
186 : : * Returns the symbol layer at the specified index. An IndexError will be raised if no layer with the specified index exists.
187 : : *
188 : : * \see symbolLayers
189 : : * \see symbolLayerCount
190 : : * \since QGIS 2.7
191 : : */
192 : : SIP_PYOBJECT symbolLayer( int layer ) SIP_TYPEHINT( QgsSymbolLayer );
193 : : % MethodCode
194 : : const int count = sipCpp->symbolLayerCount();
195 : : if ( a0 < 0 || a0 >= count )
196 : : {
197 : : PyErr_SetString( PyExc_IndexError, QByteArray::number( a0 ) );
198 : : sipIsErr = 1;
199 : : }
200 : : else
201 : : {
202 : : sipRes = sipConvertFromType( sipCpp->symbolLayer( a0 ), sipType_QgsSymbolLayer, NULL );
203 : : }
204 : : % End
205 : : #endif
206 : :
207 : : /**
208 : : * Returns the total number of symbol layers contained in the symbol.
209 : : * \returns count of symbol layers
210 : : * \see symbolLayers
211 : : * \see symbolLayer
212 : : * \since QGIS 2.7
213 : : */
214 : 0 : int symbolLayerCount() const { return mLayers.count(); }
215 : :
216 : : #ifdef SIP_RUN
217 : :
218 : : /**
219 : : * Returns the number of symbol layers contained in the symbol.
220 : : */
221 : : int __len__() const;
222 : : % MethodCode
223 : : sipRes = sipCpp->symbolLayerCount();
224 : : % End
225 : :
226 : : //! Ensures that bool(obj) returns TRUE (otherwise __len__() would be used)
227 : : int __bool__() const;
228 : : % MethodCode
229 : : sipRes = true;
230 : : % End
231 : :
232 : : /**
233 : : * Returns the symbol layer at the specified ``index``. An IndexError will be raised if no layer with the specified ``index`` exists.
234 : : *
235 : : * Indexes can be less than 0, in which case they correspond to layers from the end of the symbol. E.g. an index of -1
236 : : * corresponds to the last layer in the symbol.
237 : : *
238 : : * \since QGIS 3.10
239 : : */
240 : : SIP_PYOBJECT __getitem__( int index ) SIP_TYPEHINT( QgsSymbolLayer );
241 : : % MethodCode
242 : : const int count = sipCpp->symbolLayerCount();
243 : : if ( a0 < -count || a0 >= count )
244 : : {
245 : : PyErr_SetString( PyExc_IndexError, QByteArray::number( a0 ) );
246 : : sipIsErr = 1;
247 : : }
248 : : else if ( a0 >= 0 )
249 : : {
250 : : return sipConvertFromType( sipCpp->symbolLayer( a0 ), sipType_QgsSymbolLayer, NULL );
251 : : }
252 : : else
253 : : {
254 : : return sipConvertFromType( sipCpp->symbolLayer( count + a0 ), sipType_QgsSymbolLayer, NULL );
255 : : }
256 : : % End
257 : :
258 : : /**
259 : : * Deletes the layer at the specified ``index``. A layer at the ``index`` must already exist or an IndexError will be raised.
260 : : *
261 : : * Indexes can be less than 0, in which case they correspond to layers from the end of the symbol. E.g. an index of -1
262 : : * corresponds to the last layer in the symbol.
263 : : *
264 : : * \since QGIS 3.10
265 : : */
266 : : void __delitem__( int index );
267 : : % MethodCode
268 : : const int count = sipCpp->symbolLayerCount();
269 : : if ( a0 >= 0 && a0 < count )
270 : : sipCpp->deleteSymbolLayer( a0 );
271 : : else if ( a0 < 0 && a0 >= -count )
272 : : sipCpp->deleteSymbolLayer( count + a0 );
273 : : else
274 : : {
275 : : PyErr_SetString( PyExc_IndexError, QByteArray::number( a0 ) );
276 : : sipIsErr = 1;
277 : : }
278 : : % End
279 : : #endif
280 : :
281 : : /**
282 : : * Inserts a symbol \a layer to specified \a index.
283 : : * Ownership of \a layer is transferred to the symbol.
284 : : * \param index The index at which the layer should be added
285 : : * \param layer The symbol layer to add
286 : : * \returns TRUE if the layer is added, FALSE if the index or the layer is bad
287 : : */
288 : : bool insertSymbolLayer( int index, QgsSymbolLayer *layer SIP_TRANSFER );
289 : :
290 : : /**
291 : : * Appends a symbol \a layer at the end of the current symbol layer list.
292 : : * Ownership of \a layer is transferred to the symbol.
293 : : * \returns TRUE if the layer was successfully added, FALSE if the layer is not compatible with the
294 : : * symbol's type().
295 : : */
296 : : bool appendSymbolLayer( QgsSymbolLayer *layer SIP_TRANSFER );
297 : :
298 : : /**
299 : : * Removes and deletes the symbol layer at the specified \a index.
300 : : */
301 : : bool deleteSymbolLayer( int index );
302 : :
303 : : /**
304 : : * Removes a symbol layer from the list and returns a pointer to it.
305 : : * Ownership of the layer is handed to the caller.
306 : : * \param index The index of the layer to remove
307 : : * \returns A pointer to the removed layer
308 : : */
309 : : QgsSymbolLayer *takeSymbolLayer( int index ) SIP_TRANSFERBACK;
310 : :
311 : : /**
312 : : * Deletes the current layer at the specified \a index and replaces it with \a layer.
313 : : * Ownership of \a layer is transferred to the symbol.
314 : : *
315 : : * Returns FALSE if \a layer is not compatible with the symbol's type(), or
316 : : * TRUE if the layer was successfully replaced.
317 : : */
318 : : bool changeSymbolLayer( int index, QgsSymbolLayer *layer SIP_TRANSFER );
319 : :
320 : : /**
321 : : * Begins the rendering process for the symbol. This must be called before renderFeature(),
322 : : * and should be followed by a call to stopRender().
323 : : * \param context render context which symbol will be drawn using
324 : : * \param fields fields for features to be rendered (usually the associated
325 : : * vector layer's fields). Required for correct calculation of data defined
326 : : * overrides.
327 : : * \see stopRender()
328 : : */
329 : : void startRender( QgsRenderContext &context, const QgsFields &fields = QgsFields() );
330 : :
331 : : /**
332 : : * Ends the rendering process. This should be called after rendering all desired features.
333 : : * \param context render context, must match the context specified when startRender()
334 : : * was called.
335 : : * \see startRender()
336 : : */
337 : : void stopRender( QgsRenderContext &context );
338 : :
339 : : /**
340 : : * Sets the \a color for the symbol.
341 : : *
342 : : * Calling this method sets the color for each individual symbol layer contained
343 : : * within the symbol to \a color.
344 : : *
345 : : * Locked symbol layers are skipped and are left unchanged.
346 : : *
347 : : * \see color()
348 : : */
349 : : void setColor( const QColor &color );
350 : :
351 : : /**
352 : : * Returns the symbol's color.
353 : : *
354 : : * For multi-layer symbols, this method returns the color of the first unlocked symbol
355 : : * layer.
356 : : *
357 : : * \see setColor()
358 : : */
359 : : QColor color() const;
360 : :
361 : : /**
362 : : * Draws an icon of the symbol that occupies an area given by \a size using the specified \a painter.
363 : : *
364 : : * Optionally a custom render context may be given in order to ensure that the preview icon exactly
365 : : * matches the settings from that context.
366 : : * \param painter destination painter
367 : : * \param size size of the icon
368 : : * \param customContext the context in which the rendering happens
369 : : * \param selected set to TRUE to render the symbol in a selected state
370 : : * \param expressionContext optional custom expression context
371 : : * \param patchShape optional patch shape to use for symbol preview. If not specified a default shape will be used instead.
372 : : *
373 : : * \see exportImage()
374 : : * \see asImage()
375 : : * \note Parameter selected added in QGIS 3.10
376 : : * \since QGIS 2.6
377 : : */
378 : : void drawPreviewIcon( QPainter *painter, QSize size, QgsRenderContext *customContext = nullptr, bool selected = false, const QgsExpressionContext *expressionContext = nullptr,
379 : : const QgsLegendPatchShape *patchShape = nullptr );
380 : :
381 : : /**
382 : : * Export the symbol as an image format, to the specified \a path and with the given \a size.
383 : : *
384 : : * If \a format is "SVG" then an SVG file will be created, otherwise a raster image of the
385 : : * specified format will be created.
386 : : *
387 : : * \see asImage()
388 : : * \see drawPreviewIcon()
389 : : */
390 : : void exportImage( const QString &path, const QString &format, QSize size );
391 : :
392 : : /**
393 : : * Returns an image of the symbol at the specified \a size.
394 : : *
395 : : * Optionally a custom render context may be given in order to ensure that the preview icon exactly
396 : : * matches the settings from that context.
397 : : *
398 : : * \see exportImage()
399 : : * \see drawPreviewIcon()
400 : : */
401 : : QImage asImage( QSize size, QgsRenderContext *customContext = nullptr );
402 : :
403 : : /**
404 : : * Flags for controlling how symbol preview images are generated.
405 : : *
406 : : * \since QGIS 3.16
407 : : */
408 : : enum PreviewFlag
409 : : {
410 : : FlagIncludeCrosshairsForMarkerSymbols = 1 << 0, //!< Include a crosshairs reference image in the background of marker symbol previews
411 : : };
412 : : Q_DECLARE_FLAGS( PreviewFlags, PreviewFlag )
413 : :
414 : : /**
415 : : * Returns a large (roughly 100x100 pixel) preview image for the symbol.
416 : : *
417 : : * \param expressionContext optional expression context, for evaluation of
418 : : * data defined symbol properties
419 : : * \param flags optional flags to control how preview image is generated
420 : : *
421 : : * \see asImage()
422 : : * \see drawPreviewIcon()
423 : : */
424 : : QImage bigSymbolPreviewImage( QgsExpressionContext *expressionContext = nullptr, QgsSymbol::PreviewFlags flags = QgsSymbol::FlagIncludeCrosshairsForMarkerSymbols );
425 : :
426 : : /**
427 : : * Returns a string dump of the symbol's properties.
428 : : */
429 : : QString dump() const;
430 : :
431 : : /**
432 : : * Returns a deep copy of this symbol.
433 : : *
434 : : * Ownership is transferred to the caller.
435 : : */
436 : : virtual QgsSymbol *clone() const = 0 SIP_FACTORY;
437 : :
438 : : /**
439 : : * Converts the symbol to a SLD representation.
440 : : */
441 : : void toSld( QDomDocument &doc, QDomElement &element, QVariantMap props ) const;
442 : :
443 : : /**
444 : : * Returns the units to use for sizes and widths within the symbol. Individual
445 : : * symbol layer definitions will interpret this in different ways, e.g., a marker symbol
446 : : * may use it to specify the units for the marker size, while a line symbol
447 : : * may use it to specify the units for the line width.
448 : : * \returns output unit, or QgsUnitTypes::RenderUnknownUnit if the symbol contains mixed units
449 : : * \see setOutputUnit()
450 : : */
451 : : QgsUnitTypes::RenderUnit outputUnit() const;
452 : :
453 : : /**
454 : : * Returns TRUE if the symbol has any components which use map unit based sizes.
455 : : *
456 : : * \since QGIS 3.18
457 : : */
458 : : bool usesMapUnits() const;
459 : :
460 : : /**
461 : : * Sets the units to use for sizes and widths within the symbol. Individual
462 : : * symbol definitions will interpret this in different ways, e.g., a marker symbol
463 : : * may use it to specify the units for the marker size, while a line symbol
464 : : * may use it to specify the units for the line width.
465 : : * \param unit output units
466 : : * \see outputUnit()
467 : : */
468 : : void setOutputUnit( QgsUnitTypes::RenderUnit unit );
469 : :
470 : : /**
471 : : * Returns the map unit scale for the symbol.
472 : : *
473 : : * If the symbol consists of multiple layers, the map unit scale is only
474 : : * returned if all layers have the same scale settings. If the settings differ,
475 : : * a default constructed map unit scale is returned.
476 : : *
477 : : * \see setMapUnitScale()
478 : : */
479 : : QgsMapUnitScale mapUnitScale() const;
480 : :
481 : : /**
482 : : * Sets the map unit \a scale for the symbol.
483 : : *
484 : : * Calling this method sets the scale for all symbol layers contained within the
485 : : * symbol.
486 : : *
487 : : * \see mapUnitScale()
488 : : */
489 : : void setMapUnitScale( const QgsMapUnitScale &scale );
490 : :
491 : : /**
492 : : * Returns the opacity for the symbol.
493 : : * \returns opacity value between 0 (fully transparent) and 1 (fully opaque)
494 : : * \see setOpacity()
495 : : */
496 : 0 : qreal opacity() const { return mOpacity; }
497 : :
498 : : /**
499 : : * Sets the \a opacity for the symbol.
500 : : * \param opacity opacity value between 0 (fully transparent) and 1 (fully opaque)
501 : : * \see opacity()
502 : : */
503 : 803 : void setOpacity( qreal opacity ) { mOpacity = opacity; }
504 : :
505 : : /**
506 : : * Sets rendering hint flags for the symbol.
507 : : * \see renderHints()
508 : : */
509 : 0 : void setRenderHints( RenderHints hints ) { mRenderHints = hints; }
510 : :
511 : : /**
512 : : * Returns the rendering hint flags for the symbol.
513 : : * \see setRenderHints()
514 : : */
515 : 0 : RenderHints renderHints() const { return mRenderHints; }
516 : :
517 : : /**
518 : : * Sets whether features drawn by the symbol should be clipped to the render context's
519 : : * extent. If this option is enabled then features which are partially outside the extent
520 : : * will be clipped. This speeds up rendering of the feature, but may have undesirable
521 : : * side effects for certain symbol types.
522 : : * \param clipFeaturesToExtent set to TRUE to enable clipping (defaults to TRUE)
523 : : * \see clipFeaturesToExtent
524 : : * \since QGIS 2.9
525 : : */
526 : 725 : void setClipFeaturesToExtent( bool clipFeaturesToExtent ) { mClipFeaturesToExtent = clipFeaturesToExtent; }
527 : :
528 : : /**
529 : : * Returns whether features drawn by the symbol will be clipped to the render context's
530 : : * extent. If this option is enabled then features which are partially outside the extent
531 : : * will be clipped. This speeds up rendering of the feature, but may have undesirable
532 : : * side effects for certain symbol types.
533 : : * \returns TRUE if features will be clipped
534 : : * \see setClipFeaturesToExtent
535 : : * \since QGIS 2.9
536 : : */
537 : 0 : bool clipFeaturesToExtent() const { return mClipFeaturesToExtent; }
538 : :
539 : : /**
540 : : * Sets whether polygon features drawn by the symbol should be reoriented to follow the
541 : : * standard right-hand-rule orientation, in which the area that is
542 : : * bounded by the polygon is to the right of the boundary. In particular, the exterior
543 : : * ring is oriented in a clockwise direction and the interior rings in a counter-clockwise
544 : : * direction.
545 : : * \see forceRHR()
546 : : * \since QGIS 3.6
547 : : */
548 : 725 : void setForceRHR( bool force ) { mForceRHR = force; }
549 : :
550 : : /**
551 : : * Returns TRUE if polygon features drawn by the symbol will be reoriented to follow the
552 : : * standard right-hand-rule orientation, in which the area that is
553 : : * bounded by the polygon is to the right of the boundary. In particular, the exterior
554 : : * ring is oriented in a clockwise direction and the interior rings in a counter-clockwise
555 : : * direction.
556 : : * \see setForceRHR()
557 : : * \since QGIS 3.6
558 : : */
559 : 0 : bool forceRHR() const { return mForceRHR; }
560 : :
561 : : /**
562 : : * Returns a list of attributes required to render this feature.
563 : : * This should include any attributes required by the symbology including
564 : : * the ones required by expressions.
565 : : */
566 : : QSet<QString> usedAttributes( const QgsRenderContext &context ) const;
567 : :
568 : : /**
569 : : * Sets a data defined property for the symbol. Any existing property with the same key
570 : : * will be overwritten.
571 : : * \see dataDefinedProperties()
572 : : * \see Property
573 : : * \since QGIS 3.18
574 : : */
575 : : void setDataDefinedProperty( Property key, const QgsProperty &property );
576 : :
577 : : /**
578 : : * Returns a reference to the symbol's property collection, used for data defined overrides.
579 : : * \see setDataDefinedProperties()
580 : : * \see Property
581 : : * \since QGIS 3.18
582 : : */
583 : 580 : QgsPropertyCollection &dataDefinedProperties() { return mDataDefinedProperties; }
584 : :
585 : : /**
586 : : * Returns a reference to the symbol's property collection, used for data defined overrides.
587 : : * \see setDataDefinedProperties()
588 : : * \since QGIS 3.18
589 : : */
590 : 0 : const QgsPropertyCollection &dataDefinedProperties() const { return mDataDefinedProperties; } SIP_SKIP
591 : :
592 : : /**
593 : : * Sets the symbol's property collection, used for data defined overrides.
594 : : * \param collection property collection. Existing properties will be replaced.
595 : : * \see dataDefinedProperties()
596 : : * \since QGIS 3.18
597 : : */
598 : 0 : void setDataDefinedProperties( const QgsPropertyCollection &collection ) { mDataDefinedProperties = collection; }
599 : :
600 : : /**
601 : : * Returns whether the symbol utilizes any data defined properties.
602 : : * \since QGIS 2.12
603 : : */
604 : : bool hasDataDefinedProperties() const;
605 : :
606 : : /**
607 : : * Returns TRUE if the symbol rendering can cause visible artifacts across a single feature
608 : : * when the feature is rendered as a series of adjacent map tiles each containing a portion of the feature's geometry.
609 : : *
610 : : * Internally this calls QgsSymbolLayer::canCauseArtifactsBetweenAdjacentTiles() for all symbol layers in the symbol
611 : : * and returns TRUE if any of the layers returned TRUE.
612 : : *
613 : : * \since QGIS 3.18
614 : : */
615 : : bool canCauseArtifactsBetweenAdjacentTiles() const;
616 : :
617 : : /**
618 : : * \note the layer will be NULLPTR after stopRender
619 : : * \deprecated Will be removed in QGIS 4.0
620 : : */
621 : : Q_DECL_DEPRECATED void setLayer( const QgsVectorLayer *layer ) SIP_DEPRECATED;
622 : :
623 : : /**
624 : : * \deprecated Will be removed in QGIS 4.0
625 : : */
626 : : Q_DECL_DEPRECATED const QgsVectorLayer *layer() const SIP_DEPRECATED;
627 : :
628 : : /**
629 : : * Render a feature. Before calling this the startRender() method should be called to initialize
630 : : * the rendering process. After rendering all features stopRender() must be called.
631 : : */
632 : : void renderFeature( const QgsFeature &feature, QgsRenderContext &context, int layer = -1, bool selected = false, bool drawVertexMarker = false, int currentVertexMarkerType = 0, double currentVertexMarkerSize = 0.0 ) SIP_THROW( QgsCsException );
633 : :
634 : : /**
635 : : * Returns the symbol render context. Only valid between startRender and stopRender calls.
636 : : *
637 : : * \returns The symbol render context
638 : : */
639 : : QgsSymbolRenderContext *symbolRenderContext();
640 : :
641 : : /**
642 : : * Called before symbol layers will be rendered for a particular \a feature.
643 : : *
644 : : * This is always followed by a call to stopFeatureRender() after the feature
645 : : * has been completely rendered (i.e. all parts have been rendered).
646 : : *
647 : : * Internally, this notifies all symbol layers which will be used via a call to
648 : : * QgsSymbolLayer::startFeatureRender().
649 : : *
650 : : * \since QGIS 3.20
651 : : */
652 : : void startFeatureRender( const QgsFeature &feature, QgsRenderContext &context, int layer = -1 );
653 : :
654 : : /**
655 : : * Called after symbol layers have been rendered for a particular \a feature.
656 : : *
657 : : * This is always preceded by a call to startFeatureRender() just before the feature
658 : : * will be rendered.
659 : : *
660 : : * Internally, this notifies all symbol layers which were used via a call to
661 : : * QgsSymbolLayer::stopFeatureRender().
662 : : *
663 : : * \since QGIS 3.20
664 : : */
665 : : void stopFeatureRender( const QgsFeature &feature, QgsRenderContext &context, int layer = -1 );
666 : :
667 : : protected:
668 : : QgsSymbol( SymbolType type, const QgsSymbolLayerList &layers SIP_TRANSFER ); // can't be instantiated
669 : :
670 : : /**
671 : : * Creates a point in screen coordinates from a QgsPoint in map coordinates
672 : : */
673 : 0 : static inline QPointF _getPoint( QgsRenderContext &context, const QgsPoint &point )
674 : : {
675 : 0 : QPointF pt;
676 : 0 : if ( context.coordinateTransform().isValid() )
677 : : {
678 : 0 : double x = point.x();
679 : 0 : double y = point.y();
680 : 0 : double z = 0.0;
681 : 0 : context.coordinateTransform().transformInPlace( x, y, z );
682 : 0 : pt = QPointF( x, y );
683 : :
684 : 0 : }
685 : : else
686 : 0 : pt = point.toQPointF();
687 : :
688 : 0 : context.mapToPixel().transformInPlace( pt.rx(), pt.ry() );
689 : 0 : return pt;
690 : 0 : }
691 : :
692 : : /**
693 : : * Creates a line string in screen coordinates from a QgsCurve in map coordinates
694 : : */
695 : : static QPolygonF _getLineString( QgsRenderContext &context, const QgsCurve &curve, bool clipToExtent = true );
696 : :
697 : : /**
698 : : * Creates a polygon ring in screen coordinates from a QgsCurve in map coordinates.
699 : : *
700 : : * If \a correctRingOrientation is TRUE then the ring will be oriented to match standard ring orientation, e.g.
701 : : * clockwise for exterior rings and counter-clockwise for interior rings.
702 : : */
703 : : static QPolygonF _getPolygonRing( QgsRenderContext &context, const QgsCurve &curve, bool clipToExtent, bool isExteriorRing = false, bool correctRingOrientation = false );
704 : :
705 : : /**
706 : : * Creates a polygon in screen coordinates from a QgsPolygonXYin map coordinates
707 : : *
708 : : * If \a correctRingOrientation is TRUE then the ring will be oriented to match standard ring orientation, e.g.
709 : : * clockwise for exterior rings and counter-clockwise for interior rings.
710 : : *
711 : : */
712 : : static void _getPolygon( QPolygonF &pts, QVector<QPolygonF> &holes, QgsRenderContext &context, const QgsPolygon &polygon, bool clipToExtent = true, bool correctRingOrientation = false );
713 : :
714 : : /**
715 : : * Retrieve a cloned list of all layers that make up this symbol.
716 : : * Ownership is transferred to the caller.
717 : : */
718 : : QgsSymbolLayerList cloneLayers() const SIP_FACTORY;
719 : :
720 : : /**
721 : : * Renders a context using a particular symbol layer without passing in a
722 : : * geometry. This is used as fallback, if the symbol being rendered is not
723 : : * compatible with the specified layer. In such a case, this method can be
724 : : * called and will call the layer's rendering method anyway but the
725 : : * geometry passed to the layer will be empty.
726 : : * This is required for layers that generate their own geometry from other
727 : : * information in the rendering context.
728 : : */
729 : : void renderUsingLayer( QgsSymbolLayer *layer, QgsSymbolRenderContext &context );
730 : :
731 : : /**
732 : : * Render editing vertex marker at specified point
733 : : * \since QGIS 2.16
734 : : */
735 : : void renderVertexMarker( QPointF pt, QgsRenderContext &context, int currentVertexMarkerType, double currentVertexMarkerSize );
736 : :
737 : : SymbolType mType;
738 : : QgsSymbolLayerList mLayers;
739 : :
740 : : //! Symbol opacity (in the range 0 - 1)
741 : : qreal mOpacity = 1.0;
742 : :
743 : : RenderHints mRenderHints;
744 : : bool mClipFeaturesToExtent = true;
745 : : bool mForceRHR = false;
746 : :
747 : : Q_DECL_DEPRECATED const QgsVectorLayer *mLayer = nullptr; //current vectorlayer
748 : :
749 : : private:
750 : : #ifdef SIP_RUN
751 : : QgsSymbol( const QgsSymbol & );
752 : : #endif
753 : :
754 : : static void initPropertyDefinitions();
755 : :
756 : : //! Property definitions
757 : : static QgsPropertiesDefinition sPropertyDefinitions;
758 : :
759 : : /**
760 : : * TRUE if render has already been started - guards against multiple calls to
761 : : * startRender() (usually a result of not cloning a shared symbol instance before rendering).
762 : : */
763 : : bool mStarted = false;
764 : :
765 : : //! Initialized in startRender, destroyed in stopRender
766 : : std::unique_ptr< QgsSymbolRenderContext > mSymbolRenderContext;
767 : :
768 : : QgsPropertyCollection mDataDefinedProperties;
769 : :
770 : : Q_DISABLE_COPY( QgsSymbol )
771 : :
772 : : };
773 : :
774 : : Q_DECLARE_OPERATORS_FOR_FLAGS( QgsSymbol::RenderHints )
775 : :
776 : : ///////////////////////
777 : :
778 : : /**
779 : : * \ingroup core
780 : : * \class QgsSymbolRenderContext
781 : : */
782 : : class CORE_EXPORT QgsSymbolRenderContext
783 : : {
784 : : public:
785 : :
786 : : //TODO QGIS 4.0 - remove mapUnitScale and renderunit
787 : :
788 : : /**
789 : : * Constructor for QgsSymbolRenderContext
790 : : * \param c
791 : : * \param u
792 : : * \param opacity value between 0 (fully transparent) and 1 (fully opaque)
793 : : * \param selected set to TRUE if symbol should be drawn in a "selected" state
794 : : * \param renderHints flags controlling rendering behavior
795 : : * \param f
796 : : * \param fields
797 : : * \param mapUnitScale
798 : : */
799 : : QgsSymbolRenderContext( QgsRenderContext &c, QgsUnitTypes::RenderUnit u, qreal opacity = 1.0, bool selected = false, QgsSymbol::RenderHints renderHints = QgsSymbol::RenderHints(), const QgsFeature *f = nullptr, const QgsFields &fields = QgsFields(), const QgsMapUnitScale &mapUnitScale = QgsMapUnitScale() );
800 : :
801 : : ~QgsSymbolRenderContext();
802 : :
803 : : //! QgsSymbolRenderContext cannot be copied.
804 : : QgsSymbolRenderContext( const QgsSymbolRenderContext &rh ) = delete;
805 : :
806 : : /**
807 : : * Returns a reference to the context's render context.
808 : : */
809 : 0 : QgsRenderContext &renderContext() { return mRenderContext; }
810 : :
811 : : /**
812 : : * Returns a reference to the context's render context.
813 : : * \note Not available in Python bindings.
814 : : */
815 : 0 : const QgsRenderContext &renderContext() const { return mRenderContext; } SIP_SKIP
816 : :
817 : : /**
818 : : * Sets the original value variable value for data defined symbology
819 : : * \param value value for original value variable. This usually represents the symbol property value
820 : : * before any data defined overrides have been applied.
821 : : * \since QGIS 2.12
822 : : */
823 : : void setOriginalValueVariable( const QVariant &value );
824 : :
825 : : /**
826 : : * Returns the output unit for the context.
827 : : * \deprecated No longer used and will be removed in QGIS 4.0
828 : : */
829 : : Q_DECL_DEPRECATED QgsUnitTypes::RenderUnit outputUnit() const SIP_DEPRECATED { return mOutputUnit; }
830 : :
831 : : /**
832 : : * Sets the output unit for the context.
833 : : * \deprecated No longer used and will be removed in QGIS 4.0
834 : : */
835 : : Q_DECL_DEPRECATED void setOutputUnit( QgsUnitTypes::RenderUnit u ) SIP_DEPRECATED { mOutputUnit = u; }
836 : :
837 : : /**
838 : : * \deprecated Will be removed in QGIS 4.0
839 : : */
840 : : Q_DECL_DEPRECATED QgsMapUnitScale mapUnitScale() const SIP_DEPRECATED { return mMapUnitScale; }
841 : :
842 : : /**
843 : : * \deprecated Will be removed in QGIS 4.0
844 : : */
845 : : Q_DECL_DEPRECATED void setMapUnitScale( const QgsMapUnitScale &scale ) SIP_DEPRECATED { mMapUnitScale = scale; }
846 : :
847 : : /**
848 : : * Returns the opacity for the symbol.
849 : : * \returns opacity value between 0 (fully transparent) and 1 (fully opaque)
850 : : * \see setOpacity()
851 : : */
852 : 0 : qreal opacity() const { return mOpacity; }
853 : :
854 : : /**
855 : : * Sets the \a opacity for the symbol.
856 : : * \param opacity opacity value between 0 (fully transparent) and 1 (fully opaque)
857 : : * \see opacity()
858 : : */
859 : : void setOpacity( qreal opacity ) { mOpacity = opacity; }
860 : :
861 : : /**
862 : : * Returns TRUE if symbols should be rendered using the selected symbol coloring and style.
863 : : * \see setSelected()
864 : : */
865 : 0 : bool selected() const { return mSelected; }
866 : :
867 : : /**
868 : : * Sets whether symbols should be rendered using the selected symbol coloring and style.
869 : : * \see selected()
870 : : */
871 : 0 : void setSelected( bool selected ) { mSelected = selected; }
872 : :
873 : : /**
874 : : * Returns the rendering hint flags for the symbol.
875 : : * \see setRenderHints()
876 : : */
877 : 0 : QgsSymbol::RenderHints renderHints() const { return mRenderHints; }
878 : :
879 : : /**
880 : : * Sets rendering hint flags for the symbol.
881 : : * \see renderHints()
882 : : */
883 : : void setRenderHints( QgsSymbol::RenderHints hints ) { mRenderHints = hints; }
884 : :
885 : 0 : void setFeature( const QgsFeature *f ) { mFeature = f; }
886 : :
887 : : /**
888 : : * Returns the current feature being rendered. This may be NULLPTR.
889 : : */
890 : 0 : const QgsFeature *feature() const { return mFeature; }
891 : :
892 : : /**
893 : : * Sets the geometry type for the original feature geometry being rendered.
894 : : * \see originalGeometryType()
895 : : * \since QGIS 3.0
896 : : */
897 : 0 : void setOriginalGeometryType( QgsWkbTypes::GeometryType type ) { mOriginalGeometryType = type; }
898 : :
899 : : /**
900 : : * Returns the geometry type for the original feature geometry being rendered. This can be
901 : : * useful if symbol layers alter their appearance based on geometry type - eg offsetting a
902 : : * simple line style will look different if the simple line is rendering a polygon feature
903 : : * (a closed buffer) vs a line feature (an unclosed offset line).
904 : : * \see originalGeometryType()
905 : : * \since QGIS 3.0
906 : : */
907 : 0 : QgsWkbTypes::GeometryType originalGeometryType() const { return mOriginalGeometryType; }
908 : :
909 : : /**
910 : : * Fields of the layer. Currently only available in startRender() calls
911 : : * to allow symbols with data-defined properties prepare the expressions
912 : : * (other times fields() returns an empty QgsFields object).
913 : : * \since QGIS 2.4
914 : : */
915 : 0 : QgsFields fields() const { return mFields; }
916 : :
917 : : /**
918 : : * Part count of current geometry
919 : : * \since QGIS 2.16
920 : : */
921 : 0 : int geometryPartCount() const { return mGeometryPartCount; }
922 : :
923 : : /**
924 : : * Sets the part count of current geometry
925 : : * \since QGIS 2.16
926 : : */
927 : 0 : void setGeometryPartCount( int count ) { mGeometryPartCount = count; }
928 : :
929 : : /**
930 : : * Part number of current geometry
931 : : * \since QGIS 2.16
932 : : */
933 : 0 : int geometryPartNum() const { return mGeometryPartNum; }
934 : :
935 : : /**
936 : : * Sets the part number of current geometry
937 : : * \since QGIS 2.16
938 : : */
939 : 0 : void setGeometryPartNum( int num ) { mGeometryPartNum = num; }
940 : :
941 : : /**
942 : : * \deprecated Use the size conversion methods in QgsRenderContext instead.
943 : : */
944 : : Q_DECL_DEPRECATED double outputLineWidth( double width ) const SIP_DEPRECATED;
945 : :
946 : : /**
947 : : * \deprecated Use the size conversion methods in QgsRenderContext instead.
948 : : */
949 : : Q_DECL_DEPRECATED double outputPixelSize( double size ) const SIP_DEPRECATED;
950 : :
951 : : // workaround for sip 4.7. Don't use assignment - will fail with assertion error
952 : : QgsSymbolRenderContext &operator=( const QgsSymbolRenderContext & );
953 : :
954 : : /**
955 : : * This scope is always available when a symbol of this type is being rendered.
956 : : *
957 : : * \returns An expression scope for details about this symbol
958 : : */
959 : : QgsExpressionContextScope *expressionContextScope();
960 : :
961 : : /**
962 : : * Set an expression scope for this symbol.
963 : : *
964 : : * Will take ownership.
965 : : *
966 : : * \param contextScope An expression scope for details about this symbol
967 : : */
968 : : void setExpressionContextScope( QgsExpressionContextScope *contextScope SIP_TRANSFER );
969 : :
970 : : /**
971 : : * Returns the symbol patch shape, to use if rendering symbol preview icons.
972 : : *
973 : : * \see setPatchShape()
974 : : * \since QGIS 3.14
975 : : */
976 : : const QgsLegendPatchShape *patchShape() const;
977 : :
978 : : /**
979 : : * Sets the symbol patch \a shape, to use if rendering symbol preview icons.
980 : : *
981 : : * \see patchShape()
982 : : * \since QGIS 3.14
983 : : */
984 : : void setPatchShape( const QgsLegendPatchShape &shape );
985 : :
986 : : private:
987 : :
988 : : #ifdef SIP_RUN
989 : : QgsSymbolRenderContext( const QgsSymbolRenderContext &rh ) SIP_FORCE;
990 : : #endif
991 : :
992 : : QgsRenderContext &mRenderContext;
993 : : std::unique_ptr< QgsExpressionContextScope > mExpressionContextScope;
994 : : QgsUnitTypes::RenderUnit mOutputUnit;
995 : : QgsMapUnitScale mMapUnitScale;
996 : : qreal mOpacity = 1.0;
997 : : bool mSelected;
998 : : QgsSymbol::RenderHints mRenderHints;
999 : : const QgsFeature *mFeature; //current feature
1000 : : QgsFields mFields;
1001 : : int mGeometryPartCount;
1002 : : int mGeometryPartNum;
1003 : : QgsWkbTypes::GeometryType mOriginalGeometryType = QgsWkbTypes::UnknownGeometry;
1004 : : std::unique_ptr< QgsLegendPatchShape > mPatchShape;
1005 : : };
1006 : :
1007 : :
1008 : :
1009 : : //////////////////////
1010 : :
1011 : :
1012 : : /**
1013 : : * \ingroup core
1014 : : * \class QgsMarkerSymbol
1015 : : *
1016 : : * \brief A marker symbol type, for rendering Point and MultiPoint geometries.
1017 : : */
1018 : 462 : class CORE_EXPORT QgsMarkerSymbol : public QgsSymbol
1019 : : {
1020 : : public:
1021 : :
1022 : : /**
1023 : : * Create a marker symbol with one symbol layer: SimpleMarker with specified properties.
1024 : : * This is a convenience method for easier creation of marker symbols.
1025 : : */
1026 : : static QgsMarkerSymbol *createSimple( const QVariantMap &properties ) SIP_FACTORY;
1027 : :
1028 : : /**
1029 : : * Constructor for QgsMarkerSymbol, with the specified list of initial symbol \a layers.
1030 : : *
1031 : : * Ownership of the \a layers are transferred to the symbol.
1032 : : */
1033 : : QgsMarkerSymbol( const QgsSymbolLayerList &layers SIP_TRANSFER = QgsSymbolLayerList() );
1034 : :
1035 : : /**
1036 : : * Sets the angle for the whole symbol. Individual symbol layer sizes
1037 : : * will be rotated to maintain their current relative angle to the whole symbol angle.
1038 : : * \param symbolAngle new symbol angle
1039 : : * \see angle()
1040 : : */
1041 : : void setAngle( double symbolAngle );
1042 : :
1043 : : /**
1044 : : * Returns the marker angle for the whole symbol. Note that for symbols with
1045 : : * multiple symbol layers, this will correspond just to the angle of
1046 : : * the first symbol layer.
1047 : : * \see setAngle()
1048 : : * \since QGIS 2.16
1049 : : */
1050 : : double angle() const;
1051 : :
1052 : : /**
1053 : : * Set data defined angle for whole symbol (including all symbol layers).
1054 : : * \see dataDefinedAngle()
1055 : : * \since QGIS 3.0
1056 : : */
1057 : : void setDataDefinedAngle( const QgsProperty &property );
1058 : :
1059 : : /**
1060 : : * Returns data defined angle for whole symbol (including all symbol layers).
1061 : : * \returns data defined angle, or invalid property if angle is not set
1062 : : * at the marker level.
1063 : : * \see setDataDefinedAngle()
1064 : : * \since QGIS 3.0
1065 : : */
1066 : : QgsProperty dataDefinedAngle() const;
1067 : :
1068 : : /**
1069 : : * Sets the line angle modification for the symbol's angle. This angle is added to
1070 : : * the marker's rotation and data defined rotation before rendering the symbol, and
1071 : : * is usually used for orienting symbols to match a line's angle.
1072 : : * \param lineAngle Angle in degrees, valid values are between 0 and 360
1073 : : * \since QGIS 2.9
1074 : : */
1075 : : void setLineAngle( double lineAngle );
1076 : :
1077 : : /**
1078 : : * Sets the size for the whole symbol. Individual symbol layer sizes
1079 : : * will be scaled to maintain their current relative size to the whole symbol size.
1080 : : * \param size new symbol size
1081 : : * \see size()
1082 : : * \see setSizeUnit()
1083 : : * \see setSizeMapUnitScale()
1084 : : */
1085 : : void setSize( double size );
1086 : :
1087 : : /**
1088 : : * Returns the estimated size for the whole symbol, which is the maximum size of
1089 : : * all marker symbol layers in the symbol.
1090 : : *
1091 : : * \warning This returned value is inaccurate if the symbol consists of multiple
1092 : : * symbol layers with different size units. Use the overload accepting a QgsRenderContext
1093 : : * argument instead for accurate sizes in this case.
1094 : : *
1095 : : * \see setSize()
1096 : : * \see sizeUnit()
1097 : : * \see sizeMapUnitScale()
1098 : : */
1099 : : double size() const;
1100 : :
1101 : : /**
1102 : : * Returns the symbol size, in painter units. This is the maximum size of
1103 : : * all marker symbol layers in the symbol.
1104 : : *
1105 : : * This method returns an accurate size by calculating the actual rendered
1106 : : * size of each symbol layer using the provided render \a context.
1107 : : *
1108 : : * \see setSize()
1109 : : * \see sizeUnit()
1110 : : * \see sizeMapUnitScale()
1111 : : *
1112 : : * \since QGIS 3.4.5
1113 : : */
1114 : : double size( const QgsRenderContext &context ) const;
1115 : :
1116 : : /**
1117 : : * Sets the size units for the whole symbol (including all symbol layers).
1118 : : * \param unit size units
1119 : : * \see sizeUnit()
1120 : : * \see setSizeMapUnitScale()
1121 : : * \see setSize()
1122 : : * \since QGIS 2.16
1123 : : */
1124 : : void setSizeUnit( QgsUnitTypes::RenderUnit unit );
1125 : :
1126 : : /**
1127 : : * Returns the size units for the whole symbol (including all symbol layers).
1128 : : * \returns size units, or mixed units if symbol layers have different units
1129 : : * \see setSizeUnit()
1130 : : * \see sizeMapUnitScale()
1131 : : * \see size()
1132 : : * \since QGIS 2.16
1133 : : */
1134 : : QgsUnitTypes::RenderUnit sizeUnit() const;
1135 : :
1136 : : /**
1137 : : * Sets the size map unit scale for the whole symbol (including all symbol layers).
1138 : : * \param scale map unit scale
1139 : : * \see sizeMapUnitScale()
1140 : : * \see setSizeUnit()
1141 : : * \see setSize()
1142 : : * \since QGIS 2.16
1143 : : */
1144 : : void setSizeMapUnitScale( const QgsMapUnitScale &scale );
1145 : :
1146 : : /**
1147 : : * Returns the size map unit scale for the whole symbol. Note that for symbols with
1148 : : * multiple symbol layers, this will correspond just to the map unit scale
1149 : : * for the first symbol layer.
1150 : : * \see setSizeMapUnitScale()
1151 : : * \see sizeUnit()
1152 : : * \see size()
1153 : : * \since QGIS 2.16
1154 : : */
1155 : : QgsMapUnitScale sizeMapUnitScale() const;
1156 : :
1157 : : /**
1158 : : * Set data defined size for whole symbol (including all symbol layers).
1159 : : * \see dataDefinedSize()
1160 : : * \since QGIS 3.0
1161 : : */
1162 : : void setDataDefinedSize( const QgsProperty &property );
1163 : :
1164 : : /**
1165 : : * Returns data defined size for whole symbol (including all symbol layers).
1166 : : * \returns data defined size, or invalid property if size is not set
1167 : : * at the marker level.
1168 : : * \see setDataDefinedSize
1169 : : * \since QGIS 3.0
1170 : : */
1171 : : QgsProperty dataDefinedSize() const;
1172 : :
1173 : : void setScaleMethod( QgsSymbol::ScaleMethod scaleMethod );
1174 : : ScaleMethod scaleMethod();
1175 : :
1176 : : /**
1177 : : * Renders the symbol at the specified \a point, using the given render \a context.
1178 : : *
1179 : : * The \a f argument is used to pass the feature currently being rendered (when available).
1180 : : *
1181 : : * If only a single symbol layer from the symbol should be rendered, it should be specified
1182 : : * in the \a layer argument. A \a layer of -1 indicates that all symbol layers should be
1183 : : * rendered.
1184 : : *
1185 : : * If \a selected is TRUE then the symbol will be drawn using the "selected feature"
1186 : : * style and colors instead of the symbol's normal style.
1187 : : */
1188 : : void renderPoint( QPointF point, const QgsFeature *f, QgsRenderContext &context, int layer = -1, bool selected = false );
1189 : :
1190 : : /**
1191 : : * Returns the approximate bounding box of the marker symbol, which includes the bounding box
1192 : : * of all symbol layers for the symbol. It is recommended to use this method only between startRender()
1193 : : * and stopRender() calls, or data defined rotation and offset will not be correctly calculated.
1194 : : * \param point location of rendered point in painter units
1195 : : * \param context render context
1196 : : * \param feature feature being rendered at point (optional). If not specified, the bounds calculation will not
1197 : : * include data defined parameters such as offset and rotation
1198 : : * \returns approximate symbol bounds, in painter units
1199 : : * \since QGIS 2.14
1200 : : */
1201 : : QRectF bounds( QPointF point, QgsRenderContext &context, const QgsFeature &feature = QgsFeature() ) const;
1202 : :
1203 : : QgsMarkerSymbol *clone() const override SIP_FACTORY;
1204 : :
1205 : : private:
1206 : :
1207 : : void renderPointUsingLayer( QgsMarkerSymbolLayer *layer, QPointF point, QgsSymbolRenderContext &context );
1208 : :
1209 : : };
1210 : :
1211 : :
1212 : : /**
1213 : : * \ingroup core
1214 : : * \class QgsLineSymbol
1215 : : *
1216 : : * \brief A line symbol type, for rendering LineString and MultiLineString geometries.
1217 : : */
1218 : 664 : class CORE_EXPORT QgsLineSymbol : public QgsSymbol
1219 : : {
1220 : : public:
1221 : :
1222 : : /**
1223 : : * Create a line symbol with one symbol layer: SimpleLine with specified properties.
1224 : : * This is a convenience method for easier creation of line symbols.
1225 : : */
1226 : : static QgsLineSymbol *createSimple( const QVariantMap &properties ) SIP_FACTORY;
1227 : :
1228 : : /**
1229 : : * Constructor for QgsLineSymbol, with the specified list of initial symbol \a layers.
1230 : : *
1231 : : * Ownership of the \a layers are transferred to the symbol.
1232 : : */
1233 : : QgsLineSymbol( const QgsSymbolLayerList &layers SIP_TRANSFER = QgsSymbolLayerList() );
1234 : :
1235 : : /**
1236 : : * Sets the \a width for the whole line symbol. Individual symbol layer sizes
1237 : : * will be scaled to maintain their current relative size to the whole symbol size.
1238 : : *
1239 : : * \see width()
1240 : : */
1241 : : void setWidth( double width );
1242 : :
1243 : : /**
1244 : : * Sets the width units for the whole symbol (including all symbol layers).
1245 : : * \param unit size units
1246 : : * \since QGIS 3.16
1247 : : */
1248 : : void setWidthUnit( QgsUnitTypes::RenderUnit unit );
1249 : :
1250 : :
1251 : : /**
1252 : : * Returns the estimated width for the whole symbol, which is the maximum width of
1253 : : * all marker symbol layers in the symbol.
1254 : : *
1255 : : * \warning This returned value is inaccurate if the symbol consists of multiple
1256 : : * symbol layers with different width units. Use the overload accepting a QgsRenderContext
1257 : : * argument instead for accurate sizes in this case.
1258 : : *
1259 : : * \see setWidth()
1260 : : */
1261 : : double width() const;
1262 : :
1263 : : /**
1264 : : * Returns the symbol width, in painter units. This is the maximum width of
1265 : : * all marker symbol layers in the symbol.
1266 : : *
1267 : : * This method returns an accurate width by calculating the actual rendered
1268 : : * width of each symbol layer using the provided render \a context.
1269 : : *
1270 : : * \see setWidth()
1271 : : *
1272 : : * \since QGIS 3.4.5
1273 : : */
1274 : : double width( const QgsRenderContext &context ) const;
1275 : :
1276 : : /**
1277 : : * Set data defined width for whole symbol (including all symbol layers).
1278 : : * \see dataDefinedWidth()
1279 : : * \since QGIS 3.0
1280 : : */
1281 : : void setDataDefinedWidth( const QgsProperty &property );
1282 : :
1283 : : /**
1284 : : * Returns data defined width for whole symbol (including all symbol layers).
1285 : : * \returns data defined width, or invalid property if size is not set
1286 : : * at the line level. Caller takes responsibility for deleting the returned object.
1287 : : * \see setDataDefinedWidth
1288 : : * \since QGIS 3.0
1289 : : */
1290 : : QgsProperty dataDefinedWidth() const;
1291 : :
1292 : : /**
1293 : : * Renders the symbol along the line joining \a points, using the given render \a context.
1294 : : *
1295 : : * The \a f argument is used to pass the feature currently being rendered (when available).
1296 : : *
1297 : : * If only a single symbol layer from the symbol should be rendered, it should be specified
1298 : : * in the \a layer argument. A \a layer of -1 indicates that all symbol layers should be
1299 : : * rendered.
1300 : : *
1301 : : * If \a selected is TRUE then the symbol will be drawn using the "selected feature"
1302 : : * style and colors instead of the symbol's normal style.
1303 : : */
1304 : : void renderPolyline( const QPolygonF &points, const QgsFeature *f, QgsRenderContext &context, int layer = -1, bool selected = false );
1305 : :
1306 : : QgsLineSymbol *clone() const override SIP_FACTORY;
1307 : :
1308 : : private:
1309 : :
1310 : : void renderPolylineUsingLayer( QgsLineSymbolLayer *layer, const QPolygonF &points, QgsSymbolRenderContext &context );
1311 : :
1312 : : };
1313 : :
1314 : :
1315 : : /**
1316 : : * \ingroup core
1317 : : * \class QgsFillSymbol
1318 : : *
1319 : : * \brief A fill symbol type, for rendering Polygon and MultiPolygon geometries.
1320 : : */
1321 : 396 : class CORE_EXPORT QgsFillSymbol : public QgsSymbol
1322 : : {
1323 : : public:
1324 : :
1325 : : /**
1326 : : * Create a fill symbol with one symbol layer: SimpleFill with specified properties.
1327 : : * This is a convenience method for easier creation of fill symbols.
1328 : : */
1329 : : static QgsFillSymbol *createSimple( const QVariantMap &properties ) SIP_FACTORY;
1330 : :
1331 : : /**
1332 : : * Constructor for QgsFillSymbol, with the specified list of initial symbol \a layers.
1333 : : *
1334 : : * Ownership of the \a layers are transferred to the symbol.
1335 : : */
1336 : : QgsFillSymbol( const QgsSymbolLayerList &layers SIP_TRANSFER = QgsSymbolLayerList() );
1337 : : void setAngle( double angle );
1338 : :
1339 : : /**
1340 : : * Renders the symbol using the given render \a context.
1341 : : *
1342 : : * The \a points list dictates the exterior ring for the polygon to render, and
1343 : : * interior rings are optionally specified via the \a rings argument.
1344 : : *
1345 : : * The \a f argument is used to pass the feature currently being rendered (when available).
1346 : : *
1347 : : * If only a single symbol layer from the symbol should be rendered, it should be specified
1348 : : * in the \a layer argument. A \a layer of -1 indicates that all symbol layers should be
1349 : : * rendered.
1350 : : *
1351 : : * If \a selected is TRUE then the symbol will be drawn using the "selected feature"
1352 : : * style and colors instead of the symbol's normal style.
1353 : : */
1354 : : void renderPolygon( const QPolygonF &points, const QVector<QPolygonF> *rings, const QgsFeature *f, QgsRenderContext &context, int layer = -1, bool selected = false );
1355 : :
1356 : : QgsFillSymbol *clone() const override SIP_FACTORY;
1357 : :
1358 : : private:
1359 : :
1360 : : void renderPolygonUsingLayer( QgsSymbolLayer *layer, const QPolygonF &points, const QVector<QPolygonF> *rings, QgsSymbolRenderContext &context );
1361 : : //! Calculates the bounds of a polygon including rings
1362 : : QRectF polygonBounds( const QPolygonF &points, const QVector<QPolygonF> *rings ) const;
1363 : : //! Translates the rings in a polygon by a set distance
1364 : : QVector<QPolygonF> *translateRings( const QVector<QPolygonF> *rings, double dx, double dy ) const;
1365 : : };
1366 : :
1367 : : Q_DECLARE_OPERATORS_FOR_FLAGS( QgsSymbol::PreviewFlags )
1368 : :
1369 : : #endif
1370 : :
|