Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
[layouts] Add API allowing drawing map overviews under map layers
or under map labels
  • Loading branch information
nyalldawson committed Jan 2, 2019
1 parent 12da3af commit a441e2b
Show file tree
Hide file tree
Showing 10 changed files with 85 additions and 13 deletions.
Expand Up @@ -243,9 +243,13 @@ map item after restoration from XML.
.. seealso:: :py:func:`readXml`
%End

void drawItems( QPainter *painter );
void drawItems( QPainter *painter, bool ignoreStacking = true );
%Docstring
Draws the items from the stack on a specified ``painter``.

If ``ignoreStacking`` is true, then all items will be drawn, regardless
of their actual stacking position settings. If it is false, only items
which are set to stack above the map item will be drawn.
%End

bool containsAdvancedEffects() const;
Expand Down
20 changes: 16 additions & 4 deletions src/core/layout/qgslayoutitemmap.cpp
Expand Up @@ -854,7 +854,7 @@ void QgsLayoutItemMap::paint( QPainter *painter, const QStyleOptionGraphicsItem

if ( shouldDrawPart( OverviewMapExtent ) )
{
mOverviewStack->drawItems( painter );
mOverviewStack->drawItems( painter, false );
}
if ( shouldDrawPart( Grid ) )
{
Expand Down Expand Up @@ -922,7 +922,7 @@ void QgsLayoutItemMap::paint( QPainter *painter, const QStyleOptionGraphicsItem

if ( shouldDrawPart( OverviewMapExtent ) )
{
mOverviewStack->drawItems( &p );
mOverviewStack->drawItems( &p, false );
}
if ( shouldDrawPart( Grid ) )
{
Expand Down Expand Up @@ -960,7 +960,7 @@ void QgsLayoutItemMap::paint( QPainter *painter, const QStyleOptionGraphicsItem

if ( shouldDrawPart( OverviewMapExtent ) )
{
mOverviewStack->drawItems( painter );
mOverviewStack->drawItems( painter, false );
}
if ( shouldDrawPart( Grid ) )
{
Expand Down Expand Up @@ -1006,7 +1006,13 @@ void QgsLayoutItemMap::drawMap( QPainter *painter, const QgsRectangle &extent, Q
}

// render
QgsMapRendererCustomPainterJob job( mapSettings( extent, size, dpi, true ), painter );
QgsMapSettings ms( mapSettings( extent, size, dpi, true ) );
if ( shouldDrawPart( OverviewMapExtent ) )
{
ms.setLayers( mOverviewStack->modifyMapLayerList( ms.layers() ) );
}

QgsMapRendererCustomPainterJob job( ms, 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 @@ -1084,6 +1090,12 @@ void QgsLayoutItemMap::recreateCachedImageInBackground()
mCacheInvalidated = false;
mPainter.reset( new QPainter( mCacheRenderingImage.get() ) );
QgsMapSettings settings( mapSettings( ext, QSizeF( w, h ), mCacheRenderingImage->logicalDpiX(), true ) );

if ( shouldDrawPart( OverviewMapExtent ) )
{
settings.setLayers( mOverviewStack->modifyMapLayerList( settings.layers() ) );
}

mPainterJob.reset( new QgsMapRendererCustomPainterJob( settings, mPainter.get() ) );
connect( mPainterJob.get(), &QgsMapRendererCustomPainterJob::finished, this, &QgsLayoutItemMap::painterJobFinished );
mPainterJob->start();
Expand Down
18 changes: 16 additions & 2 deletions src/core/layout/qgslayoutitemmapitem.cpp
Expand Up @@ -239,7 +239,7 @@ void QgsLayoutItemMapItemStack::finalizeRestoreFromXml()
}
}

void QgsLayoutItemMapItemStack::drawItems( QPainter *painter )
void QgsLayoutItemMapItemStack::drawItems( QPainter *painter, bool ignoreStacking )
{
if ( !painter )
{
Expand All @@ -248,7 +248,21 @@ void QgsLayoutItemMapItemStack::drawItems( QPainter *painter )

for ( QgsLayoutItemMapItem *item : qgis::as_const( mItems ) )
{
item->draw( painter );
switch ( item->stackingPosition() )
{
case QgsLayoutItemMapItem::StackBelowMap:
case QgsLayoutItemMapItem::StackAboveMapLayer:
case QgsLayoutItemMapItem::StackBelowMapLayer:
case QgsLayoutItemMapItem::StackBelowMapLabels:
if ( !ignoreStacking )
break;

FALLTHROUGH
case QgsLayoutItemMapItem::StackAboveMapLabels:
item->draw( painter );
break;

}
}
}

Expand Down
6 changes: 5 additions & 1 deletion src/core/layout/qgslayoutitemmapitem.h
Expand Up @@ -250,8 +250,12 @@ class CORE_EXPORT QgsLayoutItemMapItemStack

/**
* Draws the items from the stack on a specified \a painter.
*
* If \a ignoreStacking is true, then all items will be drawn, regardless
* of their actual stacking position settings. If it is false, only items
* which are set to stack above the map item will be drawn.
*/
void drawItems( QPainter *painter );
void drawItems( QPainter *painter, bool ignoreStacking = true );

/**
* Returns whether any items within the stack contain advanced effects,
Expand Down
7 changes: 2 additions & 5 deletions src/core/layout/qgslayoutitemmapoverview.cpp
Expand Up @@ -230,7 +230,7 @@ void QgsLayoutItemMapOverview::setLinkedMap( QgsLayoutItemMap *map )
mFrameMap = map;
//connect to new map signals
connectSignals();
mMap->update();
mMap->invalidateCache();
}

QgsLayoutItemMap *QgsLayoutItemMapOverview::linkedMap()
Expand Down Expand Up @@ -358,13 +358,10 @@ void QgsLayoutItemMapOverview::overviewExtentChanged()
center.x() - extent.width() / 2 + extent.width(),
center.y() - extent.height() / 2 + extent.height() );
mMap->setExtent( movedExtent );

//must invalidate cache so that map gets redrawn
mMap->invalidateCache();
}

//repaint map so that overview gets updated
mMap->update();
mMap->invalidateCache();
}


Expand Down
41 changes: 41 additions & 0 deletions tests/src/python/test_qgslayoutmapoverview.py
Expand Up @@ -289,6 +289,47 @@ def test_ModifyMapLayerList(self):
self.assertEqual(overviewMap.overviews().modifyMapLayerList([self.raster_layer, self.vector_layer]),
[overviewMap.overviews().overview(1).asMapLayer(), self.raster_layer, self.vector_layer, overviewMap.overview().asMapLayer()])

def testOverviewStacking(self):
l = QgsLayout(QgsProject.instance())
l.initializeDefaults()
map = QgsLayoutItemMap(l)
map.attemptSetSceneRect(QRectF(20, 20, 200, 100))
map.setFrameEnabled(True)
map.setLayers([self.raster_layer])
l.addLayoutItem(map)

overviewMap = QgsLayoutItemMap(l)
overviewMap.attemptSetSceneRect(QRectF(20, 130, 70, 70))
l.addLayoutItem(overviewMap)
overviewMap.setFrameEnabled(True)
overviewMap.setLayers([self.raster_layer])
# zoom in
myRectangle = QgsRectangle(96, -152, 160, -120)
map.setExtent(myRectangle)
myRectangle2 = QgsRectangle(-20, -276, 276, 20)
overviewMap.setExtent(myRectangle2)
overviewMap.overview().setLinkedMap(map)
overviewMap.overview().setInverted(True)
overviewMap.overview().setStackingPosition(QgsLayoutItemMapItem.StackBelowMapLayer)
overviewMap.overview().setStackingLayer(self.raster_layer)

checker = QgsLayoutChecker('composermap_overview_belowmap', l)
checker.setColorTolerance(6)
checker.setControlPathPrefix("composer_mapoverview")
myTestResult, myMessage = checker.testLayout()
self.report += checker.report()
self.assertTrue(myTestResult, myMessage)

overviewMap.overview().setStackingPosition(QgsLayoutItemMapItem.StackAboveMapLayer)
overviewMap.overview().setStackingLayer(self.raster_layer)

checker = QgsLayoutChecker('composermap_overview_abovemap', l)
checker.setColorTolerance(6)
checker.setControlPathPrefix("composer_mapoverview")
myTestResult, myMessage = checker.testLayout()
self.report += checker.report()
self.assertTrue(myTestResult, myMessage)


if __name__ == '__main__':
unittest.main()
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit a441e2b

Please sign in to comment.