Skip to content
Permalink
Browse files

[layouts] Add API allowing drawing map overviews under map layers

or under map labels
  • Loading branch information
nyalldawson committed Dec 28, 2018
1 parent 12da3af commit a441e2b14bf9a242336cfce591a3545ac9f7df37
@@ -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;
@@ -854,7 +854,7 @@ void QgsLayoutItemMap::paint( QPainter *painter, const QStyleOptionGraphicsItem

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

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

if ( shouldDrawPart( OverviewMapExtent ) )
{
mOverviewStack->drawItems( painter );
mOverviewStack->drawItems( painter, false );
}
if ( shouldDrawPart( Grid ) )
{
@@ -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
@@ -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();
@@ -239,7 +239,7 @@ void QgsLayoutItemMapItemStack::finalizeRestoreFromXml()
}
}

void QgsLayoutItemMapItemStack::drawItems( QPainter *painter )
void QgsLayoutItemMapItemStack::drawItems( QPainter *painter, bool ignoreStacking )
{
if ( !painter )
{
@@ -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;

}
}
}

@@ -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,
@@ -230,7 +230,7 @@ void QgsLayoutItemMapOverview::setLinkedMap( QgsLayoutItemMap *map )
mFrameMap = map;
//connect to new map signals
connectSignals();
mMap->update();
mMap->invalidateCache();
}

QgsLayoutItemMap *QgsLayoutItemMapOverview::linkedMap()
@@ -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();
}


@@ -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()
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.

0 comments on commit a441e2b

Please sign in to comment.
You can’t perform that action at this time.