21 #include <QtConcurrentMap> 46 : mSettings( settings )
70 QHash<QgsMapLayer *, int> result;
74 result.insert( it.key(), it.value() );
89 QSet< QgsMapLayer * > labeledLayers;
133 static const double SPLIT_COORD = 180.0;
145 QgsDebugMsgLevel( QStringLiteral(
"\n0:%1 %2x%3\n1:%4\n2:%5 %6x%7 (w:%8 h:%9)" )
148 .arg( std::fabs( 1.0 - extent2.
width() / extent.
width() ) )
149 .arg( std::fabs( 1.0 - extent2.
height() / extent.
height() ) )
152 if ( std::fabs( 1.0 - extent2.
width() / extent.
width() ) < 0.5 &&
153 std::fabs( 1.0 - extent2.
height() / extent.
height() ) < 0.5 )
178 if ( ll.
x() > ur.
x() )
205 extent =
QgsRectangle( std::numeric_limits<double>::lowest(), std::numeric_limits<double>::lowest(), std::numeric_limits<double>::max(), std::numeric_limits<double>::max() );
213 QgsDebugMsg( QStringLiteral(
"Transform error caught" ) );
214 extent =
QgsRectangle( std::numeric_limits<double>::lowest(), std::numeric_limits<double>::lowest(), std::numeric_limits<double>::max(), std::numeric_limits<double>::max() );
215 r2 =
QgsRectangle( std::numeric_limits<double>::lowest(), std::numeric_limits<double>::lowest(), std::numeric_limits<double>::max(), std::numeric_limits<double>::max() );
223 LayerRenderJobs layerJobs;
232 Q_UNUSED( cacheValid )
233 QgsDebugMsgLevel( QStringLiteral(
"CACHE VALID: %1" ).arg( cacheValid ), 4 );
238 while ( li.hasPrevious() )
242 QgsDebugMsgLevel( QStringLiteral(
"layer %1: minscale:%2 maxscale:%3 scaledepvis:%4 blendmode:%5" )
252 QgsDebugMsgLevel( QStringLiteral(
"Layer not rendered because it is not within the defined visibility scale range" ), 3 );
262 reprojectToLayerExtent( ml, ct, r1, r2 );
267 mErrors.append( Error( ml->
id(), tr(
"There was a problem transforming the layer's extent. Layer skipped." ) ) );
276 bool requiresLabeling =
false;
284 layerJobs.append( LayerRenderJob() );
285 LayerRenderJob &job = layerJobs.last();
289 job.renderingTime = -1;
293 job.context.setPainter( painter );
294 job.context.setLabelingEngine( labelingEngine2 );
295 job.context.setCoordinateTransform( ct );
296 job.context.setExtent( r1 );
298 if ( mFeatureFilterProvider )
299 job.context.setFeatureFilterProvider( mFeatureFilterProvider );
316 job.imageInitialized =
true;
319 job.renderer =
nullptr;
320 job.context.setPainter(
nullptr );
327 if (
mCache || !painter || needTemporaryImage( ml ) )
333 if ( mypFlattenedImage->isNull() )
336 delete mypFlattenedImage;
337 layerJobs.removeLast();
341 job.img = mypFlattenedImage;
342 QPainter *mypPainter =
new QPainter( job.img );
344 job.context.setPainter( mypPainter );
350 job.renderingTime = layerTime.elapsed();
360 job.context.setPainter( painter );
361 job.context.setLabelingEngine( labelingEngine2 );
363 job.context.setFeatureFilterProvider( mFeatureFilterProvider );
373 job.context.setPainter(
nullptr );
377 if ( canUseLabelCache && (
mCache || !painter ) )
380 QImage *mypFlattenedImage =
nullptr;
384 if ( mypFlattenedImage->isNull() )
387 delete mypFlattenedImage;
391 job.img = mypFlattenedImage;
402 for ( LayerRenderJobs::iterator it = jobs.begin(); it != jobs.end(); ++it )
404 LayerRenderJob &job = *it;
407 delete job.context.painter();
408 job.context.setPainter(
nullptr );
410 if (
mCache && !job.cached && !job.context.renderingStopped() && job.layer )
412 QgsDebugMsgLevel(
"caching image for " + ( job.layer ? job.layer->id() : QString() ), 2 );
422 const auto constErrors = job.renderer->errors();
423 for (
const QString &message : constErrors )
424 mErrors.append( Error( job.renderer->layerId(), message ) );
427 job.renderer =
nullptr;
441 if (
mCache && !job.cached && !job.context.renderingStopped() )
443 QgsDebugMsg( QStringLiteral(
"caching label result image" ) );
459 QPainter painter( &image );
462 for ( LayerRenderJobs::const_iterator it = jobs.constBegin(); it != jobs.constEnd(); ++it )
464 const LayerRenderJob &job = *it;
466 if ( job.layer && job.layer->customProperty( QStringLiteral(
"rendering/renderAboveLabels" ) ).toBool() )
469 if ( !job.imageInitialized )
472 painter.setCompositionMode( job.blendMode );
473 painter.setOpacity( job.opacity );
477 painter.drawImage( 0, 0, *job.img );
483 if ( labelJob.img && labelJob.complete )
485 painter.setCompositionMode( QPainter::CompositionMode_SourceOver );
486 painter.setOpacity( 1.0 );
487 painter.drawImage( 0, 0, *labelJob.img );
491 for ( LayerRenderJobs::const_iterator it = jobs.constBegin(); it != jobs.constEnd(); ++it )
493 const LayerRenderJob &job = *it;
495 if ( !job.layer || !job.layer->customProperty( QStringLiteral(
"rendering/renderAboveLabels" ) ).toBool() )
498 if ( !job.imageInitialized )
501 painter.setCompositionMode( job.blendMode );
502 painter.setOpacity( job.opacity );
506 painter.drawImage( 0, 0, *job.img );
516 if ( !settings.
value( QStringLiteral(
"Map/logCanvasRefreshEvent" ),
false ).toBool() )
519 QMultiMap<int, QString> elapsed;
520 const auto constJobs =
jobs;
521 for (
const LayerRenderJob &job : constJobs )
522 elapsed.insert( job.renderingTime, job.layer ? job.layer->id() : QString() );
524 elapsed.insert( labelJob.renderingTime, tr(
"Labeling" ) );
526 QList<int> tt( elapsed.uniqueKeys() );
527 std::sort( tt.begin(), tt.end(), std::greater<int>() );
528 const auto constTt = tt;
529 for (
int t : constTt )
531 QgsMessageLog::logMessage( tr(
"%1 ms: %2" ).arg( t ).arg( QStringList( elapsed.values( t ) ).join( QStringLiteral(
", " ) ) ), tr(
"Rendering" ) );
QList< QgsMapLayer *> dependentLayers(const QString &cacheKey) const
Returns a list of map layers on which an image in the cache depends.
bool labelsEnabled() const
Returns whether the layer contains labels which are enabled and should be drawn.
A rectangle specified with double values.
Base class for all map layer types.
const LayerRenderJobs & jobs() const
Abstract base class for map rendering implementations.
QgsMapLayerType type() const
Returns the type of the layer.
void setXMaximum(double x)
Set the maximum x value.
This class is a composition of two QSettings instances:
void cleanupJobs(LayerRenderJobs &jobs)
Restore overridden layer style on destruction.
QSize deviceOutputSize() const
Returns the device output size of the map canvas This is equivalent to the output size multiplicated ...
QVariant value(const QString &key, const QVariant &defaultValue=QVariant(), Section section=NoSection) const
Returns the value for setting key.
A class to represent a 2D point.
QColor backgroundColor() const
Gets the background color of the map.
void setCacheImage(const QString &cacheKey, const QImage &image, const QList< QgsMapLayer * > &dependentLayers=QList< QgsMapLayer * >())
Set the cached image for a particular cacheKey.
Errors errors() const
List of errors that happened during the rendering job - available when the rendering has been finishe...
bool isInScaleRange(double scale) const
Tests whether the layer should be visible at the specified scale.
QString toString(int precision=-1) const
Returns a string representation of the point (x, y) with a preset precision.
QList< QgsMapLayer * > layers() const
Gets list of layers for map rendering The layers are stored in the reverse order of how they are rend...
static const QString LABEL_CACHE_ID
QgsMapRendererCache ID string for cached label image.
QgsRectangle visibleExtent() const
Returns the actual extent derived from requested extent that takes takes output image size into accou...
void setCache(QgsMapRendererCache *cache)
Assign a cache to be used for reading and storing rendered images of individual layers.
The QgsMapSettings class contains configuration for rendering of the map.
static bool staticWillUseLayer(QgsVectorLayer *layer)
called to find out whether the layer is used for labeling
QgsCoordinateTransform layerTransform(const QgsMapLayer *layer) const
Returns the coordinate transform from layer's CRS to destination CRS.
static QImage composeImage(const QgsMapSettings &settings, const LayerRenderJobs &jobs, const LabelRenderJob &labelJob)
LabelRenderJob prepareLabelingJob(QPainter *painter, QgsLabelingEngine *labelingEngine2, bool canUseLabelCache=true)
Prepares a labeling job.
bool isEditable() const FINAL
Returns true if the provider is in editing mode.
bool prepareLabelCache() const
Prepares the cache for storing the result of labeling.
virtual bool requiresAdvancedEffects() const =0
Returns true if drawing labels requires advanced effects like composition modes, which could prevent ...
QHash< QgsWeakMapLayerPointer, int > mPerLayerRenderingTime
Render time (in ms) per layer, by layer ID.
QString id() const
Returns the layer's unique ID, which is used to access this layer from QgsProject.
#define QgsDebugMsgLevel(str, level)
bool init(const QgsRectangle &extent, double scale)
Initialize cache: set new parameters and clears the cache if any parameters have changed since last i...
double scale() const
Returns the calculated map scale.
double width() const
Returns the width of the rectangle.
static void logMessage(const QString &message, const QString &tag=QString(), Qgis::MessageLevel level=Qgis::Warning, bool notifyUser=true)
Adds a message to the log instance (and creates it if necessary).
Enable anti-aliasing for map rendering.
QString toString(int precision=16) const
Returns a string representation of form xmin,ymin : xmax,ymax Coordinates will be truncated to the sp...
QImage::Format outputImageFormat() const
format of internal QImage, default QImage::Format_ARGB32_Premultiplied
QImage cacheImage(const QString &cacheKey) const
Returns the cached image for the specified cacheKey.
const QgsAbstractVectorLayerLabeling * labeling() const
Access to const labeling configuration.
double minimumScale() const
Returns the minimum map scale (i.e.
double maximumScale() const
Returns the maximum map scale (i.e.
QHash< QgsMapLayer *, int > perLayerRenderingTime() const
Returns the render time (in ms) per layer.
float devicePixelRatio() const
Returns device pixel ratio Common values are 1 for normal-dpi displays and 2 for high-dpi "retina" di...
bool isFinite() const
Returns true if the rectangle has finite boundaries.
void cleanupLabelJob(LabelRenderJob &job)
Handles clean up tasks for a label job, including deletion of images and storing cached label results...
double yMinimum() const
Returns the y minimum value (bottom side of rectangle).
double xMaximum() const
Returns the x maximum value (right side of rectangle).
bool hasCacheImage(const QString &cacheKey) const
Returns true if the cache contains an image with the specified cacheKey.
The QgsLabelingEngine class provides map labeling functionality.
QMap< QString, QString > layerStyleOverrides() const
Gets map of map layer style overrides (key: layer ID, value: style name) where a different style shou...
QList< QgsMapRendererJob::Error > Errors
LayerRenderJobs prepareJobs(QPainter *painter, QgsLabelingEngine *labelingEngine2)
void logRenderingTime(const LayerRenderJobs &jobs, const LabelRenderJob &labelJob)
bool hasScaleBasedVisibility() const
Returns whether scale based visibility is enabled for the layer.
static QgsRenderContext fromMapSettings(const QgsMapSettings &mapSettings)
create initialized QgsRenderContext instance from given QgsMapSettings
void clearCacheImage(const QString &cacheKey)
Removes an image from the cache with matching cacheKey.
double xMinimum() const
Returns the x minimum value (left side of rectangle).
virtual QgsMapLayerRenderer * createMapRenderer(QgsRenderContext &rendererContext)=0
Returns new instance of QgsMapLayerRenderer that will be used for rendering of given context...
QgsMapRendererQImageJob(const QgsMapSettings &settings)
double yMaximum() const
Returns the y maximum value (top side of rectangle).
This class is responsible for keeping cache of rendered images resulting from a map rendering job...
bool testFlag(Flag flag) const
Check whether a particular flag is enabled.
Custom exception class for Coordinate Reference System related exceptions.
static QgsExpressionContextScope * layerScope(const QgsMapLayer *layer)
Creates a new scope which contains variables and functions relating to a QgsMapLayer.
Represents a vector layer which manages a vector based data sets.
const QgsMapSettings & mapSettings() const
Returns map settings with which this job was started.
QgsMapRendererCache * mCache
QSize outputSize() const
Returns the size of the resulting map image.
QgsMapRendererJob(const QgsMapSettings &settings)
void setXMinimum(double x)
Set the minimum x value.
QgsCoordinateReferenceSystem crs
QPainter::CompositionMode blendMode() const
Returns the current blending mode for a layer.
double height() const
Returns the height of the rectangle.