def testCopyPaste(self): p = QgsProject() l = QgsLayout(p) # clear clipboard mime_data = QMimeData() mime_data.setData("text/xml", QByteArray()) clipboard = QApplication.clipboard() clipboard.setMimeData(mime_data) # add an item item1 = QgsLayoutItemLabel(l) item1.setText('label 1') l.addLayoutItem(item1) item1.setSelected(True) item2 = QgsLayoutItemLabel(l) item2.setText('label 2') l.addLayoutItem(item2) item2.setSelected(True) view = QgsLayoutView() view.setCurrentLayout(l) self.assertFalse(view.hasItemsInClipboard()) view.copySelectedItems(QgsLayoutView.ClipboardCopy) self.assertTrue(view.hasItemsInClipboard()) pasted = view.pasteItems(QgsLayoutView.PasteModeCursor) self.assertEqual(len(pasted), 2) self.assertIn(pasted[0], l.items()) self.assertIn(pasted[1], l.items()) self.assertIn(sip.cast(pasted[0], QgsLayoutItemLabel).text(), ('label 1', 'label 2')) self.assertIn(sip.cast(pasted[1], QgsLayoutItemLabel).text(), ('label 1', 'label 2')) # copy specific item view.copyItems([item2], QgsLayoutView.ClipboardCopy) l2 = QgsLayout(p) view2 = QgsLayoutView() view2.setCurrentLayout(l2) pasted = view2.pasteItems(QgsLayoutView.PasteModeCursor) self.assertEqual(len(pasted), 1) self.assertIn(pasted[0], l2.items()) self.assertEqual(sip.cast(pasted[0], QgsLayoutItemLabel).text(), 'label 2')
def testCombo(self): project = QgsProject() layout = QgsPrintLayout(project) combo = QgsLayoutItemComboBox(None) spy = QSignalSpy(combo.itemChanged) self.assertEqual(combo.count(), 0) self.assertIsNone(combo.currentLayout()) self.assertIsNone(combo.currentItem()) self.assertIsNone(combo.item(0)) self.assertIsNone(combo.item(-1)) self.assertIsNone(combo.item(1)) combo.setItem(None) self.assertIsNone(combo.currentItem()) self.assertEqual(combo.currentIndex(), -1) self.assertEqual(len(spy), 0) combo.setCurrentLayout(layout) self.assertEqual(combo.currentIndex(), -1) self.assertEqual(len(spy), 0) self.assertEqual(combo.currentLayout(), layout) self.assertEqual(combo.count(), 0) self.assertIsNone(combo.currentItem()) self.assertIsNone(combo.item(0)) self.assertIsNone(combo.item(-1)) self.assertIsNone(combo.item(1)) combo.setItem(None) self.assertIsNone(combo.currentItem()) self.assertEqual(len(spy), 0) combo.setAllowEmptyItem(True) self.assertEqual(combo.currentIndex(), 0) self.assertEqual(combo.count(), 1) self.assertEqual(len(spy), 2) self.assertEqual(combo.currentLayout(), layout) self.assertIsNone(combo.currentItem()) self.assertIsNone(combo.item(0)) self.assertIsNone(combo.item(-1)) self.assertIsNone(combo.item(1)) combo.setItem(None) self.assertIsNone(combo.currentItem()) self.assertEqual(len(spy), 2) self.assertEqual(combo.currentIndex(), 0) self.assertEqual(combo.itemText(0), '') combo.setAllowEmptyItem(False) self.assertEqual(combo.currentIndex(), -1) self.assertEqual(combo.count(), 0) self.assertEqual(len(spy), 4) self.assertEqual(combo.currentLayout(), layout) self.assertIsNone(combo.currentItem()) self.assertIsNone(combo.item(0)) self.assertIsNone(combo.item(-1)) self.assertIsNone(combo.item(1)) combo.setItem(None) self.assertIsNone(combo.currentItem()) self.assertEqual(len(spy), 4) self.assertEqual(combo.currentIndex(), -1) label1 = QgsLayoutItemLabel(layout) label1.setId('llll') # don't add to layout yet! combo.setItem(label1) self.assertIsNone(combo.currentItem()) self.assertEqual(len(spy), 4) self.assertEqual(combo.currentIndex(), -1) combo.setAllowEmptyItem(True) combo.setItem(label1) self.assertIsNone(combo.currentItem()) self.assertEqual(len(spy), 6) self.assertEqual(combo.currentIndex(), 0) combo.setAllowEmptyItem(False) layout.addLayoutItem(label1) self.assertEqual(combo.currentIndex(), 0) self.assertEqual(combo.count(), 1) self.assertEqual(combo.itemText(0), 'llll') self.assertEqual(len(spy), 10) self.assertEqual(combo.currentLayout(), layout) self.assertEqual(combo.currentItem(), label1) self.assertEqual(combo.item(0), label1) self.assertIsNone(combo.item(-1)) self.assertIsNone(combo.item(1)) combo.setItem(None) self.assertIsNone(combo.currentItem()) self.assertEqual(len(spy), 11) self.assertEqual(combo.currentIndex(), -1) combo.setItem(label1) self.assertEqual(combo.currentItem(), label1) self.assertEqual(len(spy), 12) self.assertEqual(combo.currentIndex(), 0) combo.setAllowEmptyItem(True) self.assertEqual(combo.currentIndex(), 1) self.assertEqual(combo.count(), 2) self.assertEqual(combo.itemText(0), '') self.assertEqual(combo.itemText(1), 'llll') self.assertEqual(len(spy), 13) self.assertEqual(combo.currentLayout(), layout) self.assertEqual(combo.currentItem(), label1) self.assertIsNone(combo.item(0)) self.assertEqual(combo.item(1), label1) self.assertIsNone(combo.item(-1)) self.assertIsNone(combo.item(2)) combo.setItem(None) self.assertIsNone(combo.currentItem()) self.assertEqual(len(spy), 14) self.assertEqual(combo.currentIndex(), 0) combo.setItem(label1) self.assertEqual(combo.currentItem(), label1) self.assertEqual(len(spy), 15) self.assertEqual(combo.currentIndex(), 1) label2 = QgsLayoutItemLabel(layout) label2.setId('mmmm') layout.addLayoutItem(label2) self.assertEqual(combo.currentIndex(), 1) self.assertEqual(combo.count(), 3) self.assertEqual(combo.itemText(0), '') self.assertEqual(combo.itemText(1), 'llll') self.assertEqual(combo.itemText(2), 'mmmm') self.assertEqual(len(spy), 15) self.assertEqual(combo.currentLayout(), layout) self.assertEqual(combo.currentItem(), label1) self.assertIsNone(combo.item(0)) self.assertEqual(combo.item(1), label1) self.assertEqual(combo.item(2), label2) self.assertIsNone(combo.item(-1)) self.assertIsNone(combo.item(3)) combo.setItem(None) self.assertIsNone(combo.currentItem()) self.assertEqual(len(spy), 16) self.assertEqual(combo.currentIndex(), 0) combo.setItem(label1) self.assertEqual(combo.currentItem(), label1) self.assertEqual(len(spy), 17) self.assertEqual(combo.currentIndex(), 1) label1.setId('nnnn') self.assertEqual(combo.itemText(0), '') self.assertEqual(combo.itemText(1), 'mmmm') self.assertEqual(combo.itemText(2), 'nnnn') self.assertIsNone(combo.item(0)) self.assertEqual(combo.item(1), label2) self.assertEqual(combo.item(2), label1) self.assertEqual(combo.currentItem(), label1) combo.setAllowEmptyItem(False) self.assertEqual(combo.itemText(0), 'mmmm') self.assertEqual(combo.itemText(1), 'nnnn') self.assertEqual(combo.item(0), label2) self.assertEqual(combo.item(1), label1) self.assertEqual(combo.currentItem(), label1) combo.setItem(label2) label2.setId('oooo') self.assertEqual(combo.itemText(0), 'nnnn') self.assertEqual(combo.itemText(1), 'oooo') self.assertEqual(combo.item(0), label1) self.assertEqual(combo.item(1), label2) self.assertEqual(combo.currentItem(), label2) combo.setAllowEmptyItem(True) layout.removeLayoutItem(label1) self.assertEqual(combo.itemText(0), '') self.assertEqual(combo.itemText(1), 'oooo') self.assertIsNone(combo.item(0)) self.assertEqual(combo.item(1), label2) self.assertEqual(combo.currentItem(), label2) map = QgsLayoutItemMap(layout) layout.addLayoutItem(map) map.setId('pppp') self.assertEqual(combo.itemText(0), '') self.assertEqual(combo.itemText(1), 'oooo') self.assertEqual(combo.itemText(2), 'pppp') self.assertIsNone(combo.item(0)) self.assertEqual(combo.item(1), label2) self.assertEqual(combo.item(2), map) self.assertEqual(combo.currentItem(), label2) combo.setItemType(QgsLayoutItemRegistry.LayoutMap) self.assertEqual(combo.itemText(0), '') self.assertEqual(combo.itemText(1), 'pppp') self.assertIsNone(combo.item(0)) self.assertEqual(combo.item(1), map) self.assertIsNone(combo.currentItem()) combo.setItemType(QgsLayoutItemRegistry.LayoutLabel) self.assertEqual(combo.itemText(0), '') self.assertEqual(combo.itemText(1), 'oooo') self.assertIsNone(combo.item(0)) self.assertEqual(combo.item(1), label2) self.assertIsNone(combo.currentItem()) combo.setItemType(QgsLayoutItemRegistry.LayoutAttributeTable) self.assertEqual(combo.itemText(0), '') self.assertIsNone(combo.item(0)) self.assertIsNone(combo.currentItem()) combo.setAllowEmptyItem(False) self.assertEqual(combo.count(), 0) self.assertIsNone(combo.currentItem()) self.assertEqual(combo.currentIndex(), -1)
def testContainsAdvancedEffectsAndRasterization(self): layout = QgsLayout(QgsProject.instance()) item = QgsLayoutItemLabel(layout) self.assertFalse(item.containsAdvancedEffects()) # item opacity requires that the individual item be flattened to a raster item item.setItemOpacity(0.5) self.assertTrue(item.containsAdvancedEffects()) # but not the WHOLE layout self.assertFalse(item.requiresRasterization()) item.dataDefinedProperties().setProperty(QgsLayoutObject.Opacity, QgsProperty.fromExpression('100')) item.refresh() self.assertFalse(item.containsAdvancedEffects()) self.assertFalse(item.requiresRasterization()) item.dataDefinedProperties().setProperty(QgsLayoutObject.Opacity, QgsProperty()) item.refresh() self.assertTrue(item.containsAdvancedEffects()) self.assertFalse(item.requiresRasterization()) item.setItemOpacity(1.0) self.assertFalse(item.containsAdvancedEffects()) self.assertFalse(item.requiresRasterization()) # item blend mode is NOT an advanced effect -- rather it requires that the WHOLE layout be rasterized to achieve item.setBlendMode(QPainter.CompositionMode_DestinationAtop) self.assertFalse(item.containsAdvancedEffects()) self.assertTrue(item.requiresRasterization()) map = QgsLayoutItemMap(layout) # map items are different -- because they override paint, they don't get the auto-flattening and rasterization map.setItemOpacity(0.5) self.assertFalse(map.containsAdvancedEffects()) # rather, a map with opacity requires the WHOLE layout to be rasterized self.assertTrue(map.requiresRasterization()) map.dataDefinedProperties().setProperty(QgsLayoutObject.Opacity, QgsProperty.fromExpression('100')) map.refresh() self.assertFalse(map.containsAdvancedEffects()) self.assertTrue(map.requiresRasterization())
def buildComposerLabel(self, key, item, page): """ Add a label to the print layout for an item and page """ cl = QgsLayoutItemLabel(self.currentComposition) # 1st page is a map for parcelle dpage = page - 1 if self.etype == 'parcelle' and self.print_parcelle_page: dpage = page cl.attemptMove( QgsLayoutPoint( item['position'][0], item['position'][1] + (dpage) * (self.pageHeight + 10), QgsUnitTypes.LayoutMillimeters)) cl.setFixedSize( QgsLayoutSize(item['position'][2], item['position'][3], QgsUnitTypes.LayoutMillimeters)) cl.setVAlign(item['align'][0]) cl.setHAlign(item['align'][1]) content = self.getContentForGivenItem(key, item, page) cl.setMargin(0) cl.setMode(1) cl.setText(content) cl.setFrameEnabled(False) if 'bgcolor' in item: cl.setBackgroundColor(item['bgcolor']) if 'htmlState' in item: cl.setMode(item['htmlState']) if 'font' in item: cl.setFont(item['font']) self.currentComposition.addLayoutItem(cl)
def testSaveLoadTemplate(self): tmpfile = os.path.join(self.basetestpath, 'testTemplate.qpt') p = QgsProject() l = QgsLayout(p) l.initializeDefaults() # add some items item1 = QgsLayoutItemLabel(l) item1.setId('xxyyxx') item1.attemptMove(QgsLayoutPoint(4, 8, QgsUnitTypes.LayoutMillimeters)) item1.attemptResize(QgsLayoutSize(18, 12, QgsUnitTypes.LayoutMillimeters)) l.addItem(item1) item2 = QgsLayoutItemLabel(l) item2.setId('zzyyzz') item2.attemptMove(QgsLayoutPoint(1.4, 1.8, QgsUnitTypes.LayoutCentimeters)) item2.attemptResize(QgsLayoutSize(2.8, 2.2, QgsUnitTypes.LayoutCentimeters)) l.addItem(item2) uuids = {item1.uuid(), item2.uuid()} original_uuids = {item1.uuid(), item2.uuid()} self.assertTrue(l.saveAsTemplate(tmpfile, QgsReadWriteContext())) l2 = QgsLayout(p) with open(tmpfile) as f: template_content = f.read() doc = QDomDocument() doc.setContent(template_content) # adding to existing items new_items, ok = l2.loadFromTemplate(doc, QgsReadWriteContext(), False) self.assertTrue(ok) self.assertEqual(len(new_items), 2) items = l2.items() self.assertTrue([i for i in items if i.id() == 'xxyyxx']) self.assertTrue([i for i in items if i.id() == 'zzyyzz']) self.assertTrue(new_items[0] in l2.items()) self.assertTrue(new_items[1] in l2.items()) # double check that new items have a unique uid self.assertNotIn(new_items[0].uuid(), uuids) self.assertIn(new_items[0].templateUuid(), original_uuids) uuids.add(new_items[0].uuid()) self.assertNotIn(new_items[1].uuid(), uuids) self.assertIn(new_items[1].templateUuid(), original_uuids) uuids.add(new_items[1].uuid()) # adding to existing items new_items2, ok = l2.loadFromTemplate(doc, QgsReadWriteContext(), False) self.assertTrue(ok) self.assertEqual(len(new_items2), 2) items = l2.items() self.assertEqual(len(items), 4) self.assertTrue([i for i in items if i.id() == 'xxyyxx']) self.assertTrue([i for i in items if i.id() == 'zzyyzz']) self.assertTrue(new_items[0] in l2.items()) self.assertTrue(new_items[1] in l2.items()) self.assertTrue(new_items2[0] in l2.items()) self.assertTrue(new_items2[1] in l2.items()) self.assertNotIn(new_items2[0].uuid(), uuids) self.assertIn(new_items2[0].templateUuid(), original_uuids) uuids.add(new_items[0].uuid()) self.assertNotIn(new_items2[1].uuid(), uuids) self.assertIn(new_items2[1].templateUuid(), original_uuids) uuids.add(new_items[1].uuid()) # clearing existing items new_items3, ok = l2.loadFromTemplate(doc, QgsReadWriteContext(), True) self.assertTrue(ok) self.assertEqual(len(new_items3), 3) # includes page items = l2.items() self.assertTrue([i for i in items if isinstance(i, QgsLayoutItem) and i.id() == 'xxyyxx']) self.assertTrue([i for i in items if isinstance(i, QgsLayoutItem) and i.id() == 'zzyyzz']) self.assertTrue(new_items3[0] in l2.items()) self.assertTrue(new_items3[1] in l2.items()) self.assertIn(new_items3[0].templateUuid(), original_uuids) self.assertIn(new_items3[1].templateUuid(), original_uuids) self.assertEqual(l2.itemByUuid(new_items3[0].templateUuid(), True), new_items3[0]) self.assertEqual(l2.itemByUuid(new_items3[1].templateUuid(), True), new_items3[1])
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 testDeleteItems(self): p = QgsProject() l = QgsLayout(p) # add some items item1 = QgsLayoutItemLabel(l) item1.setText('label 1') l.addLayoutItem(item1) item2 = QgsLayoutItemLabel(l) item2.setText('label 2') l.addLayoutItem(item2) item3 = QgsLayoutItemLabel(l) item3.setText('label 2') l.addLayoutItem(item3) view = QgsLayoutView() view.setCurrentLayout(l) count_before = len(l.items()) view.deleteSelectedItems() self.assertEqual(len(l.items()), count_before) item2.setSelected(True) view.deleteSelectedItems() self.assertEqual(len(l.items()), count_before - 1) self.assertIn(item1, l.items()) self.assertIn(item3, l.items()) view.deleteItems([item3]) self.assertEqual(len(l.items()), count_before - 2) self.assertIn(item1, l.items())
def testCopyPaste(self): p = QgsProject() l = QgsLayout(p) # clear clipboard mime_data = QMimeData() mime_data.setData("text/xml", QByteArray()) clipboard = QApplication.clipboard() clipboard.setMimeData(mime_data) # add an item item1 = QgsLayoutItemLabel(l) item1.setText('label 1') l.addLayoutItem(item1) item1.setSelected(True) item2 = QgsLayoutItemLabel(l) item2.setText('label 2') l.addLayoutItem(item2) item2.setSelected(True) # multiframes multiframe1 = QgsLayoutItemHtml(l) multiframe1.setHtml('mf1') l.addMultiFrame(multiframe1) frame1 = QgsLayoutFrame(l, multiframe1) frame1.setId('frame1a') multiframe1.addFrame(frame1) frame1b = QgsLayoutFrame(l, multiframe1) frame1b.setId('frame1b') multiframe1.addFrame(frame1b) # not selected frame1c = QgsLayoutFrame(l, multiframe1) frame1c.setId('frame1b') multiframe1.addFrame(frame1c) # not selected multiframe2 = QgsLayoutItemHtml(l) multiframe2.setHtml('mf2') l.addMultiFrame(multiframe2) frame2 = QgsLayoutFrame(l, multiframe2) frame2.setId('frame2') multiframe2.addFrame(frame2) frame1.setSelected(True) frame2.setSelected(True) view = QgsLayoutView() view.setCurrentLayout(l) self.assertFalse(view.hasItemsInClipboard()) view.copySelectedItems(QgsLayoutView.ClipboardCopy) self.assertTrue(view.hasItemsInClipboard()) pasted = view.pasteItems(QgsLayoutView.PasteModeCursor) self.assertEqual(len(pasted), 4) new_multiframes = [m for m in l.multiFrames() if m not in [multiframe1, multiframe2]] self.assertEqual(len(new_multiframes), 2) self.assertIn(pasted[0], l.items()) self.assertIn(pasted[1], l.items()) labels = [p for p in pasted if p.type() == QgsLayoutItemRegistry.LayoutLabel] self.assertIn(sip.cast(labels[0], QgsLayoutItemLabel).text(), ('label 1', 'label 2')) self.assertIn(sip.cast(labels[1], QgsLayoutItemLabel).text(), ('label 1', 'label 2')) frames = [p for p in pasted if p.type() == QgsLayoutItemRegistry.LayoutFrame] pasted_frame1 = sip.cast(frames[0], QgsLayoutFrame) pasted_frame2 = sip.cast(frames[1], QgsLayoutFrame) self.assertIn(pasted_frame1.multiFrame(), new_multiframes) self.assertIn(new_multiframes[0].frames()[0].uuid(), (pasted_frame1.uuid(), pasted_frame2.uuid())) self.assertIn(pasted_frame2.multiFrame(), new_multiframes) self.assertIn(new_multiframes[1].frames()[0].uuid(), (pasted_frame1.uuid(), pasted_frame2.uuid())) self.assertEqual(frame1.multiFrame(), multiframe1) self.assertCountEqual(multiframe1.frames(), [frame1, frame1b, frame1c]) self.assertEqual(frame1b.multiFrame(), multiframe1) self.assertEqual(frame1c.multiFrame(), multiframe1) self.assertEqual(frame2.multiFrame(), multiframe2) self.assertCountEqual(multiframe2.frames(), [frame2]) # copy specific item view.copyItems([item2], QgsLayoutView.ClipboardCopy) l2 = QgsLayout(p) view2 = QgsLayoutView() view2.setCurrentLayout(l2) pasted = view2.pasteItems(QgsLayoutView.PasteModeCursor) self.assertEqual(len(pasted), 1) self.assertIn(pasted[0], l2.items()) self.assertEqual(sip.cast(pasted[0], QgsLayoutItemLabel).text(), 'label 2')
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 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 testSaveLoadTemplate(self): tmpfile = os.path.join(self.basetestpath, 'testTemplate.qpt') p = QgsProject() l = QgsLayout(p) l.initializeDefaults() # add some items item1 = QgsLayoutItemLabel(l) item1.setId('xxyyxx') item1.attemptMove(QgsLayoutPoint(4, 8, QgsUnitTypes.LayoutMillimeters)) item1.attemptResize(QgsLayoutSize(18, 12, QgsUnitTypes.LayoutMillimeters)) l.addItem(item1) item2 = QgsLayoutItemLabel(l) item2.setId('zzyyzz') item2.attemptMove(QgsLayoutPoint(1.4, 1.8, QgsUnitTypes.LayoutCentimeters)) item2.attemptResize(QgsLayoutSize(2.8, 2.2, QgsUnitTypes.LayoutCentimeters)) l.addItem(item2) # multiframe multiframe1 = QgsLayoutItemHtml(l) multiframe1.setHtml('mf1') l.addMultiFrame(multiframe1) frame1 = QgsLayoutFrame(l, multiframe1) frame1.setId('frame1') frame1.attemptMove(QgsLayoutPoint(4, 8, QgsUnitTypes.LayoutMillimeters)) frame1.attemptResize(QgsLayoutSize(18, 12, QgsUnitTypes.LayoutMillimeters)) multiframe1.addFrame(frame1) multiframe2 = QgsLayoutItemHtml(l) multiframe2.setHtml('mf2') l.addMultiFrame(multiframe2) frame2 = QgsLayoutFrame(l, multiframe2) frame2.setId('frame2') frame2.attemptMove(QgsLayoutPoint(1.4, 1.8, QgsUnitTypes.LayoutCentimeters)) frame2.attemptResize(QgsLayoutSize(2.8, 2.2, QgsUnitTypes.LayoutCentimeters)) multiframe2.addFrame(frame2) uuids = {item1.uuid(), item2.uuid(), frame1.uuid(), frame2.uuid(), multiframe1.uuid(), multiframe2.uuid()} original_uuids = {item1.uuid(), item2.uuid(), frame1.uuid(), frame2.uuid()} self.assertTrue(l.saveAsTemplate(tmpfile, QgsReadWriteContext())) l2 = QgsLayout(p) with open(tmpfile) as f: template_content = f.read() doc = QDomDocument() doc.setContent(template_content) # adding to existing items new_items, ok = l2.loadFromTemplate(doc, QgsReadWriteContext(), False) self.assertTrue(ok) self.assertEqual(len(new_items), 4) items = l2.items() multiframes = l2.multiFrames() self.assertEqual(len(multiframes), 2) self.assertTrue([i for i in items if i.id() == 'xxyyxx']) self.assertTrue([i for i in items if i.id() == 'zzyyzz']) self.assertTrue([i for i in items if i.id() == 'frame1']) self.assertTrue([i for i in items if i.id() == 'frame2']) self.assertTrue([i for i in multiframes if i.html() == 'mf1']) self.assertTrue([i for i in multiframes if i.html() == 'mf2']) self.assertTrue(new_items[0] in l2.items()) self.assertTrue(new_items[1] in l2.items()) self.assertTrue(new_items[2] in l2.items()) self.assertTrue(new_items[3] in l2.items()) # double check that new items have a unique uid self.assertNotIn(new_items[0].uuid(), uuids) uuids.add(new_items[0].uuid()) self.assertNotIn(new_items[1].uuid(), uuids) uuids.add(new_items[1].uuid()) self.assertNotIn(new_items[2].uuid(), uuids) uuids.add(new_items[2].uuid()) self.assertNotIn(new_items[3].uuid(), uuids) uuids.add(new_items[3].uuid()) self.assertNotIn(multiframes[0].uuid(), [multiframe1.uuid(), multiframe2.uuid()]) self.assertNotIn(multiframes[1].uuid(), [multiframe1.uuid(), multiframe2.uuid()]) new_multiframe1 = [i for i in multiframes if i.html() == 'mf1'][0] self.assertEqual(new_multiframe1.layout(), l2) new_multiframe2 = [i for i in multiframes if i.html() == 'mf2'][0] self.assertEqual(new_multiframe2.layout(), l2) new_frame1 = sip.cast([i for i in items if i.id() == 'frame1'][0], QgsLayoutFrame) new_frame2 = sip.cast([i for i in items if i.id() == 'frame2'][0], QgsLayoutFrame) self.assertEqual(new_frame1.multiFrame(), new_multiframe1) self.assertEqual(new_multiframe1.frames()[0].uuid(), new_frame1.uuid()) self.assertEqual(new_frame2.multiFrame(), new_multiframe2) self.assertEqual(new_multiframe2.frames()[0].uuid(), new_frame2.uuid()) # adding to existing items new_items2, ok = l2.loadFromTemplate(doc, QgsReadWriteContext(), False) self.assertTrue(ok) self.assertEqual(len(new_items2), 4) items = l2.items() self.assertEqual(len(items), 8) multiframes2 = l2.multiFrames() self.assertEqual(len(multiframes2), 4) multiframes2 = [m for m in l2.multiFrames() if not m.uuid() in [new_multiframe1.uuid(), new_multiframe2.uuid()]] self.assertEqual(len(multiframes2), 2) self.assertTrue([i for i in items if i.id() == 'xxyyxx']) self.assertTrue([i for i in items if i.id() == 'zzyyzz']) self.assertTrue([i for i in items if i.id() == 'frame1']) self.assertTrue([i for i in items if i.id() == 'frame2']) self.assertTrue([i for i in multiframes2 if i.html() == 'mf1']) self.assertTrue([i for i in multiframes2 if i.html() == 'mf2']) self.assertTrue(new_items[0] in l2.items()) self.assertTrue(new_items[1] in l2.items()) self.assertTrue(new_items[2] in l2.items()) self.assertTrue(new_items[3] in l2.items()) self.assertTrue(new_items2[0] in l2.items()) self.assertTrue(new_items2[1] in l2.items()) self.assertTrue(new_items2[2] in l2.items()) self.assertTrue(new_items2[3] in l2.items()) self.assertNotIn(new_items2[0].uuid(), uuids) uuids.add(new_items[0].uuid()) self.assertNotIn(new_items2[1].uuid(), uuids) uuids.add(new_items[1].uuid()) self.assertNotIn(new_items2[2].uuid(), uuids) uuids.add(new_items[2].uuid()) self.assertNotIn(new_items2[3].uuid(), uuids) uuids.add(new_items[3].uuid()) self.assertNotIn(multiframes2[0].uuid(), [multiframe1.uuid(), multiframe2.uuid(), new_multiframe1.uuid(), new_multiframe2.uuid()]) self.assertNotIn(multiframes2[1].uuid(), [multiframe1.uuid(), multiframe2.uuid(), new_multiframe1.uuid(), new_multiframe2.uuid()]) new_multiframe1b = [i for i in multiframes2 if i.html() == 'mf1'][0] self.assertEqual(new_multiframe1b.layout(), l2) new_multiframe2b = [i for i in multiframes2 if i.html() == 'mf2'][0] self.assertEqual(new_multiframe2b.layout(), l2) new_frame1b = sip.cast([i for i in items if i.id() == 'frame1' and i.uuid() != new_frame1.uuid()][0], QgsLayoutFrame) new_frame2b = sip.cast([i for i in items if i.id() == 'frame2' and i.uuid() != new_frame2.uuid()][0], QgsLayoutFrame) self.assertEqual(new_frame1b.multiFrame(), new_multiframe1b) self.assertEqual(new_multiframe1b.frames()[0].uuid(), new_frame1b.uuid()) self.assertEqual(new_frame2b.multiFrame(), new_multiframe2b) self.assertEqual(new_multiframe2b.frames()[0].uuid(), new_frame2b.uuid()) # clearing existing items new_items3, ok = l2.loadFromTemplate(doc, QgsReadWriteContext(), True) new_multiframes = l2.multiFrames() self.assertTrue(ok) self.assertEqual(len(new_items3), 5) # includes page self.assertEqual(len(new_multiframes), 2) items = l2.items() self.assertTrue([i for i in items if isinstance(i, QgsLayoutItem) and i.id() == 'xxyyxx']) self.assertTrue([i for i in items if isinstance(i, QgsLayoutItem) and i.id() == 'zzyyzz']) self.assertTrue([i for i in items if isinstance(i, QgsLayoutItem) and i.id() == 'frame1']) self.assertTrue([i for i in items if isinstance(i, QgsLayoutItem) and i.id() == 'frame2']) self.assertTrue(new_items3[0] in l2.items()) self.assertTrue(new_items3[1] in l2.items()) self.assertTrue(new_items3[2] in l2.items()) self.assertTrue(new_items3[3] in l2.items()) new_multiframe1 = [i for i in new_multiframes if i.html() == 'mf1'][0] new_multiframe2 = [i for i in new_multiframes if i.html() == 'mf2'][0] new_frame1 = sip.cast([i for i in items if isinstance(i, QgsLayoutItem) and i.id() == 'frame1'][0], QgsLayoutFrame) new_frame2 = sip.cast([i for i in items if isinstance(i, QgsLayoutItem) and i.id() == 'frame2'][0], QgsLayoutFrame) self.assertEqual(new_frame1.multiFrame(), new_multiframe1) self.assertEqual(new_multiframe1.frames()[0].uuid(), new_frame1.uuid()) self.assertEqual(new_frame2.multiFrame(), new_multiframe2) self.assertEqual(new_multiframe2.frames()[0].uuid(), new_frame2.uuid())
def testContainsAdvancedEffectsAndRasterization(self): layout = QgsLayout(QgsProject.instance()) item = QgsLayoutItemLabel(layout) self.assertFalse(item.containsAdvancedEffects()) # item opacity requires that the individual item be flattened to a raster item item.setItemOpacity(0.5) self.assertTrue(item.containsAdvancedEffects()) # but not the WHOLE layout self.assertFalse(item.requiresRasterization()) item.dataDefinedProperties().setProperty( QgsLayoutObject.Opacity, QgsProperty.fromExpression('100')) item.refresh() self.assertFalse(item.containsAdvancedEffects()) self.assertFalse(item.requiresRasterization()) item.dataDefinedProperties().setProperty(QgsLayoutObject.Opacity, QgsProperty()) item.refresh() self.assertTrue(item.containsAdvancedEffects()) self.assertFalse(item.requiresRasterization()) item.setItemOpacity(1.0) self.assertFalse(item.containsAdvancedEffects()) self.assertFalse(item.requiresRasterization()) # item blend mode is NOT an advanced effect -- rather it requires that the WHOLE layout be rasterized to achieve item.setBlendMode(QPainter.CompositionMode_DestinationAtop) self.assertFalse(item.containsAdvancedEffects()) self.assertTrue(item.requiresRasterization()) map = QgsLayoutItemMap(layout) # map items are different -- because they override paint, they don't get the auto-flattening and rasterization map.setItemOpacity(0.5) self.assertFalse(map.containsAdvancedEffects()) # rather, a map with opacity requires the WHOLE layout to be rasterized self.assertTrue(map.requiresRasterization()) map.dataDefinedProperties().setProperty( QgsLayoutObject.Opacity, QgsProperty.fromExpression('100')) map.refresh() self.assertFalse(map.containsAdvancedEffects()) self.assertTrue(map.requiresRasterization())
def testAddItemsFromXml(self): p = QgsProject() l = QgsLayout(p) # add some items item1 = QgsLayoutItemLabel(l) item1.setId('xxyyxx') item1.attemptMove(QgsLayoutPoint(4, 8, QgsUnitTypes.LayoutMillimeters)) item1.attemptResize(QgsLayoutSize(18, 12, QgsUnitTypes.LayoutMillimeters)) l.addItem(item1) item2 = QgsLayoutItemLabel(l) item2.setId('zzyyzz') item2.attemptMove(QgsLayoutPoint(1.4, 1.8, QgsUnitTypes.LayoutCentimeters)) item2.attemptResize(QgsLayoutSize(2.8, 2.2, QgsUnitTypes.LayoutCentimeters)) l.addItem(item2) doc = QDomDocument("testdoc") # store in xml elem = l.writeXml(doc, QgsReadWriteContext()) l2 = QgsLayout(p) new_items = l2.addItemsFromXml(elem, doc, QgsReadWriteContext()) self.assertEqual(len(new_items), 2) items = l2.items() self.assertTrue([i for i in items if i.id() == 'xxyyxx']) self.assertTrue([i for i in items if i.id() == 'zzyyzz']) self.assertTrue(new_items[0] in l2.items()) self.assertTrue(new_items[1] in l2.items()) new_item1 = [i for i in items if i.id() == 'xxyyxx'][0] new_item2 = [i for i in items if i.id() == 'zzyyzz'][0] self.assertEqual(new_item1.positionWithUnits(), QgsLayoutPoint(4, 8, QgsUnitTypes.LayoutMillimeters)) self.assertEqual(new_item1.sizeWithUnits(), QgsLayoutSize(18, 12, QgsUnitTypes.LayoutMillimeters)) self.assertEqual(new_item2.positionWithUnits(), QgsLayoutPoint(1.4, 1.8, QgsUnitTypes.LayoutCentimeters)) self.assertEqual(new_item2.sizeWithUnits(), QgsLayoutSize(2.8, 2.2, QgsUnitTypes.LayoutCentimeters)) # test with a group group = QgsLayoutItemGroup(l) group.addItem(item1) group.addItem(item2) l.addLayoutItem(group) elem = l.writeXml(doc, QgsReadWriteContext()) l3 = QgsLayout(p) new_items = l3.addItemsFromXml(elem, doc, QgsReadWriteContext()) self.assertEqual(len(new_items), 3) items = l3.items() self.assertTrue([i for i in items if i.id() == 'xxyyxx']) self.assertTrue([i for i in items if i.id() == 'zzyyzz']) self.assertTrue(new_items[0] in l3.items()) self.assertTrue(new_items[1] in l3.items()) self.assertTrue(new_items[2] in l3.items()) # f*** you sip, I'll just manually cast new_group = sip.cast(l3.itemByUuid(group.uuid()), QgsLayoutItemGroup) self.assertIsNotNone(new_group) other_items = [i for i in new_items if i.type() != new_group.type()] self.assertCountEqual(new_group.items(), other_items) # test restoring at set position l3 = QgsLayout(p) new_items = l3.addItemsFromXml(elem, doc, QgsReadWriteContext(), QPointF(10, 30)) self.assertEqual(len(new_items), 3) items = l3.items() new_item1 = [i for i in items if i.id() == 'xxyyxx'][0] new_item2 = [i for i in items if i.id() == 'zzyyzz'][0] self.assertEqual(new_item1.positionWithUnits(), QgsLayoutPoint(10, 30, QgsUnitTypes.LayoutMillimeters)) self.assertEqual(new_item1.sizeWithUnits(), QgsLayoutSize(18, 12, QgsUnitTypes.LayoutMillimeters)) self.assertEqual(new_item2.positionWithUnits(), QgsLayoutPoint(2.0, 4.0, QgsUnitTypes.LayoutCentimeters)) self.assertEqual(new_item2.sizeWithUnits(), QgsLayoutSize(2.8, 2.2, QgsUnitTypes.LayoutCentimeters)) # paste in place l4 = QgsLayout(p) page = QgsLayoutItemPage(l) page.setPageSize('A3') l4.pageCollection().addPage(page) page = QgsLayoutItemPage(l) page.setPageSize('A6') l4.pageCollection().addPage(page) new_items = l4.addItemsFromXml(elem, doc, QgsReadWriteContext(), QPointF(10, 30), True) self.assertEqual(len(new_items), 3) new_item1 = [i for i in new_items if i.id() == 'xxyyxx'][0] new_item2 = [i for i in new_items if i.id() == 'zzyyzz'][0] self.assertEqual(new_item1.pagePositionWithUnits(), QgsLayoutPoint(4, 8, QgsUnitTypes.LayoutMillimeters)) self.assertEqual(new_item1.sizeWithUnits(), QgsLayoutSize(18, 12, QgsUnitTypes.LayoutMillimeters)) self.assertEqual(new_item1.page(), 0) self.assertEqual(new_item2.pagePositionWithUnits(), QgsLayoutPoint(1.4, 1.8, QgsUnitTypes.LayoutCentimeters)) self.assertEqual(new_item2.sizeWithUnits(), QgsLayoutSize(2.8, 2.2, QgsUnitTypes.LayoutCentimeters)) self.assertEqual(new_item2.page(), 0) # paste in place, page 2 new_items = l4.addItemsFromXml(elem, doc, QgsReadWriteContext(), QPointF(10, 550), True) self.assertEqual(len(new_items), 3) new_item1 = [i for i in new_items if i.id() == 'xxyyxx'][0] new_item2 = [i for i in new_items if i.id() == 'zzyyzz'][0] self.assertEqual(new_item1.pagePositionWithUnits(), QgsLayoutPoint(4, 8, QgsUnitTypes.LayoutMillimeters)) self.assertEqual(new_item1.page(), 1) self.assertEqual(new_item1.sizeWithUnits(), QgsLayoutSize(18, 12, QgsUnitTypes.LayoutMillimeters)) self.assertEqual(new_item2.pagePositionWithUnits(), QgsLayoutPoint(1.4, 1.8, QgsUnitTypes.LayoutCentimeters)) self.assertEqual(new_item2.page(), 1) self.assertEqual(new_item2.sizeWithUnits(), QgsLayoutSize(2.8, 2.2, QgsUnitTypes.LayoutCentimeters))
def testCutPaste(self): p = QgsProject() l = QgsLayout(p) # clear clipboard mime_data = QMimeData() mime_data.setData("text/xml", QByteArray()) clipboard = QApplication.clipboard() clipboard.setMimeData(mime_data) # add an item item1 = QgsLayoutItemLabel(l) item1.setText('label 1') l.addLayoutItem(item1) item1.setSelected(True) item2 = QgsLayoutItemLabel(l) item2.setText('label 2') l.addLayoutItem(item2) item2.setSelected(True) view = QgsLayoutView() view.setCurrentLayout(l) self.assertFalse(view.hasItemsInClipboard()) len_before = len(l.items()) view.copySelectedItems(QgsLayoutView.ClipboardCut) self.assertTrue(view.hasItemsInClipboard()) self.assertEqual(len(l.items()), len_before - 2) pasted = view.pasteItems(QgsLayoutView.PasteModeCursor) self.assertEqual(len(pasted), 2) self.assertEqual(len(l.items()), len_before) self.assertIn(pasted[0], l.items()) self.assertIn(pasted[1], l.items()) self.assertIn(sip.cast(pasted[0], QgsLayoutItemLabel).text(), ('label 1', 'label 2')) self.assertIn(sip.cast(pasted[1], QgsLayoutItemLabel).text(), ('label 1', 'label 2'))
def testAddItemsFromXml(self): p = QgsProject() l = QgsLayout(p) # add some items item1 = QgsLayoutItemLabel(l) item1.setId('xxyyxx') item1.attemptMove(QgsLayoutPoint(4, 8, QgsUnitTypes.LayoutMillimeters)) item1.attemptResize( QgsLayoutSize(18, 12, QgsUnitTypes.LayoutMillimeters)) l.addItem(item1) item2 = QgsLayoutItemLabel(l) item2.setId('zzyyzz') item2.attemptMove( QgsLayoutPoint(1.4, 1.8, QgsUnitTypes.LayoutCentimeters)) item2.attemptResize( QgsLayoutSize(2.8, 2.2, QgsUnitTypes.LayoutCentimeters)) l.addItem(item2) doc = QDomDocument("testdoc") # store in xml elem = l.writeXml(doc, QgsReadWriteContext()) l2 = QgsLayout(p) new_items = l2.addItemsFromXml(elem, doc, QgsReadWriteContext()) self.assertEqual(len(new_items), 2) items = l2.items() self.assertTrue([i for i in items if i.id() == 'xxyyxx']) self.assertTrue([i for i in items if i.id() == 'zzyyzz']) self.assertTrue(new_items[0] in l2.items()) self.assertTrue(new_items[1] in l2.items()) new_item1 = [i for i in items if i.id() == 'xxyyxx'][0] new_item2 = [i for i in items if i.id() == 'zzyyzz'][0] self.assertEqual(new_item1.positionWithUnits(), QgsLayoutPoint(4, 8, QgsUnitTypes.LayoutMillimeters)) self.assertEqual(new_item1.sizeWithUnits(), QgsLayoutSize(18, 12, QgsUnitTypes.LayoutMillimeters)) self.assertEqual( new_item2.positionWithUnits(), QgsLayoutPoint(1.4, 1.8, QgsUnitTypes.LayoutCentimeters)) self.assertEqual( new_item2.sizeWithUnits(), QgsLayoutSize(2.8, 2.2, QgsUnitTypes.LayoutCentimeters)) # test with a group group = QgsLayoutItemGroup(l) group.addItem(item1) group.addItem(item2) l.addLayoutItem(group) elem = l.writeXml(doc, QgsReadWriteContext()) l3 = QgsLayout(p) new_items = l3.addItemsFromXml(elem, doc, QgsReadWriteContext()) self.assertEqual(len(new_items), 3) items = l3.items() self.assertTrue([i for i in items if i.id() == 'xxyyxx']) self.assertTrue([i for i in items if i.id() == 'zzyyzz']) self.assertTrue(new_items[0] in l3.items()) self.assertTrue(new_items[1] in l3.items()) self.assertTrue(new_items[2] in l3.items()) # f*** you sip, I'll just manually cast new_group = sip.cast(l3.itemByUuid(group.uuid()), QgsLayoutItemGroup) self.assertIsNotNone(new_group) other_items = [i for i in new_items if i.type() != new_group.type()] self.assertCountEqual(new_group.items(), other_items) # test restoring at set position l3 = QgsLayout(p) new_items = l3.addItemsFromXml(elem, doc, QgsReadWriteContext(), QPointF(10, 30)) self.assertEqual(len(new_items), 3) items = l3.items() new_item1 = [i for i in items if i.id() == 'xxyyxx'][0] new_item2 = [i for i in items if i.id() == 'zzyyzz'][0] self.assertEqual( new_item1.positionWithUnits(), QgsLayoutPoint(10, 30, QgsUnitTypes.LayoutMillimeters)) self.assertEqual(new_item1.sizeWithUnits(), QgsLayoutSize(18, 12, QgsUnitTypes.LayoutMillimeters)) self.assertEqual( new_item2.positionWithUnits(), QgsLayoutPoint(2.0, 4.0, QgsUnitTypes.LayoutCentimeters)) self.assertEqual( new_item2.sizeWithUnits(), QgsLayoutSize(2.8, 2.2, QgsUnitTypes.LayoutCentimeters)) # paste in place l4 = QgsLayout(p) page = QgsLayoutItemPage(l) page.setPageSize('A3') l4.pageCollection().addPage(page) page = QgsLayoutItemPage(l) page.setPageSize('A6') l4.pageCollection().addPage(page) new_items = l4.addItemsFromXml(elem, doc, QgsReadWriteContext(), QPointF(10, 30), True) self.assertEqual(len(new_items), 3) new_item1 = [i for i in new_items if i.id() == 'xxyyxx'][0] new_item2 = [i for i in new_items if i.id() == 'zzyyzz'][0] self.assertEqual(new_item1.pagePositionWithUnits(), QgsLayoutPoint(4, 8, QgsUnitTypes.LayoutMillimeters)) self.assertEqual(new_item1.sizeWithUnits(), QgsLayoutSize(18, 12, QgsUnitTypes.LayoutMillimeters)) self.assertEqual(new_item1.page(), 0) self.assertEqual( new_item2.pagePositionWithUnits(), QgsLayoutPoint(1.4, 1.8, QgsUnitTypes.LayoutCentimeters)) self.assertEqual( new_item2.sizeWithUnits(), QgsLayoutSize(2.8, 2.2, QgsUnitTypes.LayoutCentimeters)) self.assertEqual(new_item2.page(), 0) # paste in place, page 2 new_items = l4.addItemsFromXml(elem, doc, QgsReadWriteContext(), QPointF(10, 550), True) self.assertEqual(len(new_items), 3) new_item1 = [i for i in new_items if i.id() == 'xxyyxx'][0] new_item2 = [i for i in new_items if i.id() == 'zzyyzz'][0] self.assertEqual(new_item1.pagePositionWithUnits(), QgsLayoutPoint(4, 8, QgsUnitTypes.LayoutMillimeters)) self.assertEqual(new_item1.page(), 1) self.assertEqual(new_item1.sizeWithUnits(), QgsLayoutSize(18, 12, QgsUnitTypes.LayoutMillimeters)) self.assertEqual( new_item2.pagePositionWithUnits(), QgsLayoutPoint(1.4, 1.8, QgsUnitTypes.LayoutCentimeters)) self.assertEqual(new_item2.page(), 1) self.assertEqual( new_item2.sizeWithUnits(), QgsLayoutSize(2.8, 2.2, QgsUnitTypes.LayoutCentimeters))
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 buildComposerLabel(self, key, item, page): ''' Add a label to the print layout for an item and page ''' cl = QgsLayoutItemLabel(self.currentComposition) # 1st page is a map for parcelle dpage = page -1 if self.etype == 'parcelle' and self.print_parcelle_page: dpage = page cl.attemptMove( QgsLayoutPoint( item['position'][0], item['position'][1]+ (dpage) * (self.pageHeight + 10), QgsUnitTypes.LayoutMillimeters ) ) cl.setFixedSize( QgsLayoutSize( item['position'][2], item['position'][3], QgsUnitTypes.LayoutMillimeters ) ) cl.setVAlign(item['align'][0]) cl.setHAlign(item['align'][1]) content = self.getContentForGivenItem( key, item, page ) cl.setMargin(0) cl.setMode(1) cl.setText(content) cl.setFrameEnabled(False) if 'bgcolor' in item: cl.setBackgroundColor(item['bgcolor']) if 'htmlState' in item: cl.setMode(item['htmlState']) if 'font' in item: cl.setFont(item['font']) self.currentComposition.addLayoutItem(cl)
def testSaveLoadTemplate(self): tmpfile = os.path.join(self.basetestpath, 'testTemplate.qpt') p = QgsProject() l = QgsLayout(p) l.initializeDefaults() # add some items item1 = QgsLayoutItemLabel(l) item1.setId('xxyyxx') item1.attemptMove(QgsLayoutPoint(4, 8, QgsUnitTypes.LayoutMillimeters)) item1.attemptResize( QgsLayoutSize(18, 12, QgsUnitTypes.LayoutMillimeters)) l.addItem(item1) item2 = QgsLayoutItemLabel(l) item2.setId('zzyyzz') item2.attemptMove( QgsLayoutPoint(1.4, 1.8, QgsUnitTypes.LayoutCentimeters)) item2.attemptResize( QgsLayoutSize(2.8, 2.2, QgsUnitTypes.LayoutCentimeters)) l.addItem(item2) uuids = {item1.uuid(), item2.uuid()} original_uuids = {item1.uuid(), item2.uuid()} self.assertTrue(l.saveAsTemplate(tmpfile, QgsReadWriteContext())) l2 = QgsLayout(p) with open(tmpfile) as f: template_content = f.read() doc = QDomDocument() doc.setContent(template_content) # adding to existing items new_items, ok = l2.loadFromTemplate(doc, QgsReadWriteContext(), False) self.assertTrue(ok) self.assertEqual(len(new_items), 2) items = l2.items() self.assertTrue([i for i in items if i.id() == 'xxyyxx']) self.assertTrue([i for i in items if i.id() == 'zzyyzz']) self.assertTrue(new_items[0] in l2.items()) self.assertTrue(new_items[1] in l2.items()) # double check that new items have a unique uid self.assertNotIn(new_items[0].uuid(), uuids) self.assertIn(new_items[0].templateUuid(), original_uuids) uuids.add(new_items[0].uuid()) self.assertNotIn(new_items[1].uuid(), uuids) self.assertIn(new_items[1].templateUuid(), original_uuids) uuids.add(new_items[1].uuid()) # adding to existing items new_items2, ok = l2.loadFromTemplate(doc, QgsReadWriteContext(), False) self.assertTrue(ok) self.assertEqual(len(new_items2), 2) items = l2.items() self.assertEqual(len(items), 4) self.assertTrue([i for i in items if i.id() == 'xxyyxx']) self.assertTrue([i for i in items if i.id() == 'zzyyzz']) self.assertTrue(new_items[0] in l2.items()) self.assertTrue(new_items[1] in l2.items()) self.assertTrue(new_items2[0] in l2.items()) self.assertTrue(new_items2[1] in l2.items()) self.assertNotIn(new_items2[0].uuid(), uuids) self.assertIn(new_items2[0].templateUuid(), original_uuids) uuids.add(new_items[0].uuid()) self.assertNotIn(new_items2[1].uuid(), uuids) self.assertIn(new_items2[1].templateUuid(), original_uuids) uuids.add(new_items[1].uuid()) # clearing existing items new_items3, ok = l2.loadFromTemplate(doc, QgsReadWriteContext(), True) self.assertTrue(ok) self.assertEqual(len(new_items3), 3) # includes page items = l2.items() self.assertTrue([ i for i in items if isinstance(i, QgsLayoutItem) and i.id() == 'xxyyxx' ]) self.assertTrue([ i for i in items if isinstance(i, QgsLayoutItem) and i.id() == 'zzyyzz' ]) self.assertTrue(new_items3[0] in l2.items()) self.assertTrue(new_items3[1] in l2.items()) self.assertIn(new_items3[0].templateUuid(), original_uuids) self.assertIn(new_items3[1].templateUuid(), original_uuids) self.assertEqual(l2.itemByUuid(new_items3[0].templateUuid(), True), new_items3[0]) self.assertEqual(l2.itemByUuid(new_items3[1].templateUuid(), True), new_items3[1])