QGIS API Documentation  3.25.0-Master (10b47c2603)
qgshighlight.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgshighlight.cpp - widget to highlight features on the map
3  --------------------------------------
4  Date : 02-03-2011
5  Copyright : (C) 2011 by Juergen E. Fischer, norBIT GmbH
6  Email : jef at norbit dot de
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 <QImage>
17 
18 #include "qgsmarkersymbollayer.h"
19 #include "qgslinesymbollayer.h"
20 
21 #include "qgscoordinatetransform.h"
22 #include "qgsfillsymbollayer.h"
23 #include "qgsgeometry.h"
24 #include "qgshighlight.h"
25 #include "qgsmapcanvas.h"
26 #include "qgsmaplayer.h"
27 #include "qgsrendercontext.h"
28 #include "qgssymbollayer.h"
29 #include "qgssymbol.h"
30 #include "qgsvectorlayer.h"
31 #include "qgsrenderer.h"
33 #include "qgspointcloudlayer.h"
36 
37 /* Few notes about highlighting (RB):
38  - The highlight fill must always be partially transparent because above highlighted layer
39  may be another layer which must remain partially visible.
40  - Because single highlight color does not work well with layers using similar layer color
41  there were considered various possibilities but no optimal solution was found.
42  What does not work:
43  - lighter/darker color: it would work more or less for fully opaque highlight, but
44  overlaying transparent lighter color over original has small visual effect.
45  - complemetary color: mixing transparent (128) complement color with original color
46  results in grey for all colors
47  - contrast line style/ fill pattern: impression is not highligh but just different style
48  - line buffer with contrast (or 2 contrast) color: the same as with patterns, no highlight impression
49  - fill with highlight or contrast color but opaque and using pattern
50  (e.g. Qt::Dense7Pattern): again no highlight impression
51 */
52 
54  : QgsMapCanvasItem( mapCanvas )
55  , mGeometry( geom )
56  , mLayer( layer )
57 
58 {
59  init();
60 }
61 
63  : QgsMapCanvasItem( mapCanvas )
64  , mLayer( layer )
65  , mFeature( feature )
66 {
67  init();
68 }
69 
70 void QgsHighlight::init()
71 {
72  mOriginalGeometry = mGeometry.isNull() ? mFeature.geometry() : mGeometry;
73  setColor( QColor( Qt::lightGray ) );
74 
75  connect( mMapCanvas, &QgsMapCanvas::destinationCrsChanged, this, &QgsHighlight::updateTransformedGeometry );
76  updateTransformedGeometry();
77 
78  if ( mGeometry.type() == QgsWkbTypes::PointGeometry )
79  {
80  mRenderContext = createRenderContext();
81  }
82 }
83 
84 void QgsHighlight::updateTransformedGeometry()
85 {
87  if ( ct.isValid() )
88  {
89  // reset to original geometry and transform
90  if ( !mGeometry.isNull() )
91  {
92  mGeometry = mOriginalGeometry;
93  try
94  {
95  mGeometry.transform( ct );
96  }
97  catch ( QgsCsException & )
98  {
99  QgsDebugMsg( QStringLiteral( "Could not transform highlight geometry to canvas CRS" ) );
100  }
101  }
102  else if ( mFeature.hasGeometry() )
103  {
104  mFeature.setGeometry( mOriginalGeometry );
105  QgsGeometry g = mFeature.geometry();
106  try
107  {
108  g.transform( ct );
109  mFeature.setGeometry( g );
110  }
111  catch ( QgsCsException & )
112  {
113  QgsDebugMsg( QStringLiteral( "Could not transform highlight geometry to canvas CRS" ) );
114  }
115  }
116  }
117  updateRect();
118  update();
119 }
120 
121 QgsHighlight::~QgsHighlight() = default;
122 
123 void QgsHighlight::setColor( const QColor &color )
124 {
125  mColor = color;
126  mPen.setColor( color );
127  QColor fillColor( color.red(), color.green(), color.blue(), 63 );
128  mBrush.setColor( fillColor );
129  mBrush.setStyle( Qt::SolidPattern );
130 }
131 
132 void QgsHighlight::setFillColor( const QColor &fillColor )
133 {
134  mFillColor = fillColor;
135  mBrush.setColor( fillColor );
136  mBrush.setStyle( Qt::SolidPattern );
137 }
138 
139 std::unique_ptr<QgsFeatureRenderer> QgsHighlight::createRenderer( QgsRenderContext &context, const QColor &color, const QColor &fillColor )
140 {
141  std::unique_ptr<QgsFeatureRenderer> renderer;
142  QgsVectorLayer *layer = qobject_cast<QgsVectorLayer *>( mLayer );
143  if ( layer && layer->renderer() )
144  {
145  renderer.reset( layer->renderer()->clone() );
146  }
147  if ( renderer )
148  {
149  const QgsSymbolList symbols = renderer->symbols( context );
150  for ( QgsSymbol *symbol : symbols )
151  {
152  if ( !symbol )
153  continue;
154  setSymbol( symbol, context, color, fillColor );
155  }
156  }
157  return renderer;
158 }
159 
160 void QgsHighlight::setSymbol( QgsSymbol *symbol, const QgsRenderContext &context, const QColor &color, const QColor &fillColor )
161 {
162  if ( !symbol )
163  return;
164 
165  for ( int i = symbol->symbolLayerCount() - 1; i >= 0; i-- )
166  {
167  QgsSymbolLayer *symbolLayer = symbol->symbolLayer( i );
168  if ( !symbolLayer )
169  continue;
170 
171  if ( symbolLayer->subSymbol() )
172  {
173  setSymbol( symbolLayer->subSymbol(), context, color, fillColor );
174  }
175  else
176  {
177  symbolLayer->setColor( color ); // line symbology layers
178  symbolLayer->setStrokeColor( color ); // marker and fill symbology layers
179  symbolLayer->setFillColor( fillColor ); // marker and fill symbology layers
180 
181  // Data defined widths overwrite what we set here (widths do not work with data defined)
182  QgsSimpleMarkerSymbolLayer *simpleMarker = dynamic_cast<QgsSimpleMarkerSymbolLayer *>( symbolLayer );
183  if ( simpleMarker )
184  {
185  simpleMarker->setStrokeWidth( getSymbolWidth( context, simpleMarker->strokeWidth(), simpleMarker->strokeWidthUnit() ) );
186  }
187  QgsSimpleLineSymbolLayer *simpleLine = dynamic_cast<QgsSimpleLineSymbolLayer *>( symbolLayer );
188  if ( simpleLine )
189  {
190  simpleLine->setWidth( getSymbolWidth( context, simpleLine->width(), simpleLine->widthUnit() ) );
191  }
192  QgsSimpleFillSymbolLayer *simpleFill = dynamic_cast<QgsSimpleFillSymbolLayer *>( symbolLayer );
193  if ( simpleFill )
194  {
195  simpleFill->setStrokeWidth( getSymbolWidth( context, simpleFill->strokeWidth(), simpleFill->outputUnit() ) );
196  }
199  }
200  }
201 }
202 
203 double QgsHighlight::getSymbolWidth( const QgsRenderContext &context, double width, QgsUnitTypes::RenderUnit unit )
204 {
205  // if necessary scale mm to map units
206  double scale = 1.;
207  if ( unit == QgsUnitTypes::RenderMapUnits )
208  {
210  }
211  width = std::max( width + 2 * mBuffer * scale, mMinWidth * scale );
212  return width;
213 }
214 
215 void QgsHighlight::setWidth( int width )
216 {
217  mWidth = width;
218  mPen.setWidth( width );
219 }
220 
221 void QgsHighlight::paintPoint( QgsRenderContext &context, const QgsPoint *point, double size, QgsUnitTypes::RenderUnit sizeUnit, PointSymbol symbol )
222 {
223  if ( !point )
224  return;
225 
226  const double radius = context.convertToPainterUnits( size, sizeUnit );
227  const double xMin = toCanvasCoordinates( *point ).x() - radius - pos().x();
228  const double yMin = toCanvasCoordinates( *point ).y() - radius - pos().y();
229 
230  switch ( symbol )
231  {
232  case QgsHighlight::Square:
233  {
234  const double xMax = xMin + 2 * radius;
235  const double yMax = yMin + 2 * radius;
236  QPolygonF r( QVector<QPointF> { QPointF( xMin, yMin ),
237  QPointF( xMax, yMin ),
238  QPointF( xMax, yMax ),
239  QPointF( xMin, yMax ),
240  QPointF( xMin, yMin )
241  } );
242  context.painter()->drawPolygon( r );
243  break;
244  }
245 
246  case QgsHighlight::Circle:
247  {
248  context.painter()->drawEllipse( QRectF( xMin, yMin, radius * 2, radius * 2 ) );
249  break;
250  }
251  }
252 }
253 
254 void QgsHighlight::paintLine( QPainter *p, QgsPolylineXY line )
255 {
256  QPolygonF polygon( line.size() );
257 
258  for ( int i = 0; i < line.size(); i++ )
259  {
260  polygon[i] = toCanvasCoordinates( line[i] ) - pos();
261  }
262 
263  p->drawPolyline( polygon );
264 }
265 
266 void QgsHighlight::paintPolygon( QPainter *p, const QgsPolygonXY &polygon )
267 {
268  // OddEven fill rule by default
269  QPainterPath path;
270 
271  p->setPen( mPen );
272  p->setBrush( mBrush );
273 
274  for ( const auto &sourceRing : polygon )
275  {
276  if ( sourceRing.empty() )
277  continue;
278 
279  QPolygonF ring;
280  ring.reserve( sourceRing.size() + 1 );
281 
282  QPointF lastVertex;
283  for ( const auto &sourceVertex : sourceRing )
284  {
285  //adding point only if it is more than a pixel apart from the previous one
286  const QPointF curVertex = toCanvasCoordinates( sourceVertex ) - pos();
287  if ( ring.isEmpty() || std::abs( ring.back().x() - curVertex.x() ) > 1 || std::abs( ring.back().y() - curVertex.y() ) > 1 )
288  {
289  ring.push_back( curVertex );
290  }
291  lastVertex = curVertex;
292  }
293 
294  ring.push_back( ring.at( 0 ) );
295 
296  path.addPolygon( ring );
297  }
298 
299  p->drawPath( path );
300 }
301 
302 QgsRenderContext QgsHighlight::createRenderContext()
303 {
304  QgsMapSettings mapSettings = mMapCanvas->mapSettings();
305  QgsRenderContext context = QgsRenderContext::fromMapSettings( mapSettings );
307  return context;
308 }
309 
311 {
312  if ( !isVisible() )
313  return;
314 
315  if ( mGeometry.type() == QgsWkbTypes::PointGeometry )
316  {
317  mRenderContext = createRenderContext();
318  }
319 
320  updateRect();
321 }
322 
323 void QgsHighlight::paint( QPainter *p )
324 {
325  if ( mFeature.hasGeometry() )
326  {
327  QgsVectorLayer *vlayer = qobject_cast<QgsVectorLayer *>( mLayer );
328  if ( !vlayer )
329  return;
330 
331  QgsRenderContext context = createRenderContext();
332 
333  // Because lower level outlines must be covered by upper level fill color
334  // we render first with temporary opaque color, which is then replaced
335  // by final transparent fill color.
336  QColor tmpColor( 255, 0, 0, 255 );
337  QColor tmpFillColor( 0, 255, 0, 255 );
338 
339  std::unique_ptr< QgsFeatureRenderer > renderer = createRenderer( context, tmpColor, tmpFillColor );
340  if ( renderer )
341  {
342 
343  QSize imageSize( mMapCanvas->mapSettings().outputSize() );
344  QImage image = QImage( imageSize.width(), imageSize.height(), QImage::Format_ARGB32 );
345  image.fill( 0 );
346  QPainter imagePainter( &image );
347  imagePainter.setRenderHint( QPainter::Antialiasing, true );
348 
349  context.setPainter( &imagePainter );
350  renderer->startRender( context, mFeature.fields() );
351  context.expressionContext().setFeature( mFeature );
352  renderer->renderFeature( mFeature, context );
353  renderer->stopRender( context );
354 
355  imagePainter.end();
356 
357  // true output color
358  int penRed = mPen.color().red();
359  int penGreen = mPen.color().green();
360  int penBlue = mPen.color().blue();
361  // coefficient to subtract alpha using green (temporary fill)
362  double k = ( 255. - mBrush.color().alpha() ) / 255.;
363  QRgb *line = nullptr;
364  const int height = image.height();
365  const int width = image.width();
366  for ( int r = 0; r < height; r++ )
367  {
368  line = reinterpret_cast<QRgb *>( image.scanLine( r ) );
369  for ( int c = 0; c < width; c++ )
370  {
371  int alpha = qAlpha( line[c] );
372  if ( alpha > 0 )
373  {
374  int green = qGreen( line[c] );
375  line[c] = qRgba( penRed, penGreen, penBlue, std::clamp( static_cast< int >( alpha - ( green * k ) ), 0, 255 ) );
376  }
377  }
378  }
379 
380  p->drawImage( 0, 0, image );
381  }
382  }
383  else if ( !mGeometry.isNull() )
384  {
385  p->setPen( mPen );
386  p->setBrush( mBrush );
387 
388  switch ( mGeometry.type() )
389  {
391  {
392  setRenderContextVariables( p, mRenderContext );
393 
394  // default to 1.5 mm radius square points
395  double pointSizeRadius = 1.5;
397  PointSymbol symbol = Square;
398 
399  // but for point clouds, use actual sizes (+a little margin!)
400  if ( QgsPointCloudLayer *pcLayer = qobject_cast<QgsPointCloudLayer *>( mLayer ) )
401  {
402  if ( QgsPointCloudRenderer *pcRenderer = pcLayer->renderer() )
403  {
404  pointSizeRadius = 1.2 * 0.5 * mRenderContext.convertToPainterUnits( pcRenderer->pointSize(), pcRenderer->pointSizeUnit(), pcRenderer->pointSizeMapUnitScale() );
405  sizeUnit = QgsUnitTypes::RenderPixels;
406  switch ( pcRenderer->pointSymbol() )
407  {
409  symbol = Circle;
410  break;
412  symbol = Square;
413  break;
414  }
415  }
416  }
417 
418  for ( auto it = mGeometry.const_parts_begin(); it != mGeometry.const_parts_end(); ++it )
419  {
420  paintPoint( mRenderContext, qgsgeometry_cast< const QgsPoint *>( *it ), pointSizeRadius, sizeUnit, symbol );
421  }
422  }
423  break;
424 
426  {
427  if ( !mGeometry.isMultipart() )
428  {
429  paintLine( p, mGeometry.asPolyline() );
430  }
431  else
432  {
433  QgsMultiPolylineXY m = mGeometry.asMultiPolyline();
434 
435  for ( int i = 0; i < m.size(); i++ )
436  {
437  paintLine( p, m[i] );
438  }
439  }
440  break;
441  }
442 
444  {
445  if ( !mGeometry.isMultipart() )
446  {
447  paintPolygon( p, mGeometry.asPolygon() );
448  }
449  else
450  {
451  QgsMultiPolygonXY m = mGeometry.asMultiPolygon();
452  for ( int i = 0; i < m.size(); i++ )
453  {
454  paintPolygon( p, m[i] );
455  }
456  }
457  break;
458  }
459 
462  return;
463  }
464  }
465 }
466 
468 {
469  if ( qobject_cast<QgsPointCloudLayer *>( mLayer ) || mFeature.hasGeometry() )
470  {
471  // We are currently using full map canvas extent for two reasons:
472  // 1) currently there is no method in QgsFeatureRenderer to get rendered feature
473  // bounding box
474  // 2) using different extent would result in shifted fill patterns
475 
476  // This is an hack to pass QgsMapCanvasItem::setRect what it
477  // expects (encoding of position and size of the item)
479  QgsPointXY topLeft = m2p.toMapCoordinates( 0, 0 );
480  double res = m2p.mapUnitsPerPixel();
481  QSizeF imageSize = mMapCanvas->mapSettings().outputSize();
482  QgsRectangle rect( topLeft.x(), topLeft.y(), topLeft.x() + imageSize.width()*res, topLeft.y() - imageSize.height()*res );
483  setRect( rect );
484 
485  setVisible( true );
486  }
487  else if ( !mGeometry.isNull() )
488  {
489  QgsRectangle r = mGeometry.boundingBox();
490 
491  if ( r.isEmpty() )
492  {
493  double d = mMapCanvas->extent().width() * 0.005;
494  r.setXMinimum( r.xMinimum() - d );
495  r.setYMinimum( r.yMinimum() - d );
496  r.setXMaximum( r.xMaximum() + d );
497  r.setYMaximum( r.yMaximum() + d );
498  }
499 
500  setRect( r );
501  setVisible( true );
502  }
503  else
504  {
505  setRect( QgsRectangle() );
506  }
507 }
@ Circle
Renders points as circles.
@ Square
Renders points as squares.
Class for doing transforms between two map coordinate systems.
bool isValid() const
Returns true if the coordinate transform is valid, ie both the source and destination CRS have been s...
Custom exception class for Coordinate Reference System related exceptions.
Definition: qgsexception.h:66
static QgsExpressionContextScope * layerScope(const QgsMapLayer *layer)
Creates a new scope which contains variables and functions relating to a QgsMapLayer.
void setFeature(const QgsFeature &feature)
Convenience function for setting a feature for the context.
The feature class encapsulates a single feature including its unique ID, geometry and a list of field...
Definition: qgsfeature.h:56
QgsFields fields
Definition: qgsfeature.h:66
QgsGeometry geometry
Definition: qgsfeature.h:67
bool hasGeometry() const
Returns true if the feature has an associated geometry.
Definition: qgsfeature.cpp:223
void setGeometry(const QgsGeometry &geometry)
Set the feature's geometry.
Definition: qgsfeature.cpp:163
A geometry is the spatial representation of a feature.
Definition: qgsgeometry.h:125
QgsMultiPolygonXY asMultiPolygon() const
Returns the contents of the geometry as a multi-polygon.
QgsAbstractGeometry::const_part_iterator const_parts_begin() const
Returns STL-style const iterator pointing to the first part of the geometry.
Qgis::GeometryOperationResult transform(const QgsCoordinateTransform &ct, Qgis::TransformDirection direction=Qgis::TransformDirection::Forward, bool transformZ=false) SIP_THROW(QgsCsException)
Transforms this geometry as described by the coordinate transform ct.
QgsPolygonXY asPolygon() const
Returns the contents of the geometry as a polygon.
Q_GADGET bool isNull
Definition: qgsgeometry.h:127
bool isMultipart() const SIP_HOLDGIL
Returns true if WKB of the geometry is of WKBMulti* type.
QgsPolylineXY asPolyline() const
Returns the contents of the geometry as a polyline.
QgsWkbTypes::GeometryType type
Definition: qgsgeometry.h:128
QgsMultiPolylineXY asMultiPolyline() const
Returns the contents of the geometry as a multi-linestring.
QgsAbstractGeometry::const_part_iterator const_parts_end() const
Returns STL-style iterator pointing to the imaginary part after the last part of the geometry.
QgsRectangle boundingBox() const
Returns the bounding box of the geometry.
void updatePosition() override
called on changed extent or resize event to update position of the item
QgsHighlight(QgsMapCanvas *mapCanvas, const QgsGeometry &geom, QgsMapLayer *layer)
Constructor for QgsHighlight.
QColor fillColor
Definition: qgshighlight.h:87
~QgsHighlight() override
QColor color
Definition: qgshighlight.h:86
QgsMapLayer * layer() const
Returns the layer for which this highlight has been created.
Definition: qgshighlight.h:171
void setFillColor(const QColor &fillColor)
Fill color for the highlight.
void setWidth(int width)
Set stroke width.
void paint(QPainter *p) override
function to be implemented by derived classes
void updateRect()
recalculates needed rectangle
void setColor(const QColor &color)
Set line/stroke to color, polygon fill to color with alpha = 63.
virtual void setWidth(double width)
Sets the width of the line symbol layer.
QgsUnitTypes::RenderUnit widthUnit() const
Returns the units for the line's width.
virtual double width() const
Returns the estimated width for the line symbol layer.
An abstract class for items that can be placed on the map canvas.
QgsRectangle rect() const
returns canvas item rectangle in map units
QPointF toCanvasCoordinates(const QgsPointXY &point) const
transformation from map coordinates to screen coordinates
QgsMapCanvas * mMapCanvas
pointer to map canvas
void setRect(const QgsRectangle &r, bool resetRotation=true)
sets canvas item rectangle in map units
bool setRenderContextVariables(QPainter *p, QgsRenderContext &context) const
Sets render context parameters.
Map canvas is a class for displaying all GIS data types on a canvas.
Definition: qgsmapcanvas.h:90
void destinationCrsChanged()
Emitted when map CRS has changed.
const QgsMapSettings & mapSettings() const
Gets access to properties used for map rendering.
QgsRectangle extent() const
Returns the current zoom extent of the map canvas.
Base class for all map layer types.
Definition: qgsmaplayer.h:73
virtual QgsMapLayer * clone() const =0
Returns a new instance equivalent to this one except for the id which is still unique.
The QgsMapSettings class contains configuration for rendering of the map.
QgsCoordinateTransform layerTransform(const QgsMapLayer *layer) const
Returns the coordinate transform from layer's CRS to destination CRS.
QSize outputSize() const
Returns the size of the resulting map image, in pixels.
const QgsMapToPixel & mapToPixel() const
Perform transforms between map coordinates and device coordinates.
Definition: qgsmaptopixel.h:39
double mapUnitsPerPixel() const
Returns the current map units per pixel.
QgsPointXY toMapCoordinates(int x, int y) const
Transforms device coordinates to map (world) coordinates.
Represents a map layer supporting display of point clouds.
Abstract base class for 2d point cloud renderers.
A class to represent a 2D point.
Definition: qgspointxy.h:59
double y
Definition: qgspointxy.h:63
Q_GADGET double x
Definition: qgspointxy.h:62
Point geometry type, with support for z-dimension and m-values.
Definition: qgspoint.h:49
A store for object properties.
Definition: qgsproperty.h:231
A rectangle specified with double values.
Definition: qgsrectangle.h:42
double yMaximum() const SIP_HOLDGIL
Returns the y maximum value (top side of rectangle).
Definition: qgsrectangle.h:193
double xMaximum() const SIP_HOLDGIL
Returns the x maximum value (right side of rectangle).
Definition: qgsrectangle.h:183
double xMinimum() const SIP_HOLDGIL
Returns the x minimum value (left side of rectangle).
Definition: qgsrectangle.h:188
double yMinimum() const SIP_HOLDGIL
Returns the y minimum value (bottom side of rectangle).
Definition: qgsrectangle.h:198
void setYMinimum(double y) SIP_HOLDGIL
Set the minimum y value.
Definition: qgsrectangle.h:161
void setXMaximum(double x) SIP_HOLDGIL
Set the maximum x value.
Definition: qgsrectangle.h:156
void setXMinimum(double x) SIP_HOLDGIL
Set the minimum x value.
Definition: qgsrectangle.h:151
void setYMaximum(double y) SIP_HOLDGIL
Set the maximum y value.
Definition: qgsrectangle.h:166
double width() const SIP_HOLDGIL
Returns the width of the rectangle.
Definition: qgsrectangle.h:223
bool isEmpty() const
Returns true if the rectangle is empty.
Definition: qgsrectangle.h:469
Contains information about the context of a rendering operation.
QPainter * painter()
Returns the destination QPainter for the render operation.
QgsExpressionContext & expressionContext()
Gets the expression context.
double convertToPainterUnits(double size, QgsUnitTypes::RenderUnit unit, const QgsMapUnitScale &scale=QgsMapUnitScale(), Qgis::RenderSubcomponentProperty property=Qgis::RenderSubcomponentProperty::Generic) const
Converts a size from the specified units to painter units (pixels).
void setPainter(QPainter *p)
Sets the destination QPainter for the render operation.
static QgsRenderContext fromMapSettings(const QgsMapSettings &mapSettings)
create initialized QgsRenderContext instance from given QgsMapSettings
QgsUnitTypes::RenderUnit outputUnit() const override
Returns the units to use for sizes and widths within the symbol layer.
void setStrokeWidth(double strokeWidth)
A simple line symbol layer, which renders lines using a line in a variety of styles (e....
Simple marker symbol layer, consisting of a rendered shape with solid fill color and an stroke.
QgsUnitTypes::RenderUnit strokeWidthUnit() const
Returns the unit for the width of the marker's stroke.
void setStrokeWidth(double w)
Sets the width of the marker's stroke.
double strokeWidth() const
Returns the width of the marker's stroke.
@ PropertyFillColor
Fill color.
@ PropertyStrokeColor
Stroke color.
virtual void setStrokeColor(const QColor &color)
Sets the stroke color for the symbol layer.
virtual void setFillColor(const QColor &color)
Sets the fill color for the symbol layer.
virtual void setDataDefinedProperty(Property key, const QgsProperty &property)
Sets a data defined property for the layer.
virtual void setColor(const QColor &color)
Sets the "representative" color for the symbol layer.
virtual QgsSymbol * subSymbol()
Returns the symbol's sub symbol, if present.
Abstract base class for all rendered symbols.
Definition: qgssymbol.h:93
QgsSymbolLayer * symbolLayer(int layer)
Returns the symbol layer at the specified index.
Definition: qgssymbol.cpp:423
int symbolLayerCount() const
Returns the total number of symbol layers contained in the symbol.
Definition: qgssymbol.h:215
RenderUnit
Rendering size units.
Definition: qgsunittypes.h:168
@ RenderPixels
Pixels.
Definition: qgsunittypes.h:171
@ RenderMillimeters
Millimeters.
Definition: qgsunittypes.h:169
@ RenderMapUnits
Map units.
Definition: qgsunittypes.h:170
Represents a vector layer which manages a vector based data sets.
As part of the API refactoring and improvements which landed in the Processing API was substantially reworked from the x version This was done in order to allow much of the underlying Processing framework to be ported into c
QVector< QgsPolylineXY > QgsPolygonXY
Polygon: first item of the list is outer ring, inner rings (if any) start from second item.
Definition: qgsgeometry.h:76
QVector< QgsPolylineXY > QgsMultiPolylineXY
A collection of QgsPolylines that share a common collection of attributes.
Definition: qgsgeometry.h:86
QVector< QgsPointXY > QgsPolylineXY
Polyline as represented as a vector of two-dimensional points.
Definition: qgsgeometry.h:52
QVector< QgsPolygonXY > QgsMultiPolygonXY
A collection of QgsPolygons that share a common collection of attributes.
Definition: qgsgeometry.h:93
#define QgsDebugMsg(str)
Definition: qgslogger.h:38
QList< QgsSymbol * > QgsSymbolList
Definition: qgsrenderer.h:44