Пример #1
0
 def testOverviewMapBlend(self):
     overviewMap = QgsLayoutItemMap(self.layout)
     overviewMap.attemptSetSceneRect(QRectF(20, 130, 70, 70))
     overviewMap.setFrameEnabled(True)
     overviewMap.setLayers([self.raster_layer])
     self.layout.addLayoutItem(overviewMap)
     # zoom in
     myRectangle = QgsRectangle(96, -152, 160, -120)
     self.map.setExtent(myRectangle)
     myRectangle2 = QgsRectangle(0, -256, 256, 0)
     overviewMap.setExtent(myRectangle2)
     overviewMap.overview().setFrameMap(self.map)
     overviewMap.overview().setBlendMode(QPainter.CompositionMode_Multiply)
     checker = QgsLayoutChecker('composermap_overview_blending', self.layout)
     checker.setControlPathPrefix("composer_mapoverview")
     myTestResult, myMessage = checker.testLayout()
     self.layout.removeLayoutItem(overviewMap)
     assert myTestResult, myMessage
Пример #2
0
 def testOverviewMap(self):
     overviewMap = QgsLayoutItemMap(self.layout)
     overviewMap.attemptSetSceneRect(QRectF(20, 130, 70, 70))
     overviewMap.setFrameEnabled(True)
     overviewMap.setLayers([self.raster_layer])
     self.layout.addLayoutItem(overviewMap)
     # zoom in
     myRectangle = QgsRectangle(96, -152, 160, -120)
     self.map.setExtent(myRectangle)
     myRectangle2 = QgsRectangle(0, -256, 256, 0)
     overviewMap.setExtent(myRectangle2)
     overviewMap.overview().setLinkedMap(self.map)
     checker = QgsLayoutChecker('composermap_overview', self.layout)
     checker.setColorTolerance(6)
     checker.setControlPathPrefix("composer_mapoverview")
     myTestResult, myMessage = checker.testLayout()
     self.report += checker.report()
     self.layout.removeLayoutItem(overviewMap)
     assert myTestResult, myMessage
Пример #3
0
    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)
Пример #4
0
 def testOverviewMapCenter(self):
     overviewMap = QgsLayoutItemMap(self.layout)
     overviewMap.attemptSetSceneRect(QRectF(20, 130, 70, 70))
     overviewMap.setFrameEnabled(True)
     overviewMap.setLayers([self.raster_layer])
     self.layout.addLayoutItem(overviewMap)
     # zoom in
     myRectangle = QgsRectangle(192, -288, 320, -224)
     self.map.setExtent(myRectangle)
     myRectangle2 = QgsRectangle(0, -256, 256, 0)
     overviewMap.setExtent(myRectangle2)
     overviewMap.overview().setFrameMap(self.map)
     overviewMap.overview().setInverted(False)
     overviewMap.overview().setCentered(True)
     checker = QgsLayoutChecker('composermap_overview_center', self.layout)
     checker.setControlPathPrefix("composer_mapoverview")
     myTestResult, myMessage = checker.testLayout()
     self.layout.removeLayoutItem(overviewMap)
     assert myTestResult, myMessage
