19 #include <QElapsedTimer> 
   21 #include <QtConcurrentMap> 
   36 #include "qgssettings.h" 
   52 bool LayerRenderJob::imageCanBeComposed()
 const 
   54   if ( imageInitialized )
 
   58       return renderer->isReadyToCompose();
 
   72   : mSettings( settings )
 
  104   QHash<QgsMapLayer *, int> result;
 
  107     if ( 
auto &&lKey = it.key() )
 
  108       result.insert( lKey, it.value() );
 
  128   QSet< QgsMapLayer * > labeledLayers;
 
  135     switch ( ml->type() )
 
  200     static const double SPLIT_COORD = 180.0;
 
  212         QgsDebugMsgLevel( QStringLiteral( 
"\n0:%1 %2x%3\n1:%4\n2:%5 %6x%7 (w:%8 h:%9)" )
 
  215                           .arg( std::fabs( 1.0 - extent2.
width() / extent.
width() ) )
 
  216                           .arg( std::fabs( 1.0 - extent2.
height() / extent.
height() ) )
 
  250         if ( ll.
x() > ur.
x() )
 
  279         extent = 
QgsRectangle( std::numeric_limits<double>::lowest(), std::numeric_limits<double>::lowest(), std::numeric_limits<double>::max(), std::numeric_limits<double>::max() );
 
  288     QgsDebugMsg( QStringLiteral( 
"Transform error caught" ) );
 
  289     extent = 
QgsRectangle( std::numeric_limits<double>::lowest(), std::numeric_limits<double>::lowest(), std::numeric_limits<double>::max(), std::numeric_limits<double>::max() );
 
  290     r2 = 
QgsRectangle( std::numeric_limits<double>::lowest(), std::numeric_limits<double>::lowest(), std::numeric_limits<double>::max(), std::numeric_limits<double>::max() );
 
  297 QImage *QgsMapRendererJob::allocateImage( QString layerId )
 
  302   if ( image->isNull() )
 
  311 QPainter *QgsMapRendererJob::allocateImageAndPainter( QString layerId, QImage *&image )
 
  313   QPainter *painter = 
nullptr;
 
  314   image = allocateImage( layerId );
 
  317     painter = 
new QPainter( image );
 
  319 #if QT_VERSION >= QT_VERSION_CHECK(5, 13, 0) 
  328   LayerRenderJobs layerJobs;
 
  337     Q_UNUSED( cacheValid )
 
  338     QgsDebugMsgLevel( QStringLiteral( 
"CACHE VALID: %1" ).arg( cacheValid ), 4 );
 
  343   while ( li.hasPrevious() )
 
  347     QgsDebugMsgLevel( QStringLiteral( 
"layer %1:  minscale:%2  maxscale:%3  scaledepvis:%4  blendmode:%5 isValid:%6" )
 
  364       QgsDebugMsgLevel( QStringLiteral( 
"Layer not rendered because it is not within the defined visibility scale range" ), 3 );
 
  370       QgsDebugMsgLevel( QStringLiteral( 
"Layer not rendered because it is not visible within the map's time range" ), 3 );
 
  376       QgsDebugMsgLevel( QStringLiteral( 
"Layer not rendered because it is not visible within the map's z range" ), 3 );
 
  385     bool haveExtentInLayerCrs = 
true;
 
  388       haveExtentInLayerCrs = reprojectToLayerExtent( ml, ct, r1, r2 );
 
  393       mErrors.append( Error( ml->
id(), tr( 
"There was a problem transforming the layer's extent. Layer skipped." ) ) );
 
  404       if ( ( vl && vl->
isEditable() ) || requiresLabeling )
 
  410     layerJobs.append( LayerRenderJob() );
 
  411     LayerRenderJob &job = layerJobs.last();
 
  415     job.layerId = ml->
id();
 
  417     job.renderingTime = -1;
 
  422     job.context.setPainter( painter );
 
  423     job.context.setLabelingEngine( labelingEngine2 );
 
  424     job.context.setCoordinateTransform( ct );
 
  425     job.context.setExtent( r1 );
 
  426     if ( !haveExtentInLayerCrs )
 
  429     if ( mFeatureFilterProvider )
 
  430       job.context.setFeatureFilterProvider( mFeatureFilterProvider );
 
  446       job.imageInitialized = 
true;
 
  449       job.renderer = 
nullptr;
 
  450       job.context.setPainter( 
nullptr );
 
  454     QElapsedTimer layerTime;
 
  463     if ( 
mCache || ( !painter && !deferredPainterSet ) || ( job.renderer && job.renderer->forceRasterRender() ) )
 
  466       job.context.setPainter( allocateImageAndPainter( ml->
id(), job.img ) );
 
  470         job.renderer = 
nullptr;
 
  471         layerJobs.removeLast();
 
  476     job.renderingTime = layerTime.elapsed(); 
 
  484   LayerRenderJobs secondPassJobs;
 
  487   QHash<QString, LayerRenderJob *> layerJobMapping;
 
  490   QSet<QString> layerHasMask;
 
  497     MaskSource( 
const QString &layerId_, 
const QString &labelRuleId_, 
int labelMaskId_ ):
 
  498       layerId( layerId_ ), labelRuleId( labelRuleId_ ), labelMaskId( labelMaskId_ ) {}
 
  503   QHash<QString, QPair<QSet<QgsSymbolLayerId>, QList<MaskSource>>> maskedSymbolLayers;
 
  507   for ( LayerRenderJob &job : firstPassJobs )
 
  513     layerJobMapping[job.layer->id()] = &job;
 
  518   for ( LayerRenderJob &job : firstPassJobs )
 
  525     auto collectMasks = [&]( QHash<QString, QSet<QgsSymbolLayerId>> *masks, QString sourceLayerId, QString ruleId = QString(), 
int labelMaskId = -1 )
 
  527       for ( 
auto it = masks->begin(); it != masks->end(); ++it )
 
  529         auto lit = maskedSymbolLayers.find( it.key() );
 
  530         if ( lit == maskedSymbolLayers.end() )
 
  532           maskedSymbolLayers[it.key()] = qMakePair( it.value(), QList<MaskSource>() << MaskSource( sourceLayerId, ruleId, labelMaskId ) );
 
  536           if ( lit->first != it.value() )
 
  538             QgsLogger::warning( QStringLiteral( 
"Layer %1 : Different sets of symbol layers are masked by different sources ! Only one (arbitrary) set will be retained !" ).arg( it.key() ) );
 
  541           lit->second.push_back( MaskSource( sourceLayerId, ruleId, labelMaskId ) );
 
  544       if ( ! masks->isEmpty() )
 
  545         layerHasMask.insert( sourceLayerId );
 
  550     for ( 
auto it = labelMasks.begin(); it != labelMasks.end(); it++ )
 
  552       QString labelRule = it.key();
 
  554       QHash<QString, QSet<QgsSymbolLayerId>> masks = it.value();
 
  557       QHash<QString, QSet<QgsSymbolLayerId>> usableMasks;
 
  558       for ( 
auto mit = masks.begin(); mit != masks.end(); mit++ )
 
  560         const QString sourceLayerId = mit.key();
 
  562         if ( !layerJobMapping.contains( sourceLayerId ) )
 
  565           usableMasks.insert( sourceLayerId, mit.value() );
 
  568       if ( usableMasks.empty() )
 
  572       QSet<QgsSymbolLayerReference> slRefs;
 
  573       for ( 
auto mit = usableMasks.begin(); mit != usableMasks.end(); mit++ )
 
  575         const QString sourceLayerId = mit.key();
 
  577         if ( !layerJobMapping.contains( sourceLayerId ) )
 
  580         for ( 
auto slIt = mit.value().begin(); slIt != mit.value().end(); slIt++ )
 
  586       int labelMaskId = labelJob.maskIdProvider.insertLabelLayer( vl->
id(), it.key(), slRefs );
 
  589       collectMasks( &usableMasks, vl->
id(), labelRule, labelMaskId );
 
  594     collectMasks( &symbolLayerMasks, vl->
id() );
 
  597   if ( maskedSymbolLayers.isEmpty() )
 
  598     return secondPassJobs;
 
  602   for ( LayerRenderJob &job : firstPassJobs )
 
  606     if ( job.img == 
nullptr )
 
  608       job.context.setPainter( allocateImageAndPainter( ml->
id(), job.img ) );
 
  610     if ( layerHasMask.contains( ml->
id() ) )
 
  613       job.context.setMaskPainter( allocateImageAndPainter( ml->
id(), job.maskImage ) );
 
  614       job.maskImage->fill( 0 );
 
  619   if ( labelJob.img == 
nullptr )
 
  621     labelJob.img = allocateImage( QStringLiteral( 
"labels" ) );
 
  625   for ( 
int maskId = 0; maskId < labelJob.maskIdProvider.size(); maskId++ )
 
  628     labelJob.context.setMaskPainter( allocateImageAndPainter( QStringLiteral( 
"label mask" ), maskImage ), maskId );
 
  629     maskImage->fill( 0 );
 
  630     labelJob.maskImages.push_back( maskImage );
 
  632   labelJob.context.setMaskIdProvider( &labelJob.maskIdProvider );
 
  635   for ( LayerRenderJob &job : firstPassJobs )
 
  639     auto it = maskedSymbolLayers.find( ml->
id() );
 
  640     if ( it == maskedSymbolLayers.end() )
 
  643     QList<MaskSource> &sourceList = it->second;
 
  644     const QSet<QgsSymbolLayerId> &symbolList = it->first;
 
  647     secondPassJobs.append( LayerRenderJob() );
 
  648     LayerRenderJob &job2 = secondPassJobs.last();
 
  651     job2.firstPassJob = &job;
 
  652     QgsVectorLayer *vl1 = qobject_cast<QgsVectorLayer *>( job.layer );
 
  655     job2.context.setMaskPainter( 
nullptr );
 
  656     job2.context.setPainter( allocateImageAndPainter( vl1->
id(), job2.img ) );
 
  659       secondPassJobs.removeLast();
 
  664     for ( MaskSource &source : sourceList )
 
  666       if ( source.labelMaskId != -1 )
 
  667         job2.maskJobs.push_back( qMakePair( 
nullptr, source.labelMaskId ) );
 
  669         job2.maskJobs.push_back( qMakePair( layerJobMapping[source.layerId], -1 ) );
 
  675     job2.renderer = mapRenderer;
 
  682   return secondPassJobs;
 
  689   job.context.setPainter( painter );
 
  690   job.context.setLabelingEngine( labelingEngine2 );
 
  692   job.context.setFeatureFilterProvider( mFeatureFilterProvider );
 
  695   job.context.setCoordinateTransform( ct );
 
  705     job.context.setPainter( 
nullptr );
 
  709     if ( canUseLabelCache && ( 
mCache || !painter ) )
 
  711       job.img = allocateImage( QStringLiteral( 
"labels" ) );
 
  721   for ( LayerRenderJobs::iterator it = jobs.begin(); it != jobs.end(); ++it )
 
  723     LayerRenderJob &job = *it;
 
  726       delete job.context.painter();
 
  727       job.context.setPainter( 
nullptr );
 
  729       if ( 
mCache && !job.cached && job.completed && job.layer )
 
  731         QgsDebugMsgLevel( QStringLiteral( 
"caching image for %1" ).arg( job.layerId ), 2 );
 
  743       delete job.context.maskPainter();
 
  744       job.context.setMaskPainter( 
nullptr );
 
  745       delete job.maskImage;
 
  750       const auto constErrors = job.renderer->errors();
 
  751       for ( 
const QString &message : constErrors )
 
  752         mErrors.append( Error( job.renderer->layerId(), message ) );
 
  755       job.renderer = 
nullptr;
 
  767   for ( 
auto &job : jobs )
 
  771       delete job.context.painter();
 
  772       job.context.setPainter( 
nullptr );
 
  781       job.renderer = 
nullptr;
 
  795     if ( 
mCache && !job.cached && !job.context.renderingStopped() )
 
  806   for ( 
int maskId = 0; maskId < job.maskImages.size(); maskId++ )
 
  808     delete job.context.maskPainter( maskId );
 
  809     job.context.setMaskPainter( 
nullptr, maskId );
 
  810     delete job.maskImages[maskId];
 
  815 #define DEBUG_RENDERING 0 
  819   const LayerRenderJobs &jobs,
 
  820   const LabelRenderJob &labelJob,
 
  826   image.setDotsPerMeterX( 
static_cast<int>( settings.
outputDpi() * 39.37 ) );
 
  827   image.setDotsPerMeterY( 
static_cast<int>( settings.
outputDpi() * 39.37 ) );
 
  830   QPainter painter( &image );
 
  835   for ( LayerRenderJobs::const_iterator it = jobs.constBegin(); it != jobs.constEnd(); ++it )
 
  837     const LayerRenderJob &job = *it;
 
  839     if ( job.layer && job.layer->customProperty( QStringLiteral( 
"rendering/renderAboveLabels" ) ).toBool() )
 
  846     painter.setCompositionMode( job.blendMode );
 
  847     painter.setOpacity( job.opacity );
 
  850     img.save( QString( 
"/tmp/final_%1.png" ).arg( i ) );
 
  854     painter.drawImage( 0, 0, img );
 
  860   if ( labelJob.img && labelJob.complete )
 
  862     painter.setCompositionMode( QPainter::CompositionMode_SourceOver );
 
  863     painter.setOpacity( 1.0 );
 
  864     painter.drawImage( 0, 0, *labelJob.img );
 
  872     painter.setCompositionMode( QPainter::CompositionMode_SourceOver );
 
  873     painter.setOpacity( 1.0 );
 
  874     painter.drawImage( 0, 0, labelCacheImage );
 
  878   for ( LayerRenderJobs::const_iterator it = jobs.constBegin(); it != jobs.constEnd(); ++it )
 
  880     const LayerRenderJob &job = *it;
 
  882     if ( !job.layer || !job.layer->customProperty( QStringLiteral( 
"rendering/renderAboveLabels" ) ).toBool() )
 
  889     painter.setCompositionMode( job.blendMode );
 
  890     painter.setOpacity( job.opacity );
 
  892     painter.drawImage( 0, 0, img );
 
  897   image.save( 
"/tmp/final.png" );
 
  904   const LayerRenderJob &job,
 
  908   if ( job.imageCanBeComposed() )
 
  915     if ( cache && cache->
hasAnyCacheImage( job.layerId + QStringLiteral( 
"_preview" ) ) )
 
  930   for ( LayerRenderJob &job : secondPassJobs )
 
  934     job.img->save( QString( 
"/tmp/second_%1.png" ).arg( i ) );
 
  939     if ( job.maskJobs.size() > 1 )
 
  941       QPainter *maskPainter = 
nullptr;
 
  942       for ( QPair<LayerRenderJob *, int> p : job.maskJobs )
 
  944         QImage *maskImage = p.first ? p.first->maskImage : labelJob.maskImages[p.second];
 
  946         maskImage->save( QString( 
"/tmp/mask_%1_%2.png" ).arg( i ).arg( mask++ ) );
 
  950           maskPainter = p.first ? p.first->context.maskPainter() : labelJob.context.maskPainter( p.second );
 
  954           maskPainter->drawImage( 0, 0, *maskImage );
 
  959     if ( ! job.maskJobs.isEmpty() )
 
  962       QPair<LayerRenderJob *, int> p = *job.maskJobs.begin();
 
  963       QImage *maskImage = p.first ? p.first->maskImage : labelJob.maskImages[p.second];
 
  965       maskImage->save( QString( 
"/tmp/mask_%1.png" ).arg( i ) );
 
  969       QPainter *painter = job.context.painter();
 
  970       painter->setCompositionMode( QPainter::CompositionMode_DestinationIn );
 
  975       QImage maskBinAlpha = maskImage->createMaskFromColor( 0 );
 
  976       QVector<QRgb> mswTable;
 
  977       mswTable.push_back( qRgba( 0, 0, 0, 255 ) );
 
  978       mswTable.push_back( qRgba( 0, 0, 0, 0 ) );
 
  979       maskBinAlpha.setColorTable( mswTable );
 
  980       painter->drawImage( 0, 0, maskBinAlpha );
 
  982       job.img->save( QString( 
"/tmp/second_%1_a.png" ).arg( i ) );
 
  987         QPainter tempPainter;
 
  990         QPainter *painter1 = job.firstPassJob->context.painter();
 
  993           tempPainter.begin( job.firstPassJob->img );
 
  994           painter1 = &tempPainter;
 
  997         job.firstPassJob->img->save( QString( 
"/tmp/second_%1_first_pass_1.png" ).arg( i ) );
 
 1000         painter1->setCompositionMode( QPainter::CompositionMode_DestinationOut );
 
 1001         painter1->drawImage( 0, 0, *maskImage );
 
 1004         job.firstPassJob->img->save( QString( 
"/tmp/second_%1_first_pass_2.png" ).arg( i ) );
 
 1007         painter1->setCompositionMode( QPainter::CompositionMode_DestinationOver );
 
 1008         painter1->drawImage( 0, 0, *job.img );
 
 1010         job.img->save( QString( 
"/tmp/second_%1_b.png" ).arg( i ) );
 
 1011         if ( job.firstPassJob )
 
 1012           job.firstPassJob->img->save( QString( 
"/tmp/second_%1_first_pass_3.png" ).arg( i ) );
 
 1024   QMultiMap<int, QString> elapsed;
 
 1025   const auto constJobs = jobs;
 
 1026   for ( 
const LayerRenderJob &job : constJobs )
 
 1027     elapsed.insert( job.renderingTime, job.layerId );
 
 1028   const auto constSecondPassJobs = secondPassJobs;
 
 1029   for ( 
const LayerRenderJob &job : constSecondPassJobs )
 
 1030     elapsed.insert( job.renderingTime, job.layerId + QString( 
" (second pass)" ) );
 
 1032   elapsed.insert( labelJob.renderingTime, tr( 
"Labeling" ) );
 
 1034   QList<int> tt( elapsed.uniqueKeys() );
 
 1035   std::sort( tt.begin(), tt.end(), std::greater<int>() );
 
 1036   const auto constTt = tt;
 
 1037   for ( 
int t : constTt )
 
 1039     QgsMessageLog::logMessage( tr( 
"%1 ms: %2" ).arg( t ).arg( QStringList( elapsed.values( t ) ).join( QLatin1String( 
", " ) ) ), tr( 
"Rendering" ) );
 
 1052   painter->setCompositionMode( QPainter::CompositionMode_SourceOver );
 
 1056   if ( labelingEngine2 )
 
 1058     labelingEngine2->
run( renderContext );
 
 1061   QgsDebugMsgLevel( QStringLiteral( 
"Draw labeling took (seconds): %1" ).arg( t.elapsed() / 1000. ), 2 );
 
 1066   Q_UNUSED( settings )
 
 1068   drawLabeling( renderContext, labelingEngine2, painter );
 
virtual bool requiresAdvancedEffects() const =0
Returns true if drawing labels requires advanced effects like composition modes, which could prevent ...
Custom exception class for Coordinate Reference System related exceptions.
bool isInfinite() const
Returns true if the range consists of all possible values.
static QgsExpressionContextScope * layerScope(const QgsMapLayer *layer)
Creates a new scope which contains variables and functions relating to a QgsMapLayer.
The QgsLabelingEngine class provides map labeling functionality.
virtual void run(QgsRenderContext &context)=0
Runs the labeling job.
static void warning(const QString &msg)
Goes to qWarning.
virtual bool isVisibleInZRange(const QgsDoubleRange &range) const
Returns true if the layer should be visible and rendered for the specified z range.
virtual void setLayerRenderingTimeHint(int time)
Sets approximate render time (in ms) for the layer to render.
Restore overridden layer style on destruction.
virtual bool isVisibleInTemporalRange(const QgsDateTimeRange &range) const
Returns true if the layer should be visible and rendered for the specified time range.
Base class for all map layer types.
bool isInScaleRange(double scale) const
Tests whether the layer should be visible at the specified scale.
QgsCoordinateReferenceSystem crs
QString id() const
Returns the layer's unique ID, which is used to access this layer from QgsProject.
QPainter::CompositionMode blendMode() const
Returns the current blending mode for a layer.
virtual QgsMapLayerRenderer * createMapRenderer(QgsRenderContext &rendererContext)=0
Returns new instance of QgsMapLayerRenderer that will be used for rendering of given context.
bool hasScaleBasedVisibility() const
Returns whether scale based visibility is enabled for the layer.
double minimumScale() const
Returns the minimum map scale (i.e.
virtual QgsMapLayerElevationProperties * elevationProperties()
Returns the layer's elevation properties.
virtual QgsMapLayerTemporalProperties * temporalProperties()
Returns the layer's temporal properties.
double maximumScale() const
Returns the maximum map scale (i.e.
This class is responsible for keeping cache of rendered images resulting from a map rendering job.
bool updateParameters(const QgsRectangle &extent, const QgsMapToPixel &mtp)
Sets extent and scale parameters.
QList< QgsMapLayer * > dependentLayers(const QString &cacheKey) const
Returns a list of map layers on which an image in the cache depends.
bool hasCacheImage(const QString &cacheKey) const
Returns true if the cache contains an image with the specified cacheKey that has the same extent and ...
QImage cacheImage(const QString &cacheKey) const
Returns the cached image for the specified cacheKey.
bool hasAnyCacheImage(const QString &cacheKey, double minimumScaleThreshold=0, double maximumScaleThreshold=0) const
Returns true if the cache contains an image with the specified cacheKey with any cache's parameters (...
void setCacheImageWithParameters(const QString &cacheKey, const QImage &image, const QgsRectangle &extent, const QgsMapToPixel &mapToPixel, const QList< QgsMapLayer * > &dependentLayers=QList< QgsMapLayer * >())
Set the cached image for a particular cacheKey, using a specific extent and mapToPixel (which may dif...
void clearCacheImage(const QString &cacheKey)
Removes an image from the cache with matching cacheKey.
QImage transformedCacheImage(const QString &cacheKey, const QgsMapToPixel &mtp) const
Returns the cached image for the specified cacheKey transformed to the particular extent and scale.
Abstract base class for map rendering implementations.
void setCache(QgsMapRendererCache *cache)
Assign a cache to be used for reading and storing rendered images of individual layers.
void cleanupSecondPassJobs(LayerRenderJobs &jobs)
QHash< QgsMapLayer *, int > perLayerRenderingTime() const
Returns the render time (in ms) per layer.
static QImage layerImageToBeComposed(const QgsMapSettings &settings, const LayerRenderJob &job, const QgsMapRendererCache *cache)
LayerRenderJobs prepareSecondPassJobs(LayerRenderJobs &firstPassJobs, LabelRenderJob &labelJob)
Prepares jobs for a second pass, if selective masks exist (from labels or symbol layers).
QHash< QString, int > mLayerRenderingTimeHints
Approximate expected layer rendering time per layer, by layer ID.
void logRenderingTime(const LayerRenderJobs &jobs, const LayerRenderJobs &secondPassJobs, const LabelRenderJob &labelJob)
Errors errors() const
List of errors that happened during the rendering job - available when the rendering has been finishe...
static Q_DECL_DEPRECATED void drawLabeling(const QgsMapSettings &settings, QgsRenderContext &renderContext, QgsLabelingEngine *labelingEngine2, QPainter *painter)
LayerRenderJobs prepareJobs(QPainter *painter, QgsLabelingEngine *labelingEngine2, bool deferredPainterSet=false)
Creates a list of layer rendering jobs and prepares them for later render.
static const QgsSettingsEntryBool settingsLogCanvasRefreshEvent
Settings entry log canvas refresh event.
static const QString LABEL_PREVIEW_CACHE_ID
QgsMapRendererCache ID string for cached label image during preview compositions only.
const QgsMapSettings & mapSettings() const
Returns map settings with which this job was started.
static void composeSecondPass(LayerRenderJobs &secondPassJobs, LabelRenderJob &labelJob)
Compose second pass images into first pass images.
QgsMapRendererCache * mCache
void finished()
emitted when asynchronous rendering is finished (or canceled).
static QImage composeImage(const QgsMapSettings &settings, const LayerRenderJobs &jobs, const LabelRenderJob &labelJob, const QgsMapRendererCache *cache=nullptr)
QgsMapRendererJob(const QgsMapSettings &settings)
void start()
Start the rendering job and immediately return.
QList< QgsMapRendererJob::Error > Errors
static const QString LABEL_CACHE_ID
QgsMapRendererCache ID string for cached label image.
QHash< QgsWeakMapLayerPointer, int > mPerLayerRenderingTime
Render time (in ms) per layer, by layer ID.
LabelRenderJob prepareLabelingJob(QPainter *painter, QgsLabelingEngine *labelingEngine2, bool canUseLabelCache=true)
Prepares a labeling job.
void setLayerRenderingTimeHints(const QHash< QString, int > &hints)
Sets approximate render times (in ms) for map layers.
void cleanupLabelJob(LabelRenderJob &job)
Handles clean up tasks for a label job, including deletion of images and storing cached label results...
void cleanupJobs(LayerRenderJobs &jobs)
bool prepareLabelCache() const
Prepares the cache for storing the result of labeling.
QgsMapRendererQImageJob(const QgsMapSettings &settings)
The QgsMapSettings class contains configuration for rendering of the map.
QSize deviceOutputSize() const
Returns the device output size of the map render.
double scale() const
Returns the calculated map scale.
QgsCoordinateTransform layerTransform(const QgsMapLayer *layer) const
Returns the coordinate transform from layer's CRS to destination CRS.
QgsDoubleRange zRange() const
Returns the range of z-values which will be visible in the map.
bool testFlag(Flag flag) const
Check whether a particular flag is enabled.
@ LosslessImageRendering
Render images losslessly whenever possible, instead of the default lossy jpeg rendering used for some...
@ Antialiasing
Enable anti-aliasing for map rendering.
QColor backgroundColor() const
Returns the background color of the map.
float devicePixelRatio() const
Returns the device pixel ratio.
QSize outputSize() const
Returns the size of the resulting map image, in pixels.
QImage::Format outputImageFormat() const
format of internal QImage, default QImage::Format_ARGB32_Premultiplied
double extentBuffer() const
Returns the buffer in map units to use around the visible extent for rendering symbols whose correspo...
const QgsMapToPixel & mapToPixel() const
QgsRectangle visibleExtent() const
Returns the actual extent derived from requested extent that takes takes output image size into accou...
QList< QgsMapLayer * > layers() const
Returns the list of layers which will be rendered in the map.
double outputDpi() const
Returns the DPI (dots per inch) used for conversion between real world units (e.g.
QMap< QString, QString > layerStyleOverrides() const
Returns the map of map layer style overrides (key: layer ID, value: style name) where a different sty...
bool hasValidSettings() const
Check whether the map settings are valid and can be used for rendering.
QgsCoordinateReferenceSystem destinationCrs() const
Returns the destination coordinate reference system for the map render.
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).
static bool staticWillUseLayer(const QgsMapLayer *layer)
Called to find out whether a specified layer is used for labeling.
A class to represent a 2D point.
QString toString(int precision=-1) const
Returns a string representation of the point (x, y) with a preset precision.
A rectangle specified with double values.
QString toString(int precision=16) const
Returns a string representation of form xmin,ymin : xmax,ymax Coordinates will be truncated to the sp...
double yMaximum() const SIP_HOLDGIL
Returns the y maximum value (top side of rectangle).
double xMaximum() const SIP_HOLDGIL
Returns the x maximum value (right side of rectangle).
double xMinimum() const SIP_HOLDGIL
Returns the x minimum value (left side of rectangle).
double yMinimum() const SIP_HOLDGIL
Returns the y minimum value (bottom side of rectangle).
void setXMaximum(double x) SIP_HOLDGIL
Set the maximum x value.
void setXMinimum(double x) SIP_HOLDGIL
Set the minimum x value.
double height() const SIP_HOLDGIL
Returns the height of the rectangle.
void grow(double delta)
Grows the rectangle in place by the specified amount.
double width() const SIP_HOLDGIL
Returns the width of the rectangle.
bool isFinite() const
Returns true if the rectangle has finite boundaries.
Contains information about the context of a rendering operation.
@ ApplyClipAfterReprojection
Feature geometry clipping to mapExtent() must be performed after the geometries are transformed using...
void setPainter(QPainter *p)
Sets the destination QPainter for the render operation.
static QgsRenderContext fromMapSettings(const QgsMapSettings &mapSettings)
create initialized QgsRenderContext instance from given QgsMapSettings
Type used to refer to a specific symbol layer in a symbol of a layer.
static QSet< const QgsSymbolLayer * > toSymbolLayerPointers(QgsFeatureRenderer *renderer, const QSet< QgsSymbolLayerId > &symbolLayerIds)
Converts a set of symbol layer id to a set of pointers to actual symbol layers carried by the feature...
const QgsDateTimeRange & temporalRange() const
Returns the datetime range for the object.
bool isTemporal() const
Returns true if the object's temporal range is enabled, and the object will be filtered when renderin...
Implementation of threaded rendering for vector layers.
QgsFeatureRenderer * featureRenderer()
Returns the feature renderer.
static QHash< QString, QHash< QString, QSet< QgsSymbolLayerId > > > labelMasks(const QgsVectorLayer *)
Returns masks defined in labeling options of a layer.
static QHash< QString, QSet< QgsSymbolLayerId > > symbolLayerMasks(const QgsVectorLayer *)
Returns all masks that may be defined on symbol layers for a given vector layer.
Represents a vector layer which manages a vector based data sets.
bool labelsEnabled() const
Returns whether the layer contains labels which are enabled and should be drawn.
QgsMapLayerRenderer * createMapRenderer(QgsRenderContext &rendererContext) FINAL
Returns new instance of QgsMapLayerRenderer that will be used for rendering of given context.
bool isEditable() const FINAL
Returns true if the provider is in editing mode.
const QgsAbstractVectorLayerLabeling * labeling() const
Access to const labeling configuration.
@ PointCloudLayer
Added in 3.18.
@ VectorTileLayer
Added in 3.14.
@ AnnotationLayer
Contains freeform, georeferenced annotations. Added in QGIS 3.16.
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference)
#define QgsDebugMsgLevel(str, level)