QGIS API Documentation  3.26.3-Buenos Aires (65e4edfdad)
qgsmaprendererstagedrenderjob.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsmaprendererstagedrenderjob.cpp
3  --------------------------------------
4  Date : August 2019
5  Copyright : (C) 2019 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 "qgsfeedback.h"
19 #include "qgslabelingengine.h"
20 #include "qgslogger.h"
21 #include "qgsproject.h"
22 #include "qgsmaplayerrenderer.h"
23 #include "qgsmaplayerlistutils_p.h"
24 #include "qgsrendereditemresults.h"
25 
28  , mFlags( flags )
29 {
30 }
31 
33 {
34  // final cleanup
35  cleanupJobs( mLayerJobs );
36  cleanupLabelJob( mLabelJob );
37 }
38 
39 
40 void QgsMapRendererStagedRenderJob::startPrivate()
41 {
42  mRenderingStart.start();
43  mErrors.clear();
44 
45  QgsDebugMsgLevel( QStringLiteral( "Preparing list of layer jobs for rendering" ), 5 );
46  QElapsedTimer prepareTime;
47  prepareTime.start();
48 
49  mLabelingEngineV2.reset();
50 
52  {
53  if ( mFlags & RenderLabelsByMapLayer )
54  mLabelingEngineV2.reset( new QgsStagedRenderLabelingEngine() );
55  else
56  mLabelingEngineV2.reset( new QgsDefaultLabelingEngine() );
57  mLabelingEngineV2->setMapSettings( mSettings );
58  }
59 
60  mLayerJobs = prepareJobs( nullptr, mLabelingEngineV2.get(), true );
61  mLabelJob = prepareLabelingJob( nullptr, mLabelingEngineV2.get(), false );
62 
63  mJobIt = mLayerJobs.begin();
64 }
65 
67 {
68 }
69 
71 {
72 }
73 
75 {
76 }
77 
79 {
80  return true;
81 }
82 
84 {
85  return false;
86 }
87 
89 {
90  if ( mLabelingEngineV2 )
91  return mLabelingEngineV2->takeResults();
92  else
93  return nullptr;
94 }
95 
97 {
98  if ( isFinished() )
99  return false;
100 
101  preparePainter( painter );
102 
103  if ( mJobIt != mLayerJobs.end() )
104  {
105  LayerRenderJob &job = *mJobIt;
106  emit layerRenderingStarted( job.layerId );
107  job.renderer->renderContext()->setPainter( painter );
108 
109  if ( job.context()->useAdvancedEffects() )
110  {
111  // Set the QPainter composition mode so that this layer is rendered using
112  // the desired blending mode
113  painter->setCompositionMode( job.blendMode );
114  }
115 
116  if ( job.img )
117  {
118  job.img->fill( 0 );
119  job.imageInitialized = true;
120  }
121 
122  job.completed = job.renderer->render();
123 
124  if ( job.img )
125  {
126  // If we flattened this layer for alternate blend modes, composite it now
127  painter->setOpacity( job.opacity );
128  painter->drawImage( 0, 0, *job.img );
129  painter->setOpacity( 1.0 );
130  }
131  job.context()->setPainter( nullptr );
132 
133  emit layerRendered( job.layerId );
134  }
135  else
136  {
137  if ( !mLabelingEngineV2 )
138  return false;
139 
140  if ( mFlags & RenderLabelsByMapLayer )
141  {
142  if ( !mPreparedStagedLabelJob || mLabelLayerIt == mLabelingLayers.end() )
143  return false;
144 
145  mLabelJob.context.setPainter( painter );
146 
147  // Reset the composition mode before rendering the labels
148  painter->setCompositionMode( QPainter::CompositionMode_SourceOver );
149 
150  // render just the current layer's labels
151  static_cast< QgsStagedRenderLabelingEngine * >( mLabelingEngineV2.get() )->renderLabelsForLayer( mLabelJob.context, *mLabelLayerIt );
152 
153  mLabelJob.context.setPainter( nullptr );
154  }
155  else
156  {
157  mLabelJob.context.setPainter( painter );
158  drawLabeling( mLabelJob.context, mLabelingEngineV2.get(), painter );
159  mLabelJob.complete = true;
160  mLabelJob.participatingLayers = _qgis_listRawToQPointer( mLabelingEngineV2->participatingLayers() );
161  mLabelJob.context.setPainter( nullptr );
162  }
163  }
164  return true;
165 }
166 
168 {
169  if ( isFinished() )
170  return false;
171 
172  if ( mJobIt != mLayerJobs.end() )
173  {
174  ++mJobIt;
175  if ( mJobIt != mLayerJobs.end() )
176  return true;
177  }
178 
179  if ( mLabelingEngineV2 )
180  {
181  if ( mFlags & RenderLabelsByMapLayer )
182  {
183  if ( !mPreparedStagedLabelJob )
184  {
185  mLabelingEngineV2->run( mLabelJob.context );
186  mPreparedStagedLabelJob = true;
187  mLabelingLayers = mLabelingEngineV2->participatingLayerIds();
188  mLabelLayerIt = mLabelingLayers.begin();
189  if ( mLabelLayerIt == mLabelingLayers.end() )
190  {
191  // no label layers to render!
192  static_cast< QgsStagedRenderLabelingEngine * >( mLabelingEngineV2.get() )->finalize();
193  return false;
194  }
195  return true;
196  }
197  else
198  {
199  if ( mLabelLayerIt != mLabelingLayers.end() )
200  {
201  ++mLabelLayerIt;
202  if ( mLabelLayerIt != mLabelingLayers.end() )
203  return true;
204  }
205  }
206  return false;
207  }
208  else
209  {
210  if ( mNextIsLabel )
211  {
212  mExportedLabels = true;
213  }
214  else if ( !mExportedLabels )
215  {
216  mNextIsLabel = true;
217  return true;
218  }
219  }
220  }
221  return false;
222 }
223 
225 {
226  return currentStage() == Finished;
227 }
228 
230 {
231  if ( mJobIt != mLayerJobs.end() )
232  {
233  const LayerRenderJob &job = *mJobIt;
234  return job.layerId;
235  }
236  else if ( mFlags & RenderLabelsByMapLayer && mPreparedStagedLabelJob )
237  {
238  if ( mLabelLayerIt != mLabelingLayers.end() )
239  return *mLabelLayerIt;
240  }
241  return QString();
242 }
243 
245 {
246  if ( mJobIt != mLayerJobs.end() )
247  {
248  const LayerRenderJob &job = *mJobIt;
249  return job.opacity;
250  }
251  return 1.0;
252 }
253 
255 {
256  if ( mJobIt != mLayerJobs.end() )
257  {
258  const LayerRenderJob &job = *mJobIt;
259  return job.blendMode;
260  }
261  return QPainter::CompositionMode_SourceOver;
262 }
263 
265 {
266  if ( mJobIt != mLayerJobs.end() )
267  return Symbology;
268  else if ( mLabelingEngineV2 && mFlags & RenderLabelsByMapLayer )
269  {
270  if ( !mPreparedStagedLabelJob )
271  return Labels;
272  if ( mLabelLayerIt != mLabelingLayers.end() )
273  return Labels;
274  }
275  else if ( mNextIsLabel && !mExportedLabels )
276  return Labels;
277 
278  return Finished;
279 }
QgsMapRendererStagedRenderJob::Symbology
@ Symbology
Rendering layer symbology.
Definition: qgsmaprendererstagedrenderjob.h:51
QgsMapRendererJob::layerRenderingStarted
void layerRenderingStarted(const QString &layerId)
Emitted just before rendering starts for a particular layer.
QgsMapRendererJob::mErrors
Errors mErrors
Definition: qgsmaprendererjob.h:492
QgsMapRendererAbstractCustomPainterJob
Abstract base class for map renderer jobs which use custom painters.
Definition: qgsmaprenderercustompainterjob.h:31
QgsDebugMsgLevel
#define QgsDebugMsgLevel(str, level)
Definition: qgslogger.h:39
QgsMapRendererStagedRenderJob::currentLayerOpacity
double currentLayerOpacity() const
Returns the opacity for the current layer about to be rendered in the next render operation.
Definition: qgsmaprendererstagedrenderjob.cpp:244
QgsMapRendererStagedRenderJob::waitForFinished
void waitForFinished() override
Block until the job has finished.
Definition: qgsmaprendererstagedrenderjob.cpp:74
Qgis::MapSettingsFlag::DrawLabeling
@ DrawLabeling
Enable drawing of labels on top of the map.
QgsStagedRenderLabelingEngine
A QgsLabelingEngine implementation, which only calculates the labeling solution during its run() meth...
Definition: qgslabelingengine.h:490
QgsMapRendererStagedRenderJob::Finished
@ Finished
Rendering is finished.
Definition: qgsmaprendererstagedrenderjob.h:53
QgsLabelingResults
Class that stores computed placement from labeling engine.
Definition: qgslabelingresults.h:32
QgsMapRendererJob::mRenderingStart
QElapsedTimer mRenderingStart
Definition: qgsmaprendererjob.h:491
QgsMapRendererStagedRenderJob::currentLayerCompositionMode
QPainter::CompositionMode currentLayerCompositionMode() const
Returns the composition mode for the current layer about to be rendered in the next render operation.
Definition: qgsmaprendererstagedrenderjob.cpp:254
QgsMapRendererJob::prepareJobs
std::vector< LayerRenderJob > prepareJobs(QPainter *painter, QgsLabelingEngine *labelingEngine2, bool deferredPainterSet=false)
Creates a list of layer rendering jobs and prepares them for later render.
QgsMapRendererStagedRenderJob::~QgsMapRendererStagedRenderJob
~QgsMapRendererStagedRenderJob() override
Definition: qgsmaprendererstagedrenderjob.cpp:32
QgsDefaultLabelingEngine
Default QgsLabelingEngine implementation, which completes the whole labeling operation (including lab...
Definition: qgslabelingengine.h:464
qgsmaprendererstagedrenderjob.h
QgsMapRendererJob::layerRendered
void layerRendered(const QString &layerId)
Emitted when a layer has completed rendering.
QgsMapRendererJob::prepareLabelingJob
LabelRenderJob prepareLabelingJob(QPainter *painter, QgsLabelingEngine *labelingEngine2, bool canUseLabelCache=true)
Prepares a labeling job.
QgsMapRendererStagedRenderJob::RenderStage
RenderStage
Represents the stages of a rendering job.
Definition: qgsmaprendererstagedrenderjob.h:49
qgsmaplayerlistutils_p.h
QgsMapSettings::testFlag
bool testFlag(Qgis::MapSettingsFlag flag) const
Check whether a particular flag is enabled.
Definition: qgsmapsettings.cpp:395
QgsMapRendererStagedRenderJob::Labels
@ Labels
Rendering labels.
Definition: qgsmaprendererstagedrenderjob.h:52
QgsMapRendererStagedRenderJob::cancel
void cancel() override
Stop the rendering job - does not return until the job has terminated.
Definition: qgsmaprendererstagedrenderjob.cpp:66
QgsMapRendererStagedRenderJob::takeLabelingResults
QgsLabelingResults * takeLabelingResults() override
Gets pointer to internal labeling engine (in order to get access to the results).
Definition: qgsmaprendererstagedrenderjob.cpp:88
qgsmaplayerrenderer.h
QgsMapRendererJob::cleanupLabelJob
void cleanupLabelJob(LabelRenderJob &job)
Handles clean up tasks for a label job, including deletion of images and storing cached label results...
QgsMapRendererStagedRenderJob::QgsMapRendererStagedRenderJob
QgsMapRendererStagedRenderJob(const QgsMapSettings &settings, Flags flags=Flags())
Constructor for QgsMapRendererStagedRenderJob, using the given map settings.
Definition: qgsmaprendererstagedrenderjob.cpp:26
QgsMapRendererStagedRenderJob::nextPart
bool nextPart()
Iterates to the next part to render.
Definition: qgsmaprendererstagedrenderjob.cpp:167
QgsMapRendererStagedRenderJob::currentLayerId
QString currentLayerId() const
Returns the ID of the current layer about to be rendered in the next render operation.
Definition: qgsmaprendererstagedrenderjob.cpp:229
QgsMapRendererStagedRenderJob::RenderLabelsByMapLayer
@ RenderLabelsByMapLayer
Labels should be rendered in individual stages by map layer. This allows separation of labels belongi...
Definition: qgsmaprendererstagedrenderjob.h:42
QgsMapRendererAbstractCustomPainterJob::preparePainter
void preparePainter(QPainter *painter, const QColor &backgroundColor=Qt::transparent)
Prepares the given painter ready for a map render.
Definition: qgsmaprenderercustompainterjob.cpp:51
QgsMapRendererJob::cleanupJobs
void cleanupJobs(std::vector< LayerRenderJob > &jobs)
QgsMapRendererStagedRenderJob::isActive
bool isActive() const override
Tell whether the rendering job is currently running in background.
Definition: qgsmaprendererstagedrenderjob.cpp:78
QgsMapRendererStagedRenderJob::isFinished
bool isFinished() const
Returns true if the job is finished, and nothing remains to render.
Definition: qgsmaprendererstagedrenderjob.cpp:224
QgsMapRendererJob::mSettings
QgsMapSettings mSettings
Definition: qgsmaprendererjob.h:490
QgsMapRendererStagedRenderJob::usedCachedLabels
bool usedCachedLabels() const override
Returns true if the render job was able to use a cached labeling solution.
Definition: qgsmaprendererstagedrenderjob.cpp:83
QgsMapRendererStagedRenderJob::renderCurrentPart
bool renderCurrentPart(QPainter *painter)
Renders the current part of the map to the specified painter.
Definition: qgsmaprendererstagedrenderjob.cpp:96
QgsMapRendererStagedRenderJob::currentStage
RenderStage currentStage() const
Returns the current stage which will be rendered in the next render operation.
Definition: qgsmaprendererstagedrenderjob.cpp:264
qgslogger.h
QgsMapSettings
The QgsMapSettings class contains configuration for rendering of the map. The rendering itself is don...
Definition: qgsmapsettings.h:88
qgsfeedback.h
QgsMapRendererStagedRenderJob::cancelWithoutBlocking
void cancelWithoutBlocking() override
Triggers cancellation of the rendering job without blocking.
Definition: qgsmaprendererstagedrenderjob.cpp:70
qgsproject.h
qgslabelingengine.h
qgsrendereditemresults.h
QgsMapRendererJob::drawLabeling
static Q_DECL_DEPRECATED void drawLabeling(const QgsMapSettings &settings, QgsRenderContext &renderContext, QgsLabelingEngine *labelingEngine2, QPainter *painter)