Пример #5
0
class TestQgsLayoutAtlas(unittest.TestCase):

    def setUp(self):
        self.report = "<h1>Python QgsLayoutAtlas Tests</h1>\n"

    def tearDown(self):
        report_file_path = "%s/qgistest.html" % QDir.tempPath()
        with open(report_file_path, 'a') as report_file:
            report_file.write(self.report)

    def testCase(self):
        self.TEST_DATA_DIR = unitTestDataPath()
        tmppath = tempfile.mkdtemp()
        for file in glob.glob(os.path.join(self.TEST_DATA_DIR, 'france_parts.*')):
            shutil.copy(os.path.join(self.TEST_DATA_DIR, file), tmppath)
        vectorFileInfo = QFileInfo(tmppath + "/france_parts.shp")
        mVectorLayer = QgsVectorLayer(vectorFileInfo.filePath(), vectorFileInfo.completeBaseName(), "ogr")

        QgsProject.instance().addMapLayers([mVectorLayer])
        self.layers = [mVectorLayer]

        # create layout with layout map

        # select epsg:2154
        crs = QgsCoordinateReferenceSystem()
        crs.createFromSrid(2154)
        QgsProject.instance().setCrs(crs)

        self.layout = QgsPrintLayout(QgsProject.instance())
        self.layout.initializeDefaults()

        # fix the renderer, fill with green
        props = {"color": "0,127,0", 'outline_color': 'black'}
        fillSymbol = QgsFillSymbol.createSimple(props)
        renderer = QgsSingleSymbolRenderer(fillSymbol)
        mVectorLayer.setRenderer(renderer)

        # the atlas map
        self.atlas_map = QgsLayoutItemMap(self.layout)
        self.atlas_map.attemptSetSceneRect(QRectF(20, 20, 130, 130))
        self.atlas_map.setFrameEnabled(True)
        self.atlas_map.setLayers([mVectorLayer])
        self.layout.addLayoutItem(self.atlas_map)

        # the atlas
        self.atlas = self.layout.atlas()
        self.atlas.setCoverageLayer(mVectorLayer)
        self.atlas.setEnabled(True)

        # an overview
        self.overview = QgsLayoutItemMap(self.layout)
        self.overview.attemptSetSceneRect(QRectF(180, 20, 50, 50))
        self.overview.setFrameEnabled(True)
        self.overview.overview().setLinkedMap(self.atlas_map)
        self.overview.setLayers([mVectorLayer])
        self.layout.addLayoutItem(self.overview)
        nextent = QgsRectangle(49670.718, 6415139.086, 699672.519, 7065140.887)
        self.overview.setExtent(nextent)

        # set the fill symbol of the overview map
        props2 = {"color": "127,0,0,127", 'outline_color': 'black'}
        fillSymbol2 = QgsFillSymbol.createSimple(props2)
        self.overview.overview().setFrameSymbol(fillSymbol2)

        # header label
        self.mLabel1 = QgsLayoutItemLabel(self.layout)
        self.layout.addLayoutItem(self.mLabel1)
        self.mLabel1.setText("[% \"NAME_1\" %] area")
        self.mLabel1.setFont(QgsFontUtils.getStandardTestFont())
        self.mLabel1.adjustSizeToText()
        self.mLabel1.attemptSetSceneRect(QRectF(150, 5, 60, 15))
        self.mLabel1.setMarginX(1)
        self.mLabel1.setMarginY(1)

        # feature number label
        self.mLabel2 = QgsLayoutItemLabel(self.layout)
        self.layout.addLayoutItem(self.mLabel2)
        self.mLabel2.setText("# [%@atlas_featurenumber || ' / ' || @atlas_totalfeatures%]")
        self.mLabel2.setFont(QgsFontUtils.getStandardTestFont())
        self.mLabel2.adjustSizeToText()
        self.mLabel2.attemptSetSceneRect(QRectF(150, 200, 60, 15))
        self.mLabel2.setMarginX(1)
        self.mLabel2.setMarginY(1)

        self.filename_test()
        self.autoscale_render_test()
        self.fixedscale_render_test()
        self.predefinedscales_render_test()
        self.hidden_render_test()
        self.legend_test()
        self.rotation_test()

        shutil.rmtree(tmppath, True)

    def testReadWriteXml(self):
        p = QgsProject()
        vectorFileInfo = QFileInfo(unitTestDataPath() + "/france_parts.shp")
        vector_layer = QgsVectorLayer(vectorFileInfo.filePath(), vectorFileInfo.completeBaseName(), "ogr")
        self.assertTrue(vector_layer.isValid())
        p.addMapLayer(vector_layer)

        l = QgsPrintLayout(p)
        atlas = l.atlas()
        atlas.setEnabled(True)
        atlas.setHideCoverage(True)
        atlas.setFilenameExpression('filename exp')
        atlas.setCoverageLayer(vector_layer)
        atlas.setPageNameExpression('page name')
        atlas.setSortFeatures(True)
        atlas.setSortAscending(False)
        atlas.setSortExpression('sort exp')
        atlas.setFilterFeatures(True)
        atlas.setFilterExpression('filter exp')

        doc = QDomDocument("testdoc")
        elem = l.writeXml(doc, QgsReadWriteContext())

        l2 = QgsPrintLayout(p)
        self.assertTrue(l2.readXml(elem, doc, QgsReadWriteContext()))
        atlas2 = l2.atlas()
        self.assertTrue(atlas2.enabled())
        self.assertTrue(atlas2.hideCoverage())
        self.assertEqual(atlas2.filenameExpression(), 'filename exp')
        self.assertEqual(atlas2.coverageLayer(), vector_layer)
        self.assertEqual(atlas2.pageNameExpression(), 'page name')
        self.assertTrue(atlas2.sortFeatures())
        self.assertFalse(atlas2.sortAscending())
        self.assertEqual(atlas2.sortExpression(), 'sort exp')
        self.assertTrue(atlas2.filterFeatures())
        self.assertEqual(atlas2.filterExpression(), 'filter exp')

    def testIteration(self):
        p = QgsProject()
        vectorFileInfo = QFileInfo(unitTestDataPath() + "/france_parts.shp")
        vector_layer = QgsVectorLayer(vectorFileInfo.filePath(), vectorFileInfo.completeBaseName(), "ogr")
        self.assertTrue(vector_layer.isValid())
        p.addMapLayer(vector_layer)

        l = QgsPrintLayout(p)
        atlas = l.atlas()
        atlas.setEnabled(True)
        atlas.setCoverageLayer(vector_layer)

        atlas_feature_changed_spy = QSignalSpy(atlas.featureChanged)
        context_changed_spy = QSignalSpy(l.reportContext().changed)

        self.assertTrue(atlas.beginRender())
        self.assertTrue(atlas.first())
        self.assertEqual(len(atlas_feature_changed_spy), 1)
        self.assertEqual(len(context_changed_spy), 1)
        self.assertEqual(atlas.currentFeatureNumber(), 0)
        self.assertEqual(l.reportContext().feature()[4], 'Basse-Normandie')
        self.assertEqual(l.reportContext().layer(), vector_layer)
        f1 = l.reportContext().feature()

        self.assertTrue(atlas.next())
        self.assertEqual(len(atlas_feature_changed_spy), 2)
        self.assertEqual(len(context_changed_spy), 2)
        self.assertEqual(atlas.currentFeatureNumber(), 1)
        self.assertEqual(l.reportContext().feature()[4], 'Bretagne')
        f2 = l.reportContext().feature()

        self.assertTrue(atlas.next())
        self.assertEqual(len(atlas_feature_changed_spy), 3)
        self.assertEqual(len(context_changed_spy), 3)
        self.assertEqual(atlas.currentFeatureNumber(), 2)
        self.assertEqual(l.reportContext().feature()[4], 'Pays de la Loire')
        f3 = l.reportContext().feature()

        self.assertTrue(atlas.next())
        self.assertEqual(len(atlas_feature_changed_spy), 4)
        self.assertEqual(len(context_changed_spy), 4)
        self.assertEqual(atlas.currentFeatureNumber(), 3)
        self.assertEqual(l.reportContext().feature()[4], 'Centre')
        f4 = l.reportContext().feature()

        self.assertFalse(atlas.next())
        self.assertTrue(atlas.seekTo(2))
        self.assertEqual(len(atlas_feature_changed_spy), 5)
        self.assertEqual(len(context_changed_spy), 5)
        self.assertEqual(atlas.currentFeatureNumber(), 2)
        self.assertEqual(l.reportContext().feature()[4], 'Pays de la Loire')

        self.assertTrue(atlas.last())
        self.assertEqual(len(atlas_feature_changed_spy), 6)
        self.assertEqual(len(context_changed_spy), 6)
        self.assertEqual(atlas.currentFeatureNumber(), 3)
        self.assertEqual(l.reportContext().feature()[4], 'Centre')

        self.assertTrue(atlas.previous())
        self.assertEqual(len(atlas_feature_changed_spy), 7)
        self.assertEqual(len(context_changed_spy), 7)
        self.assertEqual(atlas.currentFeatureNumber(), 2)
        self.assertEqual(l.reportContext().feature()[4], 'Pays de la Loire')

        self.assertTrue(atlas.previous())
        self.assertTrue(atlas.previous())
        self.assertEqual(len(atlas_feature_changed_spy), 9)
        self.assertFalse(atlas.previous())
        self.assertEqual(len(atlas_feature_changed_spy), 9)

        self.assertTrue(atlas.endRender())
        self.assertEqual(len(atlas_feature_changed_spy), 10)

        self.assertTrue(atlas.seekTo(f1))
        self.assertEqual(l.reportContext().feature()[4], 'Basse-Normandie')
        self.assertTrue(atlas.seekTo(f4))
        self.assertEqual(l.reportContext().feature()[4], 'Centre')
        self.assertTrue(atlas.seekTo(f3))
        self.assertEqual(l.reportContext().feature()[4], 'Pays de la Loire')
        self.assertTrue(atlas.seekTo(f2))
        self.assertEqual(l.reportContext().feature()[4], 'Bretagne')
        self.assertFalse(atlas.seekTo(QgsFeature(5)))

    def testUpdateFeature(self):
        p = QgsProject()
        vectorFileInfo = QFileInfo(unitTestDataPath() + "/france_parts.shp")
        vector_layer = QgsVectorLayer(vectorFileInfo.filePath(), vectorFileInfo.completeBaseName(), "ogr")
        self.assertTrue(vector_layer.isValid())
        p.addMapLayer(vector_layer)

        l = QgsPrintLayout(p)
        atlas = l.atlas()
        atlas.setEnabled(True)
        atlas.setCoverageLayer(vector_layer)

        self.assertTrue(atlas.beginRender())
        self.assertTrue(atlas.first())
        self.assertEqual(atlas.currentFeatureNumber(), 0)
        self.assertEqual(l.reportContext().feature()[4], 'Basse-Normandie')
        self.assertEqual(l.reportContext().layer(), vector_layer)

        vector_layer.startEditing()
        self.assertTrue(vector_layer.changeAttributeValue(l.reportContext().feature().id(), 4, 'Nah, Canberra mate!'))
        self.assertEqual(l.reportContext().feature()[4], 'Basse-Normandie')
        l.atlas().refreshCurrentFeature()
        self.assertEqual(l.reportContext().feature()[4], 'Nah, Canberra mate!')
        vector_layer.rollBack()

    def testFileName(self):
        p = QgsProject()
        vectorFileInfo = QFileInfo(unitTestDataPath() + "/france_parts.shp")
        vector_layer = QgsVectorLayer(vectorFileInfo.filePath(), vectorFileInfo.completeBaseName(), "ogr")
        self.assertTrue(vector_layer.isValid())
        p.addMapLayer(vector_layer)

        l = QgsPrintLayout(p)
        atlas = l.atlas()
        atlas.setEnabled(True)
        atlas.setCoverageLayer(vector_layer)
        atlas.setFilenameExpression("'output_' || \"NAME_1\"")

        self.assertTrue(atlas.beginRender())
        self.assertEqual(atlas.count(), 4)
        atlas.first()
        self.assertEqual(atlas.currentFilename(), 'output_Basse-Normandie')
        self.assertEqual(atlas.filePath('/tmp/output/', 'png'), '/tmp/output/output_Basse-Normandie.png')
        self.assertEqual(atlas.filePath('/tmp/output/', '.png'), '/tmp/output/output_Basse-Normandie.png')
        self.assertEqual(atlas.filePath('/tmp/output/', 'svg'), '/tmp/output/output_Basse-Normandie.svg')

        atlas.next()
        self.assertEqual(atlas.currentFilename(), 'output_Bretagne')
        self.assertEqual(atlas.filePath('/tmp/output/', 'png'), '/tmp/output/output_Bretagne.png')
        atlas.next()
        self.assertEqual(atlas.currentFilename(), 'output_Pays de la Loire')
        self.assertEqual(atlas.filePath('/tmp/output/', 'png'), '/tmp/output/output_Pays de la Loire.png')
        atlas.next()
        self.assertEqual(atlas.currentFilename(), 'output_Centre')
        self.assertEqual(atlas.filePath('/tmp/output/', 'png'), '/tmp/output/output_Centre.png')

        # try changing expression, filename should be updated instantly
        atlas.setFilenameExpression("'export_' || \"NAME_1\"")
        self.assertEqual(atlas.currentFilename(), 'export_Centre')

        atlas.endRender()

    def testNameForPage(self):
        p = QgsProject()
        vectorFileInfo = QFileInfo(unitTestDataPath() + "/france_parts.shp")
        vector_layer = QgsVectorLayer(vectorFileInfo.filePath(), vectorFileInfo.completeBaseName(), "ogr")
        self.assertTrue(vector_layer.isValid())
        p.addMapLayer(vector_layer)

        l = QgsPrintLayout(p)
        atlas = l.atlas()
        atlas.setEnabled(True)
        atlas.setCoverageLayer(vector_layer)
        atlas.setPageNameExpression("\"NAME_1\"")

        self.assertTrue(atlas.beginRender())
        self.assertEqual(atlas.nameForPage(0), 'Basse-Normandie')
        self.assertEqual(atlas.nameForPage(1), 'Bretagne')
        self.assertEqual(atlas.nameForPage(2), 'Pays de la Loire')
        self.assertEqual(atlas.nameForPage(3), 'Centre')

    def filename_test(self):
        self.atlas.setFilenameExpression("'output_' || @atlas_featurenumber")
        self.atlas.beginRender()
        for i in range(0, self.atlas.count()):
            self.atlas.seekTo(i)
            expected = "output_%d" % (i + 1)
            self.assertEqual(self.atlas.currentFilename(), expected)
        self.atlas.endRender()

    def autoscale_render_test(self):
        self.atlas_map.setExtent(
            QgsRectangle(332719.06221504929, 6765214.5887386119, 560957.85090677091, 6993453.3774303338))

        self.atlas_map.setAtlasDriven(True)
        self.atlas_map.setAtlasScalingMode(QgsLayoutItemMap.Auto)
        self.atlas_map.setAtlasMargin(0.10)

        self.atlas.beginRender()

        for i in range(0, 2):
            self.atlas.seekTo(i)
            self.mLabel1.adjustSizeToText()

            checker = QgsLayoutChecker('atlas_autoscale%d' % (i + 1), self.layout)
            checker.setControlPathPrefix("atlas")
            myTestResult, myMessage = checker.testLayout(0, 200)
            self.report += checker.report()

            self.assertTrue(myTestResult, myMessage)
        self.atlas.endRender()

        self.atlas_map.setAtlasDriven(False)
        self.atlas_map.setAtlasScalingMode(QgsLayoutItemMap.Fixed)
        self.atlas_map.setAtlasMargin(0)

    def fixedscale_render_test(self):
        self.atlas_map.setExtent(QgsRectangle(209838.166, 6528781.020, 610491.166, 6920530.620))
        self.atlas_map.setAtlasDriven(True)
        self.atlas_map.setAtlasScalingMode(QgsLayoutItemMap.Fixed)

        self.atlas.beginRender()

        for i in range(0, 2):
            self.atlas.seekTo(i)
            self.mLabel1.adjustSizeToText()

            checker = QgsLayoutChecker('atlas_fixedscale%d' % (i + 1), self.layout)
            checker.setControlPathPrefix("atlas")
            myTestResult, myMessage = checker.testLayout(0, 200)
            self.report += checker.report()

            self.assertTrue(myTestResult, myMessage)
        self.atlas.endRender()

    def predefinedscales_render_test(self):
        self.atlas_map.setExtent(QgsRectangle(209838.166, 6528781.020, 610491.166, 6920530.620))
        self.atlas_map.setAtlasDriven(True)
        self.atlas_map.setAtlasScalingMode(QgsLayoutItemMap.Predefined)

        scales = [1800000, 5000000]
        self.layout.reportContext().setPredefinedScales(scales)
        for i, s in enumerate(self.layout.reportContext().predefinedScales()):
            self.assertEqual(s, scales[i])

        self.atlas.beginRender()

        for i in range(0, 2):
            self.atlas.seekTo(i)
            self.mLabel1.adjustSizeToText()

            checker = QgsLayoutChecker('atlas_predefinedscales%d' % (i + 1), self.layout)
            checker.setControlPathPrefix("atlas")
            myTestResult, myMessage = checker.testLayout(0, 200)
            self.report += checker.report()

            self.assertTrue(myTestResult, myMessage)
        self.atlas.endRender()

    def hidden_render_test(self):
        self.atlas_map.setExtent(QgsRectangle(209838.166, 6528781.020, 610491.166, 6920530.620))
        self.atlas_map.setAtlasScalingMode(QgsLayoutItemMap.Fixed)
        self.atlas.setHideCoverage(True)

        self.atlas.beginRender()

        for i in range(0, 2):
            self.atlas.seekTo(i)
            self.mLabel1.adjustSizeToText()

            checker = QgsLayoutChecker('atlas_hiding%d' % (i + 1), self.layout)
            checker.setControlPathPrefix("atlas")
            myTestResult, myMessage = checker.testLayout(0, 200)
            self.report += checker.report()

            self.assertTrue(myTestResult, myMessage)
        self.atlas.endRender()

        self.atlas.setHideCoverage(False)

    def sorting_render_test(self):
        self.atlas_map.setExtent(QgsRectangle(209838.166, 6528781.020, 610491.166, 6920530.620))
        self.atlas_map.setAtlasScalingMode(QgsLayoutItemMap.Fixed)
        self.atlas.setHideCoverage(False)

        self.atlas.setSortFeatures(True)
        self.atlas.setSortKeyAttributeIndex(4)  # departement name
        self.atlas.setSortAscending(False)

        self.atlas.beginRender()

        for i in range(0, 2):
            self.atlas.seekTo(i)
            self.mLabel1.adjustSizeToText()

            checker = QgsLayoutChecker('atlas_sorting%d' % (i + 1), self.layout)
            checker.setControlPathPrefix("atlas")
            myTestResult, myMessage = checker.testLayout(0, 200)
            self.report += checker.report()

            self.assertTrue(myTestResult, myMessage)
        self.atlas.endRender()

    def filtering_render_test(self):
        self.atlas_map.setExtent(QgsRectangle(209838.166, 6528781.020, 610491.166, 6920530.620))
        self.atlas_map.setAtlasScalingMode(QgsLayoutItemMap.Fixed)
        self.atlas.setHideCoverage(False)

        self.atlas.setSortFeatures(False)

        self.atlas.setFilterFeatures(True)
        self.atlas.setFeatureFilter("substr(NAME_1,1,1)='P'")  # select only 'Pays de la loire'

        self.atlas.beginRender()

        for i in range(0, 1):
            self.atlas.seekTo(i)
            self.mLabel1.adjustSizeToText()

            checker = QgsLayoutChecker('atlas_filtering%d' % (i + 1), self.layout)
            checker.setControlPathPrefix("atlas")
            myTestResult, myMessage = checker.testLayout(0, 200)
            self.report += checker.report()

            self.assertTrue(myTestResult, myMessage)
        self.atlas.endRender()

    def legend_test(self):
        self.atlas_map.setAtlasDriven(True)
        self.atlas_map.setAtlasScalingMode(QgsLayoutItemMap.Auto)
        self.atlas_map.setAtlasMargin(0.10)

        # add a point layer
        ptLayer = QgsVectorLayer("Point?crs=epsg:4326&field=attr:int(1)&field=label:string(20)", "points", "memory")

        pr = ptLayer.dataProvider()
        f1 = QgsFeature(1)
        f1.initAttributes(2)
        f1.setAttribute(0, 1)
        f1.setAttribute(1, "Test label 1")
        f1.setGeometry(QgsGeometry.fromPointXY(QgsPointXY(-0.638, 48.954)))
        f2 = QgsFeature(2)
        f2.initAttributes(2)
        f2.setAttribute(0, 2)
        f2.setAttribute(1, "Test label 2")
        f2.setGeometry(QgsGeometry.fromPointXY(QgsPointXY(-1.682, 48.550)))
        pr.addFeatures([f1, f2])

        # categorized symbology
        r = QgsCategorizedSymbolRenderer("attr", [QgsRendererCategory(1, QgsMarkerSymbol.createSimple({"color": "255,0,0", 'outline_color': 'black'}), "red"),
                                                  QgsRendererCategory(2, QgsMarkerSymbol.createSimple({"color": "0,0,255", 'outline_color': 'black'}), "blue")])
        ptLayer.setRenderer(r)

        QgsProject.instance().addMapLayer(ptLayer)

        # add the point layer to the map settings
        layers = self.layers
        layers = [ptLayer] + layers
        self.atlas_map.setLayers(layers)
        self.overview.setLayers(layers)

        # add a legend
        legend = QgsLayoutItemLegend(self.layout)
        legend.attemptMove(QgsLayoutPoint(200, 100))
        # sets the legend filter parameter
        legend.setLinkedMap(self.atlas_map)
        legend.setLegendFilterOutAtlas(True)
        self.layout.addLayoutItem(legend)

        self.atlas.beginRender()

        self.atlas.seekTo(0)
        self.mLabel1.adjustSizeToText()

        checker = QgsLayoutChecker('atlas_legend', self.layout)
        myTestResult, myMessage = checker.testLayout()
        self.report += checker.report()
        self.assertTrue(myTestResult, myMessage)

        self.atlas.endRender()

        # restore state
        self.atlas_map.setLayers([layers[1]])
        self.layout.removeLayoutItem(legend)
        QgsProject.instance().removeMapLayer(ptLayer.id())

    def rotation_test(self):
        # We will create a polygon layer with a rotated rectangle.
        # Then we will make it the object layer for the atlas,
        # rotate the map and test that the bounding rectangle
        # is smaller than the bounds without rotation.
        polygonLayer = QgsVectorLayer('Polygon', 'test_polygon', 'memory')
        poly = QgsFeature(polygonLayer.fields())
        points = [(10, 15), (15, 10), (45, 40), (40, 45)]
        poly.setGeometry(QgsGeometry.fromPolygonXY([[QgsPointXY(x[0], x[1]) for x in points]]))
        polygonLayer.dataProvider().addFeatures([poly])
        QgsProject.instance().addMapLayer(polygonLayer)

        # Recreating the layout locally
        composition = QgsPrintLayout(QgsProject.instance())
        composition.initializeDefaults()

        # the atlas map
        atlasMap = QgsLayoutItemMap(composition)
        atlasMap.attemptSetSceneRect(QRectF(20, 20, 130, 130))
        atlasMap.setFrameEnabled(True)
        atlasMap.setLayers([polygonLayer])
        atlasMap.setExtent(QgsRectangle(0, 0, 100, 50))
        composition.addLayoutItem(atlasMap)

        # the atlas
        atlas = composition.atlas()
        atlas.setCoverageLayer(polygonLayer)
        atlas.setEnabled(True)

        atlasMap.setAtlasDriven(True)
        atlasMap.setAtlasScalingMode(QgsLayoutItemMap.Auto)
        atlasMap.setAtlasMargin(0.0)

        # Testing
        atlasMap.setMapRotation(0.0)
        atlas.beginRender()
        atlas.first()
        nonRotatedExtent = QgsRectangle(atlasMap.extent())

        atlasMap.setMapRotation(45.0)
        atlas.first()
        rotatedExtent = QgsRectangle(atlasMap.extent())

        self.assertLess(rotatedExtent.width(), nonRotatedExtent.width() * 0.9)
        self.assertLess(rotatedExtent.height(), nonRotatedExtent.height() * 0.9)

        QgsProject.instance().removeMapLayer(polygonLayer)
