From 636653df2327f608e8e83e3befa10467c639cbe9 Mon Sep 17 00:00:00 2001 From: Nyall Dawson Date: Mon, 31 Aug 2020 11:18:00 +1000 Subject: [PATCH] Always render main annotation layer above map layers in layout maps --- src/core/layout/qgslayoutitemmap.cpp | 5 ++ tests/src/python/test_qgslayoutmap.py | 55 +++++++++++++++++- .../expected_composermap_annotation_empty.png | Bin 0 -> 4269 bytes .../expected_composermap_annotation_item.png | Bin 0 -> 4362 bytes 4 files changed, 59 insertions(+), 1 deletion(-) create mode 100644 tests/testdata/control_images/composer_map/expected_composermap_annotation_empty/expected_composermap_annotation_empty.png create mode 100644 tests/testdata/control_images/composer_map/expected_composermap_annotation_item/expected_composermap_annotation_item.png diff --git a/src/core/layout/qgslayoutitemmap.cpp b/src/core/layout/qgslayoutitemmap.cpp index 89f9044e0e5..fc7b13a6446 100644 --- a/src/core/layout/qgslayoutitemmap.cpp +++ b/src/core/layout/qgslayoutitemmap.cpp @@ -33,6 +33,7 @@ #include "qgsapplication.h" #include "qgsexpressioncontextutils.h" #include "qgsstyleentityvisitor.h" +#include "qgsannotationlayer.h" #include #include @@ -1467,6 +1468,10 @@ QgsMapSettings QgsLayoutItemMap::mapSettings( const QgsRectangle &extent, QSizeF { //set layers to render QList layers = layersToRender( &expressionContext ); + + // render main annotation layer above all other layers + layers.insert( 0, mLayout->project()->mainAnnotationLayer() ); + jobMapSettings.setLayers( layers ); jobMapSettings.setLayerStyleOverrides( layerStyleOverridesToRender( expressionContext ) ); } diff --git a/tests/src/python/test_qgslayoutmap.py b/tests/src/python/test_qgslayoutmap.py index 58c3662103f..6544ac2078d 100644 --- a/tests/src/python/test_qgslayoutmap.py +++ b/tests/src/python/test_qgslayoutmap.py @@ -46,7 +46,8 @@ from qgis.core import (QgsLayoutItemMap, QgsGeometry, QgsLayoutItemShape, QgsMapClippingRegion, - QgsLayoutItemMapOverview) + QgsLayoutItemMapOverview, + QgsAnnotationPolygonItem) from qgis.testing import start_app, unittest from utilities import unitTestDataPath @@ -769,6 +770,58 @@ class TestQgsLayoutMap(unittest.TestCase, LayoutItemTestCase): TestQgsLayoutMap.report += checker.report() self.assertTrue(result, message) + def testMainAnnotationLayer(self): + """ + Make sure main annotation layer is rendered in maps above all other layers + """ + p = QgsProject() + + vl = QgsVectorLayer("Polygon?crs=epsg:4326&field=fldtxt:string", + "layer", "memory") + sym3 = QgsFillSymbol.createSimple({'color': '#b200b2'}) + vl.renderer().setSymbol(sym3) + + p.addMapLayer(vl) + layout = QgsLayout(p) + layout.initializeDefaults() + p.setCrs(QgsCoordinateReferenceSystem('EPSG:4326')) + map = QgsLayoutItemMap(layout) + map.attemptSetSceneRect(QRectF(10, 10, 180, 180)) + map.setFrameEnabled(True) + map.setFrameStrokeWidth(QgsLayoutMeasurement(2, QgsUnitTypes.LayoutMillimeters)) + map.setBackgroundEnabled(True) + map.setBackgroundColor(QColor(200, 255, 200)) + map.zoomToExtent(QgsRectangle(10, 30, 20, 35)) + map.setLayers([vl]) + layout.addLayoutItem(map) + + # add polygon to layer + f = QgsFeature() + f.setGeometry(QgsGeometry.fromRect(QgsRectangle(5, 25, 25, 45))) + self.assertTrue(vl.dataProvider().addFeatures([f])) + + # no annotation yet... + checker = QgsLayoutChecker('composermap_annotation_empty', layout) + checker.setControlPathPrefix("composer_map") + result, message = checker.testLayout() + TestQgsLayoutMap.report += checker.report() + self.assertTrue(result, message) + + annotation_layer = p.mainAnnotationLayer() + annotation_layer.setCrs(QgsCoordinateReferenceSystem(4326)) + annotation_geom = QgsGeometry.fromRect(QgsRectangle(12, 30, 18, 33)) + annotation = QgsAnnotationPolygonItem(annotation_geom.constGet().clone()) + sym3 = QgsFillSymbol.createSimple({'color': '#ff0000', 'outline_style': 'no'}) + annotation.setSymbol(sym3) + annotation_layer.addItem(annotation) + + # annotation must be drawn above map layers + checker = QgsLayoutChecker('composermap_annotation_item', layout) + checker.setControlPathPrefix("composer_map") + result, message = checker.testLayout() + TestQgsLayoutMap.report += checker.report() + self.assertTrue(result, message) + if __name__ == '__main__': unittest.main() diff --git a/tests/testdata/control_images/composer_map/expected_composermap_annotation_empty/expected_composermap_annotation_empty.png b/tests/testdata/control_images/composer_map/expected_composermap_annotation_empty/expected_composermap_annotation_empty.png new file mode 100644 index 0000000000000000000000000000000000000000..cfd804bc3f91eebdcfeb55a523e8f94930a3b9af GIT binary patch literal 4269 zcmeAS@N?(olHy`uVBq!ia0y~yU`b+NV3y)w0*W}bm%jp1oCO|{#S9F5he4R}c>anM z1_pt6PZ!6KiaBrZ9Lzjyz|a=BGiANc1H+1J1!%MpCj)~*iVy>X!vHG0 zbIvj?a#}GT6T`a9+uNRhwyb775Pb)~OD$eHe+a*}@tiCJ!=GKXZ#Jtl{5f&PC+hew ziT+MzhKBtLlNANFlX>|^>bP0l+XkK5p%5% literal 0 HcmV?d00001 diff --git a/tests/testdata/control_images/composer_map/expected_composermap_annotation_item/expected_composermap_annotation_item.png b/tests/testdata/control_images/composer_map/expected_composermap_annotation_item/expected_composermap_annotation_item.png new file mode 100644 index 0000000000000000000000000000000000000000..6c4a4a21ddae4eabeb6d7b8199c73ecd22e3ed09 GIT binary patch literal 4362 zcmeAS@N?(olHy`uVBq!ia0y~yU`b+NV3y)w0*W}bm%jp1oCO|{#S9F5he4R}c>anM z1_psWo-U3d6?5L+G3*j{kZ5~oKk3jZuMGk^IcseW&QnmRU`~8}$K{)zWoPfyN1QGZ zN6f;+^p$i9&mMVNsb>)X+vspk-|@#l!#|u}e3cnU>vj78t>l==0yNu*lYv1YMTmjH z;e-kUL&F45puFN_AmOCO$iUDta0-unvpJq)Hv6*-3q#DZzjgJ+#ha^G56s=+i`VIe z%lHrePch%Um6@TTx_rjrSDXy>si|sj)5>kHbF(ur{BQDM`d2P@cVPWCfWbOy^3g8Tea#lG2`?tf{npAHJT! z;_mWF?a2%~^hYa