QGIS API Documentation  3.26.3-Buenos Aires (65e4edfdad)
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"
27 #include "qgspainteffectregistry.h"
28 #include "qgsstyleentityvisitor.h"
29 
30 #include <QDomDocument>
31 #include <QDomElement>
32 
34  : QgsMergedFeatureRenderer( QStringLiteral( "mergedFeatureRenderer" ), subRenderer )
35 {
36 
37 }
38 
40  : QgsFeatureRenderer( type )
41 {
42  if ( subRenderer )
43  {
44  mSubRenderer.reset( subRenderer );
45  }
46 }
47 
49 {
50  mSubRenderer.reset( subRenderer );
51 }
52 
54 {
55  return mSubRenderer.get();
56 }
57 
58 void QgsMergedFeatureRenderer::setLegendSymbolItem( const QString &key, QgsSymbol *symbol )
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 
82 void 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
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 
168 bool QgsMergedFeatureRenderer::renderFeature( const QgsFeature &feature, QgsRenderContext &context, int layer, bool selected, bool drawVertexMarker )
169 {
170  if ( !context.painter() || !mSubRenderer )
171  {
172  return false;
173  }
174 
175  // store this feature as a feature to render with decoration if needed
176  if ( selected || drawVertexMarker )
177  {
178  mFeatureDecorations.append( FeatureDecoration( feature, selected, drawVertexMarker, layer ) );
179  }
180 
181  // Features are grouped by category of symbols (returned by symbol(s)ForFeature)
182  // This way, users can have multiple inverted polygon fills for a layer,
183  // for instance, with rule based renderer and different symbols
184  // that have transparency.
185  //
186  // In order to assign a unique category to a set of symbols
187  // during each rendering session (between startRender() and stopRender()),
188  // we build an unique id as a QByteArray that is the concatenation
189  // of each symbol's memory address.
190  // The only assumption made here is that symbol(s)ForFeature will
191  // always return the same address for the same symbol(s) shared amongst
192  // different features.
193  // This QByteArray can then be used as a key for a QMap where the list of
194  // features for this category is stored
195  QByteArray catId;
197  {
198  const QgsSymbolList syms( mSubRenderer->symbolsForFeature( feature, context ) );
199  for ( QgsSymbol *sym : syms )
200  {
201  // append the memory address
202  catId.append( reinterpret_cast<const char *>( &sym ), sizeof( sym ) );
203  }
204  }
205  else
206  {
207  if ( QgsSymbol *sym = mSubRenderer->symbolForFeature( feature, context ) )
208  {
209  catId.append( reinterpret_cast<const char *>( &sym ), sizeof( sym ) );
210  }
211  }
212 
213  if ( catId.isEmpty() )
214  {
215  return false;
216  }
217 
218  if ( ! mSymbolCategories.contains( catId ) )
219  {
220  CombinedFeature cFeat;
221  // store the first feature
222  cFeat.feature = feature;
223  mSymbolCategories.insert( catId, mSymbolCategories.count() );
224  mFeaturesCategories.append( cFeat );
225  }
226 
227  // update the geometry
228  CombinedFeature &cFeat = mFeaturesCategories[ mSymbolCategories[catId] ];
229  if ( !feature.hasGeometry() )
230  {
231  return false;
232  }
233  QgsGeometry geom = feature.geometry();
234 
236  if ( xform.isValid() )
237  {
238  geom.transform( xform );
239  }
240 
241  switch ( mOperation )
242  {
244  // fix the polygon if it is not valid
245  if ( ! geom.isGeosValid() )
246  {
247  geom = geom.buffer( 0, 0 );
248  }
249  break;
250 
252  case QgsMergedFeatureRenderer::Merge: // maybe we should also fix for this? not sure if the fixing step was only required for the differencing operation...
253  break;
254  }
255 
256  if ( geom.isNull() )
257  return false; // do not let invalid geometries sneak in!
258 
259  // add the geometry to the list of geometries for this feature
260  cFeat.geometries.append( geom );
261 
262  return true;
263 }
264 
266 {
268  if ( context.renderingStopped() )
269  {
270  if ( mSubRenderer )
271  mSubRenderer->stopRender( mContext );
272  return;
273  }
274 
275  if ( !mSubRenderer )
276  {
277  return;
278  }
279  if ( !context.painter() )
280  {
281  return;
282  }
283 
284  QgsMultiPolygonXY finalMulti; //avoid expensive allocation for list for every feature
285  QgsPolygonXY newPoly;
286 
287  for ( const CombinedFeature &cit : std::as_const( mFeaturesCategories ) )
288  {
289  finalMulti.resize( 0 ); //preserve capacity - don't use clear!
290  QgsFeature feat = cit.feature; // just a copy, so that we do not accumulate geometries again
291 
292  switch ( mOperation )
293  {
295  {
296  QgsGeometry unioned( QgsGeometry::unaryUnion( cit.geometries ) );
297  if ( unioned.type() == QgsWkbTypes::LineGeometry )
298  unioned = unioned.mergeLines();
299  feat.setGeometry( unioned );
300  break;
301  }
302 
304  {
305  // compute the unary union on the polygons
306  const QgsGeometry unioned( QgsGeometry::unaryUnion( cit.geometries ) );
307  // compute the difference with the extent
308  const QgsGeometry rect = QgsGeometry::fromPolygonXY( mExtentPolygon );
309  const QgsGeometry final = rect.difference( unioned );
310  feat.setGeometry( final );
311  break;
312  }
313 
315  {
316  // No preprocessing involved.
317  // We build here a "reversed" geometry of all the polygons
318  //
319  // The final geometry is a multipolygon F, with :
320  // * the first polygon of F having the current extent as its exterior ring
321  // * each polygon's exterior ring is added as interior ring of the first polygon of F
322  // * each polygon's interior ring is added as new polygons in F
323  //
324  // No validity check is done, on purpose, it will be very slow and painting
325  // operations do not need geometries to be valid
326 
327  finalMulti.append( mExtentPolygon );
328  for ( const QgsGeometry &geom : std::as_const( cit.geometries ) )
329  {
330  QgsMultiPolygonXY multi;
331  QgsWkbTypes::Type type = QgsWkbTypes::flatType( geom.constGet()->wkbType() );
332 
334  {
335  multi.append( geom.asPolygon() );
336  }
337  else if ( ( type == QgsWkbTypes::MultiPolygon ) || ( type == QgsWkbTypes::MultiSurface ) )
338  {
339  multi = geom.asMultiPolygon();
340  }
341 
342  for ( int i = 0; i < multi.size(); i++ )
343  {
344  const QgsPolylineXY &exterior = multi[i][0];
345  // add the exterior ring as interior ring to the first polygon
346  // make sure it satisfies at least very basic requirements of GEOS
347  // (otherwise the creation of GEOS geometry will fail)
348  if ( exterior.count() < 4 || exterior[0] != exterior[exterior.count() - 1] )
349  continue;
350  finalMulti[0].append( exterior );
351 
352  // add interior rings as new polygons
353  for ( int j = 1; j < multi[i].size(); j++ )
354  {
355  newPoly.resize( 0 ); //preserve capacity - don't use clear!
356  newPoly.append( multi[i][j] );
357  finalMulti.append( newPoly );
358  }
359  }
360  }
361  feat.setGeometry( QgsGeometry::fromMultiPolygonXY( finalMulti ) );
362  break;
363  }
364  }
365 
366  if ( feat.hasGeometry() )
367  {
368  mContext.expressionContext().setFeature( feat );
369  mSubRenderer->renderFeature( feat, mContext );
370  }
371  }
372 
373  // when no features are visible, we still have to draw the exterior rectangle
374  // warning: when sub renderers have more than one possible symbols,
375  // there is no way to choose a correct one, because there is no attribute here
376  // in that case, nothing will be rendered
377  switch ( mOperation )
378  {
380  break;
383  if ( mFeaturesCategories.isEmpty() )
384  {
385  // empty feature with default attributes
386  QgsFeature feat( mFields );
387  feat.setGeometry( QgsGeometry::fromPolygonXY( mExtentPolygon ) );
388  mSubRenderer->renderFeature( feat, mContext );
389  }
390  break;
391  }
392 
393  // draw feature decorations
394  for ( FeatureDecoration deco : std::as_const( mFeatureDecorations ) )
395  {
396  mSubRenderer->renderFeature( deco.feature, mContext, deco.layer, deco.selected, deco.drawMarkers );
397  }
398 
399  mSubRenderer->stopRender( mContext );
400 }
401 
403 {
404  if ( !mSubRenderer )
405  {
406  return QStringLiteral( "MERGED FEATURES: NULL" );
407  }
408  return "MERGED FEATURES [" + mSubRenderer->dump() + ']';
409 }
410 
412 {
413  QgsMergedFeatureRenderer *newRenderer = nullptr;
414  if ( !mSubRenderer )
415  {
416  newRenderer = new QgsMergedFeatureRenderer( nullptr );
417  }
418  else
419  {
420  newRenderer = new QgsMergedFeatureRenderer( mSubRenderer->clone() );
421  }
422  copyRendererData( newRenderer );
423  return newRenderer;
424 }
425 
427 {
429  //look for an embedded renderer <renderer-v2>
430  QDomElement embeddedRendererElem = element.firstChildElement( QStringLiteral( "renderer-v2" ) );
431  if ( !embeddedRendererElem.isNull() )
432  {
433  QgsFeatureRenderer *renderer = QgsFeatureRenderer::load( embeddedRendererElem, context );
434  r->setEmbeddedRenderer( renderer );
435  }
436  return r;
437 }
438 
439 QDomElement QgsMergedFeatureRenderer::save( QDomDocument &doc, const QgsReadWriteContext &context )
440 {
441  // clazy:skip
442 
443  QDomElement rendererElem = doc.createElement( RENDERER_TAG_NAME );
444  rendererElem.setAttribute( QStringLiteral( "type" ), QStringLiteral( "mergedFeatureRenderer" ) );
445 
446  if ( mSubRenderer )
447  {
448  QDomElement embeddedRendererElem = mSubRenderer->save( doc, context );
449  rendererElem.appendChild( embeddedRendererElem );
450  }
451 
452  saveRendererData( doc, rendererElem, context );
453 
454  return rendererElem;
455 }
456 
458 {
459  if ( !mSubRenderer )
460  {
461  return nullptr;
462  }
463  return mSubRenderer->symbolForFeature( feature, context );
464 }
465 
467 {
468  if ( !mSubRenderer )
469  return nullptr;
470  return mSubRenderer->originalSymbolForFeature( feature, context );
471 }
472 
474 {
475  if ( !mSubRenderer )
476  {
477  return QgsSymbolList();
478  }
479  return mSubRenderer->symbolsForFeature( feature, context );
480 }
481 
483 {
484  if ( !mSubRenderer )
485  return QgsSymbolList();
486  return mSubRenderer->originalSymbolsForFeature( feature, context );
487 }
488 
489 QSet<QString> QgsMergedFeatureRenderer::legendKeysForFeature( const QgsFeature &feature, QgsRenderContext &context ) const
490 {
491  if ( !mSubRenderer )
492  return QSet<QString>();
493  return mSubRenderer->legendKeysForFeature( feature, context );
494 }
495 
496 QString QgsMergedFeatureRenderer::legendKeyToExpression( const QString &key, QgsVectorLayer *layer, bool &ok ) const
497 {
498  ok = false;
499  if ( !mSubRenderer )
500  return QString();
501  return mSubRenderer->legendKeyToExpression( key, layer, ok );
502 }
503 
505 {
506  if ( !mSubRenderer )
507  {
508  return QgsSymbolList();
509  }
510  return mSubRenderer->symbols( context );
511 }
512 
513 QgsFeatureRenderer::Capabilities QgsMergedFeatureRenderer::capabilities()
514 {
515  if ( !mSubRenderer )
516  {
517  return Capabilities();
518  }
519  return mSubRenderer->capabilities();
520 }
521 
522 QSet<QString> QgsMergedFeatureRenderer::usedAttributes( const QgsRenderContext &context ) const
523 {
524  if ( !mSubRenderer )
525  {
526  return QSet<QString>();
527  }
528  return mSubRenderer->usedAttributes( context );
529 }
530 
532 {
533  return mSubRenderer ? mSubRenderer->filterNeedsGeometry() : false;
534 }
535 
537 {
538  if ( !mSubRenderer )
539  {
540  return QgsLegendSymbolList();
541  }
542  return mSubRenderer->legendSymbolItems();
543 }
544 
546 {
547  if ( !mSubRenderer )
548  {
549  return false;
550  }
551  return mSubRenderer->willRenderFeature( feature, context );
552 }
553 
555 {
556  if ( renderer->type() == QLatin1String( "mergedFeatureRenderer" ) )
557  {
558  return dynamic_cast<QgsMergedFeatureRenderer *>( renderer->clone() );
559  }
560 
561  if ( renderer->type() == QLatin1String( "singleSymbol" ) ||
562  renderer->type() == QLatin1String( "categorizedSymbol" ) ||
563  renderer->type() == QLatin1String( "graduatedSymbol" ) ||
564  renderer->type() == QLatin1String( "RuleRenderer" ) )
565  {
566  std::unique_ptr< QgsMergedFeatureRenderer > res = std::make_unique< QgsMergedFeatureRenderer >( renderer->clone() );
567  renderer->copyRendererData( res.get() );
568  return res.release();
569  }
570  else if ( renderer->type() == QLatin1String( "invertedPolygonRenderer" ) )
571  {
572  std::unique_ptr< QgsMergedFeatureRenderer > res = std::make_unique< QgsMergedFeatureRenderer >( renderer->embeddedRenderer() ? renderer->embeddedRenderer()->clone() : nullptr );
573  renderer->copyRendererData( res.get() );
574  return res.release();
575  }
576  return nullptr;
577 }
578 
QgsFeatureRenderer::copyRendererData
void copyRendererData(QgsFeatureRenderer *destRenderer) const
Clones generic renderer data to another renderer.
Definition: qgsrenderer.cpp:52
QgsMergedFeatureRenderer::capabilities
QgsFeatureRenderer::Capabilities capabilities() override
Returns details about internals of this renderer.
Definition: qgsmergedfeaturerenderer.cpp:513
QgsRectangle::height
double height() const SIP_HOLDGIL
Returns the height of the rectangle.
Definition: qgsrectangle.h:230
QgsMergedFeatureRenderer::checkLegendSymbolItem
void checkLegendSymbolItem(const QString &key, bool state=true) override
item in symbology was checked
Definition: qgsmergedfeaturerenderer.cpp:82
QgsMergedFeatureRenderer::dump
QString dump() const override
Returns debug information about this renderer.
Definition: qgsmergedfeaturerenderer.cpp:402
QgsRenderContext::expressionContext
QgsExpressionContext & expressionContext()
Gets the expression context.
Definition: qgsrendercontext.h:625
QgsMergedFeatureRenderer::filterNeedsGeometry
bool filterNeedsGeometry() const override
Returns true if this renderer requires the geometry to apply the filter.
Definition: qgsmergedfeaturerenderer.cpp:531
QgsReadWriteContext
The class is used as a container of context for various read/write operations on other objects.
Definition: qgsreadwritecontext.h:34
QgsMergedFeatureRenderer::save
QDomElement save(QDomDocument &doc, const QgsReadWriteContext &context) override
Stores renderer properties to an XML element.
Definition: qgsmergedfeaturerenderer.cpp:439
QgsPolygonXY
QVector< QgsPolylineXY > QgsPolygonXY
Polygon: first item of the list is outer ring, inner rings (if any) start from second item.
Definition: qgsgeometry.h:76
QgsWkbTypes::MultiPolygon
@ MultiPolygon
Definition: qgswkbtypes.h:78
QgsGeometry::transform
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.
Definition: qgsgeometry.cpp:3128
QgsMergedFeatureRenderer::mOperation
GeometryOperation mOperation
Operation to apply to collected geometries.
Definition: qgsmergedfeaturerenderer.h:140
qgsmergedfeaturerenderer.h
QgsWkbTypes::flatType
static Type flatType(Type type) SIP_HOLDGIL
Returns the flat type for a WKB type.
Definition: qgswkbtypes.h:732
QgsPolylineXY
QVector< QgsPointXY > QgsPolylineXY
Polyline as represented as a vector of two-dimensional points.
Definition: qgsgeometry.h:52
qgssymbollayerutils.h
QgsFields
Container of fields for a vector layer.
Definition: qgsfields.h:44
QgsMergedFeatureRenderer::legendSymbolItemsCheckable
bool legendSymbolItemsCheckable() const override
items of symbology items in legend should be checkable
Definition: qgsmergedfeaturerenderer.cpp:66
qgsfeature.h
QgsMergedFeatureRenderer::symbolForFeature
QgsSymbol * symbolForFeature(const QgsFeature &feature, QgsRenderContext &context) const override
To be overridden.
Definition: qgsmergedfeaturerenderer.cpp:457
QgsFeatureRenderer::type
QString type() const
Definition: qgsrenderer.h:142
QgsFeature::geometry
QgsGeometry geometry
Definition: qgsfeature.h:71
QgsRectangle::toRectF
QRectF toRectF() const
Returns a QRectF with same coordinates as the rectangle.
Definition: qgsrectangle.h:500
QgsRenderContext
Contains information about the context of a rendering operation.
Definition: qgsrendercontext.h:59
QgsMultiPolygonXY
QVector< QgsPolygonXY > QgsMultiPolygonXY
A collection of QgsPolygons that share a common collection of attributes.
Definition: qgsgeometry.h:93
QgsMergedFeatureRenderer::originalSymbolForFeature
QgsSymbol * originalSymbolForFeature(const QgsFeature &feature, QgsRenderContext &context) const override
Returns symbol for feature.
Definition: qgsmergedfeaturerenderer.cpp:466
QgsStyleEntityVisitorInterface
An interface for classes which can visit style entity (e.g. symbol) nodes (using the visitor pattern)...
Definition: qgsstyleentityvisitor.h:33
qgspainteffectregistry.h
QgsWkbTypes::Type
Type
The WKB type describes the number of dimensions a geometry has.
Definition: qgswkbtypes.h:69
QgsMergedFeatureRenderer::QgsMergedFeatureRenderer
QgsMergedFeatureRenderer(QgsFeatureRenderer *embeddedRenderer)
Constructor for QgsMergedFeatureRenderer.
Definition: qgsmergedfeaturerenderer.cpp:33
QgsSymbol
Abstract base class for all rendered symbols.
Definition: qgssymbol.h:92
qgspainteffect.h
QgsCoordinateTransform::isValid
bool isValid() const
Returns true if the coordinate transform is valid, ie both the source and destination CRS have been s...
Definition: qgscoordinatetransform.cpp:900
QgsMergedFeatureRenderer::accept
bool accept(QgsStyleEntityVisitorInterface *visitor) const override
Accepts the specified symbology visitor, causing it to visit all symbols associated with the renderer...
Definition: qgsmergedfeaturerenderer.cpp:90
QgsGeometry::buffer
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...
Definition: qgsgeometry.cpp:2050
QgsFeatureRenderer::load
static QgsFeatureRenderer * load(QDomElement &symbologyElem, const QgsReadWriteContext &context)
create a renderer from XML element
Definition: qgsrenderer.cpp:157
qgsogcutils.h
QgsFeatureRenderer::stopRender
virtual void stopRender(QgsRenderContext &context)
Must be called when a render cycle has finished, to allow the renderer to clean up.
Definition: qgsrenderer.cpp:110
QgsGeometry::mergeLines
QgsGeometry mergeLines() const
Merges any connected lines in a LineString/MultiLineString geometry and converts them to single line ...
Definition: qgsgeometry.cpp:2657
QgsRenderContext::renderingStopped
bool renderingStopped() const
Returns true if the rendering operation has been stopped and any ongoing rendering should be canceled...
Definition: qgsrendercontext.h:285
QgsRenderContext::coordinateTransform
QgsCoordinateTransform coordinateTransform() const
Returns the current coordinate transform for the context.
Definition: qgsrendercontext.h:178
QgsMergedFeatureRenderer::MergeAndInvert
@ MergeAndInvert
Merge and invert features (polygons only)
Definition: qgsmergedfeaturerenderer.h:136
QgsFeature::setGeometry
void setGeometry(const QgsGeometry &geometry)
Set the feature's geometry.
Definition: qgsfeature.cpp:170
QgsSymbolList
QList< QgsSymbol * > QgsSymbolList
Definition: qgsrenderer.h:44
QgsRenderContext::setExtent
void setExtent(const QgsRectangle &extent)
When rendering a map layer, calling this method sets the "clipping" extent for the layer (in the laye...
Definition: qgsrendercontext.h:426
QgsFeatureRenderer::saveRendererData
void saveRendererData(QDomDocument &doc, QDomElement &element, const QgsReadWriteContext &context)
Saves generic renderer data into the specified element.
Definition: qgsrenderer.cpp:204
QgsFeatureRenderer::clone
virtual QgsFeatureRenderer * clone() const =0
Create a deep copy of this renderer.
QgsRenderContext::setCoordinateTransform
void setCoordinateTransform(const QgsCoordinateTransform &t)
Sets the current coordinate transform for the context.
Definition: qgsrendercontext.cpp:320
QgsMergedFeatureRenderer::legendKeyToExpression
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...
Definition: qgsmergedfeaturerenderer.cpp:496
QgsMergedFeatureRenderer::legendSymbolItems
QgsLegendSymbolList legendSymbolItems() const override
Returns a list of symbology items for the legend.
Definition: qgsmergedfeaturerenderer.cpp:536
QgsMergedFeatureRenderer::willRenderFeature
bool willRenderFeature(const QgsFeature &feature, QgsRenderContext &context) const override
Returns whether the renderer will render a feature or not.
Definition: qgsmergedfeaturerenderer.cpp:545
QgsWkbTypes::CurvePolygon
@ CurvePolygon
Definition: qgswkbtypes.h:82
RENDERER_TAG_NAME
#define RENDERER_TAG_NAME
Definition: qgsrenderer.h:50
QgsMergedFeatureRenderer::embeddedRenderer
const QgsFeatureRenderer * embeddedRenderer() const override
Returns the current embedded renderer (subrenderer) for this feature renderer.
Definition: qgsmergedfeaturerenderer.cpp:53
QgsMergedFeatureRenderer::setEmbeddedRenderer
void setEmbeddedRenderer(QgsFeatureRenderer *subRenderer) override
Sets an embedded renderer (subrenderer) for this feature renderer.
Definition: qgsmergedfeaturerenderer.cpp:48
QgsMergedFeatureRenderer::stopRender
void stopRender(QgsRenderContext &context) override
The actual rendering will take place here.
Definition: qgsmergedfeaturerenderer.cpp:265
QgsFeatureRenderer::MoreSymbolsPerFeature
@ MoreSymbolsPerFeature
May use more than one symbol to render a feature: symbolsForFeature() will return them.
Definition: qgsrenderer.h:264
qgssymbollayer.h
QgsGeometry::isNull
bool isNull
Definition: qgsgeometry.h:127
QgsRectangle::buffered
QgsRectangle buffered(double width) const
Gets rectangle enlarged by buffer.
Definition: qgsrectangle.h:325
QgsMergedFeatureRenderer::startRender
void startRender(QgsRenderContext &context, const QgsFields &fields) override
Must be called when a new render cycle is started.
Definition: qgsmergedfeaturerenderer.cpp:98
QgsMergedFeatureRenderer::renderFeature
bool renderFeature(const QgsFeature &feature, QgsRenderContext &context, int layer=-1, bool selected=false, bool drawVertexMarker=false) override SIP_THROW(QgsCsException)
Renders a given feature.
Definition: qgsmergedfeaturerenderer.cpp:168
qgsvectorlayer.h
QgsMergedFeatureRenderer::symbols
QgsSymbolList symbols(QgsRenderContext &context) const override
Returns list of symbols used by the renderer.
Definition: qgsmergedfeaturerenderer.cpp:504
QgsMergedFeatureRenderer::convertFromRenderer
static QgsMergedFeatureRenderer * convertFromRenderer(const QgsFeatureRenderer *renderer)
Creates a QgsMergedFeatureRenderer by a conversion from an existing renderer.
Definition: qgsmergedfeaturerenderer.cpp:554
QgsWkbTypes::LineGeometry
@ LineGeometry
Definition: qgswkbtypes.h:143
QgsRenderContext::mapExtent
QgsRectangle mapExtent() const
Returns the original extent of the map being rendered.
Definition: qgsrendercontext.h:251
QgsGeometry::fromPolygonXY
static QgsGeometry fromPolygonXY(const QgsPolygonXY &polygon)
Creates a new geometry from a QgsPolygonXY.
Definition: qgsgeometry.cpp:201
QgsWkbTypes::MultiSurface
@ MultiSurface
Definition: qgswkbtypes.h:84
QgsFeatureRenderer
Definition: qgsrenderer.h:101
QgsGeometry
A geometry is the spatial representation of a feature.
Definition: qgsgeometry.h:124
QgsVectorLayer
Represents a vector layer which manages a vector based data sets.
Definition: qgsvectorlayer.h:391
QgsFeature::hasGeometry
bool hasGeometry() const
Returns true if the feature has an associated geometry.
Definition: qgsfeature.cpp:230
QgsRectangle::width
double width() const SIP_HOLDGIL
Returns the width of the rectangle.
Definition: qgsrectangle.h:223
QgsWkbTypes::Polygon
@ Polygon
Definition: qgswkbtypes.h:74
QgsMergedFeatureRenderer::usedAttributes
QSet< QString > usedAttributes(const QgsRenderContext &context) const override
Returns a list of attributes required by this renderer.
Definition: qgsmergedfeaturerenderer.cpp:522
QgsMergedFeatureRenderer::Merge
@ Merge
Merge features (union/dissolve)
Definition: qgsmergedfeaturerenderer.h:134
QgsMergedFeatureRenderer::InvertOnly
@ InvertOnly
Invert features only (polygons only)
Definition: qgsmergedfeaturerenderer.h:135
QgsMergedFeatureRenderer
QgsMergedFeatureRenderer is a polygon or line-only feature renderer used to renderer a set of feature...
Definition: qgsmergedfeaturerenderer.h:40
QgsFeature
The feature class encapsulates a single feature including its unique ID, geometry and a list of field...
Definition: qgsfeature.h:55
QgsMergedFeatureRenderer::legendKeysForFeature
QSet< QString > legendKeysForFeature(const QgsFeature &feature, QgsRenderContext &context) const override
Returns legend keys matching a specified feature.
Definition: qgsmergedfeaturerenderer.cpp:489
qgslogger.h
QgsMergedFeatureRenderer::setLegendSymbolItem
void setLegendSymbolItem(const QString &key, QgsSymbol *symbol) override
Sets the symbol to be used for a legend symbol item.
Definition: qgsmergedfeaturerenderer.cpp:58
QgsRenderContext::painter
QPainter * painter()
Returns the destination QPainter for the render operation.
Definition: qgsrendercontext.h:112
QgsMergedFeatureRenderer::create
static QgsFeatureRenderer * create(QDomElement &element, const QgsReadWriteContext &context)
Creates a renderer out of an XML, for loading.
Definition: qgsmergedfeaturerenderer.cpp:426
QgsCoordinateTransform
Class for doing transforms between two map coordinate systems.
Definition: qgscoordinatetransform.h:57
QgsLegendSymbolList
QList< QgsLegendSymbolItem > QgsLegendSymbolList
Definition: qgslegendsymbolitem.h:144
QgsFeatureRenderer::startRender
virtual void startRender(QgsRenderContext &context, const QgsFields &fields)
Must be called when a new render cycle is started.
Definition: qgsrenderer.cpp:96
QgsGeometry::type
QgsWkbTypes::GeometryType type
Definition: qgsgeometry.h:128
QgsMergedFeatureRenderer::mSubRenderer
std::unique_ptr< QgsFeatureRenderer > mSubRenderer
Embedded renderer.
Definition: qgsmergedfeaturerenderer.h:143
QgsMergedFeatureRenderer::clone
QgsMergedFeatureRenderer * clone() const override
Create a deep copy of this renderer.
Definition: qgsmergedfeaturerenderer.cpp:411
QgsMergedFeatureRenderer::legendSymbolItemChecked
bool legendSymbolItemChecked(const QString &key) override
items of symbology items in legend is checked
Definition: qgsmergedfeaturerenderer.cpp:74
QgsFeatureRenderer::embeddedRenderer
virtual const QgsFeatureRenderer * embeddedRenderer() const
Returns the current embedded renderer (subrenderer) for this feature renderer.
Definition: qgsrenderer.cpp:484
qgssymbol.h
QgsGeometry::difference
QgsGeometry difference(const QgsGeometry &geometry) const
Returns a geometry representing the points making up this geometry that do not make up other.
Definition: qgsgeometry.cpp:2677
QgsMergedFeatureRenderer::symbolsForFeature
QgsSymbolList symbolsForFeature(const QgsFeature &feature, QgsRenderContext &context) const override
Returns list of symbols used for rendering the feature.
Definition: qgsmergedfeaturerenderer.cpp:473
QgsGeometry::fromMultiPolygonXY
static QgsGeometry fromMultiPolygonXY(const QgsMultiPolygonXY &multipoly)
Creates a new geometry from a QgsMultiPolygonXY.
Definition: qgsgeometry.cpp:231
qgsstyleentityvisitor.h
QgsGeometry::unaryUnion
static QgsGeometry unaryUnion(const QVector< QgsGeometry > &geometries)
Compute the unary union on a list of geometries.
Definition: qgsgeometry.cpp:3079
QgsGeometry::isGeosValid
bool isGeosValid(Qgis::GeometryValidityFlags flags=Qgis::GeometryValidityFlags()) const
Checks validity of the geometry using GEOS.
Definition: qgsgeometry.cpp:3019
QgsExpressionContext::setFeature
void setFeature(const QgsFeature &feature)
Convenience function for setting a feature for the context.
Definition: qgsexpressioncontext.cpp:525
QgsMergedFeatureRenderer::originalSymbolsForFeature
QgsSymbolList originalSymbolsForFeature(const QgsFeature &feature, QgsRenderContext &context) const override
Equivalent of originalSymbolsForFeature() call extended to support renderers that may use more symbol...
Definition: qgsmergedfeaturerenderer.cpp:482