Пример #6
0
    def test_StackingPosition(self):
        l = QgsLayout(QgsProject.instance())
        l.initializeDefaults()

        overviewMap = QgsLayoutItemMap(l)
        overviewMap.attemptSetSceneRect(QRectF(20, 130, 70, 70))
        l.addLayoutItem(overviewMap)
        overviewMap.overview().setStackingPosition(QgsLayoutItemMapItem.StackBelowMap)
        self.assertEqual(overviewMap.overview().stackingPosition(), QgsLayoutItemMapItem.StackBelowMap)
        overviewMap.overview().setStackingPosition(QgsLayoutItemMapItem.StackBelowMapLayer)
        self.assertEqual(overviewMap.overview().stackingPosition(), QgsLayoutItemMapItem.StackBelowMapLayer)

        overviewMap.overview().setStackingLayer(self.raster_layer)
        self.assertEqual(overviewMap.overview().stackingLayer(), self.raster_layer)
        overviewMap.overview().setStackingLayer(self.vector_layer)
        self.assertEqual(overviewMap.overview().stackingLayer(), self.vector_layer)
        overviewMap.overview().setStackingLayer(None)
        self.assertIsNone(overviewMap.overview().stackingLayer())
Пример #7
0
    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()])
Пример #8
0
    def testAsMapLayer(self):
        l = QgsLayout(QgsProject.instance())
        l.initializeDefaults()
        map = QgsLayoutItemMap(l)
        map.attemptSetSceneRect(QRectF(20, 20, 200, 100))
        l.addLayoutItem(map)

        overviewMap = QgsLayoutItemMap(l)
        overviewMap.attemptSetSceneRect(QRectF(20, 130, 70, 70))
        l.addLayoutItem(overviewMap)
        # zoom in
        myRectangle = QgsRectangle(96, -152, 160, -120)
        map.setExtent(myRectangle)
        myRectangle2 = QgsRectangle(0, -256, 256, 0)
        overviewMap.setExtent(myRectangle2)
        overviewMap.overview().setLinkedMap(map)

        layer = overviewMap.overview().asMapLayer()
        self.assertIsNotNone(layer)
        self.assertTrue(layer.isValid())
        self.assertEqual([f.geometry().asWkt() for f in layer.getFeatures()], ['Polygon ((96 -120, 160 -120, 160 -152, 96 -152, 96 -120))'])

        # check that layer has correct renderer
        fill_symbol = QgsFillSymbol.createSimple({'color': '#00ff00', 'outline_color': '#ff0000', 'outline_width': '10'})
        overviewMap.overview().setFrameSymbol(fill_symbol)
        layer = overviewMap.overview().asMapLayer()
        self.assertIsInstance(layer.renderer(), QgsSingleSymbolRenderer)
        self.assertEqual(layer.renderer().symbol().symbolLayer(0).properties()['color'], '0,255,0,255')
        self.assertEqual(layer.renderer().symbol().symbolLayer(0).properties()['outline_color'], '255,0,0,255')

        # test layer blend mode
        self.assertEqual(layer.blendMode(), QPainter.CompositionMode_SourceOver)
        overviewMap.overview().setBlendMode(QPainter.CompositionMode_Clear)
        layer = overviewMap.overview().asMapLayer()
        self.assertEqual(layer.blendMode(), QPainter.CompositionMode_Clear)

        # should have no effect
        overviewMap.setMapRotation(45)
        layer = overviewMap.overview().asMapLayer()
        self.assertEqual([f.geometry().asWkt() for f in layer.getFeatures()], ['Polygon ((96 -120, 160 -120, 160 -152, 96 -152, 96 -120))'])

        map.setMapRotation(15)
        layer = overviewMap.overview().asMapLayer()
        self.assertEqual([f.geometry().asWkt(0) for f in layer.getFeatures()], ['Polygon ((93 -129, 155 -112, 163 -143, 101 -160, 93 -129))'])

        # with reprojection
        map.setCrs(QgsCoordinateReferenceSystem('EPSG:3875'))
        layer = overviewMap.overview().asMapLayer()
        self.assertEqual([f.geometry().asWkt(0) for f in layer.getFeatures()], ['Polygon ((93 -129, 96 -128, 99 -127, 102 -126, 105 -126, 108 -125, 111 -124, 114 -123, 116 -123, 119 -122, 122 -121, 125 -120, 128 -119, 131 -119, 134 -118, 137 -117, 140 -116, 143 -115, 146 -115, 149 -114, 152 -113, 155 -112, 155 -114, 156 -115, 156 -117, 156 -118, 157 -120, 157 -121, 158 -123, 158 -124, 158 -126, 159 -127, 159 -128, 160 -130, 160 -131, 160 -133, 161 -134, 161 -136, 161 -137, 162 -139, 162 -140, 163 -142, 163 -143, 160 -144, 157 -145, 154 -146, 151 -146, 148 -147, 145 -148, 142 -149, 140 -149, 137 -150, 134 -151, 131 -152, 128 -153, 125 -153, 122 -154, 119 -155, 116 -156, 113 -157, 110 -157, 107 -158, 104 -159, 101 -160, 101 -158, 100 -157, 100 -155, 100 -154, 99 -152, 99 -151, 98 -149, 98 -148, 98 -146, 97 -145, 97 -144, 96 -142, 96 -141, 96 -139, 95 -138, 95 -136, 95 -135, 94 -133, 94 -132, 93 -130, 93 -129))'])

        map.setCrs(overviewMap.crs())
        # with invert
        overviewMap.overview().setInverted(True)
        layer = overviewMap.overview().asMapLayer()
        self.assertEqual([f.geometry().asWkt(0) for f in layer.getFeatures()], ['Polygon ((-53 -128, 128 53, 309 -128, 128 -309, -53 -128),(93 -129, 101 -160, 163 -143, 155 -112, 93 -129))'])
