[layouts] Add method to alter list of map layers to render to include

overview layers
This commit is contained in:
Nyall Dawson 2018-12-28 16:54:05 +10:00
parent 97daa5080d
commit 12da3afa85
4 changed files with 124 additions and 1 deletions

View File

@ -102,6 +102,14 @@ Returns a list of QgsLayoutItemMapOverviews contained by the stack.
virtual bool readXml( const QDomElement &elem, const QDomDocument &doc, const QgsReadWriteContext &context );
QList< QgsMapLayer * > modifyMapLayerList( const QList< QgsMapLayer * > &layers );
%Docstring
Alters the list of map ``layers`` which will be rendered for the link map item, inserting
temporary layers which represent overview extents as required.
.. versionadded:: 3.6
%End
};
class QgsLayoutItemMapOverview : QgsLayoutItemMapItem

View File

@ -448,3 +448,58 @@ bool QgsLayoutItemMapOverviewStack::readXml( const QDomElement &elem, const QDom
return true;
}
QList<QgsMapLayer *> QgsLayoutItemMapOverviewStack::modifyMapLayerList( const QList<QgsMapLayer *> &layers )
{
QList<QgsMapLayer *> res = layers;
res.reserve( layers.count() + mItems.count() );
for ( QgsLayoutItemMapItem *item : qgis::as_const( mItems ) )
{
if ( !item )
continue;
QgsVectorLayer *l = static_cast< QgsLayoutItemMapOverview * >( item )->asMapLayer();
if ( !l )
continue;
switch ( item->stackingPosition() )
{
case QgsLayoutItemMapItem::StackAboveMapLabels:
continue;
case QgsLayoutItemMapItem::StackAboveMapLayer:
case QgsLayoutItemMapItem::StackBelowMapLayer:
{
QgsMapLayer *stackLayer = item->stackingLayer();
if ( !stackLayer )
continue;
auto pos = std::find( res.begin(), res.end(), stackLayer );
if ( pos == res.end() )
continue;
if ( item->stackingPosition() == QgsLayoutItemMapItem::StackBelowMapLayer )
{
pos++;
if ( pos == res.end() )
{
res.push_back( l );
break;
}
}
res.insert( pos, l );
break;
}
case QgsLayoutItemMapItem::StackBelowMap:
res.push_back( l );
break;
case QgsLayoutItemMapItem::StackBelowMapLabels:
res.push_front( l );
break;
}
}
return res;
}

View File

@ -106,6 +106,14 @@ class CORE_EXPORT QgsLayoutItemMapOverviewStack : public QgsLayoutItemMapItemSta
QList< QgsLayoutItemMapOverview * > asList() const;
bool readXml( const QDomElement &elem, const QDomDocument &doc, const QgsReadWriteContext &context ) override;
/**
* Alters the list of map \a layers which will be rendered for the link map item, inserting
* temporary layers which represent overview extents as required.
*
* \since QGIS 3.6
*/
QList< QgsMapLayer * > modifyMapLayerList( const QList< QgsMapLayer * > &layers );
};
/**

View File

@ -29,7 +29,8 @@ from qgis.core import (QgsLayoutItemMap,
QgsMultiBandColorRenderer,
QgsFillSymbol,
QgsSingleSymbolRenderer,
QgsCoordinateReferenceSystem)
QgsCoordinateReferenceSystem,
QgsLayoutItemMapOverview)
from qgis.testing import start_app, unittest
from utilities import unitTestDataPath
@ -237,6 +238,57 @@ class TestQgsLayoutMap(unittest.TestCase, LayoutItemTestCase):
overviewMap.overview().setStackingLayer(None)
self.assertIsNone(overviewMap.overview().stackingLayer())
def test_ModifyMapLayerList(self):
l = QgsLayout(QgsProject.instance())
l.initializeDefaults()
overviewMap = QgsLayoutItemMap(l)
overviewMap.attemptSetSceneRect(QRectF(20, 130, 70, 70))
l.addLayoutItem(overviewMap)
map = QgsLayoutItemMap(l)
map.attemptSetSceneRect(QRectF(20, 20, 200, 100))
l.addLayoutItem(map)
self.assertFalse(overviewMap.overviews().modifyMapLayerList([]))
self.assertEqual(overviewMap.overviews().modifyMapLayerList([self.raster_layer, self.vector_layer]), [self.raster_layer, self.vector_layer])
overviewMap.overview().setLinkedMap(map)
overviewMap.overview().setStackingPosition(QgsLayoutItemMapItem.StackBelowMap)
self.assertEqual(overviewMap.overviews().modifyMapLayerList([self.raster_layer, self.vector_layer]),
[self.raster_layer, self.vector_layer, overviewMap.overview().asMapLayer()])
overviewMap.overview().setStackingPosition(QgsLayoutItemMapItem.StackBelowMapLayer)
self.assertEqual(overviewMap.overviews().modifyMapLayerList([self.raster_layer, self.vector_layer]),
[self.raster_layer, self.vector_layer])
overviewMap.overview().setStackingLayer(self.raster_layer)
self.assertEqual(overviewMap.overviews().modifyMapLayerList([self.raster_layer, self.vector_layer]),
[self.raster_layer, overviewMap.overview().asMapLayer(), self.vector_layer])
overviewMap.overview().setStackingLayer(self.vector_layer)
self.assertEqual(overviewMap.overviews().modifyMapLayerList([self.raster_layer, self.vector_layer]),
[self.raster_layer, self.vector_layer, overviewMap.overview().asMapLayer()])
overviewMap.overview().setStackingPosition(QgsLayoutItemMapItem.StackAboveMapLayer)
overviewMap.overview().setStackingLayer(None)
self.assertEqual(overviewMap.overviews().modifyMapLayerList([self.raster_layer, self.vector_layer]),
[self.raster_layer, self.vector_layer])
overviewMap.overview().setStackingLayer(self.raster_layer)
self.assertEqual(overviewMap.overviews().modifyMapLayerList([self.raster_layer, self.vector_layer]),
[overviewMap.overview().asMapLayer(), self.raster_layer, self.vector_layer])
overviewMap.overview().setStackingLayer(self.vector_layer)
self.assertEqual(overviewMap.overviews().modifyMapLayerList([self.raster_layer, self.vector_layer]),
[self.raster_layer, overviewMap.overview().asMapLayer(), self.vector_layer])
overviewMap.overview().setStackingPosition(QgsLayoutItemMapItem.StackBelowMapLabels)
self.assertEqual(overviewMap.overviews().modifyMapLayerList([self.raster_layer, self.vector_layer]),
[overviewMap.overview().asMapLayer(), self.raster_layer, self.vector_layer])
overviewMap.overview().setStackingPosition(QgsLayoutItemMapItem.StackAboveMapLabels)
self.assertEqual(overviewMap.overviews().modifyMapLayerList([self.raster_layer, self.vector_layer]),
[self.raster_layer, self.vector_layer])
# two overviews
overviewMap.overview().setStackingPosition(QgsLayoutItemMapItem.StackBelowMap)
overviewMap.overviews().addOverview(QgsLayoutItemMapOverview('x', overviewMap))
overviewMap.overviews().overview(1).setLinkedMap(map)
overviewMap.overviews().overview(1).setStackingPosition(QgsLayoutItemMapItem.StackBelowMapLabels)
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()])
if __name__ == '__main__':
unittest.main()