QGIS API Documentation  3.14.0-Pi (9f7028fd23)
qgsinvertedpolygonrenderer.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsinvertedpolygonrenderer.cpp
3  ---------------------
4  begin : April 2014
5  copyright : (C) 2014 Hugo Mercier / Oslandia
6  email : hugo dot mercier at oslandia 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  : QgsFeatureRenderer( QStringLiteral( "invertedPolygonRenderer" ) )
35 {
36  if ( subRenderer )
37  {
38  setEmbeddedRenderer( subRenderer );
39  }
40  else
41  {
43  }
44 }
45 
47 {
48  if ( subRenderer )
49  {
50  mSubRenderer.reset( subRenderer );
51  }
52  else
53  {
54  mSubRenderer.reset( nullptr );
55  }
56 }
57 
59 {
60  return mSubRenderer.get();
61 }
62 
64 {
65  if ( !mSubRenderer )
66  return;
67 
68  mSubRenderer->setLegendSymbolItem( key, symbol );
69 }
70 
72 {
73  if ( !mSubRenderer )
74  return false;
75 
76  return mSubRenderer->legendSymbolItemsCheckable();
77 }
78 
80 {
81  if ( !mSubRenderer )
82  return false;
83 
84  return mSubRenderer->legendSymbolItemChecked( key );
85 }
86 
87 void QgsInvertedPolygonRenderer::checkLegendSymbolItem( const QString &key, bool state )
88 {
89  if ( !mSubRenderer )
90  return;
91 
92  mSubRenderer->checkLegendSymbolItem( key, state );
93 }
94 
96 {
97  if ( !mSubRenderer )
98  return true;
99 
100  return mSubRenderer->accept( visitor );
101 }
102 
104 {
105  QgsFeatureRenderer::startRender( context, fields );
106 
107  if ( !mSubRenderer )
108  {
109  return;
110  }
111 
112  // first call start render on the sub renderer
113  mSubRenderer->startRender( context, fields );
114 
115  mFeaturesCategories.clear();
116  mSymbolCategories.clear();
117  mFeatureDecorations.clear();
118  mFields = fields;
119 
120  // We compute coordinates of the extent which will serve as exterior ring
121  // for the final polygon
122  // It must be computed in the destination CRS if reprojection is enabled.
123 
124  if ( !context.painter() )
125  {
126  return;
127  }
128 
129  // convert viewport to dest CRS
130  // add some space to hide borders and tend to infinity
131  const double buffer = std::max( context.mapExtent().width(), context.mapExtent().height() ) * 0.1;
132  const QRectF outer = context.mapExtent().buffered( buffer ).toRectF();
133  QgsPolylineXY exteriorRing;
134  exteriorRing.reserve( 5 );
135  exteriorRing << outer.topLeft();
136  exteriorRing << outer.topRight();
137  exteriorRing << outer.bottomRight();
138  exteriorRing << outer.bottomLeft();
139  exteriorRing << outer.topLeft();
140 
141  // copy the rendering context
142  mContext = context;
143 
144  // If reprojection is enabled, we must reproject during renderFeature
145  // and act as if there is no reprojection
146  // If we don't do that, there is no need to have a simple rectangular extent
147  // that covers the whole screen
148  // (a rectangle in the destCRS cannot be expressed as valid coordinates in the sourceCRS in general)
149  if ( context.coordinateTransform().isValid() )
150  {
151  // disable projection
153  // recompute extent so that polygon clipping is correct
154  mContext.setExtent( context.mapExtent() );
155  // do we have to recompute the MapToPixel ?
156  }
157 
158  mExtentPolygon.clear();
159  mExtentPolygon.append( exteriorRing );
160 }
161 
162 bool QgsInvertedPolygonRenderer::renderFeature( const QgsFeature &feature, QgsRenderContext &context, int layer, bool selected, bool drawVertexMarker )
163 {
164  if ( !context.painter() )
165  {
166  return false;
167  }
168 
169  // store this feature as a feature to render with decoration if needed
170  if ( selected || drawVertexMarker )
171  {
172  mFeatureDecorations.append( FeatureDecoration( feature, selected, drawVertexMarker, layer ) );
173  }
174 
175  // Features are grouped by category of symbols (returned by symbol(s)ForFeature)
176  // This way, users can have multiple inverted polygon fills for a layer,
177  // for instance, with rule based renderer and different symbols
178  // that have transparency.
179  //
180  // In order to assign a unique category to a set of symbols
181  // during each rendering session (between startRender() and stopRender()),
182  // we build an unique id as a QByteArray that is the concatenation
183  // of each symbol's memory address.
184  // The only assumption made here is that symbol(s)ForFeature will
185  // always return the same address for the same symbol(s) shared amongst
186  // different features.
187  // This QByteArray can then be used as a key for a QMap where the list of
188  // features for this category is stored
189  QByteArray catId;
191  {
192  QgsSymbolList syms( mSubRenderer->symbolsForFeature( feature, context ) );
193  const auto constSyms = syms;
194  for ( QgsSymbol *sym : constSyms )
195  {
196  // append the memory address
197  catId.append( reinterpret_cast<const char *>( &sym ), sizeof( sym ) );
198  }
199  }
200  else
201  {
202  QgsSymbol *sym = mSubRenderer->symbolForFeature( feature, context );
203  if ( sym )
204  {
205  catId.append( reinterpret_cast<const char *>( &sym ), sizeof( sym ) );
206  }
207  }
208 
209  if ( catId.isEmpty() )
210  {
211  return false;
212  }
213 
214  if ( ! mSymbolCategories.contains( catId ) )
215  {
216  CombinedFeature cFeat;
217  // store the first feature
218  cFeat.feature = feature;
219  mSymbolCategories.insert( catId, mSymbolCategories.count() );
220  mFeaturesCategories.append( cFeat );
221  }
222 
223  // update the geometry
224  CombinedFeature &cFeat = mFeaturesCategories[ mSymbolCategories[catId] ];
225  if ( !feature.hasGeometry() )
226  {
227  return false;
228  }
229  QgsGeometry geom = feature.geometry();
230 
232  if ( xform.isValid() )
233  {
234  geom.transform( xform );
235  }
236 
237  if ( mPreprocessingEnabled )
238  {
239  // fix the polygon if it is not valid
240  if ( ! geom.isGeosValid() )
241  {
242  geom = geom.buffer( 0, 0 );
243  }
244  }
245 
246  if ( geom.isNull() )
247  return false; // do not let invalid geometries sneak in!
248 
249  // add the geometry to the list of geometries for this feature
250  cFeat.geometries.append( geom );
251 
252  return true;
253 }
254 
256 {
258  if ( context.renderingStopped() )
259  {
260  mSubRenderer->stopRender( mContext );
261  return;
262  }
263 
264  if ( !mSubRenderer )
265  {
266  return;
267  }
268  if ( !context.painter() )
269  {
270  return;
271  }
272 
273  QgsMultiPolygonXY finalMulti; //avoid expensive allocation for list for every feature
274  QgsPolygonXY newPoly;
275 
276  const auto constMFeaturesCategories = mFeaturesCategories;
277  for ( const CombinedFeature &cit : constMFeaturesCategories )
278  {
279  finalMulti.resize( 0 ); //preserve capacity - don't use clear!
280  QgsFeature feat = cit.feature; // just a copy, so that we do not accumulate geometries again
281  if ( mPreprocessingEnabled )
282  {
283  // compute the unary union on the polygons
284  QgsGeometry unioned( QgsGeometry::unaryUnion( cit.geometries ) );
285  // compute the difference with the extent
286  QgsGeometry rect = QgsGeometry::fromPolygonXY( mExtentPolygon );
287  QgsGeometry final = rect.difference( unioned );
288  feat.setGeometry( final );
289  }
290  else
291  {
292  // No preprocessing involved.
293  // We build here a "reversed" geometry of all the polygons
294  //
295  // The final geometry is a multipolygon F, with :
296  // * the first polygon of F having the current extent as its exterior ring
297  // * each polygon's exterior ring is added as interior ring of the first polygon of F
298  // * each polygon's interior ring is added as new polygons in F
299  //
300  // No validity check is done, on purpose, it will be very slow and painting
301  // operations do not need geometries to be valid
302 
303  finalMulti.append( mExtentPolygon );
304  for ( const QgsGeometry &geom : qgis::as_const( cit.geometries ) )
305  {
306  QgsMultiPolygonXY multi;
307  QgsWkbTypes::Type type = QgsWkbTypes::flatType( geom.constGet()->wkbType() );
308 
310  {
311  multi.append( geom.asPolygon() );
312  }
313  else if ( ( type == QgsWkbTypes::MultiPolygon ) || ( type == QgsWkbTypes::MultiSurface ) )
314  {
315  multi = geom.asMultiPolygon();
316  }
317 
318  for ( int i = 0; i < multi.size(); i++ )
319  {
320  const QgsPolylineXY &exterior = multi[i][0];
321  // add the exterior ring as interior ring to the first polygon
322  // make sure it satisfies at least very basic requirements of GEOS
323  // (otherwise the creation of GEOS geometry will fail)
324  if ( exterior.count() < 4 || exterior[0] != exterior[exterior.count() - 1] )
325  continue;
326  finalMulti[0].append( exterior );
327 
328  // add interior rings as new polygons
329  for ( int j = 1; j < multi[i].size(); j++ )
330  {
331  newPoly.resize( 0 ); //preserve capacity - don't use clear!
332  newPoly.append( multi[i][j] );
333  finalMulti.append( newPoly );
334  }
335  }
336  }
337  feat.setGeometry( QgsGeometry::fromMultiPolygonXY( finalMulti ) );
338  }
339  if ( feat.hasGeometry() )
340  {
341  mContext.expressionContext().setFeature( feat );
342  mSubRenderer->renderFeature( feat, mContext );
343  }
344  }
345 
346  // when no features are visible, we still have to draw the exterior rectangle
347  // warning: when sub renderers have more than one possible symbols,
348  // there is no way to choose a correct one, because there is no attribute here
349  // in that case, nothing will be rendered
350  if ( mFeaturesCategories.isEmpty() )
351  {
352  // empty feature with default attributes
353  QgsFeature feat( mFields );
354  feat.setGeometry( QgsGeometry::fromPolygonXY( mExtentPolygon ) );
355  mSubRenderer->renderFeature( feat, mContext );
356  }
357 
358  // draw feature decorations
359  const auto constMFeatureDecorations = mFeatureDecorations;
360  for ( FeatureDecoration deco : constMFeatureDecorations )
361  {
362  mSubRenderer->renderFeature( deco.feature, mContext, deco.layer, deco.selected, deco.drawMarkers );
363  }
364 
365  mSubRenderer->stopRender( mContext );
366 }
367 
369 {
370  if ( !mSubRenderer )
371  {
372  return QStringLiteral( "INVERTED: NULL" );
373  }
374  return "INVERTED [" + mSubRenderer->dump() + ']';
375 }
376 
378 {
379  QgsInvertedPolygonRenderer *newRenderer = nullptr;
380  if ( !mSubRenderer )
381  {
382  newRenderer = new QgsInvertedPolygonRenderer( nullptr );
383  }
384  else
385  {
386  newRenderer = new QgsInvertedPolygonRenderer( mSubRenderer->clone() );
387  }
389  copyRendererData( newRenderer );
390  return newRenderer;
391 }
392 
394 {
396  //look for an embedded renderer <renderer-v2>
397  QDomElement embeddedRendererElem = element.firstChildElement( QStringLiteral( "renderer-v2" ) );
398  if ( !embeddedRendererElem.isNull() )
399  {
400  QgsFeatureRenderer *renderer = QgsFeatureRenderer::load( embeddedRendererElem, context );
401  r->setEmbeddedRenderer( renderer );
402  }
403  r->setPreprocessingEnabled( element.attribute( QStringLiteral( "preprocessing" ), QStringLiteral( "0" ) ).toInt() == 1 );
404  return r;
405 }
406 
407 QDomElement QgsInvertedPolygonRenderer::save( QDomDocument &doc, const QgsReadWriteContext &context )
408 {
409  // clazy:skip
410 
411  QDomElement rendererElem = doc.createElement( RENDERER_TAG_NAME );
412  rendererElem.setAttribute( QStringLiteral( "type" ), QStringLiteral( "invertedPolygonRenderer" ) );
413  rendererElem.setAttribute( QStringLiteral( "preprocessing" ), preprocessingEnabled() ? QStringLiteral( "1" ) : QStringLiteral( "0" ) );
414  rendererElem.setAttribute( QStringLiteral( "forceraster" ), ( mForceRaster ? QStringLiteral( "1" ) : QStringLiteral( "0" ) ) );
415 
416  if ( mSubRenderer )
417  {
418  QDomElement embeddedRendererElem = mSubRenderer->save( doc, context );
419  rendererElem.appendChild( embeddedRendererElem );
420  }
421 
423  mPaintEffect->saveProperties( doc, rendererElem );
424 
425  if ( !mOrderBy.isEmpty() )
426  {
427  QDomElement orderBy = doc.createElement( QStringLiteral( "orderby" ) );
428  mOrderBy.save( orderBy );
429  rendererElem.appendChild( orderBy );
430  }
431  rendererElem.setAttribute( QStringLiteral( "enableorderby" ), ( mOrderByEnabled ? QStringLiteral( "1" ) : QStringLiteral( "0" ) ) );
432 
433  return rendererElem;
434 }
435 
437 {
438  if ( !mSubRenderer )
439  {
440  return nullptr;
441  }
442  return mSubRenderer->symbolForFeature( feature, context );
443 }
444 
446 {
447  if ( !mSubRenderer )
448  return nullptr;
449  return mSubRenderer->originalSymbolForFeature( feature, context );
450 }
451 
453 {
454  if ( !mSubRenderer )
455  {
456  return QgsSymbolList();
457  }
458  return mSubRenderer->symbolsForFeature( feature, context );
459 }
460 
462 {
463  if ( !mSubRenderer )
464  return QgsSymbolList();
465  return mSubRenderer->originalSymbolsForFeature( feature, context );
466 }
467 
468 QSet<QString> QgsInvertedPolygonRenderer::legendKeysForFeature( const QgsFeature &feature, QgsRenderContext &context ) const
469 {
470  if ( !mSubRenderer )
471  return QSet<QString>();
472  return mSubRenderer->legendKeysForFeature( feature, context );
473 }
474 
476 {
477  if ( !mSubRenderer )
478  {
479  return QgsSymbolList();
480  }
481  return mSubRenderer->symbols( context );
482 }
483 
484 QgsFeatureRenderer::Capabilities QgsInvertedPolygonRenderer::capabilities()
485 {
486  if ( !mSubRenderer )
487  {
488  return nullptr;
489  }
490  return mSubRenderer->capabilities();
491 }
492 
494 {
495  if ( !mSubRenderer )
496  {
497  return QSet<QString>();
498  }
499  return mSubRenderer->usedAttributes( context );
500 }
501 
503 {
504  return mSubRenderer ? mSubRenderer->filterNeedsGeometry() : false;
505 }
506 
508 {
509  if ( !mSubRenderer )
510  {
511  return QgsLegendSymbolList();
512  }
513  return mSubRenderer->legendSymbolItems();
514 }
515 
517 {
518  if ( !mSubRenderer )
519  {
520  return false;
521  }
522  return mSubRenderer->willRenderFeature( feature, context );
523 }
524 
526 {
527  if ( renderer->type() == QLatin1String( "invertedPolygonRenderer" ) )
528  {
529  return dynamic_cast<QgsInvertedPolygonRenderer *>( renderer->clone() );
530  }
531 
532  if ( renderer->type() == QLatin1String( "singleSymbol" ) ||
533  renderer->type() == QLatin1String( "categorizedSymbol" ) ||
534  renderer->type() == QLatin1String( "graduatedSymbol" ) ||
535  renderer->type() == QLatin1String( "RuleRenderer" ) )
536  {
537  return new QgsInvertedPolygonRenderer( renderer->clone() );
538  }
539  return nullptr;
540 }
541 
QgsFeatureRenderer::copyRendererData
void copyRendererData(QgsFeatureRenderer *destRenderer) const
Clones generic renderer data to another renderer.
Definition: qgsrenderer.cpp:49
QgsFeatureRenderer::mOrderByEnabled
bool mOrderByEnabled
Definition: qgsrenderer.h:547
QgsFeatureRenderer::mForceRaster
bool mForceRaster
Definition: qgsrenderer.h:531
QgsFeatureRenderer::defaultRenderer
static QgsFeatureRenderer * defaultRenderer(QgsWkbTypes::GeometryType geomType)
Returns a new renderer - used by default in vector layers.
Definition: qgsrenderer.cpp:76
QgsInvertedPolygonRenderer::symbolsForFeature
QgsSymbolList symbolsForFeature(const QgsFeature &feature, QgsRenderContext &context) const override
Returns list of symbols used for rendering the feature.
Definition: qgsinvertedpolygonrenderer.cpp:452
QgsGeometry::transform
OperationResult transform(const QgsCoordinateTransform &ct, QgsCoordinateTransform::TransformDirection direction=QgsCoordinateTransform::ForwardTransform, bool transformZ=false) SIP_THROW(QgsCsException)
Transforms this geometry as described by the coordinate transform ct.
Definition: qgsgeometry.cpp:2836
QgsFeatureRenderer::mPaintEffect
QgsPaintEffect * mPaintEffect
Definition: qgsrenderer.h:529
QgsRenderContext::expressionContext
QgsExpressionContext & expressionContext()
Gets the expression context.
Definition: qgsrendercontext.h:580
QgsInvertedPolygonRenderer::preprocessingEnabled
bool preprocessingEnabled() const
Definition: qgsinvertedpolygonrenderer.h:120
QgsReadWriteContext
Definition: qgsreadwritecontext.h:34
QgsPolygonXY
QVector< QgsPolylineXY > QgsPolygonXY
Polygon: first item of the list is outer ring, inner rings (if any) start from second item.
Definition: qgsgeometry.h:74
QgsWkbTypes::MultiPolygon
@ MultiPolygon
Definition: qgswkbtypes.h:77
QgsFeatureRequest::OrderBy::save
void CORE_EXPORT save(QDomElement &elem) const
Serialize to XML.
Definition: qgsfeaturerequest.cpp:453
QgsInvertedPolygonRenderer::convertFromRenderer
static QgsInvertedPolygonRenderer * convertFromRenderer(const QgsFeatureRenderer *renderer)
Creates a QgsInvertedPolygonRenderer by a conversion from an existing renderer.
Definition: qgsinvertedpolygonrenderer.cpp:525
QgsInvertedPolygonRenderer::QgsInvertedPolygonRenderer
QgsInvertedPolygonRenderer(QgsFeatureRenderer *embeddedRenderer=nullptr)
Constructor.
Definition: qgsinvertedpolygonrenderer.cpp:33
QgsPolylineXY
QVector< QgsPointXY > QgsPolylineXY
Polyline as represented as a vector of two-dimensional points.
Definition: qgsgeometry.h:50
qgssymbollayerutils.h
QgsFields
Definition: qgsfields.h:44
qgsfeature.h
QgsFeatureRenderer::type
QString type() const
Definition: qgsrenderer.h:141
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:468
QgsRenderContext
Definition: qgsrendercontext.h:57
QgsMultiPolygonXY
QVector< QgsPolygonXY > QgsMultiPolygonXY
A collection of QgsPolygons that share a common collection of attributes.
Definition: qgsgeometry.h:91
QgsStyleEntityVisitorInterface
Definition: qgsstyleentityvisitor.h:33
qgspainteffectregistry.h
QgsWkbTypes::Type
Type
The WKB type describes the number of dimensions a geometry has.
Definition: qgswkbtypes.h:68
QgsSymbol
Definition: qgssymbol.h:63
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:876
QgsInvertedPolygonRenderer::startRender
void startRender(QgsRenderContext &context, const QgsFields &fields) override
Must be called when a new render cycle is started.
Definition: qgsinvertedpolygonrenderer.cpp:103
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:1919
QgsFeatureRenderer::load
static QgsFeatureRenderer * load(QDomElement &symbologyElem, const QgsReadWriteContext &context)
create a renderer from XML element
Definition: qgsrenderer.cpp:149
QgsPaintEffect::saveProperties
virtual bool saveProperties(QDomDocument &doc, QDomElement &element) const
Saves the current state of the effect to a DOM element.
Definition: qgspainteffect.cpp:54
QgsWkbTypes::PolygonGeometry
@ PolygonGeometry
Definition: qgswkbtypes.h:143
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:107
QgsFeatureRenderer::orderBy
QgsFeatureRequest::OrderBy orderBy() const
Gets the order in which features shall be processed by this renderer.
Definition: qgsrenderer.cpp:435
QgsInvertedPolygonRenderer::accept
bool accept(QgsStyleEntityVisitorInterface *visitor) const override
Accepts the specified symbology visitor, causing it to visit all symbols associated with the renderer...
Definition: qgsinvertedpolygonrenderer.cpp:95
QgsRenderContext::renderingStopped
bool renderingStopped() const
Returns true if the rendering operation has been stopped and any ongoing rendering should be canceled...
Definition: qgsrendercontext.h:325
QgsInvertedPolygonRenderer::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: qgsinvertedpolygonrenderer.cpp:162
QgsInvertedPolygonRenderer::legendSymbolItems
QgsLegendSymbolList legendSymbolItems() const override
Returns a list of symbology items for the legend.
Definition: qgsinvertedpolygonrenderer.cpp:507
QgsRenderContext::coordinateTransform
QgsCoordinateTransform coordinateTransform() const
Returns the current coordinate transform for the context.
Definition: qgsrendercontext.h:229
QgsPaintEffectRegistry::isDefaultStack
static bool isDefaultStack(QgsPaintEffect *effect)
Tests whether a paint effect matches the default effects stack.
Definition: qgspainteffectregistry.cpp:134
QgsInvertedPolygonRenderer::symbolForFeature
QgsSymbol * symbolForFeature(const QgsFeature &feature, QgsRenderContext &context) const override
To be overridden.
Definition: qgsinvertedpolygonrenderer.cpp:436
QgsInvertedPolygonRenderer::legendKeysForFeature
QSet< QString > legendKeysForFeature(const QgsFeature &feature, QgsRenderContext &context) const override
Returns legend keys matching a specified feature.
Definition: qgsinvertedpolygonrenderer.cpp:468
QgsInvertedPolygonRenderer::embeddedRenderer
const QgsFeatureRenderer * embeddedRenderer() const override
Returns the current embedded renderer (subrenderer) for this feature renderer.
Definition: qgsinvertedpolygonrenderer.cpp:58
QgsFeature::setGeometry
void setGeometry(const QgsGeometry &geometry)
Set the feature's geometry.
Definition: qgsfeature.cpp:137
QgsInvertedPolygonRenderer::dump
QString dump() const override
Returns debug information about this renderer.
Definition: qgsinvertedpolygonrenderer.cpp:368
QgsSymbolList
QList< QgsSymbol * > QgsSymbolList
Definition: qgsrenderer.h:45
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:418
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:240
QgsInvertedPolygonRenderer::originalSymbolsForFeature
QgsSymbolList originalSymbolsForFeature(const QgsFeature &feature, QgsRenderContext &context) const override
Equivalent of originalSymbolsForFeature() call extended to support renderers that may use more symbol...
Definition: qgsinvertedpolygonrenderer.cpp:461
QgsWkbTypes::CurvePolygon
@ CurvePolygon
Definition: qgswkbtypes.h:81
RENDERER_TAG_NAME
#define RENDERER_TAG_NAME
Definition: qgsrenderer.h:51
QgsInvertedPolygonRenderer::legendSymbolItemsCheckable
bool legendSymbolItemsCheckable() const override
items of symbology items in legend should be checkable
Definition: qgsinvertedpolygonrenderer.cpp:71
QgsFeatureRenderer::MoreSymbolsPerFeature
@ MoreSymbolsPerFeature
May use more than one symbol to render a feature: symbolsForFeature() will return them.
Definition: qgsrenderer.h:255
qgssymbollayer.h
QgsGeometry::isNull
bool isNull
Definition: qgsgeometry.h:125
QgsInvertedPolygonRenderer::checkLegendSymbolItem
void checkLegendSymbolItem(const QString &key, bool state=true) override
item in symbology was checked
Definition: qgsinvertedpolygonrenderer.cpp:87
QgsRectangle::buffered
QgsRectangle buffered(double width) const
Gets rectangle enlarged by buffer.
Definition: qgsrectangle.h:304
QgsFeatureRenderer::mOrderBy
QgsFeatureRequest::OrderBy mOrderBy
Definition: qgsrenderer.h:545
qgsvectorlayer.h
QgsInvertedPolygonRenderer::save
QDomElement save(QDomDocument &doc, const QgsReadWriteContext &context) override
store renderer info to XML element
Definition: qgsinvertedpolygonrenderer.cpp:407
QgsInvertedPolygonRenderer::stopRender
void stopRender(QgsRenderContext &context) override
The actual rendering will take place here.
Definition: qgsinvertedpolygonrenderer.cpp:255
QgsInvertedPolygonRenderer::originalSymbolForFeature
QgsSymbol * originalSymbolForFeature(const QgsFeature &feature, QgsRenderContext &context) const override
Returns symbol for feature.
Definition: qgsinvertedpolygonrenderer.cpp:445
QgsRenderContext::mapExtent
QgsRectangle mapExtent() const
Returns the original extent of the map being rendered.
Definition: qgsrendercontext.h:302
QgsGeometry::fromPolygonXY
static QgsGeometry fromPolygonXY(const QgsPolygonXY &polygon)
Creates a new geometry from a QgsPolygon.
Definition: qgsgeometry.cpp:189
QgsWkbTypes::MultiSurface
@ MultiSurface
Definition: qgswkbtypes.h:83
QgsFeatureRenderer
Definition: qgsrenderer.h:102
QgsGeometry
Definition: qgsgeometry.h:122
QgsFeature::hasGeometry
bool hasGeometry() const
Returns true if the feature has an associated geometry.
Definition: qgsfeature.cpp:197
QgsInvertedPolygonRenderer::filterNeedsGeometry
bool filterNeedsGeometry() const override
Returns true if this renderer requires the geometry to apply the filter.
Definition: qgsinvertedpolygonrenderer.cpp:502
QgsWkbTypes::Polygon
@ Polygon
Definition: qgswkbtypes.h:73
QgsInvertedPolygonRenderer::legendSymbolItemChecked
bool legendSymbolItemChecked(const QString &key) override
items of symbology items in legend is checked
Definition: qgsinvertedpolygonrenderer.cpp:79
QgsRectangle::height
double height() const
Returns the height of the rectangle.
Definition: qgsrectangle.h:209
QgsInvertedPolygonRenderer::create
static QgsFeatureRenderer * create(QDomElement &element, const QgsReadWriteContext &context)
Creates a renderer out of an XML, for loading.
Definition: qgsinvertedpolygonrenderer.cpp:393
QgsInvertedPolygonRenderer::setLegendSymbolItem
void setLegendSymbolItem(const QString &key, QgsSymbol *symbol) override
Sets the symbol to be used for a legend symbol item.
Definition: qgsinvertedpolygonrenderer.cpp:63
QgsInvertedPolygonRenderer::willRenderFeature
bool willRenderFeature(const QgsFeature &feature, QgsRenderContext &context) const override
Returns whether the renderer will render a feature or not.
Definition: qgsinvertedpolygonrenderer.cpp:516
QgsInvertedPolygonRenderer::clone
QgsInvertedPolygonRenderer * clone() const override
Create a deep copy of this renderer.
Definition: qgsinvertedpolygonrenderer.cpp:377
QgsInvertedPolygonRenderer::usedAttributes
QSet< QString > usedAttributes(const QgsRenderContext &context) const override
Returns a list of attributes required by this renderer.
Definition: qgsinvertedpolygonrenderer.cpp:493
qgsinvertedpolygonrenderer.h
QgsFeature
Definition: qgsfeature.h:55
QgsInvertedPolygonRenderer::setPreprocessingEnabled
void setPreprocessingEnabled(bool enabled)
Definition: qgsinvertedpolygonrenderer.h:128
QgsGeometry::isGeosValid
bool isGeosValid(QgsGeometry::ValidityFlags flags=QgsGeometry::ValidityFlags()) const
Checks validity of the geometry using GEOS.
Definition: qgsgeometry.cpp:2734
qgslogger.h
QgsInvertedPolygonRenderer::setEmbeddedRenderer
void setEmbeddedRenderer(QgsFeatureRenderer *subRenderer) override
Sets an embedded renderer (subrenderer) for this feature renderer.
Definition: qgsinvertedpolygonrenderer.cpp:46
QgsRenderContext::painter
QPainter * painter()
Returns the destination QPainter for the render operation.
Definition: qgsrendercontext.h:174
QgsCoordinateTransform
Definition: qgscoordinatetransform.h:52
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:93
qgssymbol.h
QgsRectangle::width
double width() const
Returns the width of the rectangle.
Definition: qgsrectangle.h:202
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:2456
QgsWkbTypes::flatType
static Type flatType(Type type)
Returns the flat type for a WKB type.
Definition: qgswkbtypes.h:701
QgsGeometry::fromMultiPolygonXY
static QgsGeometry fromMultiPolygonXY(const QgsMultiPolygonXY &multipoly)
Creates a new geometry from a QgsMultiPolygon.
Definition: qgsgeometry.cpp:219
qgsstyleentityvisitor.h
QgsGeometry::unaryUnion
static QgsGeometry unaryUnion(const QVector< QgsGeometry > &geometries)
Compute the unary union on a list of geometries.
Definition: qgsgeometry.cpp:2785
QgsInvertedPolygonRenderer
Definition: qgsinvertedpolygonrenderer.h:41
QgsExpressionContext::setFeature
void setFeature(const QgsFeature &feature)
Convenience function for setting a feature for the context.
Definition: qgsexpressioncontext.cpp:521
QgsInvertedPolygonRenderer::symbols
QgsSymbolList symbols(QgsRenderContext &context) const override
Returns list of symbols used by the renderer.
Definition: qgsinvertedpolygonrenderer.cpp:475
QgsInvertedPolygonRenderer::capabilities
QgsFeatureRenderer::Capabilities capabilities() override
Returns details about internals of this renderer.
Definition: qgsinvertedpolygonrenderer.cpp:484