[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. current visible map extent.
%End %End
QgsMapSettings mapSettings( const QgsRectangle &extent, QSizeF size, double dpi ) const; QgsMapSettings mapSettings( const QgsRectangle &extent, QSizeF size, double dpi, bool includeLayerSettings ) const;
%Docstring %Docstring
Return map settings that will be used for drawing of the map. 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 %End
virtual void finalizeRestoreFromXml(); 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 ); QSizeF mapSizePixels = QSizeF( mMap->rect().width() * dotsPerMM, mMap->rect().height() * dotsPerMM );
QgsRectangle mapExtent = mMap->extent(); QgsRectangle mapExtent = mMap->extent();
QgsMapSettings ms = mMap->mapSettings( mapExtent, mapSizePixels, dpi ); QgsMapSettings ms = mMap->mapSettings( mapExtent, mapSizePixels, dpi, false );
mSettings.setMapScale( ms.scale() ); mSettings.setMapScale( ms.scale() );
} }
mInitialMapScaleCalculated = true; mInitialMapScaleCalculated = true;
@ -761,7 +761,7 @@ void QgsLayoutItemLegend::doUpdateFilterByMap()
QSizeF size( requestRectangle.width(), requestRectangle.height() ); QSizeF size( requestRectangle.width(), requestRectangle.height() );
size *= mLayout->convertFromLayoutUnits( mMap->mapUnitsToLayoutUnits(), QgsUnitTypes::LayoutMillimeters ).length() * dpi / 25.4; 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; QgsGeometry filterPolygon;
if ( mInAtlas ) if ( mInAtlas )

View File

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

View File

@ -123,7 +123,7 @@ QgsRenderContext QgsLayoutUtils::createRenderContextForMap( QgsLayoutItemMap *ma
QgsRectangle extent = map->extent(); QgsRectangle extent = map->extent();
QSizeF mapSizeLayoutUnits = map->rect().size(); QSizeF mapSizeLayoutUnits = map->rect().size();
QSizeF mapSizeMM = map->layout()->convertFromLayoutUnits( mapSizeLayoutUnits, QgsUnitTypes::LayoutMillimeters ).toQSizeF(); 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 ); QgsRenderContext context = QgsRenderContext::fromMapSettings( ms );
if ( painter ) if ( painter )
context.setPainter( painter ); context.setPainter( painter );