Skip to content

Commit

Permalink
[layouts] Don't needlessly calculate layer sets for maps linked
Browse files Browse the repository at this point in the history
to a map theme

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

Refs #17027
  • Loading branch information
nyalldawson committed Jan 18, 2018
1 parent a09cb6f commit f5876ea
Show file tree
Hide file tree
Showing 5 changed files with 35 additions and 24 deletions.
6 changes: 5 additions & 1 deletion python/core/layout/qgslayoutitemmap.sip.in
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down
4 changes: 2 additions & 2 deletions src/core/layout/qgslayoutitemlegend.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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 )
Expand Down
41 changes: 22 additions & 19 deletions src/core/layout/qgslayoutitemmap.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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();
Expand All @@ -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() )
{
Expand Down
6 changes: 5 additions & 1 deletion src/core/layout/qgslayoutitemmap.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down
2 changes: 1 addition & 1 deletion src/core/layout/qgslayoututils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 );
Expand Down

0 comments on commit f5876ea

Please sign in to comment.