QGIS API Documentation 3.99.0-Master (d270888f95f)
Loading...
Searching...
No Matches
qgsmergedfeaturerenderer.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgsmergedfeaturerenderer.h
3 ---------------------
4 begin : December 2020
5 copyright : (C) 2020 by Nyall Dawson
6 email : nyall dot dawson 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
17
18#include "qgsfeature.h"
19#include "qgslogger.h"
21#include "qgsogcutils.h"
22#include "qgspainteffect.h"
25#include "qgssymbol.h"
26#include "qgssymbollayer.h"
27#include "qgssymbollayerutils.h"
28#include "qgsvectorlayer.h"
29
30#include <QDomDocument>
31#include <QDomElement>
32#include <QString>
33
34using namespace Qt::StringLiterals;
35
37 : QgsMergedFeatureRenderer( u"mergedFeatureRenderer"_s, subRenderer )
38{
39
40}
41
44{
45 if ( subRenderer )
46 {
47 mSubRenderer.reset( subRenderer );
48 }
49}
50
52{
53 mSubRenderer.reset( subRenderer );
54}
55
60
62{
63 if ( !mSubRenderer )
64 return;
65
66 mSubRenderer->setLegendSymbolItem( key, symbol );
67}
68
70{
71 if ( !mSubRenderer )
72 return false;
73
74 return mSubRenderer->legendSymbolItemsCheckable();
75}
76
78{
79 if ( !mSubRenderer )
80 return false;
81
82 return mSubRenderer->legendSymbolItemChecked( key );
83}
84
85void QgsMergedFeatureRenderer::checkLegendSymbolItem( const QString &key, bool state )
86{
87 if ( !mSubRenderer )
88 return;
89
90 mSubRenderer->checkLegendSymbolItem( key, state );
91}
92
94{
95 if ( !mSubRenderer )
96 return true;
97
98 return mSubRenderer->accept( visitor );
99}
100
102{
103 QgsFeatureRenderer::startRender( context, fields );
104
105 if ( !mSubRenderer )
106 {
107 return;
108 }
109
110 // first call start render on the sub renderer
111 mSubRenderer->startRender( context, fields );
112
113 mFeaturesCategories.clear();
114 mSymbolCategories.clear();
115 mFeatureDecorations.clear();
116 mFields = fields;
117
118 // We compute coordinates of the extent which will serve as exterior ring
119 // for the final polygon
120 // It must be computed in the destination CRS if reprojection is enabled.
121
122 if ( !context.painter() )
123 {
124 return;
125 }
126
127 // copy the rendering context
128 mContext = context;
129
130 // If reprojection is enabled, we must reproject during renderFeature
131 // and act as if there is no reprojection
132 // If we don't do that, there is no need to have a simple rectangular extent
133 // that covers the whole screen
134 // (a rectangle in the destCRS cannot be expressed as valid coordinates in the sourceCRS in general)
135 if ( context.coordinateTransform().isValid() )
136 {
137 // disable projection
138 mContext.setCoordinateTransform( QgsCoordinateTransform() );
139 // recompute extent so that polygon clipping is correct
140 mContext.setExtent( context.mapExtent() );
141 // do we have to recompute the MapToPixel ?
142 }
143
144 switch ( mOperation )
145 {
146 case InvertOnly:
147 case MergeAndInvert:
148 {
149 // convert viewport to dest CRS
150 // add some space to hide borders and tend to infinity
151 const double buffer = std::max( context.mapExtent().width(), context.mapExtent().height() ) * 0.1;
152 const QRectF outer = context.mapExtent().buffered( buffer ).toRectF();
153 QgsPolylineXY exteriorRing;
154 exteriorRing.reserve( 5 );
155 exteriorRing << outer.topLeft();
156 exteriorRing << outer.topRight();
157 exteriorRing << outer.bottomRight();
158 exteriorRing << outer.bottomLeft();
159 exteriorRing << outer.topLeft();
160
161 mExtentPolygon.clear();
162 mExtentPolygon.append( exteriorRing );
163 break;
164 }
165
166 case Merge:
167 break;
168 }
169}
170
172{
174 if ( mSubRenderer )
175 {
176 res = mSubRenderer->flags();
177 }
178 return res;
179}
180
181bool QgsMergedFeatureRenderer::renderFeature( const QgsFeature &feature, QgsRenderContext &context, int layer, bool selected, bool drawVertexMarker )
182{
183 if ( !context.painter() || !mSubRenderer )
184 {
185 return false;
186 }
187
188 // store this feature as a feature to render with decoration if needed
189 if ( selected || drawVertexMarker )
190 {
191 mFeatureDecorations.append( FeatureDecoration( feature, selected, drawVertexMarker, layer ) );
192 }
193
194 // Features are grouped by category of symbols (returned by symbol(s)ForFeature)
195 // This way, users can have multiple inverted polygon fills for a layer,
196 // for instance, with rule based renderer and different symbols
197 // that have transparency.
198 //
199 // In order to assign a unique category to a set of symbols
200 // during each rendering session (between startRender() and stopRender()),
201 // we build an unique id as a QByteArray that is the concatenation
202 // of each symbol's memory address.
203 // The only assumption made here is that symbol(s)ForFeature will
204 // always return the same address for the same symbol(s) shared amongst
205 // different features.
206 // This QByteArray can then be used as a key for a QMap where the list of
207 // features for this category is stored
208 QByteArray catId;
210 {
211 const QgsSymbolList syms( mSubRenderer->symbolsForFeature( feature, context ) );
212 for ( QgsSymbol *sym : syms )
213 {
214 // append the memory address
215 catId.append( reinterpret_cast<const char *>( &sym ), sizeof( sym ) );
216 }
217 }
218 else
219 {
220 if ( QgsSymbol *sym = mSubRenderer->symbolForFeature( feature, context ) )
221 {
222 catId.append( reinterpret_cast<const char *>( &sym ), sizeof( sym ) );
223 }
224 }
225
226 if ( catId.isEmpty() )
227 {
228 return false;
229 }
230
231 if ( ! mSymbolCategories.contains( catId ) )
232 {
233 CombinedFeature cFeat;
234 // store the first feature
235 cFeat.feature = feature;
236 mSymbolCategories.insert( catId, mSymbolCategories.count() );
237 mFeaturesCategories.append( cFeat );
238 }
239
240 // update the geometry
241 CombinedFeature &cFeat = mFeaturesCategories[ mSymbolCategories[catId] ];
242 if ( !feature.hasGeometry() )
243 {
244 return false;
245 }
246 QgsGeometry geom = feature.geometry();
247
248 // Simplify the geometry, if needed.
250 {
251 const int simplifyHints = context.vectorSimplifyMethod().simplifyHints();
252 const QgsMapToPixelSimplifier simplifier( simplifyHints, context.vectorSimplifyMethod().tolerance(),
254
255 QgsGeometry simplified( simplifier.simplify( geom ) );
256 if ( !simplified.isEmpty() )
257 {
258 geom = simplified;
259 }
260 }
261
263 if ( xform.isValid() )
264 {
265 geom.transform( xform );
266 }
267
268 switch ( mOperation )
269 {
271 // fix the polygon if it is not valid
272 if ( ! geom.isGeosValid() )
273 {
274 geom = geom.buffer( 0, 0 );
275 }
276 break;
277
279 case QgsMergedFeatureRenderer::Merge: // maybe we should also fix for this? not sure if the fixing step was only required for the differencing operation...
280 break;
281 }
282
283 if ( geom.isNull() )
284 return false; // do not let invalid geometries sneak in!
285
286 // add the geometry to the list of geometries for this feature
287 cFeat.geometries.append( geom );
288
289 return true;
290}
291
293{
295 if ( context.renderingStopped() )
296 {
297 if ( mSubRenderer )
298 mSubRenderer->stopRender( mContext );
299 return;
300 }
301
302 if ( !mSubRenderer )
303 {
304 return;
305 }
306 if ( !context.painter() )
307 {
308 return;
309 }
310
311 QgsMultiPolygonXY finalMulti; //avoid expensive allocation for list for every feature
312 QgsPolygonXY newPoly;
313
314 for ( const CombinedFeature &cit : std::as_const( mFeaturesCategories ) )
315 {
316 finalMulti.resize( 0 ); //preserve capacity - don't use clear!
317 QgsFeature feat = cit.feature; // just a copy, so that we do not accumulate geometries again
318
319 switch ( mOperation )
320 {
322 {
323 QgsGeometry unioned( QgsGeometry::unaryUnion( cit.geometries ) );
324 if ( unioned.type() == Qgis::GeometryType::Line )
325 unioned = unioned.mergeLines();
326 feat.setGeometry( unioned );
327 break;
328 }
329
331 {
332 // compute the unary union on the polygons
333 const QgsGeometry unioned( QgsGeometry::unaryUnion( cit.geometries ) );
334 // compute the difference with the extent
335 const QgsGeometry rect = QgsGeometry::fromPolygonXY( mExtentPolygon );
336 const QgsGeometry final = rect.difference( unioned );
337 feat.setGeometry( final );
338 break;
339 }
340
342 {
343 // No preprocessing involved.
344 // We build here a "reversed" geometry of all the polygons
345 //
346 // The final geometry is a multipolygon F, with :
347 // * the first polygon of F having the current extent as its exterior ring
348 // * each polygon's exterior ring is added as interior ring of the first polygon of F
349 // * each polygon's interior ring is added as new polygons in F
350 //
351 // No validity check is done, on purpose, it will be very slow and painting
352 // operations do not need geometries to be valid
353
354 finalMulti.append( mExtentPolygon );
355 for ( const QgsGeometry &geom : std::as_const( cit.geometries ) )
356 {
357 QgsMultiPolygonXY multi;
358 Qgis::WkbType type = QgsWkbTypes::flatType( geom.constGet()->wkbType() );
359
361 {
362 multi.append( geom.asPolygon() );
363 }
365 {
366 multi = geom.asMultiPolygon();
367 }
368
369 for ( int i = 0; i < multi.size(); i++ )
370 {
371 const QgsPolylineXY &exterior = multi[i][0];
372 // add the exterior ring as interior ring to the first polygon
373 // make sure it satisfies at least very basic requirements of GEOS
374 // (otherwise the creation of GEOS geometry will fail)
375 if ( exterior.count() < 4 || exterior[0] != exterior[exterior.count() - 1] )
376 continue;
377 finalMulti[0].append( exterior );
378
379 // add interior rings as new polygons
380 for ( int j = 1; j < multi[i].size(); j++ )
381 {
382 newPoly.resize( 0 ); //preserve capacity - don't use clear!
383 newPoly.append( multi[i][j] );
384 finalMulti.append( newPoly );
385 }
386 }
387 }
388 feat.setGeometry( QgsGeometry::fromMultiPolygonXY( finalMulti ) );
389 break;
390 }
391 }
392
393 if ( feat.hasGeometry() )
394 {
395 mContext.expressionContext().setFeature( feat );
396 const bool prevSimplify = context.vectorSimplifyMethod().forceLocalOptimization();
397 // we've already simplified, no need to re-do simplification
398 mContext.vectorSimplifyMethod().setForceLocalOptimization( false );
399 mSubRenderer->renderFeature( feat, mContext );
400 mContext.vectorSimplifyMethod().setForceLocalOptimization( prevSimplify );
401 }
402 }
403
404 // when no features are visible, we still have to draw the exterior rectangle
405 // warning: when sub renderers have more than one possible symbols,
406 // there is no way to choose a correct one, because there is no attribute here
407 // in that case, nothing will be rendered
408 switch ( mOperation )
409 {
411 break;
414 if ( mFeaturesCategories.isEmpty() )
415 {
416 // empty feature with default attributes
417 QgsFeature feat( mFields );
418 feat.setGeometry( QgsGeometry::fromPolygonXY( mExtentPolygon ) );
419 mSubRenderer->renderFeature( feat, mContext );
420 }
421 break;
422 }
423
424 // draw feature decorations
425 for ( FeatureDecoration deco : std::as_const( mFeatureDecorations ) )
426 {
427 mSubRenderer->renderFeature( deco.feature, mContext, deco.layer, deco.selected, deco.drawMarkers );
428 }
429
430 mSubRenderer->stopRender( mContext );
431}
432
434{
435 if ( !mSubRenderer )
436 {
437 return u"MERGED FEATURES: NULL"_s;
438 }
439 return "MERGED FEATURES [" + mSubRenderer->dump() + ']';
440}
441
443{
444 QgsMergedFeatureRenderer *newRenderer = nullptr;
445 if ( !mSubRenderer )
446 {
447 newRenderer = new QgsMergedFeatureRenderer( nullptr );
448 }
449 else
450 {
451 newRenderer = new QgsMergedFeatureRenderer( mSubRenderer->clone() );
452 }
453 copyRendererData( newRenderer );
454 return newRenderer;
455}
456
458{
460 //look for an embedded renderer <renderer-v2>
461 QDomElement embeddedRendererElem = element.firstChildElement( u"renderer-v2"_s );
462 if ( !embeddedRendererElem.isNull() )
463 {
464 QgsFeatureRenderer *renderer = QgsFeatureRenderer::load( embeddedRendererElem, context );
465 r->setEmbeddedRenderer( renderer );
466 }
467 return r;
468}
469
470QDomElement QgsMergedFeatureRenderer::save( QDomDocument &doc, const QgsReadWriteContext &context )
471{
472 // clazy:skip
473
474 QDomElement rendererElem = doc.createElement( RENDERER_TAG_NAME );
475 rendererElem.setAttribute( u"type"_s, u"mergedFeatureRenderer"_s );
476
477 if ( mSubRenderer )
478 {
479 QDomElement embeddedRendererElem = mSubRenderer->save( doc, context );
480 rendererElem.appendChild( embeddedRendererElem );
481 }
482
483 saveRendererData( doc, rendererElem, context );
484
485 return rendererElem;
486}
487
489{
490 if ( !mSubRenderer )
491 {
492 return nullptr;
493 }
494 return mSubRenderer->symbolForFeature( feature, context );
495}
496
498{
499 if ( !mSubRenderer )
500 return nullptr;
501 return mSubRenderer->originalSymbolForFeature( feature, context );
502}
503
505{
506 if ( !mSubRenderer )
507 {
508 return QgsSymbolList();
509 }
510 return mSubRenderer->symbolsForFeature( feature, context );
511}
512
514{
515 if ( !mSubRenderer )
516 return QgsSymbolList();
517 return mSubRenderer->originalSymbolsForFeature( feature, context );
518}
519
521{
522 if ( !mSubRenderer )
523 return QSet<QString>();
524 return mSubRenderer->legendKeysForFeature( feature, context );
525}
526
527QString QgsMergedFeatureRenderer::legendKeyToExpression( const QString &key, QgsVectorLayer *layer, bool &ok ) const
528{
529 ok = false;
530 if ( !mSubRenderer )
531 return QString();
532 return mSubRenderer->legendKeyToExpression( key, layer, ok );
533}
534
536{
537 if ( !mSubRenderer )
538 {
539 return QgsSymbolList();
540 }
541 return mSubRenderer->symbols( context );
542}
543
545{
546 if ( !mSubRenderer )
547 {
548 return Capabilities();
549 }
550 return mSubRenderer->capabilities();
551}
552
554{
555 if ( !mSubRenderer )
556 {
557 return QSet<QString>();
558 }
559 return mSubRenderer->usedAttributes( context );
560}
561
563{
564 return mSubRenderer ? mSubRenderer->filterNeedsGeometry() : false;
565}
566
568{
569 if ( !mSubRenderer )
570 {
571 return QgsLegendSymbolList();
572 }
573 return mSubRenderer->legendSymbolItems();
574}
575
577{
578 if ( !mSubRenderer )
579 {
580 return false;
581 }
582 return mSubRenderer->willRenderFeature( feature, context );
583}
584
586{
587 if ( renderer->type() == "mergedFeatureRenderer"_L1 )
588 {
589 return dynamic_cast<QgsMergedFeatureRenderer *>( renderer->clone() );
590 }
591
592 if ( renderer->type() == "singleSymbol"_L1 ||
593 renderer->type() == "categorizedSymbol"_L1 ||
594 renderer->type() == "graduatedSymbol"_L1 ||
595 renderer->type() == "RuleRenderer"_L1 )
596 {
597 auto res = std::make_unique< QgsMergedFeatureRenderer >( renderer->clone() );
598 renderer->copyRendererData( res.get() );
599 return res.release();
600 }
601 else if ( renderer->type() == "invertedPolygonRenderer"_L1 )
602 {
603 auto res = std::make_unique< QgsMergedFeatureRenderer >( renderer->embeddedRenderer() ? renderer->embeddedRenderer()->clone() : nullptr );
604 renderer->copyRendererData( res.get() );
605 return res.release();
606 }
607 return nullptr;
608}
609
QFlags< FeatureRendererFlag > FeatureRendererFlags
Flags controlling behavior of vector feature renderers.
Definition qgis.h:857
@ Line
Lines.
Definition qgis.h:367
WkbType
The WKB type describes the number of dimensions a geometry has.
Definition qgis.h:280
@ Polygon
Polygon.
Definition qgis.h:284
@ MultiPolygon
MultiPolygon.
Definition qgis.h:288
@ CurvePolygon
CurvePolygon.
Definition qgis.h:292
@ MultiSurface
MultiSurface.
Definition qgis.h:294
Handles coordinate transforms between two coordinate systems.
bool isValid() const
Returns true if the coordinate transform is valid, ie both the source and destination CRS have been s...
QgsFeatureRenderer(const QString &type)
virtual void stopRender(QgsRenderContext &context)
Must be called when a render cycle has finished, to allow the renderer to clean up.
QFlags< Capability > Capabilities
QString type() const
void copyRendererData(QgsFeatureRenderer *destRenderer) const
Clones generic renderer data to another renderer.
@ MoreSymbolsPerFeature
May use more than one symbol to render a feature: symbolsForFeature() will return them.
static QgsFeatureRenderer * load(QDomElement &symbologyElem, const QgsReadWriteContext &context)
create a renderer from XML element
void saveRendererData(QDomDocument &doc, QDomElement &element, const QgsReadWriteContext &context)
Saves generic renderer data into the specified element.
virtual const QgsFeatureRenderer * embeddedRenderer() const
Returns the current embedded renderer (subrenderer) for this feature renderer.
virtual void startRender(QgsRenderContext &context, const QgsFields &fields)
Must be called when a new render cycle is started.
virtual QgsFeatureRenderer * clone() const =0
Create a deep copy of this renderer.
The feature class encapsulates a single feature including its unique ID, geometry and a list of field...
Definition qgsfeature.h:60
QgsGeometry geometry
Definition qgsfeature.h:71
bool hasGeometry() const
Returns true if the feature has an associated geometry.
void setGeometry(const QgsGeometry &geometry)
Set the feature's geometry.
Container of fields for a vector layer.
Definition qgsfields.h:46
A geometry is the spatial representation of a feature.
QgsGeometry difference(const QgsGeometry &geometry, const QgsGeometryParameters &parameters=QgsGeometryParameters()) const
Returns a geometry representing the points making up this geometry that do not make up other.
QgsGeometry mergeLines(const QgsGeometryParameters &parameters=QgsGeometryParameters()) const
Merges any connected lines in a LineString/MultiLineString geometry and converts them to single line ...
Qgis::GeometryOperationResult transform(const QgsCoordinateTransform &ct, Qgis::TransformDirection direction=Qgis::TransformDirection::Forward, bool transformZ=false)
Transforms this geometry as described by the coordinate transform ct.
bool isGeosValid(Qgis::GeometryValidityFlags flags=Qgis::GeometryValidityFlags()) const
Checks validity of the geometry using GEOS.
Qgis::GeometryType type
static QgsGeometry fromPolygonXY(const QgsPolygonXY &polygon)
Creates a new geometry from a QgsPolygonXY.
static QgsGeometry fromMultiPolygonXY(const QgsMultiPolygonXY &multipoly)
Creates a new geometry from a QgsMultiPolygonXY.
QgsGeometry buffer(double distance, int segments) const
Returns a buffer region around this geometry having the given width and with a specified number of se...
bool isEmpty() const
Returns true if the geometry is empty (eg a linestring with no vertices, or a collection with no geom...
static QgsGeometry unaryUnion(const QVector< QgsGeometry > &geometries, const QgsGeometryParameters &parameters=QgsGeometryParameters())
Compute the unary union on a list of geometries.
Implementation of a geometry simplifier using the "MapToPixel" algorithm.
QgsGeometry simplify(const QgsGeometry &geometry) const override
Returns a simplified version the specified geometry.
void setLegendSymbolItem(const QString &key, QgsSymbol *symbol) override
Sets the symbol to be used for a legend symbol item.
static QgsFeatureRenderer * create(QDomElement &element, const QgsReadWriteContext &context)
Creates a renderer out of an XML, for loading.
QgsSymbol * symbolForFeature(const QgsFeature &feature, QgsRenderContext &context) const override
To be overridden.
void stopRender(QgsRenderContext &context) override
The actual rendering will take place here.
QSet< QString > legendKeysForFeature(const QgsFeature &feature, QgsRenderContext &context) const override
Returns legend keys matching a specified feature.
QgsSymbolList symbols(QgsRenderContext &context) const override
Returns list of symbols used by the renderer.
QgsSymbolList symbolsForFeature(const QgsFeature &feature, QgsRenderContext &context) const override
Returns list of symbols used for rendering the feature.
void startRender(QgsRenderContext &context, const QgsFields &fields) override
Must be called when a new render cycle is started.
QString legendKeyToExpression(const QString &key, QgsVectorLayer *layer, bool &ok) const override
Attempts to convert the specified legend rule key to a QGIS expression matching the features displaye...
QgsSymbol * originalSymbolForFeature(const QgsFeature &feature, QgsRenderContext &context) const override
Returns symbol for feature.
QString dump() const override
Returns debug information about this renderer.
QgsMergedFeatureRenderer(QgsFeatureRenderer *embeddedRenderer)
Constructor for QgsMergedFeatureRenderer.
bool renderFeature(const QgsFeature &feature, QgsRenderContext &context, int layer=-1, bool selected=false, bool drawVertexMarker=false) override
Renders a given feature.
const QgsFeatureRenderer * embeddedRenderer() const override
Returns the current embedded renderer (subrenderer) for this feature renderer.
QgsSymbolList originalSymbolsForFeature(const QgsFeature &feature, QgsRenderContext &context) const override
Equivalent of originalSymbolsForFeature() call extended to support renderers that may use more symbol...
bool accept(QgsStyleEntityVisitorInterface *visitor) const override
Accepts the specified symbology visitor, causing it to visit all symbols associated with the renderer...
QSet< QString > usedAttributes(const QgsRenderContext &context) const override
Returns a list of attributes required by this renderer.
QgsLegendSymbolList legendSymbolItems() const override
Returns a list of symbology items for the legend.
QDomElement save(QDomDocument &doc, const QgsReadWriteContext &context) override
Stores renderer properties to an XML element.
@ Merge
Merge features (union/dissolve).
@ InvertOnly
Invert features only (polygons only).
@ MergeAndInvert
Merge and invert features (polygons only).
GeometryOperation mOperation
Operation to apply to collected geometries.
void checkLegendSymbolItem(const QString &key, bool state=true) override
Sets whether the legend symbology item with the specified ley should be checked.
bool filterNeedsGeometry() const override
Returns true if this renderer requires the geometry to apply the filter.
bool legendSymbolItemChecked(const QString &key) override
Returns true if the legend symbology item with the specified key is checked.
void setEmbeddedRenderer(QgsFeatureRenderer *subRenderer) override
Sets an embedded renderer (subrenderer) for this feature renderer.
std::unique_ptr< QgsFeatureRenderer > mSubRenderer
Embedded renderer.
QgsFeatureRenderer::Capabilities capabilities() override
Returns details about internals of this renderer.
bool legendSymbolItemsCheckable() const override
Returns true if symbology items in legend are checkable.
bool willRenderFeature(const QgsFeature &feature, QgsRenderContext &context) const override
Returns whether the renderer will render a feature or not.
static QgsMergedFeatureRenderer * convertFromRenderer(const QgsFeatureRenderer *renderer)
Creates a QgsMergedFeatureRenderer by a conversion from an existing renderer.
Qgis::FeatureRendererFlags flags() const override
Returns flags associated with the renderer.
QgsMergedFeatureRenderer * clone() const override
Create a deep copy of this renderer.
A container for the context for various read/write operations on objects.
QRectF toRectF() const
Returns a QRectF with same coordinates as the rectangle.
QgsRectangle buffered(double width) const
Gets rectangle enlarged by buffer.
Contains information about the context of a rendering operation.
QgsVectorSimplifyMethod & vectorSimplifyMethod()
Returns the simplification settings to use when rendering vector layers.
QPainter * painter()
Returns the destination QPainter for the render operation.
QgsRectangle mapExtent() const
Returns the original extent of the map being rendered.
bool renderingStopped() const
Returns true if the rendering operation has been stopped and any ongoing rendering should be canceled...
QgsCoordinateTransform coordinateTransform() const
Returns the current coordinate transform for the context.
An interface for classes which can visit style entity (e.g.
Abstract base class for all rendered symbols.
Definition qgssymbol.h:231
Represents a vector layer which manages a vector based dataset.
double tolerance() const
Gets the tolerance of simplification in map units. Represents the maximum distance in map units betwe...
bool forceLocalOptimization() const
Gets where the simplification executes, after fetch the geometries from provider, or when supported,...
Qgis::VectorRenderingSimplificationFlags simplifyHints() const
Gets the simplification hints of the vector layer managed.
Qgis::VectorSimplificationAlgorithm simplifyAlgorithm() const
Gets the local simplification algorithm of the vector layer managed.
static Qgis::WkbType flatType(Qgis::WkbType type)
Returns the flat type for a WKB type.
QVector< QgsPolylineXY > QgsPolygonXY
Polygon: first item of the list is outer ring, inner rings (if any) start from second item.
Definition qgsgeometry.h:92
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.
QList< QgsLegendSymbolItem > QgsLegendSymbolList
#define RENDERER_TAG_NAME
Definition qgsrenderer.h:57
QList< QgsSymbol * > QgsSymbolList
Definition qgsrenderer.h:51