27 #include <QtConcurrentRun>    33   , mRenderSynchronously( false )
    41   Q_ASSERT( !mFutureWatcher.isRunning() );
    58   QgsDebugMsgLevel( QStringLiteral( 
"Preparing list of layer jobs for rendering" ), 5 );
    68   QPaintDevice *paintDevice = mPainter->device();
    69   QString errMsg = QStringLiteral( 
"pre-set DPI not equal to painter's DPI (%1 vs %2)" )
    70                    .arg( paintDevice->logicalDpiX() )
    73               "Job::startRender()", errMsg.toLatin1().data() );
    76   mLabelingEngineV2.reset();
    81     mLabelingEngineV2->setMapSettings( 
mSettings );
    85   mLayerJobs = 
prepareJobs( mPainter, mLabelingEngineV2.get() );
    88   QgsDebugMsgLevel( 
"Rendering prepared in (seconds): " + QString( 
"%1" ).arg( prepareTime.elapsed() / 1000.0 ), 4 );
    90   if ( mRenderSynchronously )
    98   connect( &mFutureWatcher, &QFutureWatcher<void>::finished, 
this, &QgsMapRendererCustomPainterJob::futureFinished );
   100   mFuture = QtConcurrent::run( staticRender, 
this );
   101   mFutureWatcher.setFuture( mFuture );
   114   disconnect( &mFutureWatcher, &QFutureWatcher<void>::finished, 
this, &QgsMapRendererCustomPainterJob::futureFinished );
   120   mFutureWatcher.waitForFinished();
   122   QgsDebugMsgLevel( QStringLiteral( 
"QPAINER cancel waited %1 ms" ).arg( t.elapsed() / 1000.0 ), 5 );
   133     QgsDebugMsg( QStringLiteral( 
"QPAINTER not running!" ) );
   137   mLabelJob.context.setRenderingStopped( 
true );
   138   for ( LayerRenderJobs::iterator it = mLayerJobs.begin(); it != mLayerJobs.end(); ++it )
   140     it->context.setRenderingStopped( 
true );
   141     if ( it->renderer && it->renderer->feedback() )
   142       it->renderer->feedback()->cancel();
   151   disconnect( &mFutureWatcher, &QFutureWatcher<void>::finished, 
this, &QgsMapRendererCustomPainterJob::futureFinished );
   156   mFutureWatcher.waitForFinished();
   158   QgsDebugMsgLevel( QStringLiteral( 
"waitForFinished: %1 ms" ).arg( t.elapsed() / 1000.0 ), 4 );
   170   return mLabelJob.cached;
   175   if ( mLabelingEngineV2 )
   176     return mLabelingEngineV2->takeResults();
   185   connect( &mFutureWatcher, &QFutureWatcher<void>::finished, &loop, &QEventLoop::quit );
   192   mRenderSynchronously = 
true;
   195   mRenderSynchronously = 
false;
   199 void QgsMapRendererCustomPainterJob::futureFinished()
   226   catch ( std::exception &e )
   229     QgsDebugMsg( 
"Caught unhandled std::exception: " + QString::fromLatin1( e.what() ) );
   233     QgsDebugMsg( QStringLiteral( 
"Caught unhandled unknown exception" ) );
   237 void QgsMapRendererCustomPainterJob::doRender()
   243   for ( LayerRenderJobs::iterator it = mLayerJobs.begin(); it != mLayerJobs.end(); ++it )
   245     LayerRenderJob &job = *it;
   247     if ( job.context.renderingStopped() )
   250     if ( job.context.useAdvancedEffects() )
   254       mPainter->setCompositionMode( job.blendMode );
   265         job.imageInitialized = 
true;
   268       job.renderer->render();
   270       job.renderingTime += layerTime.elapsed();
   276       mPainter->setOpacity( job.opacity );
   277       mPainter->drawImage( 0, 0, *job.img );
   278       mPainter->setOpacity( 1.0 );
   287     if ( !mLabelJob.cached )
   295         mLabelJob.img->fill( 0 );
   296         painter.begin( mLabelJob.img );
   297         mLabelJob.context.setPainter( &painter );
   298         drawLabeling( mLabelJob.context, mLabelingEngineV2.get(), &painter );
   303         drawLabeling( mLabelJob.context, mLabelingEngineV2.get(), mPainter );
   306       mLabelJob.complete = 
