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
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
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)
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
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)
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())
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()])
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))'])
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)
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() ])
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())
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))' ])