QGIS API Documentation 3.99.0-Master (26c88405ac0)
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
34 : QgsMergedFeatureRenderer( QStringLiteral( "mergedFeatureRenderer" ), subRenderer )
35{
36
37}
38
41{
42 if ( subRenderer )
43 {
44 mSubRenderer.reset( subRenderer );
45 }
46}
47
49{
50 mSubRenderer.reset( subRenderer );
51}
52
57
59{
60 if ( !mSubRenderer )
61 return;
62
63 mSubRenderer->setLegendSymbolItem( key, symbol );
64}
65
67{
68 if ( !mSubRenderer )
69 return false;
70
71 return mSubRenderer->legendSymbolItemsCheckable();
72}
73
75{
76 if ( !mSubRenderer )
77 return false;
78
79 return mSubRenderer->legendSymbolItemChecked( key );
80}
81
82void QgsMergedFeatureRenderer::checkLegendSymbolItem( const QString &key, bool state )
83{
84 if ( !mSubRenderer )
85 return;
86
87 mSubRenderer->checkLegendSymbolItem( key, state );
88}
89
91{
92 if ( !mSubRenderer )
93 return true;
94
95 return mSubRenderer->accept( visitor );
96}
97
99{
100 QgsFeatureRenderer::startRender( context, fields );
101
102 if ( !mSubRenderer )
103 {
104 return;
105 }
106
107 // first call start render on the sub renderer
108 mSubRenderer->startRender( context, fields );
109
110 mFeaturesCategories.clear();
111 mSymbolCategories.clear();
112 mFeatureDecorations.clear();
113 mFields = fields;
114
115 // We compute coordinates of the extent which will serve as exterior ring
116 // for the final polygon
117 // It must be computed in the destination CRS if reprojection is enabled.
118
119 if ( !context.painter() )
120 {
121 return;
122 }
123
124 // copy the rendering context
125 mContext = context;
126
127 // If reprojection is enabled, we must reproject during renderFeature
128 // and act as if there is no reprojection
129 // If we don't do that, there is no need to have a simple rectangular extent
130 // that covers the whole screen
131 // (a rectangle in the destCRS cannot be expressed as valid coordinates in the sourceCRS in general)
132 if ( context.coordinateTransform().isValid() )
133 {
134 // disable projection
135 mContext.setCoordinateTransform( QgsCoordinateTransform() );
136 // recompute extent so that polygon clipping is correct
137 mContext.setExtent( context.mapExtent() );
138 // do we have to recompute the MapToPixel ?
139 }
140
141 switch ( mOperation )
142 {
143 case InvertOnly:
144 case MergeAndInvert:
145 {
146 // convert viewport to dest CRS
147 // add some space to hide borders and tend to infinity
148 const double buffer = std::max( context.mapExtent().width(), context.mapExtent().height() ) * 0.1;
149 const QRectF outer = context.mapExtent().buffered( buffer ).toRectF();
150 QgsPolylineXY exteriorRing;
151 exteriorRing.reserve( 5 );
152 exteriorRing << outer.topLeft();
153 exteriorRing << outer.topRight();
154 exteriorRing << outer.bottomRight();
155 exteriorRing << outer.bottomLeft();
156 exteriorRing << outer.topLeft();
157
158 mExtentPolygon.clear();
159 mExtentPolygon.append( exteriorRing );
160 break;
161 }
162
163 case Merge:
164 break;
165 }
166}
167
169{
171 if ( mSubRenderer )
172 {
173 res = mSubRenderer->flags();
174 }
175 return res;
176}
177
178bool QgsMergedFeatureRenderer::renderFeature( const QgsFeature &feature, QgsRenderContext &context, int layer, bool selected, bool drawVertexMarker )
179{
180 if ( !context.painter() || !mSubRenderer )
181 {
182 return false;
183 }
184
185 // store this feature as a feature to render with decoration if needed
186 if ( selected || drawVertexMarker )
187 {
188 mFeatureDecorations.append( FeatureDecoration( feature, selected, drawVertexMarker, layer ) );
189 }
190
191 // Features are grouped by category of symbols (returned by symbol(s)ForFeature)
192 // This way, users can have multiple inverted polygon fills for a layer,
193 // for instance, with rule based renderer and different symbols
194 // that have transparency.
195 //
196 // In order to assign a unique category to a set of symbols
197 // during each rendering session (between startRender() and stopRender()),
198 // we build an unique id as a QByteArray that is the concatenation
199 // of each symbol's memory address.
200 // The only assumption made here is that symbol(s)ForFeature will
201 // always return the same address for the same symbol(s) shared amongst
202 // different features.
203 // This QByteArray can then be used as a key for a QMap where the list of
204 // features for this category is stored
205 QByteArray catId;
207 {
208 const QgsSymbolList syms( mSubRenderer->symbolsForFeature( feature, context ) );
209 for ( QgsSymbol *sym : syms )
210 {
211 // append the memory address
212 catId.append( reinterpret_cast<const char *>( &sym ), sizeof( sym ) );
213 }
214 }
215 else
216 {
217 if ( QgsSymbol *sym = mSubRenderer->symbolForFeature( feature, context ) )
218 {
219 catId.append( reinterpret_cast<const char *>( &sym ), sizeof( sym ) );
220 }
221 }
222
223 if ( catId.isEmpty() )
224 {
225 return false;
226 }
227
228 if ( ! mSymbolCategories.contains( catId ) )
229 {
230 CombinedFeature cFeat;
231 // store the first feature
232 cFeat.feature = feature;
233 mSymbolCategories.insert( catId, mSymbolCategories.count() );
234 mFeaturesCategories.append( cFeat );
235 }
236
237 // update the geometry
238 CombinedFeature &cFeat = mFeaturesCategories[ mSymbolCategories[catId] ];
239 if ( !feature.hasGeometry() )
240 {
241 return false;
242 }
243 QgsGeometry geom = feature.geometry();
244
245 // Simplify the geometry, if needed.
247 {
248 const int simplifyHints = context.vectorSimplifyMethod().simplifyHints();
249 const QgsMapToPixelSimplifier simplifier( simplifyHints, context.vectorSimplifyMethod().tolerance(),
251
252 QgsGeometry simplified( simplifier.simplify( geom ) );
253 if ( !simplified.isEmpty() )
254 {
255 geom = simplified;
256 }
257 }
258
260 if ( xform.isValid() )
261 {
262 geom.transform( xform );
263 }
264
265 switch ( mOperation )
266 {
268 // fix the polygon if it is not valid
269 if ( ! geom.isGeosValid() )
270 {
271 geom = geom.buffer( 0, 0 );
272 }
273 break;
274
276 case QgsMergedFeatureRenderer::Merge: // maybe we should also fix for this? not sure if the fixing step was only required for the differencing operation...
277 break;
278 }
279
280 if ( geom.isNull() )
281 return false; // do not let invalid geometries sneak in!
282
283 // add the geometry to the list of geometries for this feature
284 cFeat.geometries.append( geom );
285
286 return true;
287}
288
290{
292 if ( context.renderingStopped() )
293 {
294 if ( mSubRenderer )
295 mSubRenderer->stopRender( mContext );
296 return;
297 }
298
299 if ( !mSubRenderer )
300 {
301 return;
302 }
303 if ( !context.painter() )
304 {
305 return;
306 }
307
308 QgsMultiPolygonXY finalMulti; //avoid expensive allocation for list for every feature
309 QgsPolygonXY newPoly;
310
311 for ( const CombinedFeature &cit : std::as_const( mFeaturesCategories ) )
312 {
313 finalMulti.resize( 0 ); //preserve capacity - don't use clear!
314 QgsFeature feat = cit.feature; // just a copy, so that we do not accumulate geometries again
315
316 switch ( mOperation )
317 {
319 {
320 QgsGeometry unioned( QgsGeometry::unaryUnion( cit.geometries ) );
321 if ( unioned.type() == Qgis::GeometryType::Line )
322 unioned = unioned.mergeLines();
323 feat.setGeometry( unioned );
324 break;
325 }
326
328 {
329 // compute the unary union on the polygons
330 const QgsGeometry unioned( QgsGeometry::unaryUnion( cit.geometries ) );
331 // compute the difference with the extent
332 const QgsGeometry rect = QgsGeometry::fromPolygonXY( mExtentPolygon );
333 const QgsGeometry final = rect.difference( unioned );
334 feat.setGeometry( final );
335 break;
336 }
337
339 {
340 // No preprocessing involved.
341 // We build here a "reversed" geometry of all the polygons
342 //
343 // The final geometry is a multipolygon F, with :
344 // * the first polygon of F having the current extent as its exterior ring
345 // * each polygon's exterior ring is added as interior ring of the first polygon of F
346 // * each polygon's interior ring is added as new polygons in F
347 //
348 // No validity check is done, on purpose, it will be very slow and painting
349 // operations do not need geometries to be valid
350
351 finalMulti.append( mExtentPolygon );
352 for ( const QgsGeometry &geom : std::as_const( cit.geometries ) )
353 {
354 QgsMultiPolygonXY multi;
355 Qgis::WkbType type = QgsWkbTypes::flatType( geom.constGet()->wkbType() );
356
358 {
359 multi.append( geom.asPolygon() );
360 }
362 {
363 multi = geom.asMultiPolygon();
364 }
365
366 for ( int i = 0; i < multi.size(); i++ )
367 {
368 const QgsPolylineXY &exterior = multi[i][0];
369 // add the exterior ring as interior ring to the first polygon
370 // make sure it satisfies at least very basic requirements of GEOS
371 // (otherwise the creation of GEOS geometry will fail)
372 if ( exterior.count() < 4 || exterior[0] != exterior[exterior.count() - 1] )
373 continue;
374 finalMulti[0].append( exterior );
375
376 // add interior rings as new polygons
377 for ( int j = 1; j < multi[i].size(); j++ )
378 {
379 newPoly.resize( 0 ); //preserve capacity - don't use clear!
380 newPoly.append( multi[i][j] );
381 finalMulti.append( newPoly );
382 }
383 }
384 }
385 feat.setGeometry( QgsGeometry::fromMultiPolygonXY( finalMulti ) );
386 break;
387 }
388 }
389
390 if ( feat.hasGeometry() )
391 {
392 mContext.expressionContext().setFeature( feat );
393 const bool prevSimplify = context.vectorSimplifyMethod().forceLocalOptimization();
394 // we've already simplified, no need to re-do simplification
395 mContext.vectorSimplifyMethod().setForceLocalOptimization( false );
396 mSubRenderer->renderFeature( feat, mContext );
397 mContext.vectorSimplifyMethod().setForceLocalOptimization( prevSimplify );
398 }
399 }
400
401 // when no features are visible, we still have to draw the exterior rectangle
402 // warning: when sub renderers have more than one possible symbols,
403 // there is no way to choose a correct one, because there is no attribute here
404 // in that case, nothing will be rendered
405 switch ( mOperation )
406 {
408 break;
411 if ( mFeaturesCategories.isEmpty() )
412 {
413 // empty feature with default attributes
414 QgsFeature feat( mFields );
415 feat.setGeometry( QgsGeometry::fromPolygonXY( mExtentPolygon ) );
416 mSubRenderer->renderFeature( feat, mContext );
417 }
418 break;
419 }
420
421 // draw feature decorations
422 for ( FeatureDecoration deco : std::as_const( mFeatureDecorations ) )
423 {
424 mSubRenderer->renderFeature( deco.feature, mContext, deco.layer, deco.selected, deco.drawMarkers );
425 }
426
427 mSubRenderer->stopRender( mContext );
428}
429
431{
432 if ( !mSubRenderer )
433 {
434 return QStringLiteral( "MERGED FEATURES: NULL" );
435 }
436 return "MERGED FEATURES [" + mSubRenderer->dump() + ']';
437}
438
440{
441 QgsMergedFeatureRenderer *newRenderer = nullptr;
442 if ( !mSubRenderer )
443 {
444 newRenderer = new QgsMergedFeatureRenderer( nullptr );
445 }
446 else
447 {
448 newRenderer = new QgsMergedFeatureRenderer( mSubRenderer->clone() );
449 }
450 copyRendererData( newRenderer );
451 return newRenderer;
452}
453
455{
457 //look for an embedded renderer <renderer-v2>
458 QDomElement embeddedRendererElem = element.firstChildElement( QStringLiteral( "renderer-v2" ) );
459 if ( !embeddedRendererElem.isNull() )
460 {
461 QgsFeatureRenderer *renderer = QgsFeatureRenderer::load( embeddedRendererElem, context );
462 r->setEmbeddedRenderer( renderer );
463 }
464 return r;
465}
466
467QDomElement QgsMergedFeatureRenderer::save( QDomDocument &doc, const QgsReadWriteContext &context )
468{
469 // clazy:skip
470
471 QDomElement rendererElem = doc.createElement( RENDERER_TAG_NAME );
472 rendererElem.setAttribute( QStringLiteral( "type" ), QStringLiteral( "mergedFeatureRenderer" ) );
473
474 if ( mSubRenderer )
475 {
476 QDomElement embeddedRendererElem = mSubRenderer->save( doc, context );
477 rendererElem.appendChild( embeddedRendererElem );
478 }
479
480 saveRendererData( doc, rendererElem, context );
481
482 return rendererElem;
483}
484
486{
487 if ( !mSubRenderer )
488 {
489 return nullptr;
490 }
491 return mSubRenderer->symbolForFeature( feature, context );
492}
493
495{
496 if ( !mSubRenderer )
497 return nullptr;
498 return mSubRenderer->originalSymbolForFeature( feature, context );
499}
500
502{
503 if ( !mSubRenderer )
504 {
505 return QgsSymbolList();
506 }
507 return mSubRenderer->symbolsForFeature( feature, context );
508}
509
511{
512 if ( !mSubRenderer )
513 return QgsSymbolList();
514 return mSubRenderer->originalSymbolsForFeature( feature, context );
515}
516
518{
519 if ( !mSubRenderer )
520 return QSet<QString>();
521 return mSubRenderer->legendKeysForFeature( feature, context );
522}
523
524QString QgsMergedFeatureRenderer::legendKeyToExpression( const QString &key, QgsVectorLayer *layer, bool &ok ) const
525{
526 ok = false;
527 if ( !mSubRenderer )
528 return QString();
529 return mSubRenderer->legendKeyToExpression( key, layer, ok );
530}
531
533{
534 if ( !mSubRenderer )
535 {
536 return QgsSymbolList();
537 }
538 return mSubRenderer->symbols( context );
539}
540
542{
543 if ( !mSubRenderer )
544 {
545 return Capabilities();
546 }
547 return mSubRenderer->capabilities();
548}
549
551{
552 if ( !mSubRenderer )
553 {
554 return QSet<QString>();
555 }
556 return mSubRenderer->usedAttributes( context );
557}
558
560{
561 return mSubRenderer ? mSubRenderer->filterNeedsGeometry() : false;
562}
563
565{
566 if ( !mSubRenderer )
567 {
568 return QgsLegendSymbolList();
569 }
570 return mSubRenderer->legendSymbolItems();
571}
572
574{
575 if ( !mSubRenderer )
576 {
577 return false;
578 }
579 return mSubRenderer->willRenderFeature( feature, context );
580}
581
583{
584 if ( renderer->type() == QLatin1String( "mergedFeatureRenderer" ) )
585 {
586 return dynamic_cast<QgsMergedFeatureRenderer *>( renderer->clone() );
587 }
588
589 if ( renderer->type() == QLatin1String( "singleSymbol" ) ||
590 renderer->type() == QLatin1String( "categorizedSymbol" ) ||
591 renderer->type() == QLatin1String( "graduatedSymbol" ) ||
592 renderer->type() == QLatin1String( "RuleRenderer" ) )
593 {
594 auto res = std::make_unique< QgsMergedFeatureRenderer >( renderer->clone() );
595 renderer->copyRendererData( res.get() );
596 return res.release();
597 }
598 else if ( renderer->type() == QLatin1String( "invertedPolygonRenderer" ) )
599 {
600 auto res = std::make_unique< QgsMergedFeatureRenderer >( renderer->embeddedRenderer() ? renderer->embeddedRenderer()->clone() : nullptr );
601 renderer->copyRendererData( res.get() );
602 return res.release();
603 }
604 return nullptr;
605}
606
QFlags< FeatureRendererFlag > FeatureRendererFlags
Flags controlling behavior of vector feature renderers.
Definition qgis.h:838
@ Line
Lines.
Definition qgis.h:360
WkbType
The WKB type describes the number of dimensions a geometry has.
Definition qgis.h:277
@ Polygon
Polygon.
Definition qgis.h:281
@ MultiPolygon
MultiPolygon.
Definition qgis.h:285
@ CurvePolygon
CurvePolygon.
Definition qgis.h:289
@ MultiSurface
MultiSurface.
Definition qgis.h:291
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:58
QgsGeometry geometry
Definition qgsfeature.h:69
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:90
QVector< QgsPointXY > QgsPolylineXY
Polyline as represented as a vector of two-dimensional points.
Definition qgsgeometry.h:61
QVector< QgsPolygonXY > QgsMultiPolygonXY
A collection of QgsPolygons that share a common collection of attributes.
QList< QgsLegendSymbolItem > QgsLegendSymbolList
#define RENDERER_TAG_NAME
Definition qgsrenderer.h:55
QList< QgsSymbol * > QgsSymbolList
Definition qgsrenderer.h:49