Пример #9
0
class TestQgsLayoutAtlas(unittest.TestCase):
    def setUp(self):
        self.report = "<h1>Python QgsLayoutAtlas Tests</h1>\n"

    def tearDown(self):
        report_file_path = "%s/qgistest.html" % QDir.tempPath()
        with open(report_file_path, 'a') as report_file:
            report_file.write(self.report)

    def testCase(self):
        self.TEST_DATA_DIR = unitTestDataPath()
        tmppath = tempfile.mkdtemp()
        for file in glob.glob(
                os.path.join(self.TEST_DATA_DIR, 'france_parts.*')):
            shutil.copy(os.path.join(self.TEST_DATA_DIR, file), tmppath)
        vectorFileInfo = QFileInfo(tmppath + "/france_parts.shp")
        mVectorLayer = QgsVectorLayer(vectorFileInfo.filePath(),
                                      vectorFileInfo.completeBaseName(), "ogr")

        QgsProject.instance().addMapLayers([mVectorLayer])
        self.layers = [mVectorLayer]

        # create layout with layout map

        # select epsg:2154
        crs = QgsCoordinateReferenceSystem()
        crs.createFromSrid(2154)
        QgsProject.instance().setCrs(crs)

        self.layout = QgsPrintLayout(QgsProject.instance())
        self.layout.initializeDefaults()

        # fix the renderer, fill with green
        props = {"color": "0,127,0", 'outline_color': 'black'}
        fillSymbol = QgsFillSymbol.createSimple(props)
        renderer = QgsSingleSymbolRenderer(fillSymbol)
        mVectorLayer.setRenderer(renderer)

        # the atlas map
        self.atlas_map = QgsLayoutItemMap(self.layout)
        self.atlas_map.attemptSetSceneRect(QRectF(20, 20, 130, 130))
        self.atlas_map.setFrameEnabled(True)
        self.atlas_map.setLayers([mVectorLayer])
        self.layout.addLayoutItem(self.atlas_map)

        # the atlas
        self.atlas = self.layout.atlas()
        self.atlas.setCoverageLayer(mVectorLayer)
        self.atlas.setEnabled(True)

        # an overview
        self.overview = QgsLayoutItemMap(self.layout)
        self.overview.attemptSetSceneRect(QRectF(180, 20, 50, 50))
        self.overview.setFrameEnabled(True)
        self.overview.overview().setLinkedMap(self.atlas_map)
        self.overview.setLayers([mVectorLayer])
        self.layout.addLayoutItem(self.overview)
        nextent = QgsRectangle(49670.718, 6415139.086, 699672.519, 7065140.887)
        self.overview.setExtent(nextent)

        # set the fill symbol of the overview map
        props2 = {"color": "127,0,0,127", 'outline_color': 'black'}
        fillSymbol2 = QgsFillSymbol.createSimple(props2)
        self.overview.overview().setFrameSymbol(fillSymbol2)

        # header label
        self.mLabel1 = QgsLayoutItemLabel(self.layout)
        self.layout.addLayoutItem(self.mLabel1)
        self.mLabel1.setText("[% \"NAME_1\" %] area")
        self.mLabel1.setFont(QgsFontUtils.getStandardTestFont())
        self.mLabel1.adjustSizeToText()
        self.mLabel1.attemptSetSceneRect(QRectF(150, 5, 60, 15))
        self.mLabel1.setMarginX(1)
        self.mLabel1.setMarginY(1)

        # feature number label
        self.mLabel2 = QgsLayoutItemLabel(self.layout)
        self.layout.addLayoutItem(self.mLabel2)
        self.mLabel2.setText(
            "# [%@atlas_featurenumber || ' / ' || @atlas_totalfeatures%]")
        self.mLabel2.setFont(QgsFontUtils.getStandardTestFont())
        self.mLabel2.adjustSizeToText()
        self.mLabel2.attemptSetSceneRect(QRectF(150, 200, 60, 15))
        self.mLabel2.setMarginX(1)
        self.mLabel2.setMarginY(1)

        self.filename_test()
        self.autoscale_render_test()
        self.fixedscale_render_test()
        self.predefinedscales_render_test()
        self.hidden_render_test()
        self.legend_test()
        self.rotation_test()

        shutil.rmtree(tmppath, True)

    def testReadWriteXml(self):
        p = QgsProject()
        vectorFileInfo = QFileInfo(unitTestDataPath() + "/france_parts.shp")
        vector_layer = QgsVectorLayer(vectorFileInfo.filePath(),
                                      vectorFileInfo.completeBaseName(), "ogr")
        self.assertTrue(vector_layer.isValid())
        p.addMapLayer(vector_layer)

        l = QgsPrintLayout(p)
        atlas = l.atlas()
        atlas.setEnabled(True)
        atlas.setHideCoverage(True)
        atlas.setFilenameExpression('filename exp')
        atlas.setCoverageLayer(vector_layer)
        atlas.setPageNameExpression('page name')
        atlas.setSortFeatures(True)
        atlas.setSortAscending(False)
        atlas.setSortExpression('sort exp')
        atlas.setFilterFeatures(True)
        atlas.setFilterExpression('filter exp')

        doc = QDomDocument("testdoc")
        elem = l.writeXml(doc, QgsReadWriteContext())

        l2 = QgsPrintLayout(p)
        self.assertTrue(l2.readXml(elem, doc, QgsReadWriteContext()))
        atlas2 = l2.atlas()
        self.assertTrue(atlas2.enabled())
        self.assertTrue(atlas2.hideCoverage())
        self.assertEqual(atlas2.filenameExpression(), 'filename exp')
        self.assertEqual(atlas2.coverageLayer(), vector_layer)
        self.assertEqual(atlas2.pageNameExpression(), 'page name')
        self.assertTrue(atlas2.sortFeatures())
        self.assertFalse(atlas2.sortAscending())
        self.assertEqual(atlas2.sortExpression(), 'sort exp')
        self.assertTrue(atlas2.filterFeatures())
        self.assertEqual(atlas2.filterExpression(), 'filter exp')

    def testIteration(self):
        p = QgsProject()
        vectorFileInfo = QFileInfo(unitTestDataPath() + "/france_parts.shp")
        vector_layer = QgsVectorLayer(vectorFileInfo.filePath(),
                                      vectorFileInfo.completeBaseName(), "ogr")
        self.assertTrue(vector_layer.isValid())
        p.addMapLayer(vector_layer)

        l = QgsPrintLayout(p)
        atlas = l.atlas()
        atlas.setEnabled(True)
        atlas.setCoverageLayer(vector_layer)

        atlas_feature_changed_spy = QSignalSpy(atlas.featureChanged)
        context_changed_spy = QSignalSpy(l.reportContext().changed)

        self.assertTrue(atlas.beginRender())
        self.assertTrue(atlas.first())
        self.assertEqual(len(atlas_feature_changed_spy), 1)
        self.assertEqual(len(context_changed_spy), 1)
        self.assertEqual(atlas.currentFeatureNumber(), 0)
        self.assertEqual(l.reportContext().feature()[4], 'Basse-Normandie')
        self.assertEqual(l.reportContext().layer(), vector_layer)
        f1 = l.reportContext().feature()

        self.assertTrue(atlas.next())
        self.assertEqual(len(atlas_feature_changed_spy), 2)
        self.assertEqual(len(context_changed_spy), 2)
        self.assertEqual(atlas.currentFeatureNumber(), 1)
        self.assertEqual(l.reportContext().feature()[4], 'Bretagne')
        f2 = l.reportContext().feature()

        self.assertTrue(atlas.next())
        self.assertEqual(len(atlas_feature_changed_spy), 3)
        self.assertEqual(len(context_changed_spy), 3)
        self.assertEqual(atlas.currentFeatureNumber(), 2)
        self.assertEqual(l.reportContext().feature()[4], 'Pays de la Loire')
        f3 = l.reportContext().feature()

        self.assertTrue(atlas.next())
        self.assertEqual(len(atlas_feature_changed_spy), 4)
        self.assertEqual(len(context_changed_spy), 4)
        self.assertEqual(atlas.currentFeatureNumber(), 3)
        self.assertEqual(l.reportContext().feature()[4], 'Centre')
        f4 = l.reportContext().feature()

        self.assertFalse(atlas.next())
        self.assertTrue(atlas.seekTo(2))
        self.assertEqual(len(atlas_feature_changed_spy), 5)
        self.assertEqual(len(context_changed_spy), 5)
        self.assertEqual(atlas.currentFeatureNumber(), 2)
        self.assertEqual(l.reportContext().feature()[4], 'Pays de la Loire')

        self.assertTrue(atlas.last())
        self.assertEqual(len(atlas_feature_changed_spy), 6)
        self.assertEqual(len(context_changed_spy), 6)
        self.assertEqual(atlas.currentFeatureNumber(), 3)
        self.assertEqual(l.reportContext().feature()[4], 'Centre')

        self.assertTrue(atlas.previous())
        self.assertEqual(len(atlas_feature_changed_spy), 7)
        self.assertEqual(len(context_changed_spy), 7)
        self.assertEqual(atlas.currentFeatureNumber(), 2)
        self.assertEqual(l.reportContext().feature()[4], 'Pays de la Loire')

        self.assertTrue(atlas.previous())
        self.assertTrue(atlas.previous())
        self.assertEqual(len(atlas_feature_changed_spy), 9)
        self.assertFalse(atlas.previous())
        self.assertEqual(len(atlas_feature_changed_spy), 9)

        self.assertTrue(atlas.endRender())
        self.assertEqual(len(atlas_feature_changed_spy), 10)

        self.assertTrue(atlas.seekTo(f1))
        self.assertEqual(l.reportContext().feature()[4], 'Basse-Normandie')
        self.assertTrue(atlas.seekTo(f4))
        self.assertEqual(l.reportContext().feature()[4], 'Centre')
        self.assertTrue(atlas.seekTo(f3))
        self.assertEqual(l.reportContext().feature()[4], 'Pays de la Loire')
        self.assertTrue(atlas.seekTo(f2))
        self.assertEqual(l.reportContext().feature()[4], 'Bretagne')
        self.assertFalse(atlas.seekTo(QgsFeature(5)))

    def testUpdateFeature(self):
        p = QgsProject()
        vectorFileInfo = QFileInfo(unitTestDataPath() + "/france_parts.shp")
        vector_layer = QgsVectorLayer(vectorFileInfo.filePath(),
                                      vectorFileInfo.completeBaseName(), "ogr")
        self.assertTrue(vector_layer.isValid())
        p.addMapLayer(vector_layer)

        l = QgsPrintLayout(p)
        atlas = l.atlas()
        atlas.setEnabled(True)
        atlas.setCoverageLayer(vector_layer)

        self.assertTrue(atlas.beginRender())
        self.assertTrue(atlas.first())
        self.assertEqual(atlas.currentFeatureNumber(), 0)
        self.assertEqual(l.reportContext().feature()[4], 'Basse-Normandie')
        self.assertEqual(l.reportContext().layer(), vector_layer)

        vector_layer.startEditing()
        self.assertTrue(
            vector_layer.changeAttributeValue(l.reportContext().feature().id(),
                                              4, 'Nah, Canberra mate!'))
        self.assertEqual(l.reportContext().feature()[4], 'Basse-Normandie')
        l.atlas().refreshCurrentFeature()
        self.assertEqual(l.reportContext().feature()[4], 'Nah, Canberra mate!')
        vector_layer.rollBack()

    def testFileName(self):
        p = QgsProject()
        vectorFileInfo = QFileInfo(unitTestDataPath() + "/france_parts.shp")
        vector_layer = QgsVectorLayer(vectorFileInfo.filePath(),
                                      vectorFileInfo.completeBaseName(), "ogr")
        self.assertTrue(vector_layer.isValid())
        p.addMapLayer(vector_layer)

        l = QgsPrintLayout(p)
        atlas = l.atlas()
        atlas.setEnabled(True)
        atlas.setCoverageLayer(vector_layer)
        atlas.setFilenameExpression("'output_' || \"NAME_1\"")

        self.assertTrue(atlas.beginRender())
        self.assertEqual(atlas.count(), 4)
        atlas.first()
        self.assertEqual(atlas.currentFilename(), 'output_Basse-Normandie')
        self.assertEqual(atlas.filePath('/tmp/output/', 'png'),
                         '/tmp/output/output_Basse-Normandie.png')
        self.assertEqual(atlas.filePath('/tmp/output/', '.png'),
                         '/tmp/output/output_Basse-Normandie.png')
        self.assertEqual(atlas.filePath('/tmp/output/', 'svg'),
                         '/tmp/output/output_Basse-Normandie.svg')

        atlas.next()
        self.assertEqual(atlas.currentFilename(), 'output_Bretagne')
        self.assertEqual(atlas.filePath('/tmp/output/', 'png'),
                         '/tmp/output/output_Bretagne.png')
        atlas.next()
        self.assertEqual(atlas.currentFilename(), 'output_Pays de la Loire')
        self.assertEqual(atlas.filePath('/tmp/output/', 'png'),
                         '/tmp/output/output_Pays de la Loire.png')
        atlas.next()
        self.assertEqual(atlas.currentFilename(), 'output_Centre')
        self.assertEqual(atlas.filePath('/tmp/output/', 'png'),
                         '/tmp/output/output_Centre.png')

        # try changing expression, filename should be updated instantly
        atlas.setFilenameExpression("'export_' || \"NAME_1\"")
        self.assertEqual(atlas.currentFilename(), 'export_Centre')

        atlas.endRender()

    def testNameForPage(self):
        p = QgsProject()
        vectorFileInfo = QFileInfo(unitTestDataPath() + "/france_parts.shp")
        vector_layer = QgsVectorLayer(vectorFileInfo.filePath(),
                                      vectorFileInfo.completeBaseName(), "ogr")
        self.assertTrue(vector_layer.isValid())
        p.addMapLayer(vector_layer)

        l = QgsPrintLayout(p)
        atlas = l.atlas()
        atlas.setEnabled(True)
        atlas.setCoverageLayer(vector_layer)
        atlas.setPageNameExpression("\"NAME_1\"")

        self.assertTrue(atlas.beginRender())
        self.assertEqual(atlas.nameForPage(0), 'Basse-Normandie')
        self.assertEqual(atlas.nameForPage(1), 'Bretagne')
        self.assertEqual(atlas.nameForPage(2), 'Pays de la Loire')
        self.assertEqual(atlas.nameForPage(3), 'Centre')

    def filename_test(self):
        self.atlas.setFilenameExpression("'output_' || @atlas_featurenumber")
        self.atlas.beginRender()
        for i in range(0, self.atlas.count()):
            self.atlas.seekTo(i)
            expected = "output_%d" % (i + 1)
            self.assertEqual(self.atlas.currentFilename(), expected)
        self.atlas.endRender()

        # using feature attribute (refs https://issues.qgis.org/issues/19552)

        self.atlas.setFilenameExpression(
            "'output_' || attribute(@atlas_feature,'NAME_1')")
        expected = [
            'output_Basse-Normandie', 'output_Bretagne',
            'output_Pays de la Loire', 'output_Centre'
        ]
        self.atlas.beginRender()
        for i in range(0, self.atlas.count()):
            self.atlas.seekTo(i)
            self.assertEqual(self.atlas.currentFilename(), expected[i])
        self.atlas.endRender()

    def autoscale_render_test(self):
        self.atlas_map.setExtent(
            QgsRectangle(332719.06221504929, 6765214.5887386119,
                         560957.85090677091, 6993453.3774303338))

        self.atlas_map.setAtlasDriven(True)
        self.atlas_map.setAtlasScalingMode(QgsLayoutItemMap.Auto)
        self.atlas_map.setAtlasMargin(0.10)

        self.atlas.beginRender()

        for i in range(0, 2):
            self.atlas.seekTo(i)
            self.mLabel1.adjustSizeToText()

            checker = QgsLayoutChecker('atlas_autoscale%d' % (i + 1),
                                       self.layout)
            checker.setControlPathPrefix("atlas")
            myTestResult, myMessage = checker.testLayout(0, 200)
            self.report += checker.report()

            self.assertTrue(myTestResult, myMessage)
        self.atlas.endRender()

        self.atlas_map.setAtlasDriven(False)
        self.atlas_map.setAtlasScalingMode(QgsLayoutItemMap.Fixed)
        self.atlas_map.setAtlasMargin(0)

    def fixedscale_render_test(self):
        self.atlas_map.setExtent(
            QgsRectangle(209838.166, 6528781.020, 610491.166, 6920530.620))
        self.atlas_map.setAtlasDriven(True)
        self.atlas_map.setAtlasScalingMode(QgsLayoutItemMap.Fixed)

        self.atlas.beginRender()

        for i in range(0, 2):
            self.atlas.seekTo(i)
            self.mLabel1.adjustSizeToText()

            checker = QgsLayoutChecker('atlas_fixedscale%d' % (i + 1),
                                       self.layout)
            checker.setControlPathPrefix("atlas")
            myTestResult, myMessage = checker.testLayout(0, 200)
            self.report += checker.report()

            self.assertTrue(myTestResult, myMessage)
        self.atlas.endRender()

    def predefinedscales_render_test(self):
        self.atlas_map.setExtent(
            QgsRectangle(209838.166, 6528781.020, 610491.166, 6920530.620))
        self.atlas_map.setAtlasDriven(True)
        self.atlas_map.setAtlasScalingMode(QgsLayoutItemMap.Predefined)

        scales = [1800000, 5000000]
        self.layout.reportContext().setPredefinedScales(scales)
        for i, s in enumerate(self.layout.reportContext().predefinedScales()):
            self.assertEqual(s, scales[i])

        self.atlas.beginRender()

        for i in range(0, 2):
            self.atlas.seekTo(i)
            self.mLabel1.adjustSizeToText()

            checker = QgsLayoutChecker('atlas_predefinedscales%d' % (i + 1),
                                       self.layout)
            checker.setControlPathPrefix("atlas")
            myTestResult, myMessage = checker.testLayout(0, 200)
            self.report += checker.report()

            self.assertTrue(myTestResult, myMessage)
        self.atlas.endRender()

    def hidden_render_test(self):
        self.atlas_map.setExtent(
            QgsRectangle(209838.166, 6528781.020, 610491.166, 6920530.620))
        self.atlas_map.setAtlasScalingMode(QgsLayoutItemMap.Fixed)
        self.atlas.setHideCoverage(True)

        self.atlas.beginRender()

        for i in range(0, 2):
            self.atlas.seekTo(i)
            self.mLabel1.adjustSizeToText()

            checker = QgsLayoutChecker('atlas_hiding%d' % (i + 1), self.layout)
            checker.setControlPathPrefix("atlas")
            myTestResult, myMessage = checker.testLayout(0, 200)
            self.report += checker.report()

            self.assertTrue(myTestResult, myMessage)
        self.atlas.endRender()

        self.atlas.setHideCoverage(False)

    def sorting_render_test(self):
        self.atlas_map.setExtent(
            QgsRectangle(209838.166, 6528781.020, 610491.166, 6920530.620))
        self.atlas_map.setAtlasScalingMode(QgsLayoutItemMap.Fixed)
        self.atlas.setHideCoverage(False)

        self.atlas.setSortFeatures(True)
        self.atlas.setSortKeyAttributeIndex(4)  # departement name
        self.atlas.setSortAscending(False)

        self.atlas.beginRender()

        for i in range(0, 2):
            self.atlas.seekTo(i)
            self.mLabel1.adjustSizeToText()

            checker = QgsLayoutChecker('atlas_sorting%d' % (i + 1),
                                       self.layout)
            checker.setControlPathPrefix("atlas")
            myTestResult, myMessage = checker.testLayout(0, 200)
            self.report += checker.report()

            self.assertTrue(myTestResult, myMessage)
        self.atlas.endRender()

    def filtering_render_test(self):
        self.atlas_map.setExtent(
            QgsRectangle(209838.166, 6528781.020, 610491.166, 6920530.620))
        self.atlas_map.setAtlasScalingMode(QgsLayoutItemMap.Fixed)
        self.atlas.setHideCoverage(False)

        self.atlas.setSortFeatures(False)

        self.atlas.setFilterFeatures(True)
        self.atlas.setFeatureFilter(
            "substr(NAME_1,1,1)='P'")  # select only 'Pays de la loire'

        self.atlas.beginRender()

        for i in range(0, 1):
            self.atlas.seekTo(i)
            self.mLabel1.adjustSizeToText()

            checker = QgsLayoutChecker('atlas_filtering%d' % (i + 1),
                                       self.layout)
            checker.setControlPathPrefix("atlas")
            myTestResult, myMessage = checker.testLayout(0, 200)
            self.report += checker.report()

            self.assertTrue(myTestResult, myMessage)
        self.atlas.endRender()

    def legend_test(self):
        self.atlas_map.setAtlasDriven(True)
        self.atlas_map.setAtlasScalingMode(QgsLayoutItemMap.Auto)
        self.atlas_map.setAtlasMargin(0.10)

        # add a point layer
        ptLayer = QgsVectorLayer(
            "Point?crs=epsg:4326&field=attr:int(1)&field=label:string(20)",
            "points", "memory")

        pr = ptLayer.dataProvider()
        f1 = QgsFeature(1)
        f1.initAttributes(2)
        f1.setAttribute(0, 1)
        f1.setAttribute(1, "Test label 1")
        f1.setGeometry(QgsGeometry.fromPointXY(QgsPointXY(-0.638, 48.954)))
        f2 = QgsFeature(2)
        f2.initAttributes(2)
        f2.setAttribute(0, 2)
        f2.setAttribute(1, "Test label 2")
        f2.setGeometry(QgsGeometry.fromPointXY(QgsPointXY(-1.682, 48.550)))
        pr.addFeatures([f1, f2])

        # categorized symbology
        r = QgsCategorizedSymbolRenderer("attr", [
            QgsRendererCategory(
                1,
                QgsMarkerSymbol.createSimple({
                    "color": "255,0,0",
                    'outline_color': 'black'
                }), "red"),
            QgsRendererCategory(
                2,
                QgsMarkerSymbol.createSimple({
                    "color": "0,0,255",
                    'outline_color': 'black'
                }), "blue")
        ])
        ptLayer.setRenderer(r)

        QgsProject.instance().addMapLayer(ptLayer)

        # add the point layer to the map settings
        layers = self.layers
        layers = [ptLayer] + layers
        self.atlas_map.setLayers(layers)
        self.overview.setLayers(layers)

        # add a legend
        legend = QgsLayoutItemLegend(self.layout)
        legend.setTitle("Legend")
        legend.attemptMove(QgsLayoutPoint(200, 100))
        # sets the legend filter parameter
        legend.setLinkedMap(self.atlas_map)
        legend.setLegendFilterOutAtlas(True)
        self.layout.addLayoutItem(legend)

        self.atlas.beginRender()

        self.atlas.seekTo(0)
        self.mLabel1.adjustSizeToText()

        checker = QgsLayoutChecker('atlas_legend', self.layout)
        myTestResult, myMessage = checker.testLayout()
        self.report += checker.report()
        self.assertTrue(myTestResult, myMessage)

        self.atlas.endRender()

        # restore state
        self.atlas_map.setLayers([layers[1]])
        self.layout.removeLayoutItem(legend)
        QgsProject.instance().removeMapLayer(ptLayer.id())

    def rotation_test(self):
        # We will create a polygon layer with a rotated rectangle.
        # Then we will make it the object layer for the atlas,
        # rotate the map and test that the bounding rectangle
        # is smaller than the bounds without rotation.
        polygonLayer = QgsVectorLayer('Polygon', 'test_polygon', 'memory')
        poly = QgsFeature(polygonLayer.fields())
        points = [(10, 15), (15, 10), (45, 40), (40, 45)]
        poly.setGeometry(
            QgsGeometry.fromPolygonXY(
                [[QgsPointXY(x[0], x[1]) for x in points]]))
        polygonLayer.dataProvider().addFeatures([poly])
        QgsProject.instance().addMapLayer(polygonLayer)

        # Recreating the layout locally
        composition = QgsPrintLayout(QgsProject.instance())
        composition.initializeDefaults()

        # the atlas map
        atlasMap = QgsLayoutItemMap(composition)
        atlasMap.attemptSetSceneRect(QRectF(20, 20, 130, 130))
        atlasMap.setFrameEnabled(True)
        atlasMap.setLayers([polygonLayer])
        atlasMap.setExtent(QgsRectangle(0, 0, 100, 50))
        composition.addLayoutItem(atlasMap)

        # the atlas
        atlas = composition.atlas()
        atlas.setCoverageLayer(polygonLayer)
        atlas.setEnabled(True)

        atlasMap.setAtlasDriven(True)
        atlasMap.setAtlasScalingMode(QgsLayoutItemMap.Auto)
        atlasMap.setAtlasMargin(0.0)

        # Testing
        atlasMap.setMapRotation(0.0)
        atlas.beginRender()
        atlas.first()
        nonRotatedExtent = QgsRectangle(atlasMap.extent())

        atlasMap.setMapRotation(45.0)
        atlas.first()
        rotatedExtent = QgsRectangle(atlasMap.extent())

        self.assertLess(rotatedExtent.width(), nonRotatedExtent.width() * 0.9)
        self.assertLess(rotatedExtent.height(),
                        nonRotatedExtent.height() * 0.9)

        QgsProject.instance().removeMapLayer(polygonLayer)

    def test_datadefined_margin(self):
        polygonLayer = QgsVectorLayer('Polygon?field=margin:int',
                                      'test_polygon', 'memory')
        poly = QgsFeature(polygonLayer.fields())
        poly.setAttributes([0])
        poly.setGeometry(
            QgsGeometry.fromWkt(
                'Polygon((30 30, 40 30, 40 40, 30 40, 30 30))'))
        polygonLayer.dataProvider().addFeatures([poly])
        poly = QgsFeature(polygonLayer.fields())
        poly.setAttributes([10])
        poly.setGeometry(
            QgsGeometry.fromWkt(
                'Polygon((10 10, 20 10, 20 20, 10 20, 10 10))'))
        polygonLayer.dataProvider().addFeatures([poly])
        poly = QgsFeature(polygonLayer.fields())
        poly.setAttributes([20])
        poly.setGeometry(
            QgsGeometry.fromWkt(
                'Polygon((50 50, 60 50, 60 60, 50 60, 50 50))'))
        polygonLayer.dataProvider().addFeatures([poly])
        QgsProject.instance().addMapLayer(polygonLayer)

        layout = QgsPrintLayout(QgsProject.instance())
        map = QgsLayoutItemMap(layout)
        map.setCrs(polygonLayer.crs())
        map.attemptSetSceneRect(QRectF(20, 20, 130, 130))
        map.setFrameEnabled(True)
        map.setLayers([polygonLayer])
        map.setExtent(QgsRectangle(0, 0, 100, 50))
        layout.addLayoutItem(map)

        atlas = layout.atlas()
        atlas.setCoverageLayer(polygonLayer)
        atlas.setEnabled(True)

        map.setAtlasDriven(True)
        map.setAtlasScalingMode(QgsLayoutItemMap.Auto)
        map.setAtlasMargin(77.0)
        map.dataDefinedProperties().setProperty(
            QgsLayoutObject.MapAtlasMargin,
            QgsProperty.fromExpression('margin/2'))

        atlas.beginRender()
        atlas.first()

        self.assertEqual(map.extent(), QgsRectangle(25, 30, 45, 40))
        self.assertTrue(atlas.next())
        self.assertEqual(map.extent(), QgsRectangle(4.5, 9.75, 25.5, 20.25))
        self.assertTrue(atlas.next())
        self.assertEqual(map.extent(), QgsRectangle(44, 49.5, 66, 60.5))

        QgsProject.instance().removeMapLayer(polygonLayer)