true;
   307       mLabelJob.renderingTime = labelTime.elapsed();
   308       mLabelJob.participatingLayers = _qgis_listRawToQPointer( mLabelingEngineV2->participatingLayers() );
   311   if ( mLabelJob.img && mLabelJob.complete )
   313     mPainter->setCompositionMode( QPainter::CompositionMode_SourceOver );
   314     mPainter->setOpacity( 1.0 );
   315     mPainter->drawImage( 0, 0, *mLabelJob.img );
   318   QgsDebugMsgLevel( 
"Rendering completed in (seconds): " + QString( 
"%1" ).arg( renderTime.elapsed() / 1000.0 ), 2 );
   329   painter->setCompositionMode( QPainter::CompositionMode_SourceOver );
   333   if ( labelingEngine2 )
   335     labelingEngine2->
run( renderContext );
   338   QgsDebugMsg( QStringLiteral( 
"Draw labeling took (seconds): %1" ).arg( t.elapsed() / 1000. ) );
   343   Q_UNUSED( settings );
   345   drawLabeling( renderContext, labelingEngine2, painter );
   348 bool QgsMapRendererJob::needTemporaryImage( 
QgsMapLayer *ml )
   350   switch ( ml->
type() )
   361            ( ( vl->
blendMode() != QPainter::CompositionMode_SourceOver )
 QgsMapRendererCustomPainterJob(const QgsMapSettings &settings, QPainter *painter)
 
void finished()
emitted when asynchronous rendering is finished (or canceled). 
 
Base class for all map layer types. 
 
Job implementation that renders everything sequentially using a custom painter. 
 
Abstract base class for map rendering implementations. 
 
void cleanupJobs(LayerRenderJobs &jobs)
 
QSize deviceOutputSize() const
Returns the device output size of the map canvas This is equivalent to the output size multiplicated ...
 
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference) 
 
static Q_DECL_DEPRECATED void drawLabeling(const QgsMapSettings &settings, QgsRenderContext &renderContext, QgsLabelingEngine *labelingEngine2, QPainter *painter)
 
QColor backgroundColor() const
Gets the background color of the map. 
 
Whether to make extra effort to update map image with partially rendered layers (better for interacti...
 
bool forceRasterRender() const
Returns whether the renderer must render as a raster. 
 
void cancel() override
Stop the rendering job - does not return until the job has terminated. 
 
Enable layer opacity and blending effects. 
 
QgsMapLayer::LayerType type() const
Returns the type of the layer. 
 
void waitForFinishedWithEventLoop(QEventLoop::ProcessEventsFlags flags=QEventLoop::AllEvents)
Wait for the job to be finished - and keep the thread's event loop running while waiting. 
 
Enable drawing of labels on top of the map. 
 
The QgsMapSettings class contains configuration for rendering of the map. 
 
LabelRenderJob prepareLabelingJob(QPainter *painter, QgsLabelingEngine *labelingEngine2, bool canUseLabelCache=true)
Prepares a labeling job. 
 
bool prepareLabelCache() const
Prepares the cache for storing the result of labeling. 
 
void start() override
Start the rendering job and immediately return. 
 
#define QgsDebugMsgLevel(str, level)
 
Enable anti-aliasing for map rendering. 
 
void setPainter(QPainter *p)
Sets the destination QPainter for the render operation. 
 
QgsFeatureRenderer * renderer()
Returns renderer. 
 
bool usedCachedLabels() const override
Returns true if the render job was able to use a cached labeling solution. 
 
float devicePixelRatio() const
Returns device pixel ratio Common values are 1 for normal-dpi displays and 2 for high-dpi "retina" di...
 
QPainter::CompositionMode featureBlendMode() const
Returns the current blending mode for features. 
 
void cleanupLabelJob(LabelRenderJob &job)
Handles clean up tasks for a label job, including deletion of images and storing cached label results...
 
void cancelWithoutBlocking() override
Triggers cancelation of the rendering job without blocking. 
 
double outputDpi() const
Returns DPI used for conversion between real world units (e.g. 
 
The QgsLabelingEngine class provides map labeling functionality. 
 
void run(QgsRenderContext &context)
compute the labeling with given map settings and providers 
 
Contains information about the context of a rendering operation. 
 
LayerRenderJobs prepareJobs(QPainter *painter, QgsLabelingEngine *labelingEngine2)
 
void logRenderingTime(const LayerRenderJobs &jobs, const LabelRenderJob &labelJob)
 
~QgsMapRendererCustomPainterJob() override
 
Class that stores computed placement from labeling engine. 
 
bool testFlag(Flag flag) const
Check whether a particular flag is enabled. 
 
QgsLabelingResults * takeLabelingResults() override
Gets pointer to internal labeling engine (in order to get access to the results). ...
 
void waitForFinished() override
Block until the job has finished. 
 
Represents a vector layer which manages a vector based data sets. 
 
Defines a QGIS exception class. 
 
void renderSynchronously()
Render the map synchronously in this thread. 
 
QPainter::CompositionMode blendMode() const
Returns the current blending mode for a layer. 
 
bool isActive() const override
Tell whether the rendering job is currently running in background.