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