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