[layouts] Don't needlessly calculate layer sets for maps linked

to a map theme

This is very expensive to do, so avoid calculating it as much
as possible

Refs #17027
This commit is contained in:
Nyall Dawson 2018-01-18 12:08:59 +10:00
parent a09cb6f364
commit f5876eab98
5 changed files with 35 additions and 24 deletions

View File

@ -458,9 +458,13 @@ This is calculated using the width of the map item and the width of the
current visible map extent.
%End
QgsMapSettings mapSettings( const QgsRectangle &extent, QSizeF size, double dpi ) const;
QgsMapSettings mapSettings( const QgsRectangle &extent, QSizeF size, double dpi, bool includeLayerSettings ) const;
%Docstring
Return map settings that will be used for drawing of the map.
If ``includeLayerSettings`` is true, than settings specifically relating to map layers and map layer styles
will be calculated. This can be expensive to calculate, so if they are not required in the map settings
(e.g. for map settings which are used for scale related calculations only) then ``includeLayerSettings`` should be false.
%End
virtual void finalizeRestoreFromXml();

View File

@ -89,7 +89,7 @@ void QgsLayoutItemLegend::paint( QPainter *painter, const QStyleOptionGraphicsIt
QSizeF mapSizePixels = QSizeF( mMap->rect().width() * dotsPerMM, mMap->rect().height() * dotsPerMM );
QgsRectangle mapExtent = mMap->extent();
QgsMapSettings ms = mMap->mapSettings( mapExtent, mapSizePixels, dpi );
QgsMapSettings ms = mMap->mapSettings( mapExtent, mapSizePixels, dpi, false );
mSettings.setMapScale( ms.scale() );
}
mInitialMapScaleCalculated = true;
@ -761,7 +761,7 @@ void QgsLayoutItemLegend::doUpdateFilterByMap()
QSizeF size( requestRectangle.width(), requestRectangle.height() );
size *= mLayout->convertFromLayoutUnits( mMap->mapUnitsToLayoutUnits(), QgsUnitTypes::LayoutMillimeters ).length() * dpi / 25.4;
QgsMapSettings ms = mMap->mapSettings( requestRectangle, size, dpi );
QgsMapSettings ms = mMap->mapSettings( requestRectangle, size, dpi, true );
QgsGeometry filterPolygon;
if ( mInAtlas )

View File

@ -960,7 +960,7 @@ void QgsLayoutItemMap::drawMap( QPainter *painter, const QgsRectangle &extent, Q
}
// render
QgsMapRendererCustomPainterJob job( mapSettings( extent, size, dpi ), painter );
QgsMapRendererCustomPainterJob job( mapSettings( extent, size, dpi, true ), painter );
// Render the map in this thread. This is done because of problems
// with printing to printer on Windows (printing to PDF is fine though).
// Raster images were not displayed - see #10599
@ -1037,13 +1037,13 @@ void QgsLayoutItemMap::recreateCachedImageInBackground( double viewScaleFactor )
mCacheInvalidated = false;
mPainter.reset( new QPainter( mCacheRenderingImage.get() ) );
QgsMapSettings settings( mapSettings( ext, QSizeF( w, h ), mCacheRenderingImage->logicalDpiX() ) );
QgsMapSettings settings( mapSettings( ext, QSizeF( w, h ), mCacheRenderingImage->logicalDpiX(), true ) );
mPainterJob.reset( new QgsMapRendererCustomPainterJob( settings, mPainter.get() ) );
connect( mPainterJob.get(), &QgsMapRendererCustomPainterJob::finished, this, &QgsLayoutItemMap::painterJobFinished );
mPainterJob->start();
}
QgsMapSettings QgsLayoutItemMap::mapSettings( const QgsRectangle &extent, QSizeF size, double dpi ) const
QgsMapSettings QgsLayoutItemMap::mapSettings( const QgsRectangle &extent, QSizeF size, double dpi, bool includeLayerSettings ) const
{
QgsExpressionContext expressionContext = createExpressionContext();
QgsCoordinateReferenceSystem renderCrs = crs();
@ -1058,26 +1058,29 @@ QgsMapSettings QgsLayoutItemMap::mapSettings( const QgsRectangle &extent, QSizeF
if ( mLayout )
jobMapSettings.setEllipsoid( mLayout->project()->ellipsoid() );
//set layers to render
QList<QgsMapLayer *> layers = layersToRender( &expressionContext );
if ( mLayout && -1 != mLayout->renderContext().currentExportLayer() )
if ( includeLayerSettings )
{
const int layerIdx = mLayout->renderContext().currentExportLayer() - ( hasBackground() ? 1 : 0 );
if ( layerIdx >= 0 && layerIdx < layers.length() )
//set layers to render
QList<QgsMapLayer *> layers = layersToRender( &expressionContext );
if ( mLayout && -1 != mLayout->renderContext().currentExportLayer() )
{
// exporting with separate layers (e.g., to svg layers), so we only want to render a single map layer
QgsMapLayer *ml = layers[ layers.length() - layerIdx - 1 ];
layers.clear();
layers << ml;
}
else
{
// exporting decorations such as map frame/grid/overview, so no map layers required
layers.clear();
const int layerIdx = mLayout->renderContext().currentExportLayer() - ( hasBackground() ? 1 : 0 );
if ( layerIdx >= 0 && layerIdx < layers.length() )
{
// exporting with separate layers (e.g., to svg layers), so we only want to render a single map layer
QgsMapLayer *ml = layers[ layers.length() - layerIdx - 1 ];
layers.clear();
layers << ml;
}
else
{
// exporting decorations such as map frame/grid/overview, so no map layers required
layers.clear();
}
}
jobMapSettings.setLayers( layers );
jobMapSettings.setLayerStyleOverrides( layerStyleOverridesToRender( expressionContext ) );
}
jobMapSettings.setLayers( layers );
jobMapSettings.setLayerStyleOverrides( layerStyleOverridesToRender( expressionContext ) );
if ( !mLayout->renderContext().isPreviewRender() )
{

View File

@ -408,8 +408,12 @@ class CORE_EXPORT QgsLayoutItemMap : public QgsLayoutItem
/**
* Return map settings that will be used for drawing of the map.
*
* If \a includeLayerSettings is true, than settings specifically relating to map layers and map layer styles
* will be calculated. This can be expensive to calculate, so if they are not required in the map settings
* (e.g. for map settings which are used for scale related calculations only) then \a includeLayerSettings should be false.
*/
QgsMapSettings mapSettings( const QgsRectangle &extent, QSizeF size, double dpi ) const;
QgsMapSettings mapSettings( const QgsRectangle &extent, QSizeF size, double dpi, bool includeLayerSettings ) const;
void finalizeRestoreFromXml() override;

View File

@ -123,7 +123,7 @@ QgsRenderContext QgsLayoutUtils::createRenderContextForMap( QgsLayoutItemMap *ma
QgsRectangle extent = map->extent();
QSizeF mapSizeLayoutUnits = map->rect().size();
QSizeF mapSizeMM = map->layout()->convertFromLayoutUnits( mapSizeLayoutUnits, QgsUnitTypes::LayoutMillimeters ).toQSizeF();
QgsMapSettings ms = map->mapSettings( extent, mapSizeMM * dotsPerMM, dpi );
QgsMapSettings ms = map->mapSettings( extent, mapSizeMM * dotsPerMM, dpi, false );
QgsRenderContext context = QgsRenderContext::fromMapSettings( ms );
if ( painter )
context.setPainter( painter );