QGIS API Documentation 3.28.0-Firenze (ed3ad0430f)
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
19#include "qgslinesymbollayer.h"
20
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
70void 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
84void QgsHighlight::updateTransformedGeometry()
85{
87
88 // we don't auto-transform if we are highlighting a feature -- the renderer will take care
89 // of that for us
90 if ( ct.isValid() && !mGeometry.isNull() )
91 {
92 // reset to original geometry and transform
93 mGeometry = mOriginalGeometry;
94 try
95 {
96 mGeometry.transform( ct );
97 }
98 catch ( QgsCsException & )
99 {
100 QgsDebugMsg( QStringLiteral( "Could not transform highlight geometry to canvas CRS" ) );
101 }
102 }
103 updateRect();
104 update();
105}
106
108
109void QgsHighlight::setColor( const QColor &color )
110{
111 mColor = color;
112 mPen.setColor( color );
113 QColor fillColor( color.red(), color.green(), color.blue(), 63 );
114 mBrush.setColor( fillColor );
115 mBrush.setStyle( Qt::SolidPattern );
116}
117
118void QgsHighlight::setFillColor( const QColor &fillColor )
119{
120 mFillColor = fillColor;
121 mBrush.setColor( fillColor );
122 mBrush.setStyle( Qt::SolidPattern );
123}
124
125std::unique_ptr<QgsFeatureRenderer> QgsHighlight::createRenderer( QgsRenderContext &context, const QColor &color, const QColor &fillColor )
126{
127 std::unique_ptr<QgsFeatureRenderer> renderer;
128 QgsVectorLayer *layer = qobject_cast<QgsVectorLayer *>( mLayer );
129 if ( layer && layer->renderer() )
130 {
131 renderer.reset( layer->renderer()->clone() );
132 }
133 if ( renderer )
134 {
135 const QgsSymbolList symbols = renderer->symbols( context );
136 for ( QgsSymbol *symbol : symbols )
137 {
138 if ( !symbol )
139 continue;
140 setSymbol( symbol, context, color, fillColor );
141 }
142 }
143 return renderer;
144}
145
146void QgsHighlight::setSymbol( QgsSymbol *symbol, const QgsRenderContext &context, const QColor &color, const QColor &fillColor )
147{
148 if ( !symbol )
149 return;
150
151 for ( int i = symbol->symbolLayerCount() - 1; i >= 0; i-- )
152 {
153 QgsSymbolLayer *symbolLayer = symbol->symbolLayer( i );
154 if ( !symbolLayer )
155 continue;
156
157 if ( symbolLayer->subSymbol() )
158 {
159 setSymbol( symbolLayer->subSymbol(), context, color, fillColor );
160 }
161 else
162 {
163 symbolLayer->setColor( color ); // line symbology layers
164 symbolLayer->setStrokeColor( color ); // marker and fill symbology layers
165 symbolLayer->setFillColor( fillColor ); // marker and fill symbology layers
166
167 // Data defined widths overwrite what we set here (widths do not work with data defined)
168 QgsSimpleMarkerSymbolLayer *simpleMarker = dynamic_cast<QgsSimpleMarkerSymbolLayer *>( symbolLayer );
169 if ( simpleMarker )
170 {
171 simpleMarker->setStrokeWidth( getSymbolWidth( context, simpleMarker->strokeWidth(), simpleMarker->strokeWidthUnit() ) );
172 }
173 QgsSimpleLineSymbolLayer *simpleLine = dynamic_cast<QgsSimpleLineSymbolLayer *>( symbolLayer );
174 if ( simpleLine )
175 {
176 simpleLine->setWidth( getSymbolWidth( context, simpleLine->width(), simpleLine->widthUnit() ) );
177 }
178 QgsSimpleFillSymbolLayer *simpleFill = dynamic_cast<QgsSimpleFillSymbolLayer *>( symbolLayer );
179 if ( simpleFill )
180 {
181 simpleFill->setStrokeWidth( getSymbolWidth( context, simpleFill->strokeWidth(), simpleFill->outputUnit() ) );
182 }
185 }
186 }
187}
188
189double QgsHighlight::getSymbolWidth( const QgsRenderContext &context, double width, QgsUnitTypes::RenderUnit unit )
190{
191 // if necessary scale mm to map units
192 double scale = 1.;
193 if ( unit == QgsUnitTypes::RenderMapUnits )
194 {
196 }
197 width = std::max( width + 2 * mBuffer * scale, mMinWidth * scale );
198 return width;
199}
200
201void QgsHighlight::setWidth( int width )
202{
203 mWidth = width;
204 mPen.setWidth( width );
205}
206
207void QgsHighlight::paintPoint( QgsRenderContext &context, const QgsPoint *point, double size, QgsUnitTypes::RenderUnit sizeUnit, PointSymbol symbol )
208{
209 if ( !point )
210 return;
211
212 const double radius = context.convertToPainterUnits( size, sizeUnit );
213 const double xMin = toCanvasCoordinates( *point ).x() - radius - pos().x();
214 const double yMin = toCanvasCoordinates( *point ).y() - radius - pos().y();
215
216 switch ( symbol )
217 {
218 case QgsHighlight::Square:
219 {
220 const double xMax = xMin + 2 * radius;
221 const double yMax = yMin + 2 * radius;
222 QPolygonF r( QVector<QPointF> { QPointF( xMin, yMin ),
223 QPointF( xMax, yMin ),
224 QPointF( xMax, yMax ),
225 QPointF( xMin, yMax ),
226 QPointF( xMin, yMin )
227 } );
228 context.painter()->drawPolygon( r );
229 break;
230 }
231
232 case QgsHighlight::Circle:
233 {
234 context.painter()->drawEllipse( QRectF( xMin, yMin, radius * 2, radius * 2 ) );
235 break;
236 }
237 }
238}
239
240void QgsHighlight::paintLine( QPainter *p, QgsPolylineXY line )
241{
242 QPolygonF polygon( line.size() );
243
244 for ( int i = 0; i < line.size(); i++ )
245 {
246 polygon[i] = toCanvasCoordinates( line[i] ) - pos();
247 }
248
249 p->drawPolyline( polygon );
250}
251
252void QgsHighlight::paintPolygon( QPainter *p, const QgsPolygonXY &polygon )
253{
254 // OddEven fill rule by default
255 QPainterPath path;
256
257 p->setPen( mPen );
258 p->setBrush( mBrush );
259
260 for ( const auto &sourceRing : polygon )
261 {
262 if ( sourceRing.empty() )
263 continue;
264
265 QPolygonF ring;
266 ring.reserve( sourceRing.size() + 1 );
267
268 QPointF lastVertex;
269 for ( const auto &sourceVertex : sourceRing )
270 {
271 //adding point only if it is more than a pixel apart from the previous one
272 const QPointF curVertex = toCanvasCoordinates( sourceVertex ) - pos();
273 if ( ring.isEmpty() || std::abs( ring.back().x() - curVertex.x() ) > 1 || std::abs( ring.back().y() - curVertex.y() ) > 1 )
274 {
275 ring.push_back( curVertex );
276 }
277 lastVertex = curVertex;
278 }
279
280 ring.push_back( ring.at( 0 ) );
281
282 path.addPolygon( ring );
283 }
284
285 p->drawPath( path );
286}
287
288QgsRenderContext QgsHighlight::createRenderContext()
289{
290 QgsMapSettings mapSettings = mMapCanvas->mapSettings();
293 return context;
294}
295
297{
298 if ( !isVisible() )
299 return;
300
301 if ( mGeometry.type() == QgsWkbTypes::PointGeometry )
302 {
303 mRenderContext = createRenderContext();
304 }
305
306 updateRect();
307}
308
309void QgsHighlight::paint( QPainter *p )
310{
311 if ( mFeature.hasGeometry() )
312 {
313 QgsVectorLayer *vlayer = qobject_cast<QgsVectorLayer *>( mLayer );
314 if ( !vlayer )
315 return;
316
317 QgsRenderContext context = createRenderContext();
318 const QgsCoordinateTransform layerToCanvasTransform = mMapCanvas->mapSettings().layerTransform( mLayer );
319 context.setCoordinateTransform( layerToCanvasTransform );
320 QgsRectangle mapExtentInLayerCrs = mMapCanvas->mapSettings().visibleExtent();
321 if ( layerToCanvasTransform.isValid() )
322 {
323 QgsCoordinateTransform approxTransform = layerToCanvasTransform;
324 approxTransform.setBallparkTransformsAreAppropriate( true );
325 try
326 {
327 mapExtentInLayerCrs = approxTransform.transformBoundingBox( mapExtentInLayerCrs, Qgis::TransformDirection::Reverse );
328 }
329 catch ( QgsCsException & )
330 {
331 QgsDebugMsg( QStringLiteral( "Error transforming canvas extent to layer CRS" ) );
332 }
333 }
334 if ( !mapExtentInLayerCrs.isFinite() )
335 {
336 return;
337 }
338 context.setExtent( mapExtentInLayerCrs );
339
340 // Because lower level outlines must be covered by upper level fill color
341 // we render first with temporary opaque color, which is then replaced
342 // by final transparent fill color.
343 QColor tmpColor( 255, 0, 0, 255 );
344 QColor tmpFillColor( 0, 255, 0, 255 );
345
346 std::unique_ptr< QgsFeatureRenderer > renderer = createRenderer( context, tmpColor, tmpFillColor );
347 if ( renderer )
348 {
349
350 QSize imageSize( mMapCanvas->mapSettings().outputSize() );
351 QImage image = QImage( imageSize.width(), imageSize.height(), QImage::Format_ARGB32 );
352 image.fill( 0 );
353 QPainter imagePainter( &image );
354 imagePainter.setRenderHint( QPainter::Antialiasing, true );
355
356 context.setPainter( &imagePainter );
357 renderer->startRender( context, mFeature.fields() );
358 context.expressionContext().setFeature( mFeature );
359 renderer->renderFeature( mFeature, context );
360 renderer->stopRender( context );
361
362 imagePainter.end();
363
364 // true output color
365 int penRed = mPen.color().red();
366 int penGreen = mPen.color().green();
367 int penBlue = mPen.color().blue();
368 // coefficient to subtract alpha using green (temporary fill)
369 double k = ( 255. - mBrush.color().alpha() ) / 255.;
370 QRgb *line = nullptr;
371 const int height = image.height();
372 const int width = image.width();
373 for ( int r = 0; r < height; r++ )
374 {
375 line = reinterpret_cast<QRgb *>( image.scanLine( r ) );
376 for ( int c = 0; c < width; c++ )
377 {
378 int alpha = qAlpha( line[c] );
379 if ( alpha > 0 )
380 {
381 int green = qGreen( line[c] );
382 line[c] = qRgba( penRed, penGreen, penBlue, std::clamp( static_cast< int >( alpha - ( green * k ) ), 0, 255 ) );
383 }
384 }
385 }
386
387 p->drawImage( 0, 0, image );
388 }
389 }
390 else if ( !mGeometry.isNull() )
391 {
392 p->setPen( mPen );
393 p->setBrush( mBrush );
394
395 switch ( mGeometry.type() )
396 {
398 {
399 setRenderContextVariables( p, mRenderContext );
400
401 // default to 1.5 mm radius square points
402 double pointSizeRadius = 1.5;
404 PointSymbol symbol = Square;
405
406 // but for point clouds, use actual sizes (+a little margin!)
407 if ( QgsPointCloudLayer *pcLayer = qobject_cast<QgsPointCloudLayer *>( mLayer ) )
408 {
409 if ( QgsPointCloudRenderer *pcRenderer = pcLayer->renderer() )
410 {
411 pointSizeRadius = 1.2 * 0.5 * mRenderContext.convertToPainterUnits( pcRenderer->pointSize(), pcRenderer->pointSizeUnit(), pcRenderer->pointSizeMapUnitScale() );
413 switch ( pcRenderer->pointSymbol() )
414 {
416 symbol = Circle;
417 break;
419 symbol = Square;
420 break;
421 }
422 }
423 }
424
425 for ( auto it = mGeometry.const_parts_begin(); it != mGeometry.const_parts_end(); ++it )
426 {
427 paintPoint( mRenderContext, qgsgeometry_cast< const QgsPoint *>( *it ), pointSizeRadius, sizeUnit, symbol );
428 }
429 }
430 break;
431
433 {
434 if ( !mGeometry.isMultipart() )
435 {
436 paintLine( p, mGeometry.asPolyline() );
437 }
438 else
439 {
440 QgsMultiPolylineXY m = mGeometry.asMultiPolyline();
441
442 for ( int i = 0; i < m.size(); i++ )
443 {
444 paintLine( p, m[i] );
445 }
446 }
447 break;
448 }
449
451 {
452 if ( !mGeometry.isMultipart() )
453 {
454 paintPolygon( p, mGeometry.asPolygon() );
455 }
456 else
457 {
458 QgsMultiPolygonXY m = mGeometry.asMultiPolygon();
459 for ( int i = 0; i < m.size(); i++ )
460 {
461 paintPolygon( p, m[i] );
462 }
463 }
464 break;
465 }
466
469 return;
470 }
471 }
472}
473
475{
476 if ( qobject_cast<QgsPointCloudLayer *>( mLayer ) || mFeature.hasGeometry() )
477 {
478 // We are currently using full map canvas extent for two reasons:
479 // 1) currently there is no method in QgsFeatureRenderer to get rendered feature
480 // bounding box
481 // 2) using different extent would result in shifted fill patterns
482
483 // This is an hack to pass QgsMapCanvasItem::setRect what it
484 // expects (encoding of position and size of the item)
486 QgsPointXY topLeft = m2p.toMapCoordinates( 0, 0 );
487 double res = m2p.mapUnitsPerPixel();
488 QSizeF imageSize = mMapCanvas->mapSettings().outputSize();
489 QgsRectangle rect( topLeft.x(), topLeft.y(), topLeft.x() + imageSize.width()*res, topLeft.y() - imageSize.height()*res );
490 setRect( rect );
491
492 setVisible( true );
493 }
494 else if ( !mGeometry.isNull() )
495 {
496 QgsRectangle r = mGeometry.boundingBox();
497
498 if ( r.isEmpty() )
499 {
500 double d = mMapCanvas->extent().width() * 0.005;
501 r.setXMinimum( r.xMinimum() - d );
502 r.setYMinimum( r.yMinimum() - d );
503 r.setXMaximum( r.xMaximum() + d );
504 r.setYMaximum( r.yMaximum() + d );
505 }
506
507 setRect( r );
508 setVisible( true );
509 }
510 else
511 {
513 }
514}
@ Circle
Renders points as circles.
@ Square
Renders points as squares.
Class for doing transforms between two map coordinate systems.
void setBallparkTransformsAreAppropriate(bool appropriate)
Sets whether approximate "ballpark" results are appropriate for this coordinate transform.
bool isValid() const
Returns true if the coordinate transform is valid, ie both the source and destination CRS have been s...
QgsRectangle transformBoundingBox(const QgsRectangle &rectangle, Qgis::TransformDirection direction=Qgis::TransformDirection::Forward, bool handle180Crossover=false) const SIP_THROW(QgsCsException)
Transforms a rectangle from the source CRS to the destination CRS.
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:233
A geometry is the spatial representation of a feature.
Definition: qgsgeometry.h:164
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:166
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:167
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
QgsMapLayer * layer() const
Returns the layer for which this highlight has been created.
Definition: qgshighlight.h:171
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
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.
const QgsMapToPixel & mapToPixel() const
QSize outputSize() const
Returns the size of the resulting map image, in pixels.
QgsRectangle visibleExtent() const
Returns the actual extent derived from requested extent that takes output image size into account.
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:230
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
bool isFinite() const
Returns true if the rectangle has finite boundaries.
Definition: qgsrectangle.h:559
Contains information about the context of a rendering operation.
void setCoordinateTransform(const QgsCoordinateTransform &t)
Sets the current coordinate transform for the context.
QPainter * painter()
Returns the destination QPainter for the render operation.
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).
QgsExpressionContext & expressionContext()
Gets the expression context.
void setExtent(const QgsRectangle &extent)
When rendering a map layer, calling this method sets the "clipping" extent for the layer (in the laye...
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:756
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:63
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