19 #include <QElapsedTimer>
21 #include <QtConcurrentMap>
53 LayerRenderJob &LayerRenderJob::operator=( LayerRenderJob &&other )
55 mContext = std::move( other.mContext );
60 renderer = other.renderer;
61 other.renderer =
nullptr;
63 imageInitialized = other.imageInitialized;
64 blendMode = other.blendMode;
65 opacity = other.opacity;
66 cached = other.cached;
68 completed = other.completed;
69 renderingTime = other.renderingTime;
70 estimatedRenderingTime = other.estimatedRenderingTime ;
71 errors = other.errors;
72 layerId = other.layerId;
74 maskImage = other.maskImage;
75 other.maskImage =
nullptr;
77 firstPassJob = other.firstPassJob;
78 other.firstPassJob =
nullptr;
80 maskJobs = other.maskJobs;
85 LayerRenderJob::LayerRenderJob( LayerRenderJob &&other )
86 : imageInitialized( other.imageInitialized )
87 , blendMode( other.blendMode )
88 , opacity( other.opacity )
89 , cached( other.cached )
90 , layer( other.layer )
91 , completed( other.completed )
92 , renderingTime( other.renderingTime )
93 , estimatedRenderingTime( other.estimatedRenderingTime )
94 , errors( other.errors )
95 , layerId( other.layerId )
96 , maskJobs( other.maskJobs )
98 mContext = std::move( other.mContext );
103 renderer = other.renderer;
104 other.renderer =
nullptr;
106 maskImage = other.maskImage;
107 other.maskImage =
nullptr;
109 firstPassJob = other.firstPassJob;
110 other.firstPassJob =
nullptr;
113 bool LayerRenderJob::imageCanBeComposed()
const
115 if ( imageInitialized )
119 return renderer->isReadyToCompose();
133 : mSettings( settings )
179 return mLabelingEngineFeedback;
184 QHash<QgsMapLayer *, int> result;
187 if (
auto &&lKey = it.key() )
188 result.insert( lKey, it.value() );
208 QSet< QgsMapLayer * > labeledLayers;
215 switch ( ml->type() )
281 static const double SPLIT_COORD = 180.0;
293 QgsDebugMsgLevel( QStringLiteral(
"\n0:%1 %2x%3\n1:%4\n2:%5 %6x%7 (w:%8 h:%9)" )
296 .arg( std::fabs( 1.0 - extent2.
width() / extent.
width() ) )
297 .arg( std::fabs( 1.0 - extent2.
height() / extent.
height() ) )
319 Qgis::TransformDirection::Reverse );
323 Qgis::TransformDirection::Reverse );
331 if ( ll.
x() > ur.
x() )
360 extent =
QgsRectangle( std::numeric_limits<double>::lowest(), std::numeric_limits<double>::lowest(), std::numeric_limits<double>::max(), std::numeric_limits<double>::max() );
369 QgsDebugMsg( QStringLiteral(
"Transform error caught" ) );
370 extent =
QgsRectangle( std::numeric_limits<double>::lowest(), std::numeric_limits<double>::lowest(), std::numeric_limits<double>::max(), std::numeric_limits<double>::max() );
371 r2 =
QgsRectangle( std::numeric_limits<double>::lowest(), std::numeric_limits<double>::lowest(), std::numeric_limits<double>::max(), std::numeric_limits<double>::max() );
378 QImage *QgsMapRendererJob::allocateImage( QString layerId )
385 if ( image->isNull() )
394 QPainter *QgsMapRendererJob::allocateImageAndPainter( QString layerId, QImage *&image )
396 QPainter *painter =
nullptr;
397 image = allocateImage( layerId );
400 painter =
new QPainter( image );
403 #if QT_VERSION >= QT_VERSION_CHECK(5, 13, 0)
412 std::vector< LayerRenderJob > layerJobs;
421 Q_UNUSED( cacheValid )
422 QgsDebugMsgLevel( QStringLiteral(
"CACHE VALID: %1" ).arg( cacheValid ), 4 );
427 while ( li.hasPrevious() )
431 QgsDebugMsgLevel( QStringLiteral(
"layer %1: minscale:%2 maxscale:%3 scaledepvis:%4 blendmode:%5 isValid:%6" )
448 QgsDebugMsgLevel( QStringLiteral(
"Layer not rendered because it is not within the defined visibility scale range" ), 3 );
454 QgsDebugMsgLevel( QStringLiteral(
"Layer not rendered because it is not visible within the map's time range" ), 3 );
460 QgsDebugMsgLevel( QStringLiteral(
"Layer not rendered because it is not visible within the map's z range" ), 3 );
469 bool haveExtentInLayerCrs =
true;
472 haveExtentInLayerCrs = reprojectToLayerExtent( ml, ct, r1, r2 );
477 mErrors.append( Error( ml->
id(), tr(
"There was a problem transforming the layer's extent. Layer skipped." ) ) );
488 if ( ( vl && vl->
isEditable() ) || requiresLabeling )
494 layerJobs.emplace_back( LayerRenderJob() );
495 LayerRenderJob &job = layerJobs.back();
497 job.layerId = ml->
id();
502 job.context()->setPainter( painter );
503 job.context()->setLabelingEngine( labelingEngine2 );
504 job.context()->setLabelSink(
labelSink() );
505 job.context()->setCoordinateTransform( ct );
506 job.context()->setExtent( r1 );
507 if ( !haveExtentInLayerCrs )
510 if ( mFeatureFilterProvider )
511 job.context()->setFeatureFilterProvider( mFeatureFilterProvider );
527 job.imageInitialized =
true;
530 job.renderer =
nullptr;
531 job.context()->setPainter(
nullptr );
536 QElapsedTimer layerTime;
542 job.context()->setFeedback( job.renderer->feedback() );
548 if (
mCache || ( !painter && !deferredPainterSet ) || ( job.renderer && job.renderer->forceRasterRender() ) )
551 job.context()->setPainter( allocateImageAndPainter( ml->
id(), job.img ) );
555 job.renderer =
nullptr;
556 layerJobs.pop_back();
561 job.renderingTime = layerTime.elapsed();
569 std::vector< LayerRenderJob > secondPassJobs;
572 QHash<QString, LayerRenderJob *> layerJobMapping;
575 QSet<QString> layerHasMask;
582 MaskSource(
const QString &layerId_,
const QString &labelRuleId_,
int labelMaskId_ ):
583 layerId( layerId_ ), labelRuleId( labelRuleId_ ), labelMaskId( labelMaskId_ ) {}
588 QHash<QString, QPair<QSet<QgsSymbolLayerId>, QList<MaskSource>>> maskedSymbolLayers;
592 for ( LayerRenderJob &job : firstPassJobs )
594 layerJobMapping[job.layerId] = &job;
599 for ( LayerRenderJob &job : firstPassJobs )
606 auto collectMasks = [&]( QHash<QString, QSet<QgsSymbolLayerId>> *masks, QString sourceLayerId, QString ruleId = QString(),
int labelMaskId = -1 )
608 for (
auto it = masks->begin(); it != masks->end(); ++it )
610 auto lit = maskedSymbolLayers.find( it.key() );
611 if ( lit == maskedSymbolLayers.end() )
613 maskedSymbolLayers[it.key()] = qMakePair( it.value(), QList<MaskSource>() << MaskSource( sourceLayerId, ruleId, labelMaskId ) );
617 if ( lit->first != it.value() )
619 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() ) );
622 lit->second.push_back( MaskSource( sourceLayerId, ruleId, labelMaskId ) );
625 if ( ! masks->isEmpty() )
626 layerHasMask.insert( sourceLayerId );
631 for (
auto it = labelMasks.begin(); it != labelMasks.end(); it++ )
633 QString labelRule = it.key();
635 QHash<QString, QSet<QgsSymbolLayerId>> masks = it.value();
638 QHash<QString, QSet<QgsSymbolLayerId>> usableMasks;
639 for (
auto mit = masks.begin(); mit != masks.end(); mit++ )
641 const QString sourceLayerId = mit.key();
643 if ( !layerJobMapping.contains( sourceLayerId ) )
646 usableMasks.insert( sourceLayerId, mit.value() );
649 if ( usableMasks.empty() )
653 QSet<QgsSymbolLayerReference> slRefs;
654 for (
auto mit = usableMasks.begin(); mit != usableMasks.end(); mit++ )
656 const QString sourceLayerId = mit.key();
658 if ( !layerJobMapping.contains( sourceLayerId ) )
661 for (
auto slIt = mit.value().begin(); slIt != mit.value().end(); slIt++ )
667 int labelMaskId = labelJob.maskIdProvider.insertLabelLayer( vl->
id(), it.key(), slRefs );
670 collectMasks( &usableMasks, vl->
id(), labelRule, labelMaskId );
675 collectMasks( &symbolLayerMasks, vl->
id() );
678 if ( maskedSymbolLayers.isEmpty() )
679 return secondPassJobs;
683 for ( LayerRenderJob &job : firstPassJobs )
685 if ( job.img ==
nullptr )
687 job.context()->setPainter( allocateImageAndPainter( job.layerId, job.img ) );
689 if ( layerHasMask.contains( job.layerId ) )
692 job.context()->setMaskPainter( allocateImageAndPainter( job.layerId, job.maskImage ) );
693 job.maskImage->fill( 0 );
698 if ( labelJob.img ==
nullptr )
700 labelJob.img = allocateImage( QStringLiteral(
"labels" ) );
704 for (
int maskId = 0; maskId < labelJob.maskIdProvider.size(); maskId++ )
707 labelJob.context.setMaskPainter( allocateImageAndPainter( QStringLiteral(
"label mask" ), maskImage ), maskId );
708 maskImage->fill( 0 );
709 labelJob.maskImages.push_back( maskImage );
711 labelJob.context.setMaskIdProvider( &labelJob.maskIdProvider );
714 for ( LayerRenderJob &job : firstPassJobs )
718 auto it = maskedSymbolLayers.find( ml->
id() );
719 if ( it == maskedSymbolLayers.end() )
722 QList<MaskSource> &sourceList = it->second;
723 const QSet<QgsSymbolLayerId> &symbolList = it->first;
725 secondPassJobs.emplace_back( LayerRenderJob() );
726 LayerRenderJob &job2 = secondPassJobs.back();
729 job2.setContext( std::make_unique< QgsRenderContext >( *job.context() ) );
731 job2.layer = job.layer;
732 job2.layerId = job.layerId;
734 job2.firstPassJob = &job;
736 QgsVectorLayer *vl1 = qobject_cast<QgsVectorLayer *>( job.layer );
740 job2.context()->setMaskPainter(
nullptr );
741 job2.context()->setPainter( allocateImageAndPainter( job.layerId, job2.img ) );
744 secondPassJobs.pop_back();
749 for ( MaskSource &source : sourceList )
751 if ( source.labelMaskId != -1 )
752 job2.maskJobs.push_back( qMakePair(
nullptr, source.labelMaskId ) );
754 job2.maskJobs.push_back( qMakePair( layerJobMapping[source.layerId], -1 ) );
760 job2.renderer = mapRenderer;
763 job2.context()->setFeedback( job2.renderer->feedback() );
771 return secondPassJobs;
778 job.context.setPainter( painter );
779 job.context.setLabelingEngine( labelingEngine2 );
780 job.context.setFeedback( mLabelingEngineFeedback );
784 job.context.setExtent( r1 );
786 job.context.setFeatureFilterProvider( mFeatureFilterProvider );
789 job.context.setCoordinateTransform( ct );
799 job.context.setPainter(
nullptr );
803 if ( canUseLabelCache && (
mCache || !painter ) )
805 job.img = allocateImage( QStringLiteral(
"labels" ) );
815 for ( LayerRenderJob &job : jobs )
819 delete job.context()->painter();
820 job.context()->setPainter(
nullptr );
822 if (
mCache && !job.cached && job.completed && job.layer )
824 QgsDebugMsgLevel( QStringLiteral(
"caching image for %1" ).arg( job.layerId ), 2 );
836 delete job.context()->maskPainter();
837 job.context()->setMaskPainter(
nullptr );
838 delete job.maskImage;
843 const QStringList
errors = job.renderer->errors();
844 for (
const QString &message :
errors )
845 mErrors.append( Error( job.renderer->layerId(), message ) );
850 job.renderer =
nullptr;
862 for ( LayerRenderJob &job : jobs )
866 delete job.context()->painter();
867 job.context()->setPainter(
nullptr );
876 job.renderer =
nullptr;
890 if (
mCache && !job.cached && !job.context.renderingStopped() )
901 for (
int maskId = 0; maskId < job.maskImages.size(); maskId++ )
903 delete job.context.maskPainter( maskId );
904 job.context.setMaskPainter(
nullptr, maskId );
905 delete job.maskImages[maskId];
910 #define DEBUG_RENDERING 0
913 const std::vector<LayerRenderJob> &jobs,
914 const LabelRenderJob &labelJob,
920 image.setDotsPerMeterX(
static_cast<int>( settings.
outputDpi() * 39.37 ) );
921 image.setDotsPerMeterY(
static_cast<int>( settings.
outputDpi() * 39.37 ) );
924 QPainter painter( &image );
929 for (
const LayerRenderJob &job : jobs )
931 if ( job.layer && job.layer->customProperty( QStringLiteral(
"rendering/renderAboveLabels" ) ).toBool() )
938 painter.setCompositionMode( job.blendMode );
939 painter.setOpacity( job.opacity );
942 img.save( QString(
"/tmp/final_%1.png" ).arg( i ) );
946 painter.drawImage( 0, 0, img );
952 if ( labelJob.img && labelJob.complete )
954 painter.setCompositionMode( QPainter::CompositionMode_SourceOver );
955 painter.setOpacity( 1.0 );
956 painter.drawImage( 0, 0, *labelJob.img );
964 painter.setCompositionMode( QPainter::CompositionMode_SourceOver );
965 painter.setOpacity( 1.0 );
966 painter.drawImage( 0, 0, labelCacheImage );
970 for (
const LayerRenderJob &job : jobs )
972 if ( !job.layer || !job.layer->customProperty( QStringLiteral(
"rendering/renderAboveLabels" ) ).toBool() )
979 painter.setCompositionMode( job.blendMode );
980 painter.setOpacity( job.opacity );
982 painter.drawImage( 0, 0, img );
987 image.save(
"/tmp/final.png" );
994 const LayerRenderJob &job,
998 if ( job.imageCanBeComposed() )
1000 Q_ASSERT( job.img );
1005 if ( cache && cache->
hasAnyCacheImage( job.layerId + QStringLiteral(
"_preview" ) ) )
1020 for ( LayerRenderJob &job : secondPassJobs )
1024 job.img->save( QString(
"/tmp/second_%1.png" ).arg( i ) );
1029 if ( job.maskJobs.size() > 1 )
1031 QPainter *maskPainter =
nullptr;
1032 for ( QPair<LayerRenderJob *, int> p : job.maskJobs )
1034 QImage *maskImage = p.first ? p.first->maskImage : labelJob.maskImages[p.second];
1036 maskImage->save( QString(
"/tmp/mask_%1_%2.png" ).arg( i ).arg( mask++ ) );
1038 if ( ! maskPainter )
1040 maskPainter = p.first ? p.first->context()->maskPainter() : labelJob.context.maskPainter( p.second );
1044 maskPainter->drawImage( 0, 0, *maskImage );
1049 if ( ! job.maskJobs.isEmpty() )
1052 QPair<LayerRenderJob *, int> p = *job.maskJobs.begin();
1053 QImage *maskImage = p.first ? p.first->maskImage : labelJob.maskImages[p.second];
1055 maskImage->save( QString(
"/tmp/mask_%1.png" ).arg( i ) );
1059 QPainter *painter = job.context()->painter();
1060 painter->setCompositionMode( QPainter::CompositionMode_DestinationIn );
1065 QImage maskBinAlpha = maskImage->createMaskFromColor( 0 );
1066 QVector<QRgb> mswTable;
1067 mswTable.push_back( qRgba( 0, 0, 0, 255 ) );
1068 mswTable.push_back( qRgba( 0, 0, 0, 0 ) );
1069 maskBinAlpha.setColorTable( mswTable );
1070 painter->drawImage( 0, 0, maskBinAlpha );
1072 job.img->save( QString(
"/tmp/second_%1_a.png" ).arg( i ) );
1077 QPainter tempPainter;
1080 QPainter *painter1 = job.firstPassJob->context()->painter();
1083 tempPainter.begin( job.firstPassJob->img );
1084 painter1 = &tempPainter;
1087 job.firstPassJob->img->save( QString(
"/tmp/second_%1_first_pass_1.png" ).arg( i ) );
1090 painter1->setCompositionMode( QPainter::CompositionMode_DestinationOut );
1091 painter1->drawImage( 0, 0, *maskImage );
1094 job.firstPassJob->img->save( QString(
"/tmp/second_%1_first_pass_2.png" ).arg( i ) );
1097 painter1->setCompositionMode( QPainter::CompositionMode_DestinationOver );
1098 painter1->drawImage( 0, 0, *job.img );
1100 job.img->save( QString(
"/tmp/second_%1_b.png" ).arg( i ) );
1101 if ( job.firstPassJob )
1102 job.firstPassJob->img->save( QString(
"/tmp/second_%1_first_pass_3.png" ).arg( i ) );
1109 void QgsMapRendererJob::logRenderingTime(
const std::vector< LayerRenderJob > &jobs,
const std::vector< LayerRenderJob > &secondPassJobs,
const LabelRenderJob &labelJob )
1114 QMultiMap<int, QString> elapsed;
1115 for (
const LayerRenderJob &job : jobs )
1116 elapsed.insert( job.renderingTime, job.layerId );
1117 for (
const LayerRenderJob &job : secondPassJobs )
1118 elapsed.insert( job.renderingTime, job.layerId + QString(
" (second pass)" ) );
1120 elapsed.insert( labelJob.renderingTime, tr(
"Labeling" ) );
1122 QList<int> tt( elapsed.uniqueKeys() );
1123 std::sort( tt.begin(), tt.end(), std::greater<int>() );
1124 for (
int t : std::as_const( tt ) )
1126 QgsMessageLog::logMessage( tr(
"%1 ms: %2" ).arg( t ).arg( QStringList( elapsed.values( t ) ).join( QLatin1String(
", " ) ) ), tr(
"Rendering" ) );
1139 painter->setCompositionMode( QPainter::CompositionMode_SourceOver );
1143 if ( labelingEngine2 )
1145 labelingEngine2->
run( renderContext );
1148 QgsDebugMsgLevel( QStringLiteral(
"Draw labeling took (seconds): %1" ).arg( t.elapsed() / 1000. ), 2 );
1153 Q_UNUSED( settings )
1155 drawLabeling( renderContext, labelingEngine2, painter );
@ ApplyClipAfterReprojection
Feature geometry clipping to mapExtent() must be performed after the geometries are transformed using...
@ LosslessImageRendering
Render images losslessly whenever possible, instead of the default lossy jpeg rendering used for some...
@ Antialiasing
Enable anti-aliasing for map rendering.
@ HighQualityImageTransforms
Enable high quality image transformations, which results in better appearance of scaled or rotated ra...
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.
QgsFeedback subclass for granular reporting of labeling engine progress.
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 logRenderingTime(const std::vector< LayerRenderJob > &jobs, const std::vector< LayerRenderJob > &secondPassJobs, const LabelRenderJob &labelJob)
static void composeSecondPass(std::vector< LayerRenderJob > &secondPassJobs, LabelRenderJob &labelJob)
Compose second pass images into first pass images.
static QImage composeImage(const QgsMapSettings &settings, const std::vector< LayerRenderJob > &jobs, const LabelRenderJob &labelJob, const QgsMapRendererCache *cache=nullptr)
void cleanupSecondPassJobs(std::vector< LayerRenderJob > &jobs)
void setCache(QgsMapRendererCache *cache)
Assign a cache to be used for reading and storing rendered images of individual layers.
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)
QHash< QString, int > mLayerRenderingTimeHints
Approximate expected layer rendering time per layer, by layer ID.
std::unique_ptr< QgsRenderedItemResults > mRenderedItemResults
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)
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.
std::vector< LayerRenderJob > prepareJobs(QPainter *painter, QgsLabelingEngine *labelingEngine2, bool deferredPainterSet=false)
Creates a list of layer rendering jobs and prepares them for later render.
const QgsMapSettings & mapSettings() const
Returns map settings with which this job was started.
void cleanupJobs(std::vector< LayerRenderJob > &jobs)
QgsMapRendererCache * mCache
void finished()
emitted when asynchronous rendering is finished (or canceled).
QgsLabelSink * labelSink() const
Returns the label sink associated to this rendering job.
QgsMapRendererJob(const QgsMapSettings &settings)
~QgsMapRendererJob() override
void start()
Start the rendering job and immediately return.
QStringList mLayersRedrawnFromCache
QStringList layersRedrawnFromCache() const
Returns a list of the layer IDs for all layers which were redrawn from cached images.
QList< QgsMapRendererJob::Error > Errors
static const QString LABEL_CACHE_ID
QgsMapRendererCache ID string for cached label image.
QgsLabelingEngineFeedback * labelingEngineFeedback()
Returns the associated labeling engine feedback object.
QHash< QgsWeakMapLayerPointer, int > mPerLayerRenderingTime
Render time (in ms) per layer, by layer ID.
std::vector< LayerRenderJob > prepareSecondPassJobs(std::vector< LayerRenderJob > &firstPassJobs, LabelRenderJob &labelJob)
Prepares jobs for a second pass, if selective masks exist (from labels or symbol layers).
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...
QgsRenderedItemResults * takeRenderedItemResults()
Takes the rendered item results from the map render job and returns them.
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.
QList< QgsMapLayer * > layers(bool expandGroupLayers=false) const
Returns the list of layers which will be rendered in the map.
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.
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 output image size into account.
double outputDpi() const
Returns the DPI (dots per inch) used for conversion between real world units (e.g.
bool testFlag(Qgis::MapSettingsFlag flag) const
Check whether a particular flag is enabled.
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.
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
Stores collated details of rendered items during a map rendering operation.
bool value(const QString &dynamicKeyPart=QString(), bool useDefaultValueOverride=false, bool defaultValueOverride=false) const
Returns settings value.
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
Point cloud layer. Added in QGIS 3.18.
@ MeshLayer
Mesh layer. Added in QGIS 3.2.
@ VectorLayer
Vector layer.
@ RasterLayer
Raster layer.
@ GroupLayer
Composite group layer. Added in QGIS 3.24.
@ VectorTileLayer
Vector tile layer. Added in QGIS 3.14.
@ AnnotationLayer
Contains freeform, georeferenced annotations. Added in QGIS 3.16.
@ PluginLayer
Plugin based layer.
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)