QGIS API Documentation 3.37.0-Master (fdefdf9c27f)
qgsmaprendererjobproxy.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgsmaprendererjobproxy.cpp
3 --------------------------
4 begin : January 2017
5 copyright : (C) 2017 by Paul Blottiere
6 email : paul dot blottiere at oslandia dot com
7***************************************************************************/
8
9/***************************************************************************
10 * *
11 * This program is free software; you can redistribute it and/or modify *
12 * it under the terms of the GNU General Public License as published by *
13 * the Free Software Foundation; either version 2 of the License, or *
14 * (at your option) any later version. *
15 * *
16 ***************************************************************************/
17
19
20#include "qgsmessagelog.h"
23#include "qgsapplication.h"
24#include <QThread>
25
26namespace QgsWms
27{
28
30 bool parallelRendering
31 , int maxThreads
32 , QgsFeatureFilterProvider *featureFilterProvider
33 )
34 :
35 mParallelRendering( parallelRendering )
36 , mFeatureFilterProvider( featureFilterProvider )
37 {
38#ifndef HAVE_SERVER_PYTHON_PLUGINS
39 Q_UNUSED( mFeatureFilterProvider )
40#endif
41 if ( mParallelRendering )
42 {
44 QgsMessageLog::logMessage( QStringLiteral( "Parallel rendering activated with %1 threads" ).arg( maxThreads ), QStringLiteral( "server" ), Qgis::MessageLevel::Info );
45 }
46 else
47 {
48 QgsMessageLog::logMessage( QStringLiteral( "Parallel rendering deactivated" ), QStringLiteral( "server" ), Qgis::MessageLevel::Info );
49 }
50 }
51
52 void QgsMapRendererJobProxy::render( const QgsMapSettings &mapSettings, QImage *image, const QgsFeedback *feedback )
53 {
54 if ( mParallelRendering )
55 {
56 QgsMapRendererParallelJob renderJob( mapSettings );
57#ifdef HAVE_SERVER_PYTHON_PLUGINS
58 renderJob.setFeatureFilterProvider( mFeatureFilterProvider );
59#endif
60
61 // Allows the main thread to manage blocking call coming from rendering
62 // threads (see discussion in https://github.com/qgis/QGIS/issues/26819).
63 QEventLoop loop;
64 QObject::connect( &renderJob, &QgsMapRendererParallelJob::finished, &loop, &QEventLoop::quit );
65 if ( feedback )
66 QObject::connect( feedback, &QgsFeedback::canceled, &renderJob, &QgsMapRendererParallelJob::cancel );
67
68 if ( !feedback || !feedback->isCanceled() )
69 renderJob.start();
70
71 if ( renderJob.isActive() )
72 {
73 loop.exec();
74
75 renderJob.waitForFinished();
76 *image = renderJob.renderedImage();
77 mPainter.reset( new QPainter( image ) );
78 }
79
80 mErrors = renderJob.errors();
81
82 if ( feedback )
83 QObject::disconnect( feedback, &QgsFeedback::canceled, &renderJob, &QgsMapRendererParallelJob::cancel );
84 }
85 else
86 {
87 mPainter.reset( new QPainter( image ) );
88 QgsMapRendererCustomPainterJob renderJob( mapSettings, mPainter.get() );
89 if ( feedback )
90 QObject::connect( feedback, &QgsFeedback::canceled, &renderJob, &QgsMapRendererCustomPainterJob::cancel );
91#ifdef HAVE_SERVER_PYTHON_PLUGINS
92 renderJob.setFeatureFilterProvider( mFeatureFilterProvider );
93#endif
94 if ( !feedback || !feedback->isCanceled() )
95 renderJob.renderSynchronously();
96
97 mErrors = renderJob.errors();
98
99 if ( feedback )
100 QObject::disconnect( feedback, &QgsFeedback::canceled, &renderJob, &QgsMapRendererCustomPainterJob::cancel );
101 }
102 }
103
105 {
106 return mPainter.release();
107 }
108} // namespace qgsws
static void setMaxThreads(int maxThreads)
Set maximum concurrent thread count.
Abstract interface for use by classes that filter the features or attributes of a layer.
Base class for feedback objects to be used for cancellation of something running in a worker thread.
Definition: qgsfeedback.h:44
bool isCanceled() const
Tells whether the operation has been canceled already.
Definition: qgsfeedback.h:53
void canceled()
Internal routines can connect to this signal if they use event loop.
Job implementation that renders everything sequentially using a custom painter.
void renderSynchronously()
Render the map synchronously in this thread.
void cancel() override
Stop the rendering job - does not return until the job has terminated.
Errors errors() const
List of errors that happened during the rendering job - available when the rendering has been finishe...
void finished()
emitted when asynchronous rendering is finished (or canceled).
void start()
Start the rendering job and immediately return.
void setFeatureFilterProvider(const QgsFeatureFilterProvider *f)
Set the feature filter provider used by the QgsRenderContext of each LayerRenderJob.
Job implementation that renders all layers in parallel.
bool isActive() const override
Tell whether the rendering job is currently running in background.
QImage renderedImage() override
Gets a preview/resulting image.
void cancel() override
Stop the rendering job - does not return until the job has terminated.
void waitForFinished() override
Block until the job has finished.
The QgsMapSettings class contains configuration for rendering of the map.
static void logMessage(const QString &message, const QString &tag=QString(), Qgis::MessageLevel level=Qgis::MessageLevel::Warning, bool notifyUser=true)
Adds a message to the log instance (and creates it if necessary).
QPainter * takePainter()
Takes ownership of the painter used for rendering.
void render(const QgsMapSettings &mapSettings, QImage *image, const QgsFeedback *feedback)
Sequential or parallel map rendering.
QgsMapRendererJobProxy(bool parallelRendering, int maxThreads, QgsFeatureFilterProvider *featureFilterProvider)
Constructor for QgsMapRendererJobProxy.
Median cut implementation.