Пример #10
0
    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()
                ])
Пример #11
0
    def test_StackingPosition(self):
        l = QgsLayout(QgsProject.instance())
        l.initializeDefaults()

        overviewMap = QgsLayoutItemMap(l)
        overviewMap.attemptSetSceneRect(QRectF(20, 130, 70, 70))
        l.addLayoutItem(overviewMap)
        overviewMap.overview().setStackingPosition(
            QgsLayoutItemMapItem.StackBelowMap)
        self.assertEqual(overviewMap.overview().stackingPosition(),
                         QgsLayoutItemMapItem.StackBelowMap)
        overviewMap.overview().setStackingPosition(
            QgsLayoutItemMapItem.StackBelowMapLayer)
        self.assertEqual(overviewMap.overview().stackingPosition(),
                         QgsLayoutItemMapItem.StackBelowMapLayer)

        overviewMap.overview().setStackingLayer(self.raster_layer)
        self.assertEqual(overviewMap.overview().stackingLayer(),
                         self.raster_layer)
        overviewMap.overview().setStackingLayer(self.vector_layer)
        self.assertEqual(overviewMap.overview().stackingLayer(),
                         self.vector_layer)
        overviewMap.overview().setStackingLayer(None)
        self.assertIsNone(overviewMap.overview().stackingLayer())
