QGIS API Documentation  3.15.0-Master (dbe1ef8aa2)
qgsvectorlayerrenderer.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsvectorlayerrenderer.cpp
3  --------------------------------------
4  Date : December 2013
5  Copyright : (C) 2013 by Martin Dobias
6  Email : wonder dot sk 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 
16 #include "qgsvectorlayerrenderer.h"
17 
18 #include "diagram/qgsdiagram.h"
19 
20 #include "qgsdiagramrenderer.h"
21 #include "qgsmessagelog.h"
22 #include "qgspallabeling.h"
23 #include "qgsrenderer.h"
24 #include "qgsrendercontext.h"
26 #include "qgssymbollayer.h"
27 #include "qgssymbollayerutils.h"
28 #include "qgssymbol.h"
29 #include "qgsvectorlayer.h"
32 #include "qgsvectorlayerlabeling.h"
34 #include "qgspainteffect.h"
36 #include "qgsexception.h"
37 #include "qgslogger.h"
38 #include "qgssettings.h"
42 #include "qgsmapclippingutils.h"
43 
44 #include <QPicture>
45 
46 
48  : QgsMapLayerRenderer( layer->id(), &context )
49  , mLayer( layer )
50  , mFields( layer->fields() )
51  , mLabeling( false )
52  , mDiagrams( false )
53 {
54  mSource = new QgsVectorLayerFeatureSource( layer );
55 
56  mRenderer = layer->renderer() ? layer->renderer()->clone() : nullptr;
58 
59  mDrawVertexMarkers = nullptr != layer->editBuffer();
60 
61  mGeometryType = layer->geometryType();
62 
64 
65  if ( context.isTemporal() )
66  {
67  QgsVectorLayerTemporalContext temporalContext;
68  temporalContext.setLayer( layer );
69  mTemporalFilter = qobject_cast< const QgsVectorLayerTemporalProperties * >( layer->temporalProperties() )->createFilterString( temporalContext, context.temporalRange() );
70  }
71 
72  // if there's already a simplification method specified via the context, we respect that. Otherwise, we fall back
73  // to the layer's individual setting
75  {
79  }
80  else
81  {
84  }
85 
86  QgsSettings settings;
87  mVertexMarkerOnlyForSelection = settings.value( QStringLiteral( "qgis/digitizing/marker_only_for_selected" ), true ).toBool();
88 
89  QString markerTypeString = settings.value( QStringLiteral( "qgis/digitizing/marker_style" ), "Cross" ).toString();
90  if ( markerTypeString == QLatin1String( "Cross" ) )
91  {
93  }
94  else if ( markerTypeString == QLatin1String( "SemiTransparentCircle" ) )
95  {
97  }
98  else
99  {
101  }
102 
103  mVertexMarkerSize = settings.value( QStringLiteral( "qgis/digitizing/marker_size_mm" ), 2.0 ).toDouble();
104 
105  if ( !mRenderer )
106  return;
107 
108  QgsDebugMsgLevel( "rendering v2:\n " + mRenderer->dump(), 2 );
109 
110  if ( mDrawVertexMarkers )
111  {
112  // set editing vertex markers style
114  }
116 
117  mAttrNames = mRenderer->usedAttributes( context );
118  if ( context.hasRenderedFeatureHandlers() )
119  {
120  const QList< QgsRenderedFeatureHandlerInterface * > handlers = context.renderedFeatureHandlers();
121  for ( QgsRenderedFeatureHandlerInterface *handler : handlers )
122  mAttrNames.unite( handler->usedAttributes( layer, context ) );
123  }
124 
125  //register label and diagram layer to the labeling engine
126  prepareLabeling( layer, mAttrNames );
127  prepareDiagrams( layer, mAttrNames );
128 
130 }
131 
133 {
134  delete mRenderer;
135  delete mSource;
136 }
137 
139 {
140  return mInterruptionChecker.get();
141 }
142 
144 {
146  return true;
147 
148  if ( !mRenderer )
149  {
150  mErrors.append( QObject::tr( "No renderer for drawing." ) );
151  return false;
152  }
153 
154  if ( mRenderer->type() == QStringLiteral( "nullSymbol" ) )
155  {
156  // a little shortcut for the null symbol renderer - most of the time it is not going to render anything
157  // so we can even skip the whole loop to fetch features
159  return true;
160  }
161 
162  QgsRenderContext &context = *renderContext();
163 
164  QgsScopedQPainterState painterState( context.painter() );
165 
166  // MUST be created in the thread doing the rendering
167  mInterruptionChecker = qgis::make_unique< QgsVectorLayerRendererInterruptionChecker >( context );
168  bool usingEffect = false;
170  {
171  usingEffect = true;
172  mRenderer->paintEffect()->begin( context );
173  }
174 
175  // Per feature blending mode
176  if ( context.useAdvancedEffects() && mFeatureBlendMode != QPainter::CompositionMode_SourceOver )
177  {
178  // set the painter to the feature blend mode, so that features drawn
179  // on this layer will interact and blend with each other
180  context.painter()->setCompositionMode( mFeatureBlendMode );
181  }
182 
183  mRenderer->startRender( context, mFields );
184 
185  QString rendererFilter = mRenderer->filter( mFields );
186 
187  QgsRectangle requestExtent = context.extent();
188  if ( !mClippingRegions.empty() )
189  {
191  requestExtent = requestExtent.intersect( mClipFilterGeom.boundingBox() );
192 
194 
195  bool needsPainterClipPath = false;
196  const QPainterPath path = QgsMapClippingUtils::calculatePainterClipRegion( mClippingRegions, context, QgsMapLayerType::VectorLayer, needsPainterClipPath );
197  if ( needsPainterClipPath )
198  context.painter()->setClipPath( path, Qt::IntersectClip );
199 
201 
202  if ( mDiagramProvider )
204  }
205  mRenderer->modifyRequestExtent( requestExtent, context );
206 
207  QgsFeatureRequest featureRequest = QgsFeatureRequest()
208  .setFilterRect( requestExtent )
211  if ( mRenderer->orderByEnabled() )
212  {
213  featureRequest.setOrderBy( mRenderer->orderBy() );
214  }
215 
216  const QgsFeatureFilterProvider *featureFilterProvider = context.featureFilterProvider();
217  if ( featureFilterProvider )
218  {
219  featureFilterProvider->filterFeatures( mLayer, featureRequest );
220  }
221  if ( !rendererFilter.isEmpty() && rendererFilter != QLatin1String( "TRUE" ) )
222  {
223  featureRequest.combineFilterExpression( rendererFilter );
224  }
225  if ( !mTemporalFilter.isEmpty() )
226  {
227  featureRequest.combineFilterExpression( mTemporalFilter );
228  }
229 
230  // enable the simplification of the geometries (Using the current map2pixel context) before send it to renderer engine.
231  if ( mSimplifyGeometry )
232  {
233  double map2pixelTol = mSimplifyMethod.threshold();
234  bool validTransform = true;
235 
236  const QgsMapToPixel &mtp = context.mapToPixel();
237  map2pixelTol *= mtp.mapUnitsPerPixel();
239 
240  // resize the tolerance using the change of size of an 1-BBOX from the source CoordinateSystem to the target CoordinateSystem
241  if ( ct.isValid() && !ct.isShortCircuited() )
242  {
243  try
244  {
245  QgsPointXY center = context.extent().center();
246  double rectSize = ct.sourceCrs().isGeographic() ? 0.0008983 /* ~100/(40075014/360=111319.4833) */ : 100;
247 
248  QgsRectangle sourceRect = QgsRectangle( center.x(), center.y(), center.x() + rectSize, center.y() + rectSize );
249  QgsRectangle targetRect = ct.transform( sourceRect );
250 
251  QgsDebugMsgLevel( QStringLiteral( "Simplify - SourceTransformRect=%1" ).arg( sourceRect.toString( 16 ) ), 4 );
252  QgsDebugMsgLevel( QStringLiteral( "Simplify - TargetTransformRect=%1" ).arg( targetRect.toString( 16 ) ), 4 );
253 
254  if ( !sourceRect.isEmpty() && sourceRect.isFinite() && !targetRect.isEmpty() && targetRect.isFinite() )
255  {
256  QgsPointXY minimumSrcPoint( sourceRect.xMinimum(), sourceRect.yMinimum() );
257  QgsPointXY maximumSrcPoint( sourceRect.xMaximum(), sourceRect.yMaximum() );
258  QgsPointXY minimumDstPoint( targetRect.xMinimum(), targetRect.yMinimum() );
259  QgsPointXY maximumDstPoint( targetRect.xMaximum(), targetRect.yMaximum() );
260 
261  double sourceHypothenuse = std::sqrt( minimumSrcPoint.sqrDist( maximumSrcPoint ) );
262  double targetHypothenuse = std::sqrt( minimumDstPoint.sqrDist( maximumDstPoint ) );
263 
264  QgsDebugMsgLevel( QStringLiteral( "Simplify - SourceHypothenuse=%1" ).arg( sourceHypothenuse ), 4 );
265  QgsDebugMsgLevel( QStringLiteral( "Simplify - TargetHypothenuse=%1" ).arg( targetHypothenuse ), 4 );
266 
267  if ( !qgsDoubleNear( targetHypothenuse, 0.0 ) )
268  map2pixelTol *= ( sourceHypothenuse / targetHypothenuse );
269  }
270  }
271  catch ( QgsCsException &cse )
272  {
273  QgsMessageLog::logMessage( QObject::tr( "Simplify transform error caught: %1" ).arg( cse.what() ), QObject::tr( "CRS" ) );
274  validTransform = false;
275  }
276  }
277 
278  if ( validTransform )
279  {
280  QgsSimplifyMethod simplifyMethod;
282  simplifyMethod.setTolerance( map2pixelTol );
283  simplifyMethod.setThreshold( mSimplifyMethod.threshold() );
285  featureRequest.setSimplifyMethod( simplifyMethod );
286 
288  vectorMethod.setTolerance( map2pixelTol );
289  context.setVectorSimplifyMethod( vectorMethod );
290  }
291  else
292  {
293  QgsVectorSimplifyMethod vectorMethod;
295  context.setVectorSimplifyMethod( vectorMethod );
296  }
297  }
298  else
299  {
300  QgsVectorSimplifyMethod vectorMethod;
302  context.setVectorSimplifyMethod( vectorMethod );
303  }
304 
305  QgsFeatureIterator fit = mSource->getFeatures( featureRequest );
306  // Attach an interruption checker so that iterators that have potentially
307  // slow fetchFeature() implementations, such as in the WFS provider, can
308  // check it, instead of relying on just the mContext.renderingStopped() check
309  // in drawRenderer()
310  fit.setInterruptionChecker( mInterruptionChecker.get() );
311 
313  drawRendererLevels( fit );
314  else
315  drawRenderer( fit );
316 
317  if ( !fit.isValid() )
318  {
319  mErrors.append( QStringLiteral( "Data source invalid" ) );
320  }
321 
322  if ( usingEffect )
323  {
324  mRenderer->paintEffect()->end( context );
325  }
326 
327  mInterruptionChecker.reset();
328  return true;
329 }
330 
331 
332 void QgsVectorLayerRenderer::drawRenderer( QgsFeatureIterator &fit )
333 {
335  QgsRenderContext &context = *renderContext();
336  context.expressionContext().appendScope( symbolScope );
337 
338  std::unique_ptr< QgsGeometryEngine > clipEngine;
339  if ( mApplyClipFilter )
340  {
342  clipEngine->prepareGeometry();
343  }
344 
345  QgsFeature fet;
346  while ( fit.nextFeature( fet ) )
347  {
348  try
349  {
350  if ( context.renderingStopped() )
351  {
352  QgsDebugMsgLevel( QStringLiteral( "Drawing of vector layer %1 canceled." ).arg( layerId() ), 2 );
353  break;
354  }
355 
356  if ( !fet.hasGeometry() || fet.geometry().isEmpty() )
357  continue; // skip features without geometry
358 
359  if ( clipEngine && !clipEngine->intersects( fet.geometry().constGet() ) )
360  continue; // skip features outside of clipping region
361 
362  if ( mApplyClipGeometries )
364 
365  context.expressionContext().setFeature( fet );
366 
367  bool sel = context.showSelection() && mSelectedFeatureIds.contains( fet.id() );
368  bool drawMarker = ( mDrawVertexMarkers && context.drawEditingInformation() && ( !mVertexMarkerOnlyForSelection || sel ) );
369 
370  // render feature
371  bool rendered = mRenderer->renderFeature( fet, context, -1, sel, drawMarker );
372 
373  // labeling - register feature
374  if ( rendered )
375  {
376  // new labeling engine
377  if ( context.labelingEngine() && ( mLabelProvider || mDiagramProvider ) )
378  {
379  QgsGeometry obstacleGeometry;
380  QgsSymbolList symbols = mRenderer->originalSymbolsForFeature( fet, context );
381  QgsSymbol *symbol = nullptr;
382  if ( !symbols.isEmpty() && fet.geometry().type() == QgsWkbTypes::PointGeometry )
383  {
384  obstacleGeometry = QgsVectorLayerLabelProvider::getPointObstacleGeometry( fet, context, symbols );
385  }
386 
387  if ( !symbols.isEmpty() )
388  {
389  symbol = symbols.at( 0 );
390  QgsExpressionContextUtils::updateSymbolScope( symbol, symbolScope );
391  }
392 
395 
396  if ( mLabelProvider )
397  {
398  mLabelProvider->registerFeature( fet, context, obstacleGeometry, symbol );
399  }
400  if ( mDiagramProvider )
401  {
402  mDiagramProvider->registerFeature( fet, context, obstacleGeometry );
403  }
404 
406  context.setFeatureClipGeometry( QgsGeometry() );
407  }
408  }
409  }
410  catch ( const QgsCsException &cse )
411  {
412  Q_UNUSED( cse )
413  QgsDebugMsg( QStringLiteral( "Failed to transform a point while drawing a feature with ID '%1'. Ignoring this feature. %2" )
414  .arg( fet.id() ).arg( cse.what() ) );
415  }
416  }
417 
418  delete context.expressionContext().popScope();
419 
420  stopRenderer( nullptr );
421 }
422 
423 void QgsVectorLayerRenderer::drawRendererLevels( QgsFeatureIterator &fit )
424 {
425  QHash< QgsSymbol *, QList<QgsFeature> > features; // key = symbol, value = array of features
426  QgsRenderContext &context = *renderContext();
427 
428  QgsSingleSymbolRenderer *selRenderer = nullptr;
429  if ( !mSelectedFeatureIds.isEmpty() )
430  {
432  selRenderer->symbol()->setColor( context.selectionColor() );
434  selRenderer->startRender( context, mFields );
435  }
436 
438  std::unique_ptr< QgsExpressionContextScopePopper > scopePopper = qgis::make_unique< QgsExpressionContextScopePopper >( context.expressionContext(), symbolScope );
439 
440 
441  std::unique_ptr< QgsGeometryEngine > clipEngine;
442  if ( mApplyClipFilter )
443  {
445  clipEngine->prepareGeometry();
446  }
447 
450 
451  // 1. fetch features
452  QgsFeature fet;
453  while ( fit.nextFeature( fet ) )
454  {
455  if ( context.renderingStopped() )
456  {
457  qDebug( "rendering stop!" );
458  stopRenderer( selRenderer );
459  return;
460  }
461 
462  if ( !fet.hasGeometry() )
463  continue; // skip features without geometry
464 
465  if ( clipEngine && !clipEngine->intersects( fet.geometry().constGet() ) )
466  continue; // skip features outside of clipping region
467 
468  context.expressionContext().setFeature( fet );
469  QgsSymbol *sym = mRenderer->symbolForFeature( fet, context );
470  if ( !sym )
471  {
472  continue;
473  }
474 
475  if ( !features.contains( sym ) )
476  {
477  features.insert( sym, QList<QgsFeature>() );
478  }
479  features[sym].append( fet );
480 
481  // new labeling engine
482  if ( context.labelingEngine() && ( mLabelProvider || mDiagramProvider ) )
483  {
484  QgsGeometry obstacleGeometry;
485  QgsSymbolList symbols = mRenderer->originalSymbolsForFeature( fet, context );
486  QgsSymbol *symbol = nullptr;
487  if ( !symbols.isEmpty() && fet.geometry().type() == QgsWkbTypes::PointGeometry )
488  {
489  obstacleGeometry = QgsVectorLayerLabelProvider::getPointObstacleGeometry( fet, context, symbols );
490  }
491 
492  if ( !symbols.isEmpty() )
493  {
494  symbol = symbols.at( 0 );
495  QgsExpressionContextUtils::updateSymbolScope( symbol, symbolScope );
496  }
497 
498  if ( mLabelProvider )
499  {
500  mLabelProvider->registerFeature( fet, context, obstacleGeometry, symbol );
501  }
502  if ( mDiagramProvider )
503  {
504  mDiagramProvider->registerFeature( fet, context, obstacleGeometry );
505  }
506  }
507  }
508 
510  context.setFeatureClipGeometry( QgsGeometry() );
511 
512  scopePopper.reset();
513 
514  if ( features.empty() )
515  {
516  // nothing to draw
517  stopRenderer( selRenderer );
518  return;
519  }
520 
521  // find out the order
522  QgsSymbolLevelOrder levels;
523  QgsSymbolList symbols = mRenderer->symbols( context );
524  for ( int i = 0; i < symbols.count(); i++ )
525  {
526  QgsSymbol *sym = symbols[i];
527  for ( int j = 0; j < sym->symbolLayerCount(); j++ )
528  {
529  int level = sym->symbolLayer( j )->renderingPass();
530  if ( level < 0 || level >= 1000 ) // ignore invalid levels
531  continue;
532  QgsSymbolLevelItem item( sym, j );
533  while ( level >= levels.count() ) // append new empty levels
534  levels.append( QgsSymbolLevel() );
535  levels[level].append( item );
536  }
537  }
538 
539  if ( mApplyClipGeometries )
541 
542  // 2. draw features in correct order
543  for ( int l = 0; l < levels.count(); l++ )
544  {
545  QgsSymbolLevel &level = levels[l];
546  for ( int i = 0; i < level.count(); i++ )
547  {
548  QgsSymbolLevelItem &item = level[i];
549  if ( !features.contains( item.symbol() ) )
550  {
551  QgsDebugMsg( QStringLiteral( "level item's symbol not found!" ) );
552  continue;
553  }
554  int layer = item.layer();
555  QList<QgsFeature> &lst = features[item.symbol()];
556  QList<QgsFeature>::iterator fit;
557  for ( fit = lst.begin(); fit != lst.end(); ++fit )
558  {
559  if ( context.renderingStopped() )
560  {
561  stopRenderer( selRenderer );
562  return;
563  }
564 
565  bool sel = context.showSelection() && mSelectedFeatureIds.contains( fit->id() );
566  // maybe vertex markers should be drawn only during the last pass...
567  bool drawMarker = ( mDrawVertexMarkers && context.drawEditingInformation() && ( !mVertexMarkerOnlyForSelection || sel ) );
568 
569  context.expressionContext().setFeature( *fit );
570 
571  try
572  {
573  mRenderer->renderFeature( *fit, context, layer, sel, drawMarker );
574  }
575  catch ( const QgsCsException &cse )
576  {
577  Q_UNUSED( cse )
578  QgsDebugMsg( QStringLiteral( "Failed to transform a point while drawing a feature with ID '%1'. Ignoring this feature. %2" )
579  .arg( fet.id() ).arg( cse.what() ) );
580  }
581  }
582  }
583  }
584 
585  stopRenderer( selRenderer );
586 }
587 
588 
589 void QgsVectorLayerRenderer::stopRenderer( QgsSingleSymbolRenderer *selRenderer )
590 {
591  QgsRenderContext &context = *renderContext();
592  mRenderer->stopRender( context );
593  if ( selRenderer )
594  {
595  selRenderer->stopRender( context );
596  delete selRenderer;
597  }
598 }
599 
600 
601 
602 
603 void QgsVectorLayerRenderer::prepareLabeling( QgsVectorLayer *layer, QSet<QString> &attributeNames )
604 {
605  QgsRenderContext &context = *renderContext();
606  // TODO: add attributes for geometry generator
607  if ( QgsLabelingEngine *engine2 = context.labelingEngine() )
608  {
609  if ( layer->labelsEnabled() )
610  {
611  mLabelProvider = layer->labeling()->provider( layer );
612  if ( mLabelProvider )
613  {
614  engine2->addProvider( mLabelProvider );
615  if ( !mLabelProvider->prepare( context, attributeNames ) )
616  {
617  engine2->removeProvider( mLabelProvider );
618  mLabelProvider = nullptr; // deleted by engine
619  }
620  }
621  }
622  }
623 
624 #if 0 // TODO: limit of labels, font not found
625  QgsPalLayerSettings &palyr = mContext.labelingEngine()->layer( mLayerID );
626 
627  // see if feature count limit is set for labeling
628  if ( palyr.limitNumLabels && palyr.maxNumLabels > 0 )
629  {
630  QgsFeatureIterator fit = getFeatures( QgsFeatureRequest()
631  .setFilterRect( mContext.extent() )
632  .setNoAttributes() );
633 
634  // total number of features that may be labeled
635  QgsFeature f;
636  int nFeatsToLabel = 0;
637  while ( fit.nextFeature( f ) )
638  {
639  nFeatsToLabel++;
640  }
641  palyr.mFeaturesToLabel = nFeatsToLabel;
642  }
643 
644  // notify user about any font substitution
645  if ( !palyr.mTextFontFound && !mLabelFontNotFoundNotified )
646  {
647  emit labelingFontNotFound( this, palyr.mTextFontFamily );
648  mLabelFontNotFoundNotified = true;
649  }
650 #endif
651 }
652 
653 void QgsVectorLayerRenderer::prepareDiagrams( QgsVectorLayer *layer, QSet<QString> &attributeNames )
654 {
655  QgsRenderContext &context = *renderContext();
656  if ( QgsLabelingEngine *engine2 = context.labelingEngine() )
657  {
658  if ( layer->diagramsEnabled() )
659  {
661  // need to be added before calling prepare() - uses map settings from engine
662  engine2->addProvider( mDiagramProvider );
663  if ( !mDiagramProvider->prepare( context, attributeNames ) )
664  {
665  engine2->removeProvider( mDiagramProvider );
666  mDiagramProvider = nullptr; // deleted by engine
667  }
668  }
669  }
670 }
671 
672 /* ----------------------------------------- */
673 /* QgsVectorLayerRendererInterruptionChecker */
674 /* ----------------------------------------- */
675 
677 ( const QgsRenderContext &context )
678  : mContext( context )
679  , mTimer( new QTimer( this ) )
680 {
681  connect( mTimer, &QTimer::timeout, this, [ = ]
682  {
683  if ( mContext.renderingStopped() )
684  {
685  mTimer->stop();
686  cancel();
687  }
688  } );
689  mTimer->start( 50 );
690 
691 }
bool labelsEnabled() const
Returns whether the layer contains labels which are enabled and should be drawn.
QgsFeatureId id
Definition: qgsfeature.h:64
static QgsExpressionContextScope * updateSymbolScope(const QgsSymbol *symbol, QgsExpressionContextScope *symbolScope=nullptr)
Updates a symbol scope related to a QgsSymbol to an expression context.
Wrapper for iterator of features from vector data provider or vector layer.
void setThreshold(float threshold)
Sets the simplification threshold in pixels. Represents the maximum distance in pixels between two co...
A rectangle specified with double values.
Definition: qgsrectangle.h:41
QgsVectorLayer * mLayer
The rendered layer.
const QgsVectorSimplifyMethod & vectorSimplifyMethod() const
Returns the simplification settings to use when rendering vector layers.
Implementation of map layer temporal properties for vector layers.
Abstract base class for all rendered symbols.
Definition: qgssymbol.h:63
static QgsGeometry calculateFeatureRequestGeometry(const QList< QgsMapClippingRegion > &regions, const QgsRenderContext &context, bool &shouldFilter)
Returns the geometry representing the intersection of clipping regions from context.
virtual bool prepare(QgsRenderContext &context, QSet< QString > &attributeNames)
Prepare for registration of features.
This class is a composition of two QSettings instances:
Definition: qgssettings.h:61
QgsLabelingEngine * labelingEngine() const
Gets access to new labeling engine (may be nullptr)
QVariant value(const QString &key, const QVariant &defaultValue=QVariant(), Section section=NoSection) const
Returns the value for setting key.
void setFeature(const QgsFeature &feature)
Convenience function for setting a feature for the context.
#define QgsDebugMsg(str)
Definition: qgslogger.h:38
QgsPointXY transform(const QgsPointXY &point, TransformDirection direction=ForwardTransform) const SIP_THROW(QgsCsException)
Transform the point from the source CRS to the destination CRS.
The geometries can be simplified using the current map2pixel context state.
double y
Definition: qgspointxy.h:48
QgsSymbol * symbol() const
The symbol of this symbol level.
A class to represent a 2D point.
Definition: qgspointxy.h:43
QList< QgsRenderedFeatureHandlerInterface * > renderedFeatureHandlers() const
Returns the list of rendered feature handlers to use while rendering map layers.
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference)
Definition: qgis.h:315
QgsFeatureRequest::OrderBy orderBy() const
Gets the order in which features shall be processed by this renderer.
QgsFeatureIterator getFeatures(const QgsFeatureRequest &request=QgsFeatureRequest()) override
Gets an iterator for features matching the specified request.
void stopRender(QgsRenderContext &context) override
Must be called when a render cycle has finished, to allow the renderer to clean up.
void setSimplifyHints(SimplifyHints simplifyHints)
Sets the simplification hints of the vector layer managed.
virtual QString filter(const QgsFields &fields=QgsFields())
If a renderer does not require all the features this method may be overridden and return an expressio...
Definition: qgsrenderer.h:205
static QgsGeometry calculateLabelIntersectionGeometry(const QList< QgsMapClippingRegion > &regions, const QgsRenderContext &context, bool &shouldClip)
Returns the geometry representing the intersection of clipping regions from context which should be u...
QgsFeatureRequest & setSubsetOfAttributes(const QgsAttributeList &attrs)
Set a subset of attributes that will be fetched.
bool renderingStopped() const
Returns true if the rendering operation has been stopped and any ongoing rendering should be canceled...
QPainter::CompositionMode mFeatureBlendMode
Q_INVOKABLE QgsWkbTypes::GeometryType geometryType() const
Returns point, line or polygon.
void setVectorSimplifyMethod(const QgsVectorSimplifyMethod &simplifyMethod)
Sets the simplification setting to use when rendering vector layers.
A geometry is the spatial representation of a feature.
Definition: qgsgeometry.h:123
int symbolLayerCount() const
Returns the total number of symbol layers contained in the symbol.
Definition: qgssymbol.h:183
The feature class encapsulates a single feature including its id, geometry and a list of field/values...
Definition: qgsfeature.h:55
QgsFeedback * feedback() const override
Access to feedback object of the layer renderer (may be nullptr)
Encapsulates the context in which a QgsVectorLayer&#39;s temporal capabilities will be applied...
bool hasGeometry() const
Returns true if the feature has an associated geometry.
Definition: qgsfeature.cpp:197
QgsVectorSimplifyMethod mSimplifyMethod
void setClipFeatureGeometry(const QgsGeometry &geometry)
Sets a geometry to use to clip features to when registering them as diagrams.
virtual bool prepare(const QgsRenderContext &context, QSet< QString > &attributeNames)
Prepare for registration of features.
bool isValid() const
Returns true if the coordinate transform is valid, ie both the source and destination CRS have been s...
const QgsFeatureFilterProvider * featureFilterProvider() const
Gets the filter feature provider used for additional filtering of rendered features.
virtual QgsSymbolList originalSymbolsForFeature(const QgsFeature &feature, QgsRenderContext &context) const
Equivalent of originalSymbolsForFeature() call extended to support renderers that may use more symbol...
QString what() const
Definition: qgsexception.h:48
All simplification hints can be applied ( Geometry + AA-disabling )
bool hasRenderedFeatureHandlers() const
Returns true if the context has any rendered feature handlers.
QList< QgsSymbolLevel > QgsSymbolLevelOrder
Definition: qgsrenderer.h:89
virtual QgsSymbol * symbolForFeature(const QgsFeature &feature, QgsRenderContext &context) const =0
To be overridden.
QgsFeatureRequest & combineFilterExpression(const QString &expression)
Modifies the existing filter expression to add an additional expression filter.
Base class for feedback objects to be used for cancellation of something running in a worker thread...
Definition: qgsfeedback.h:43
Perform transforms between map coordinates and device coordinates.
Definition: qgsmaptopixel.h:37
QgsFeatureRequest & setExpressionContext(const QgsExpressionContext &context)
Sets the expression context used to evaluate filter expressions.
virtual QSet< QString > usedAttributes(const QgsRenderContext &context) const =0
Returns a list of attributes required by this renderer.
void setLayer(QgsVectorLayer *layer)
Sets the associated layer.
Q_INVOKABLE QgsVectorLayerEditBuffer * editBuffer()
Buffer with uncommitted editing operations. Only valid after editing has been turned on...
QgsWkbTypes::GeometryType mGeometryType
Simplify using the map2pixel data to optimize the rendering of geometries.
QgsPaintEffect * paintEffect() const
Returns the current paint effect for the renderer.
static QgsGeometry calculateFeatureIntersectionGeometry(const QList< QgsMapClippingRegion > &regions, const QgsRenderContext &context, bool &shouldClip)
Returns the geometry representing the intersection of clipping regions from context which should be u...
Scoped object for saving and restoring a QPainter object&#39;s state.
int renderingPass() const
Specifies the rendering pass in which this symbol layer should be rendered.
No simplification can be applied.
QgsVectorLayerRendererInterruptionChecker(const QgsRenderContext &context)
Constructor.
QList< QgsSymbol * > QgsSymbolList
Definition: qgsrenderer.h:45
static QgsSymbol * defaultSymbol(QgsWkbTypes::GeometryType geomType)
Returns a new default symbol for the specified geometry type.
Definition: qgssymbol.cpp:301
QgsCoordinateReferenceSystem sourceCrs() const
Returns the source coordinate reference system, which the transform will transform coordinates from...
QString type() const
Definition: qgsrenderer.h:141
Q_INVOKABLE const QgsFeatureIds & selectedFeatureIds() const
Returns a list of the selected features IDs in this layer.
QgsFeatureRenderer * mRenderer
#define QgsDebugMsgLevel(str, level)
Definition: qgslogger.h:39
bool isEmpty() const
Returns true if the rectangle is empty.
Definition: qgsrectangle.h:437
void setTolerance(double tolerance)
Sets the tolerance of simplification in map units. Represents the maximum distance in map units betwe...
const QgsRectangle & extent() const
When rendering a map layer, calling this method returns the "clipping" extent for the layer (in the l...
QgsVectorLayerRenderer(QgsVectorLayer *layer, QgsRenderContext &context)
QgsVectorLayerLabelProvider * mLabelProvider
used with new labeling engine (QgsLabelingEngine): provider for labels.
virtual void modifyRequestExtent(QgsRectangle &extent, QgsRenderContext &context)
Allows for a renderer to modify the extent of a feature request prior to rendering.
bool isShortCircuited() const
Returns true if the transform short circuits because the source and destination are equivalent...
The QgsVectorLayerDiagramProvider class implements support for diagrams within the labeling engine...
int layer() const
The layer of this symbol level.
std::unique_ptr< QgsVectorLayerRendererInterruptionChecker > mInterruptionChecker
void setTolerance(double tolerance)
Sets the tolerance of simplification in map units. Represents the maximum distance in map units betwe...
void setFeatureClipGeometry(const QgsGeometry &geometry)
Sets a geometry to use to clip features at render time.
An interface for classes which provider custom handlers for features rendered as part of a map render...
static void logMessage(const QString &message, const QString &tag=QString(), Qgis::MessageLevel level=Qgis::Warning, bool notifyUser=true)
Adds a message to the log instance (and creates it if necessary).
QgsRectangle intersect(const QgsRectangle &rect) const
Returns the intersection with the given rectangle.
Definition: qgsrectangle.h:312
void setInterruptionChecker(QgsFeedback *interruptionChecker)
Attach an object that can be queried regularly by the iterator to check if it must stopped...
QgsMapLayerTemporalProperties * temporalProperties() override
Returns temporal properties associated with the vector layer.
QString toString(int precision=16) const
Returns a string representation of form xmin,ymin : xmax,ymax Coordinates will be truncated to the sp...
static QList< QgsMapClippingRegion > collectClippingRegionsForLayer(const QgsRenderContext &context, const QgsMapLayer *layer)
Collects the list of map clipping regions from a context which apply to a map layer.
bool drawEditingInformation() const
Returns true if edit markers should be drawn during the render operation.
This class wraps a request for features to a vector layer (or directly its vector data provider)...
QgsVectorLayerFeatureSource * mSource
QColor selectionColor() const
Returns the color to use when rendering selected features.
float threshold() const
Gets the simplification threshold of the vector layer managed.
QgsFeatureRequest & setFilterRect(const QgsRectangle &rectangle)
Sets the rectangle from which features will be taken.
bool isEmpty() const
Returns true if the geometry is empty (eg a linestring with no vertices, or a collection with no geom...
QgsCoordinateTransform coordinateTransform() const
Returns the current coordinate transform for the context.
Abstract interface for use by classes that filter the features of a layer.
QgsFeatureRenderer * renderer()
Returns renderer.
bool enabled() const
Returns whether the effect is enabled.
const QgsAbstractVectorLayerLabeling * labeling() const
Access to const labeling configuration.
Single scope for storing variables and functions for use within a QgsExpressionContext.
double mapUnitsPerPixel() const
Returns current map units per pixel.
QgsSymbolLayer * symbolLayer(int layer)
Returns the symbol layer at the specified index.
Definition: qgssymbol.cpp:366
bool orderByEnabled() const
Returns whether custom ordering will be applied before features are processed by this renderer...
QPainter::CompositionMode featureBlendMode() const
Returns the current blending mode for features.
const QgsVectorSimplifyMethod & simplifyMethod() const
Returns the simplification settings for fast rendering of features.
virtual QgsVectorLayerLabelProvider * provider(QgsVectorLayer *layer) const
Factory for label provider implementation.
bool isFinite() const
Returns true if the rectangle has finite boundaries.
Definition: qgsrectangle.h:527
double x
Definition: qgspointxy.h:47
virtual bool renderFeature(const QgsFeature &feature, QgsRenderContext &context, int layer=-1, bool selected=false, bool drawVertexMarker=false) SIP_THROW(QgsCsException)
Render a feature using this renderer in the given context.
Partial snapshot of vector layer&#39;s state (only the members necessary for access to features) ...
virtual void filterFeatures(const QgsVectorLayer *layer, QgsFeatureRequest &featureRequest) const =0
Add additional filters to the feature request to further restrict the features returned by the reques...
virtual void registerFeature(const QgsFeature &feature, QgsRenderContext &context, const QgsGeometry &obstacleGeometry=QgsGeometry(), const QgsSymbol *symbol=nullptr)
Register a feature for labeling as one or more QgsLabelFeature objects stored into mLabels...
static QgsGeometryEngine * createGeometryEngine(const QgsAbstractGeometry *geometry)
Creates and returns a new geometry engine.
const QgsAbstractGeometry * constGet() const
Returns a non-modifiable (const) reference to the underlying abstract geometry primitive.
Rendering with symbol levels (i.e. implements symbols(), symbolForFeature())
Definition: qgsrenderer.h:254
double yMinimum() const
Returns the y minimum value (bottom side of rectangle).
Definition: qgsrectangle.h:177
QgsExpressionContext & expressionContext()
Gets the expression context.
QgsFeatureRequest & setSimplifyMethod(const QgsSimplifyMethod &simplifyMethod)
Set a simplification method for geometries that will be fetched.
double xMaximum() const
Returns the x maximum value (right side of rectangle).
Definition: qgsrectangle.h:162
void startRender(QgsRenderContext &context, const QgsFields &fields) override
Must be called when a new render cycle is started.
const QgsDateTimeRange & temporalRange() const
Returns the datetime range for the object.
void setForceLocalOptimization(bool localOptimization)
Sets whether the simplification executes after fetch the geometries from provider, otherwise it executes, when supported, in provider before fetch the geometries.
The QgsLabelingEngine class provides map labeling functionality.
bool render() override
Do the rendering (based on data stored in the class)
This class contains information how to simplify geometries fetched from a vector layer.
bool isTemporal() const
Returns true if the object&#39;s temporal range is enabled, and the object will be filtered when renderin...
Contains information about the context of a rendering operation.
bool usingSymbolLevels() const
Definition: qgsrenderer.h:283
QPainter * painter()
Returns the destination QPainter for the render operation.
const QgsMapToPixel & mapToPixel() const
Returns the context&#39;s map to pixel transform, which transforms between map coordinates and device coo...
bool simplifyDrawingCanbeApplied(const QgsRenderContext &renderContext, QgsVectorSimplifyMethod::SimplifyHint simplifyHint) const
Returns whether the VectorLayer can apply the specified simplification hint.
QList< QgsSymbolLevelItem > QgsSymbolLevel
Definition: qgsrenderer.h:85
virtual void registerFeature(QgsFeature &feature, QgsRenderContext &context, const QgsGeometry &obstacleGeometry=QgsGeometry())
Register a feature for labeling as one or more QgsLabelFeature objects stored into mFeatures...
virtual QgsSymbolList symbols(QgsRenderContext &context) const
Returns list of symbols used by the renderer.
virtual void startRender(QgsRenderContext &context, const QgsFields &fields)
Must be called when a new render cycle is started.
Definition: qgsrenderer.cpp:93
QList< QgsMapClippingRegion > mClippingRegions
bool forceLocalOptimization() const
Gets where the simplification executes, after fetch the geometries from provider, or when supported...
QString layerId() const
Gets access to the ID of the layer rendered by this class.
void setMethodType(MethodType methodType)
Sets the simplification type.
void appendScope(QgsExpressionContextScope *scope)
Appends a scope to the end of the context.
bool useAdvancedEffects() const
Returns true if advanced effects such as blend modes such be used.
QgsRectangle boundingBox() const
Returns the bounding box of the geometry.
SimplifyHints simplifyHints() const
Gets the simplification hints of the vector layer managed.
virtual void stopRender(QgsRenderContext &context)
Must be called when a render cycle has finished, to allow the renderer to clean up.
Class for doing transforms between two map coordinate systems.
bool showSelection() const
Returns true if vector selections should be shown in the rendered map.
double xMinimum() const
Returns the x minimum value (left side of rectangle).
Definition: qgsrectangle.h:167
Base class for utility classes that encapsulate information necessary for rendering of map layers...
void setVertexMarkerAppearance(int type, double size)
Sets type and size of editing vertex markers for subsequent rendering.
double yMaximum() const
Returns the y maximum value (top side of rectangle).
Definition: qgsrectangle.h:172
This class contains information about how to simplify geometries fetched from a QgsFeatureIterator.
QgsFeatureRequest & setOrderBy(const OrderBy &orderBy)
Set a list of order by clauses.
QgsWkbTypes::GeometryType type
Definition: qgsgeometry.h:127
QgsGeometry geometry
Definition: qgsfeature.h:67
Custom exception class for Coordinate Reference System related exceptions.
Definition: qgsexception.h:65
QgsPointXY center() const
Returns the center point of the rectangle.
Definition: qgsrectangle.h:230
QgsExpressionContextScope * popScope()
Removes the last scope from the expression context and return it.
static QgsExpressionContextScope * layerScope(const QgsMapLayer *layer)
Creates a new scope which contains variables and functions relating to a QgsMapLayer.
bool nextFeature(QgsFeature &f)
QgsVectorLayerDiagramProvider * mDiagramProvider
used with new labeling engine (QgsLabelingEngine): provider for diagrams.
QgsRenderContext * renderContext()
Returns the render context associated with the renderer.
Represents a vector layer which manages a vector based data sets.
virtual void end(QgsRenderContext &context)
Ends interception of paint operations to a render context, and draws the result to the render context...
QgsSymbol * symbol() const
Returns the symbol which will be rendered for every feature.
bool isValid() const
Will return if this iterator is valid.
virtual void begin(QgsRenderContext &context)
Begins intercepting paint operations to a render context.
virtual QgsFeatureRenderer::Capabilities capabilities()
Returns details about internals of this renderer.
Definition: qgsrenderer.h:274
virtual QgsFeatureRenderer * clone() const =0
Create a deep copy of this renderer.
bool diagramsEnabled() const
Returns whether the layer contains diagrams which are enabled and should be drawn.
static QPainterPath calculatePainterClipRegion(const QList< QgsMapClippingRegion > &regions, const QgsRenderContext &context, QgsMapLayerType layerType, bool &shouldClip)
Returns a QPainterPath representing the intersection of clipping regions from context which should be...
static QgsGeometry getPointObstacleGeometry(QgsFeature &fet, QgsRenderContext &context, const QgsSymbolList &symbols)
Returns the geometry for a point feature which should be used as an obstacle for labels.
void setColor(const QColor &color)
Sets the color for the symbol.
Definition: qgssymbol.cpp:485
virtual QString dump() const
Returns debug information about this renderer.