21 #include <QtConcurrentMap> 45 : mSettings( settings )
69 QHash<QgsMapLayer *, int> result;
73 result.insert( it.key(), it.value() );
88 QSet< QgsMapLayer * > labeledLayers;
131 static const double SPLIT_COORD = 180.0;
143 QgsDebugMsgLevel( QStringLiteral(
"\n0:%1 %2x%3\n1:%4\n2:%5 %6x%7 (w:%8 h:%9)" )
146 .arg( std::fabs( 1.0 - extent2.
width() / extent.
width() ) )
147 .arg( std::fabs( 1.0 - extent2.
height() / extent.
height() ) )
150 if ( std::fabs( 1.0 - extent2.
width() / extent.
width() ) < 0.5 &&
151 std::fabs( 1.0 - extent2.
height() / extent.
height() ) < 0.5 )
176 if ( ll.
x() > ur.
x() )
203 extent =
QgsRectangle( std::numeric_limits<double>::lowest(), std::numeric_limits<double>::lowest(), std::numeric_limits<double>::max(), std::numeric_limits<double>::max() );
211 QgsDebugMsg( QStringLiteral(
"Transform error caught" ) );
212 extent =
QgsRectangle( std::numeric_limits<double>::lowest(), std::numeric_limits<double>::lowest(), std::numeric_limits<double>::max(), std::numeric_limits<double>::max() );
213 r2 =
QgsRectangle( std::numeric_limits<double>::lowest(), std::numeric_limits<double>::lowest(), std::numeric_limits<double>::max(), std::numeric_limits<double>::max() );
221 LayerRenderJobs layerJobs;
230 Q_UNUSED( cacheValid );
231 QgsDebugMsgLevel( QStringLiteral(
"CACHE VALID: %1" ).arg( cacheValid ), 4 );
236 while ( li.hasPrevious() )
240 QgsDebugMsgLevel( QStringLiteral(
"layer %1: minscale:%2 maxscale:%3 scaledepvis:%4 blendmode:%5" )
250 QgsDebugMsgLevel( QStringLiteral(
"Layer not rendered because it is not within the defined visibility scale range" ), 3 );
260 reprojectToLayerExtent( ml, ct, r1, r2 );
265 mErrors.append( Error( ml->
id(), tr(
"There was a problem transforming the layer's extent. Layer skipped." ) ) );
274 bool requiresLabeling =
false;
282 layerJobs.append( LayerRenderJob() );
283 LayerRenderJob &job = layerJobs.last();
287 job.renderingTime = -1;
291 job.context.setPainter( painter );
292 job.context.setLabelingEngine( labelingEngine2 );
293 job.context.setCoordinateTransform( ct );
294 job.context.setExtent( r1 );
296 if ( mFeatureFilterProvider )
297 job.context.setFeatureFilterProvider( mFeatureFilterProvider );
314 job.imageInitialized =
true;
317 job.renderer =
nullptr;
318 job.context.setPainter(
nullptr );
325 if (
mCache || !painter || needTemporaryImage( ml ) )
331 if ( mypFlattenedImage->isNull() )
334 delete mypFlattenedImage;
335 layerJobs.removeLast();
339 job.img = mypFlattenedImage;
340 QPainter *mypPainter =
new QPainter( job.img );
342 job.context.setPainter( mypPainter );
348 job.renderingTime = layerTime.elapsed();
358 job.context.setPainter( painter );
359 job.context.setLabelingEngine( labelingEngine2 );
361 job.context.setFeatureFilterProvider( mFeatureFilterProvider );
371 job.context.setPainter(
nullptr );
375 if ( canUseLabelCache && (
mCache || !painter ) )
378 QImage *mypFlattenedImage =
nullptr;
382 if ( mypFlattenedImage->isNull() )
385 delete mypFlattenedImage;
389 job.img = mypFlattenedImage;
400 for ( LayerRenderJobs::iterator it = jobs.begin(); it != jobs.end(); ++it )
402 LayerRenderJob &job = *it;
405 delete job.context.painter();
406 job.context.setPainter(
nullptr );
408 if (
mCache && !job.cached && !job.context.renderingStopped() && job.layer )
410 QgsDebugMsgLevel(
"caching image for " + ( job.layer ? job.layer->id() : QString() ), 2 );
420 Q_FOREACH (
const QString &message, job.renderer->errors() )
421 mErrors.append( Error( job.renderer->layerId(), message ) );
424 job.renderer =
nullptr;
438 if (
mCache && !job.cached && !job.context.renderingStopped() )
440 QgsDebugMsg( QStringLiteral(
"caching label result image" ) );
456 QPainter painter( &image );
459 for ( LayerRenderJobs::const_iterator it = jobs.constBegin(); it != jobs.constEnd(); ++it )
461 const LayerRenderJob &job = *it;
463 if ( job.layer && job.layer->customProperty( QStringLiteral(
"rendering/renderAboveLabels" ) ).toBool() )
466 if ( !job.imageInitialized )
469 painter.setCompositionMode( job.blendMode );
470 painter.setOpacity( job.opacity );
474 painter.drawImage( 0, 0, *job.img );
480 if ( labelJob.img && labelJob.complete )
482 painter.setCompositionMode( QPainter::CompositionMode_SourceOver );
483 painter.setOpacity( 1.0 );
484 painter.drawImage( 0, 0, *labelJob.img );
488 for ( LayerRenderJobs::const_iterator it = jobs.constBegin(); it != jobs.constEnd(); ++it )
490 const LayerRenderJob &job = *it;
492 if ( !job.layer || !job.layer->customProperty( QStringLiteral(
"rendering/renderAboveLabels" ) ).toBool() )
495 if ( !job.imageInitialized )
498 painter.setCompositionMode( job.blendMode );
499 painter.setOpacity( job.opacity );
503 painter.drawImage( 0, 0, *job.img );
513 if ( !settings.
value( QStringLiteral(
"Map/logCanvasRefreshEvent" ),
false ).toBool() )
516 QMultiMap<int, QString> elapsed;
517 Q_FOREACH (
const LayerRenderJob &job, jobs )
518 elapsed.insert( job.
renderingTime, job.layer ? job.layer->
id() : QString() );
520 elapsed.insert( labelJob.renderingTime, tr( "Labeling" ) );
522 QList<
int> tt( elapsed.uniqueKeys() );
523 std::sort( tt.begin(), tt.end(), std::greater<
int>() );
524 Q_FOREACH (
int t, tt )
526 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.
A rectangle specified with double values.
Base class for all map layer types.
QgsMapLayer::LayerType type() const
Returns the type of the layer.
Abstract base class for map rendering implementations.
double scale() const
Returns the calculated map scale.
void setXMaximum(double x)
Set the maximum x value.
This class is a composition of two QSettings instances:
void cleanupJobs(LayerRenderJobs &jobs)
Errors errors() const
List of errors that happened during the rendering job - available when the rendering has been finishe...
Restore overridden layer style on destruction.
bool isFinite() const
Returns true if the rectangle has finite boundaries.
double yMaximum() const
Returns the y maximum value (top side of rectangle).
double maximumScale() const
Returns the maximum map scale (i.e.
float devicePixelRatio() const
Returns device pixel ratio Common values are 1 for normal-dpi displays and 2 for high-dpi "retina" di...
A class to represent a 2D point.
void setCacheImage(const QString &cacheKey, const QImage &image, const QList< QgsMapLayer * > &dependentLayers=QList< QgsMapLayer * >())
Set the cached image for a particular cacheKey.
QgsRectangle visibleExtent() const
Returns the actual extent derived from requested extent that takes takes output image size into accou...
QMap< QString, QString > layerStyleOverrides() const
Gets map of map layer style overrides (key: layer ID, value: style name) where a different style shou...
QVariant value(const QString &key, const QVariant &defaultValue=QVariant(), Section section=NoSection) const
Returns the value for setting key.
static const QString LABEL_CACHE_ID
QgsMapRendererCache ID string for cached label image.
QgsCoordinateTransform layerTransform(const QgsMapLayer *layer) const
Returns the coordinate transform from layer's CRS to destination CRS.
QString toString(int precision=-1) const
Returns a string representation of the point (x, y) with a preset precision.
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
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.
QList< QgsMapLayer * > layers() const
Gets list of layers for map rendering The layers are stored in the reverse order of how they are rend...
bool isEditable() const FINAL
Returns true if the provider is in editing mode.
virtual bool requiresAdvancedEffects() const =0
Returns true if drawing labels requires advanced effects like composition modes, which could prevent ...
QPainter::CompositionMode blendMode() const
Returns the current blending mode for a layer.
QHash< QgsWeakMapLayerPointer, int > mPerLayerRenderingTime
Render time (in ms) per layer, by layer ID.
bool hasScaleBasedVisibility() const
Returns whether scale based visibility is enabled for the layer.
bool isInScaleRange(double scale) const
Tests whether the layer should be visible at the specified scale.
double yMinimum() const
Returns the y minimum value (bottom side of rectangle).
const QgsAbstractVectorLayerLabeling * labeling() const
Access to const labeling configuration.
QSize outputSize() const
Returns the size of the resulting map image.
double xMaximum() const
Returns the x maximum value (right side of rectangle).
#define QgsDebugMsgLevel(str, level)
QString toString(int precision=16) const
Returns a string representation of form xmin,ymin : xmax,ymax Coordinates will be truncated to the sp...
bool init(const QgsRectangle &extent, double scale)
Initialize cache: set new parameters and clears the cache if any parameters have changed since last i...
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).
const LayerRenderJobs & jobs() const
Enable anti-aliasing for map rendering.
QString id() const
Returns the layer's unique ID, which is used to access this layer from QgsProject.
double minimumScale() const
Returns the minimum map scale (i.e.
void cleanupLabelJob(LabelRenderJob &job)
Handles clean up tasks for a label job, including deletion of images and storing cached label results...
QColor backgroundColor() const
Gets the background color of the map.
QHash< QgsMapLayer *, int > perLayerRenderingTime() const
Returns the render time (in ms) per layer.
bool testFlag(Flag flag) const
Check whether a particular flag is enabled.
bool prepareLabelCache() const
Prepares the cache for storing the result of labeling.
The QgsLabelingEngine class provides map labeling functionality.
bool hasCacheImage(const QString &cacheKey) const
Returns true if the cache contains an image with the specified cacheKey.
QList< QgsMapRendererJob::Error > Errors
LayerRenderJobs prepareJobs(QPainter *painter, QgsLabelingEngine *labelingEngine2)
void logRenderingTime(const LayerRenderJobs &jobs, const LabelRenderJob &labelJob)
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.
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.
virtual QgsMapLayerRenderer * createMapRenderer(QgsRenderContext &rendererContext)=0
Returns new instance of QgsMapLayerRenderer that will be used for rendering of given context...
QgsMapRendererQImageJob(const QgsMapSettings &settings)
This class is responsible for keeping cache of rendered images resulting from a map rendering job...
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.
bool labelsEnabled() const
Returns whether the layer contains labels which are enabled and should be drawn.
const QgsMapSettings & mapSettings() const
Returns map settings with which this job was started.
double width() const
Returns the width of the rectangle.
Represents a vector layer which manages a vector based data sets.
bool isGeographic() const
Returns whether the CRS is a geographic CRS (using lat/lon coordinates)
QgsMapRendererCache * mCache
double xMinimum() const
Returns the x minimum value (left side of rectangle).
int renderingTime() const
Returns the total time it took to finish the job (in milliseconds).
QgsMapRendererJob(const QgsMapSettings &settings)
void setXMinimum(double x)
Set the minimum x value.
QgsCoordinateReferenceSystem crs
QSize deviceOutputSize() const
Returns the device output size of the map canvas This is equivalent to the output size multiplicated ...
double height() const
Returns the height of the rectangle.