Пример #12
0
    def testAsMapLayer(self):
        l = QgsLayout(QgsProject.instance())
        l.initializeDefaults()
        map = QgsLayoutItemMap(l)
        map.attemptSetSceneRect(QRectF(20, 20, 200, 100))
        l.addLayoutItem(map)

        overviewMap = QgsLayoutItemMap(l)
        overviewMap.attemptSetSceneRect(QRectF(20, 130, 70, 70))
        l.addLayoutItem(overviewMap)
        # zoom in
        myRectangle = QgsRectangle(96, -152, 160, -120)
        map.setExtent(myRectangle)
        myRectangle2 = QgsRectangle(0, -256, 256, 0)
        overviewMap.setExtent(myRectangle2)
        overviewMap.overview().setLinkedMap(map)

        layer = overviewMap.overview().asMapLayer()
        self.assertIsNotNone(layer)
        self.assertTrue(layer.isValid())
        self.assertEqual(
            [f.geometry().asWkt() for f in layer.getFeatures()],
            ['Polygon ((96 -120, 160 -120, 160 -152, 96 -152, 96 -120))'])

        # check that layer has correct renderer
        fill_symbol = QgsFillSymbol.createSimple({
            'color': '#00ff00',
            'outline_color': '#ff0000',
            'outline_width': '10'
        })
        overviewMap.overview().setFrameSymbol(fill_symbol)
        layer = overviewMap.overview().asMapLayer()
        self.assertIsInstance(layer.renderer(), QgsSingleSymbolRenderer)
        self.assertEqual(
            layer.renderer().symbol().symbolLayer(0).properties()['color'],
            '0,255,0,255')
        self.assertEqual(
            layer.renderer().symbol().symbolLayer(0).properties()
            ['outline_color'], '255,0,0,255')

        # test layer blend mode
        self.assertEqual(layer.blendMode(),
                         QPainter.CompositionMode_SourceOver)
        overviewMap.overview().setBlendMode(QPainter.CompositionMode_Clear)
        layer = overviewMap.overview().asMapLayer()
        self.assertEqual(layer.blendMode(), QPainter.CompositionMode_Clear)

        # should have no effect
        overviewMap.setMapRotation(45)
        layer = overviewMap.overview().asMapLayer()
        self.assertEqual(
            [f.geometry().asWkt() for f in layer.getFeatures()],
            ['Polygon ((96 -120, 160 -120, 160 -152, 96 -152, 96 -120))'])

        map.setMapRotation(15)
        layer = overviewMap.overview().asMapLayer()
        self.assertEqual(
            [f.geometry().asWkt(0) for f in layer.getFeatures()],
            ['Polygon ((93 -129, 155 -112, 163 -143, 101 -160, 93 -129))'])

        # with reprojection
        map.setCrs(QgsCoordinateReferenceSystem('EPSG:3875'))
        layer = overviewMap.overview().asMapLayer()
        self.assertEqual([
            f.geometry().asWkt(0) for f in layer.getFeatures()
        ], [
            'Polygon ((93 -129, 96 -128, 99 -127, 102 -126, 105 -126, 108 -125, 111 -124, 114 -123, 116 -123, 119 -122, 122 -121, 125 -120, 128 -119, 131 -119, 134 -118, 137 -117, 140 -116, 143 -115, 146 -115, 149 -114, 152 -113, 155 -112, 155 -114, 156 -115, 156 -117, 156 -118, 157 -120, 157 -121, 158 -123, 158 -124, 158 -126, 159 -127, 159 -128, 160 -130, 160 -131, 160 -133, 161 -134, 161 -136, 161 -137, 162 -139, 162 -140, 163 -142, 163 -143, 160 -144, 157 -145, 154 -146, 151 -146, 148 -147, 145 -148, 142 -149, 140 -149, 137 -150, 134 -151, 131 -152, 128 -153, 125 -153, 122 -154, 119 -155, 116 -156, 113 -157, 110 -157, 107 -158, 104 -159, 101 -160, 101 -158, 100 -157, 100 -155, 100 -154, 99 -152, 99 -151, 98 -149, 98 -148, 98 -146, 97 -145, 97 -144, 96 -142, 96 -141, 96 -139, 95 -138, 95 -136, 95 -135, 94 -133, 94 -132, 93 -130, 93 -129))'
        ])

        map.setCrs(overviewMap.crs())
        # with invert
        overviewMap.overview().setInverted(True)
        layer = overviewMap.overview().asMapLayer()
        self.assertEqual([
            f.geometry().asWkt(0) for f in layer.getFeatures()
        ], [
            'Polygon ((-53 -128, 128 53, 309 -128, 128 -309, -53 -128),(93 -129, 101 -160, 163 -143, 155 -112, 93 -129))'
        ])