def testTakePage(self): p = QgsProject() l = QgsLayout(p) collection = l.pageCollection() # add some pages page = QgsLayoutItemPage(l) page.setPageSize('A4') collection.addPage(page) page2 = QgsLayoutItemPage(l) page2.setPageSize('A5') collection.addPage(page2) self.assertEqual(collection.pageCount(), 2) self.assertFalse(collection.takePage(None)) self.assertEqual(collection.takePage(page), page) self.assertFalse(sip.isdeleted(page)) self.assertEqual(collection.pageCount(), 1) self.assertEqual(collection.pages(), [page2]) self.assertEqual(collection.page(0), page2) self.assertEqual(collection.takePage(page2), page2) self.assertFalse(sip.isdeleted(page2)) self.assertEqual(collection.pageCount(), 0) self.assertEqual(collection.pages(), []) self.assertFalse(collection.page(0))
def testRemoveLayout(self): project = QgsProject() layout = QgsLayout(project) layout.setName('test layout') self.manager = QgsLayoutManager(project) layout_removed_spy = QSignalSpy(self.manager.layoutRemoved) layout_about_to_be_removed_spy = QSignalSpy(self.manager.layoutAboutToBeRemoved) # tests that layout still exists when layoutAboutToBeRemoved is fired self.manager.layoutAboutToBeRemoved.connect(self.layoutAboutToBeRemoved) # not added, should fail self.assertFalse(self.manager.removeLayout(layout)) self.assertEqual(len(layout_removed_spy), 0) self.assertEqual(len(layout_about_to_be_removed_spy), 0) self.assertTrue(self.manager.addLayout(layout)) self.assertEqual(self.manager.layouts(), [layout]) self.assertTrue(self.manager.removeLayout(layout)) self.assertEqual(len(self.manager.layouts()), 0) self.assertEqual(len(layout_removed_spy), 1) self.assertEqual(layout_removed_spy[0][0], 'test layout') self.assertEqual(len(layout_about_to_be_removed_spy), 1) self.assertEqual(layout_about_to_be_removed_spy[0][0], 'test layout') self.assertTrue(self.aboutFired) self.manager = None
def testTrueNorth(self): """Test syncing picture to true north""" layout = QgsLayout(QgsProject.instance()) map = QgsLayoutItemMap(layout) map.attemptSetSceneRect(QRectF(0, 0, 10, 10)) map.setCrs(QgsCoordinateReferenceSystem.fromEpsgId(3575)) map.setExtent(QgsRectangle(-2126029.962, -2200807.749, -119078.102, -757031.156)) layout.addLayoutItem(map) picture = QgsLayoutItemPicture(layout) layout.addLayoutItem(picture) picture.setLinkedMap(map) self.assertEqual(picture.linkedMap(), map) picture.setNorthMode(QgsLayoutItemPicture.TrueNorth) self.assertAlmostEqual(picture.pictureRotation(), 37.20, 1) # shift map map.setExtent(QgsRectangle(2120672.293, -3056394.691, 2481640.226, -2796718.780)) self.assertAlmostEqual(picture.pictureRotation(), -38.18, 1) # rotate map map.setMapRotation(45) self.assertAlmostEqual(picture.pictureRotation(), -38.18 + 45, 1) # add an offset picture.setNorthOffset(-10) self.assertAlmostEqual(picture.pictureRotation(), -38.18 + 35, 1)
def testRenderPage(self): l = QgsLayout(QgsProject.instance()) l.initializeDefaults() # add some items item1 = QgsLayoutItemShape(l) item1.attemptSetSceneRect(QRectF(10, 20, 100, 150)) fill = QgsSimpleFillSymbolLayer() fill_symbol = QgsFillSymbol() fill_symbol.changeSymbolLayer(0, fill) fill.setColor(Qt.green) fill.setStrokeStyle(Qt.NoPen) item1.setSymbol(fill_symbol) l.addItem(item1) # get width/height, create image and render the composition to it size = QSize(1122, 794) output_image = QImage(size, QImage.Format_RGB32) output_image.setDotsPerMeterX(self.dots_per_meter) output_image.setDotsPerMeterY(self.dots_per_meter) QgsMultiRenderChecker.drawBackground(output_image) painter = QPainter(output_image) exporter = QgsLayoutExporter(l) # valid page exporter.renderPage(painter, 0) painter.end() rendered_file_path = os.path.join(self.basetestpath, 'test_renderpage.png') output_image.save(rendered_file_path, "PNG") self.assertTrue(self.checkImage('renderpage', 'renderpage', rendered_file_path))
def testClear(self): """ Test clearing the collection """ p = QgsProject() l = QgsLayout(p) collection = l.pageCollection() collection.clear() # add a page page = QgsLayoutItemPage(l) page.setPageSize('A4') collection.addPage(page) # add a second page page2 = QgsLayoutItemPage(l) page2.setPageSize('A5') collection.addPage(page2) page_about_to_be_removed_spy = QSignalSpy(collection.pageAboutToBeRemoved) # clear collection.clear() self.assertEqual(collection.pageCount(), 0) self.assertEqual(len(page_about_to_be_removed_spy), 2) QCoreApplication.sendPostedEvents(None, QEvent.DeferredDelete) self.assertTrue(sip.isdeleted(page)) self.assertTrue(sip.isdeleted(page2))
def testMaxPageWidthAndSize(self): """ Test calculating maximum page width and size """ p = QgsProject() l = QgsLayout(p) collection = l.pageCollection() # add a page page = QgsLayoutItemPage(l) page.setPageSize('A4') collection.addPage(page) self.assertEqual(collection.maximumPageWidth(), 210.0) self.assertEqual(collection.maximumPageSize().width(), 210.0) self.assertEqual(collection.maximumPageSize().height(), 297.0) # add a second page page2 = QgsLayoutItemPage(l) page2.setPageSize('A3') collection.addPage(page2) self.assertEqual(collection.maximumPageWidth(), 297.0) self.assertEqual(collection.maximumPageSize().width(), 297.0) self.assertEqual(collection.maximumPageSize().height(), 420.0) # add a page with other units page3 = QgsLayoutItemPage(l) page3.setPageSize(QgsLayoutSize(100, 100, QgsUnitTypes.LayoutMeters)) collection.addPage(page3) self.assertEqual(collection.maximumPageWidth(), 100000.0) self.assertEqual(collection.maximumPageSize().width(), 100000.0) self.assertEqual(collection.maximumPageSize().height(), 100000.0)
def testExtendByNewPage(self): """ Test extend by adding new page """ p = QgsProject() l = QgsLayout(p) collection = l.pageCollection() # no existing page to extend self.assertIsNone(collection.extendByNewPage()) self.assertEqual(collection.pageCount(), 0) # add a page page = QgsLayoutItemPage(l) page.setPageSize(QgsLayoutSize(10, 10)) collection.addPage(page) self.assertEqual(collection.pageCount(), 1) new_page = collection.extendByNewPage() self.assertIsNotNone(new_page) self.assertEqual(collection.pageCount(), 2) self.assertEqual(new_page.sizeWithUnits(), page.sizeWithUnits()) new_page.setPageSize(QgsLayoutSize(20, 20)) new_page2 = collection.extendByNewPage() self.assertIsNotNone(new_page2) self.assertEqual(collection.pageCount(), 3) self.assertEqual(new_page2.sizeWithUnits(), new_page.sizeWithUnits())
def testZebraStyle(self): layout = QgsLayout(QgsProject.instance()) layout.initializeDefaults() map = QgsLayoutItemMap(layout) map.attemptSetSceneRect(QRectF(20, 20, 200, 100)) map.setFrameEnabled(True) map.setBackgroundColor(QColor(150, 100, 100)) layout.addLayoutItem(map) map.grid().setFrameStyle(QgsLayoutItemMapGrid.Zebra) myRectangle = QgsRectangle(785462.375, 3341423.125, 789262.375, 3343323.125) map.setExtent(myRectangle) map.grid().setIntervalX(2000) map.grid().setIntervalY(2000) map.grid().setGridLineColor(QColor(0, 0, 0)) map.grid().setAnnotationFontColor(QColor(0, 0, 0)) map.grid().setBlendMode(QPainter.CompositionMode_SourceOver) map.grid().setFrameStyle(QgsLayoutItemMapGrid.Zebra) map.grid().setFrameWidth(10) map.grid().setFramePenSize(1) map.grid().setGridLineWidth(0.5) map.grid().setFramePenColor(QColor(255, 100, 0, 200)) map.grid().setFrameFillColor1(QColor(50, 90, 50, 100)) map.grid().setFrameFillColor2(QColor(200, 220, 100, 60)) map.grid().setEnabled(True) map.updateBoundingRect() checker = QgsLayoutChecker('composermap_zebrastyle', layout) checker.setControlPathPrefix("composer_mapgrid") myTestResult, myMessage = checker.testLayout(0, 100) assert myTestResult, myMessage
def testUniformPageSizes(self): """ Test detection of uniform page sizes """ p = QgsProject() l = QgsLayout(p) collection = l.pageCollection() self.assertTrue(collection.hasUniformPageSizes()) # add a page page = QgsLayoutItemPage(l) page.setPageSize('A4') collection.addPage(page) self.assertTrue(collection.hasUniformPageSizes()) # add a second page page2 = QgsLayoutItemPage(l) page2.setPageSize(QgsLayoutSize(21.0, 29.7, QgsUnitTypes.LayoutCentimeters)) collection.addPage(page2) self.assertTrue(collection.hasUniformPageSizes()) # add a page with other units page3 = QgsLayoutItemPage(l) page3.setPageSize('A5') collection.addPage(page3) self.assertFalse(collection.hasUniformPageSizes())
def testRenderPageToImage(self): l = QgsLayout(QgsProject.instance()) l.initializeDefaults() # add some items item1 = QgsLayoutItemShape(l) item1.attemptSetSceneRect(QRectF(10, 20, 100, 150)) fill = QgsSimpleFillSymbolLayer() fill_symbol = QgsFillSymbol() fill_symbol.changeSymbolLayer(0, fill) fill.setColor(Qt.green) fill.setStrokeStyle(Qt.NoPen) item1.setSymbol(fill_symbol) l.addItem(item1) exporter = QgsLayoutExporter(l) size = QSize(1122, 794) # bad page numbers image = exporter.renderPageToImage(-1, size) self.assertTrue(image.isNull()) image = exporter.renderPageToImage(1, size) self.assertTrue(image.isNull()) # good page image = exporter.renderPageToImage(0, size) self.assertFalse(image.isNull()) rendered_file_path = os.path.join(self.basetestpath, 'test_rendertoimagepage.png') image.save(rendered_file_path, "PNG") self.assertTrue(self.checkImage('rendertoimagepage', 'rendertoimagepage', rendered_file_path))
def testInteriorTicks(self): layout = QgsLayout(QgsProject.instance()) layout.initializeDefaults() map = QgsLayoutItemMap(layout) map.attemptSetSceneRect(QRectF(20, 20, 200, 100)) map.setFrameEnabled(True) map.setBackgroundColor(QColor(150, 100, 100)) layout.addLayoutItem(map) map.grid().setFrameStyle(QgsLayoutItemMapGrid.Zebra) myRectangle = QgsRectangle(781662.375, 3339523.125, 793062.375, 3345223.125) map.setExtent(myRectangle) map.grid().setIntervalX(2000) map.grid().setIntervalY(2000) map.grid().setAnnotationFontColor(QColor(0, 0, 0)) map.grid().setBlendMode(QPainter.CompositionMode_SourceOver) map.grid().setFrameStyle(QgsLayoutItemMapGrid.InteriorTicks) map.grid().setFrameWidth(10) map.grid().setFramePenSize(1) map.grid().setFramePenColor(QColor(0, 0, 0)) map.grid().setEnabled(True) map.grid().setStyle(QgsLayoutItemMapGrid.FrameAnnotationsOnly) map.updateBoundingRect() checker = QgsLayoutChecker('composermap_interiorticks', layout) checker.setControlPathPrefix("composer_mapgrid") myTestResult, myMessage = checker.testLayout(0, 100) assert myTestResult, myMessage
def testCrossGrid(self): layout = QgsLayout(QgsProject.instance()) layout.initializeDefaults() map = QgsLayoutItemMap(layout) map.attemptSetSceneRect(QRectF(20, 20, 200, 100)) map.setFrameEnabled(True) map.setBackgroundColor(QColor(150, 100, 100)) layout.addLayoutItem(map) myRectangle = QgsRectangle(781662.375, 3339523.125, 793062.375, 3345223.125) map.setExtent(myRectangle) map.grid().setEnabled(True) map.grid().setStyle(QgsLayoutItemMapGrid.Cross) map.grid().setCrossLength(2.0) map.grid().setIntervalX(2000) map.grid().setIntervalY(2000) map.grid().setAnnotationEnabled(False) map.grid().setGridLineColor(QColor(0, 255, 0)) map.grid().setGridLineWidth(0.5) map.grid().setBlendMode(QPainter.CompositionMode_SourceOver) map.updateBoundingRect() checker = QgsLayoutChecker('composermap_crossgrid', layout) checker.setControlPathPrefix("composer_mapgrid") myTestResult, myMessage = checker.testLayout() map.grid().setStyle(QgsLayoutItemMapGrid.Solid) map.grid().setEnabled(False) map.grid().setAnnotationEnabled(False) assert myTestResult, myMessage
def testAddLayout(self): project = QgsProject() layout = QgsLayout(project) layout.setName('test layout') manager = QgsLayoutManager(project) layout_about_to_be_added_spy = QSignalSpy(manager.layoutAboutToBeAdded) layout_added_spy = QSignalSpy(manager.layoutAdded) self.assertTrue(manager.addLayout(layout)) self.assertEqual(len(layout_about_to_be_added_spy), 1) self.assertEqual(layout_about_to_be_added_spy[0][0], 'test layout') self.assertEqual(len(layout_added_spy), 1) self.assertEqual(layout_added_spy[0][0], 'test layout') # adding it again should fail self.assertFalse(manager.addLayout(layout)) # try adding a second layout layout2 = QgsLayout(project) layout2.setName('test layout2') self.assertTrue(manager.addLayout(layout2)) self.assertEqual(len(layout_added_spy), 2) self.assertEqual(layout_about_to_be_added_spy[1][0], 'test layout2') self.assertEqual(len(layout_about_to_be_added_spy), 2) self.assertEqual(layout_added_spy[1][0], 'test layout2') # adding a layout with duplicate name should fail layout3 = QgsLayout(project) layout3.setName('test layout2') self.assertFalse(manager.addLayout(layout3))
def testReflow(self): """ Test reflowing pages """ p = QgsProject() l = QgsLayout(p) collection = l.pageCollection() # add a page page = QgsLayoutItemPage(l) page.setPageSize('A4') collection.addPage(page) # should be positioned at origin self.assertEqual(page.pos().x(), 0) self.assertEqual(page.pos().y(), 0) # second page page2 = QgsLayoutItemPage(l) page2.setPageSize('A5') collection.addPage(page2) self.assertEqual(page.pos().x(), 0) self.assertEqual(page.pos().y(), 0) self.assertEqual(page2.pos().x(), 0) self.assertEqual(page2.pos().y(), 307) # third page, slotted in middle page3 = QgsLayoutItemPage(l) page3.setPageSize('A3') collection.insertPage(page3, 1) self.assertEqual(page.pos().x(), 0) self.assertEqual(page.pos().y(), 0) self.assertEqual(page2.pos().x(), 0) self.assertEqual(page2.pos().y(), 737) self.assertEqual(page3.pos().x(), 0) self.assertEqual(page3.pos().y(), 307) page.setPageSize(QgsLayoutSize(100, 120)) # no update until reflow is called self.assertEqual(page.pos().x(), 0) self.assertEqual(page.pos().y(), 0) self.assertEqual(page2.pos().x(), 0) self.assertEqual(page2.pos().y(), 737) self.assertEqual(page3.pos().x(), 0) self.assertEqual(page3.pos().y(), 307) collection.reflow() self.assertEqual(page.pos().x(), 0) self.assertEqual(page.pos().y(), 0) self.assertEqual(page2.pos().x(), 0) self.assertEqual(page2.pos().y(), 560) self.assertEqual(page3.pos().x(), 0) self.assertEqual(page3.pos().y(), 130)
def testLayoutScalePixels(self): p = QgsProject() l = QgsLayout(p) l.setUnits(QgsUnitTypes.LayoutPixels) view = QgsLayoutView() view.setCurrentLayout(l) view.setZoomLevel(1) # should be no transform, since 100% with pixel units should be pixel-pixel self.assertEqual(view.transform().m11(), 1) view.setZoomLevel(0.5) self.assertEqual(view.transform().m11(), 0.5)
def testZebraStyleSides(self): layout = QgsLayout(QgsProject.instance()) layout.initializeDefaults() map = QgsLayoutItemMap(layout) map.attemptSetSceneRect(QRectF(20, 20, 200, 100)) map.setFrameEnabled(True) map.setBackgroundColor(QColor(150, 100, 100)) layout.addLayoutItem(map) map.grid().setFrameStyle(QgsLayoutItemMapGrid.Zebra) myRectangle = QgsRectangle(781662.375, 3339523.125, 793062.375, 3345223.125) map.setExtent(myRectangle) map.grid().setIntervalX(2000) map.grid().setIntervalY(2000) map.grid().setGridLineColor(QColor(0, 0, 0)) map.grid().setAnnotationFontColor(QColor(0, 0, 0)) map.grid().setBlendMode(QPainter.CompositionMode_SourceOver) map.grid().setFrameStyle(QgsLayoutItemMapGrid.Zebra) map.grid().setFrameWidth(10) map.grid().setFramePenSize(1) map.grid().setGridLineWidth(0.5) map.grid().setFramePenColor(QColor(0, 0, 0)) map.grid().setFrameFillColor1(QColor(0, 0, 0)) map.grid().setFrameFillColor2(QColor(255, 255, 255)) map.grid().setEnabled(True) map.grid().setFrameSideFlag(QgsLayoutItemMapGrid.FrameLeft, True) map.grid().setFrameSideFlag(QgsLayoutItemMapGrid.FrameRight, False) map.grid().setFrameSideFlag(QgsLayoutItemMapGrid.FrameTop, False) map.grid().setFrameSideFlag(QgsLayoutItemMapGrid.FrameBottom, False) map.updateBoundingRect() checker = QgsLayoutChecker('composermap_zebrastyle_left', layout) checker.setControlPathPrefix("composer_mapgrid") myTestResult, myMessage = checker.testLayout(0, 100) assert myTestResult, myMessage map.grid().setFrameSideFlag(QgsLayoutItemMapGrid.FrameTop, True) map.updateBoundingRect() checker = QgsLayoutChecker('composermap_zebrastyle_lefttop', layout) checker.setControlPathPrefix("composer_mapgrid") myTestResult, myMessage = checker.testLayout(0, 100) assert myTestResult, myMessage map.grid().setFrameSideFlag(QgsLayoutItemMapGrid.FrameRight, True) map.updateBoundingRect() checker = QgsLayoutChecker('composermap_zebrastyle_lefttopright', layout) checker.setControlPathPrefix("composer_mapgrid") myTestResult, myMessage = checker.testLayout(0, 100) assert myTestResult, myMessage map.grid().setFrameSideFlag(QgsLayoutItemMapGrid.FrameBottom, True) map.grid().setFrameStyle(QgsLayoutItemMapGrid.NoFrame)
def testSnapPointsToGuides(self): p = QgsProject() l = QgsLayout(p) page = QgsLayoutItemPage(l) page.setPageSize('A4') l.pageCollection().addPage(page) s = QgsLayoutSnapper(l) guides = l.guides() s.setSnapToGuides(True) s.setSnapTolerance(1) # no guides delta, snapped = s.snapPointsToGuides([0.5], Qt.Vertical, 1) self.assertFalse(snapped) guides.addGuide(QgsLayoutGuide(Qt.Vertical, QgsLayoutMeasurement(1), page)) point, snapped = s.snapPointsToGuides([0.7], Qt.Vertical, 1) self.assertTrue(snapped) self.assertAlmostEqual(point, 0.3, 5) point, snapped = s.snapPointsToGuides([0.7, 1.2], Qt.Vertical, 1) self.assertTrue(snapped) self.assertAlmostEqual(point, -0.2, 5) # outside tolerance point, snapped = s.snapPointsToGuides([5.5], Qt.Vertical, 1) self.assertFalse(snapped) # snapping off s.setSnapToGuides(False) point, snapped = s.snapPointsToGuides([0.5], Qt.Vertical, 1) self.assertFalse(snapped) s.setSnapToGuides(True) # snap to hoz point, snapped = s.snapPointsToGuides([0.5], Qt.Horizontal, 1) self.assertFalse(snapped) guides.addGuide(QgsLayoutGuide(Qt.Horizontal, QgsLayoutMeasurement(1), page)) point, snapped = s.snapPointsToGuides([0.7], Qt.Horizontal, 1) self.assertTrue(snapped) self.assertAlmostEqual(point, 0.3, 5) point, snapped = s.snapPointsToGuides([0.7, 1.2], Qt.Horizontal, 1) self.assertTrue(snapped) self.assertAlmostEqual(point, -0.2, 5) point, snapped = s.snapPointsToGuides([0.7, 0.9, 1.2], Qt.Horizontal, 1) self.assertTrue(snapped) self.assertAlmostEqual(point, 0.1, 5) # with different pixel scale point, snapped = s.snapPointsToGuides([0.5, 1.5], Qt.Horizontal, 3) self.assertFalse(snapped)
def testRemoveGuide(self): p = QgsProject() l = QgsLayout(p) l.initializeDefaults() # add a page guides = l.guides() # add a guide g1 = QgsLayoutGuide(QgsLayoutGuide.Horizontal, QgsLayoutMeasurement(5, QgsUnitTypes.LayoutCentimeters), l.pageCollection().page(0)) guides.addGuide(g1) self.assertEqual(guides.guides(QgsLayoutGuide.Horizontal), [g1]) guides.removeGuide(None) self.assertEqual(guides.guides(QgsLayoutGuide.Horizontal), [g1]) guides.removeGuide(g1) self.assertEqual(guides.guides(QgsLayoutGuide.Horizontal), [])
def testClear(self): p = QgsProject() l = QgsLayout(p) l.initializeDefaults() # add a page guides = l.guides() # add a guide g1 = QgsLayoutGuide(Qt.Horizontal, QgsLayoutMeasurement(5, QgsUnitTypes.LayoutCentimeters), l.pageCollection().page(0)) guides.addGuide(g1) g2 = QgsLayoutGuide(Qt.Horizontal, QgsLayoutMeasurement(5, QgsUnitTypes.LayoutCentimeters), l.pageCollection().page(0)) guides.addGuide(g2) self.assertEqual(guides.guides(Qt.Horizontal), [g1, g2]) guides.clear() self.assertEqual(guides.guides(Qt.Horizontal), [])
def testReadWriteXml(self): p = QgsProject() l = QgsLayout(p) l.initializeDefaults() guides = l.guides() # add some guides g1 = QgsLayoutGuide(Qt.Horizontal, QgsLayoutMeasurement(5, QgsUnitTypes.LayoutCentimeters), l.pageCollection().page(0)) guides.addGuide(g1) g2 = QgsLayoutGuide(Qt.Vertical, QgsLayoutMeasurement(6, QgsUnitTypes.LayoutInches), l.pageCollection().page(0)) guides.addGuide(g2) guides.setVisible(False) doc = QDomDocument("testdoc") elem = doc.createElement("test") self.assertTrue(guides.writeXml(elem, doc, QgsReadWriteContext())) l2 = QgsLayout(p) l2.initializeDefaults() guides2 = l2.guides() self.assertTrue(guides2.readXml(elem.firstChildElement(), doc, QgsReadWriteContext())) guide_list = guides2.guidesOnPage(0) self.assertEqual(len(guide_list), 2) self.assertEqual(guide_list[0].orientation(), Qt.Horizontal) self.assertEqual(guide_list[0].position().length(), 5.0) self.assertEqual(guide_list[0].position().units(), QgsUnitTypes.LayoutCentimeters) self.assertEqual(guide_list[1].orientation(), Qt.Vertical) self.assertEqual(guide_list[1].position().length(), 6.0) self.assertEqual(guide_list[1].position().units(), QgsUnitTypes.LayoutInches)
def testExportReport(self): p = QgsProject() r = QgsReport(p) # add a header r.setHeaderEnabled(True) report_header = QgsLayout(p) report_header.initializeDefaults() item1 = QgsLayoutItemShape(report_header) item1.attemptSetSceneRect(QRectF(10, 20, 100, 150)) fill = QgsSimpleFillSymbolLayer() fill_symbol = QgsFillSymbol() fill_symbol.changeSymbolLayer(0, fill) fill.setColor(Qt.green) fill.setStrokeStyle(Qt.NoPen) item1.setSymbol(fill_symbol) report_header.addItem(item1) r.setHeader(report_header) # add a footer r.setFooterEnabled(True) report_footer = QgsLayout(p) report_footer.initializeDefaults() item2 = QgsLayoutItemShape(report_footer) item2.attemptSetSceneRect(QRectF(10, 20, 100, 150)) item2.attemptMove(QgsLayoutPoint(10, 20)) fill = QgsSimpleFillSymbolLayer() fill_symbol = QgsFillSymbol() fill_symbol.changeSymbolLayer(0, fill) fill.setColor(Qt.cyan) fill.setStrokeStyle(Qt.NoPen) item2.setSymbol(fill_symbol) report_footer.addItem(item2) r.setFooter(report_footer) # setup settings settings = QgsLayoutExporter.ImageExportSettings() settings.dpi = 80 report_path = os.path.join(self.basetestpath, 'test_report') result, error = QgsLayoutExporter.exportToImage(r, report_path, 'png', settings) self.assertEqual(result, QgsLayoutExporter.Success, error) page1_path = os.path.join(self.basetestpath, 'test_report_0001.png') self.assertTrue(self.checkImage('report_page1', 'report_page1', page1_path)) page2_path = os.path.join(self.basetestpath, 'test_report_0002.png') self.assertTrue(self.checkImage('report_page2', 'report_page2', page2_path))
def testPredictionPageNumberForPoint(self): """ Test predictPageNumberForPoint """ p = QgsProject() l = QgsLayout(p) collection = l.pageCollection() # no crash if no pages self.assertEqual(collection.predictPageNumberForPoint(QPointF(1, 1)), 0) # add a page page = QgsLayoutItemPage(l) page.setPageSize(QgsLayoutSize(100, 100)) collection.addPage(page) self.assertEqual(collection.predictPageNumberForPoint(QPointF(-100, -100)), 0) self.assertEqual(collection.predictPageNumberForPoint(QPointF(-100, -1)), 0) self.assertEqual(collection.predictPageNumberForPoint(QPointF(-100, 20)), 0) self.assertEqual(collection.predictPageNumberForPoint(QPointF(-100, 120)), 1) self.assertEqual(collection.predictPageNumberForPoint(QPointF(-100, 230)), 2) self.assertEqual(collection.predictPageNumberForPoint(QPointF(-100, 350)), 3) page2 = QgsLayoutItemPage(l) page2.setPageSize(QgsLayoutSize(100, 50)) collection.addPage(page2) self.assertEqual(collection.predictPageNumberForPoint(QPointF(-100, -100)), 0) self.assertEqual(collection.predictPageNumberForPoint(QPointF(-100, -1)), 0) self.assertEqual(collection.predictPageNumberForPoint(QPointF(-100, 20)), 0) self.assertEqual(collection.predictPageNumberForPoint(QPointF(-100, 120)), 1) self.assertEqual(collection.predictPageNumberForPoint(QPointF(-100, 230)), 2) self.assertEqual(collection.predictPageNumberForPoint(QPointF(-100, 280)), 3) self.assertEqual(collection.predictPageNumberForPoint(QPointF(-100, 340)), 4) self.assertEqual(collection.predictPageNumberForPoint(QPointF(-100, 370)), 5) page3 = QgsLayoutItemPage(l) page3.setPageSize(QgsLayoutSize(100, 200)) collection.addPage(page3) self.assertEqual(collection.predictPageNumberForPoint(QPointF(-100, -100)), 0) self.assertEqual(collection.predictPageNumberForPoint(QPointF(-100, -1)), 0) self.assertEqual(collection.predictPageNumberForPoint(QPointF(-100, 20)), 0) self.assertEqual(collection.predictPageNumberForPoint(QPointF(-100, 120)), 1) self.assertEqual(collection.predictPageNumberForPoint(QPointF(-100, 230)), 2) self.assertEqual(collection.predictPageNumberForPoint(QPointF(-100, 280)), 2) self.assertEqual(collection.predictPageNumberForPoint(QPointF(-100, 340)), 2) self.assertEqual(collection.predictPageNumberForPoint(QPointF(-100, 370)), 2) self.assertEqual(collection.predictPageNumberForPoint(QPointF(-100, 470)), 3)
def testPrint(self): l = QgsLayout(QgsProject.instance()) l.initializeDefaults() # add a second page page2 = QgsLayoutItemPage(l) page2.setPageSize('A5') l.pageCollection().addPage(page2) # add some items item1 = QgsLayoutItemShape(l) item1.attemptSetSceneRect(QRectF(10, 20, 100, 150)) fill = QgsSimpleFillSymbolLayer() fill_symbol = QgsFillSymbol() fill_symbol.changeSymbolLayer(0, fill) fill.setColor(Qt.green) fill.setStrokeStyle(Qt.NoPen) item1.setSymbol(fill_symbol) l.addItem(item1) item2 = QgsLayoutItemShape(l) item2.attemptSetSceneRect(QRectF(10, 20, 100, 150)) item2.attemptMove(QgsLayoutPoint(10, 20), page=1) fill = QgsSimpleFillSymbolLayer() fill_symbol = QgsFillSymbol() fill_symbol.changeSymbolLayer(0, fill) fill.setColor(Qt.cyan) fill.setStrokeStyle(Qt.NoPen) item2.setSymbol(fill_symbol) l.addItem(item2) exporter = QgsLayoutExporter(l) # setup settings settings = QgsLayoutExporter.PrintExportSettings() settings.dpi = 80 settings.rasterizeWholeImage = False pdf_file_path = os.path.join(self.basetestpath, 'test_printdpi.pdf') # make a qprinter directed to pdf printer = QPrinter() printer.setOutputFileName(pdf_file_path) printer.setOutputFormat(QPrinter.PdfFormat) self.assertEqual(exporter.print(printer, settings), QgsLayoutExporter.Success) self.assertTrue(os.path.exists(pdf_file_path)) rendered_page_1 = os.path.join(self.basetestpath, 'test_exporttopdfdpi.png') dpi = 80 pdfToPng(pdf_file_path, rendered_page_1, dpi=dpi, page=1) rendered_page_2 = os.path.join(self.basetestpath, 'test_exporttopdfdpi2.png') pdfToPng(pdf_file_path, rendered_page_2, dpi=dpi, page=2) self.assertTrue(self.checkImage('printdpi_page1', 'exporttopdfdpi_page1', rendered_page_1, size_tolerance=1)) self.assertTrue(self.checkImage('printdpi_page2', 'exporttopdfdpi_page2', rendered_page_2, size_tolerance=1))
def testGuideLayoutPosition(self): p = QgsProject() l = QgsLayout(p) l.initializeDefaults() guides = l.guides() # add some guides g1 = QgsLayoutGuide(Qt.Horizontal, QgsLayoutMeasurement(1, QgsUnitTypes.LayoutCentimeters), l.pageCollection().page(0)) guides.addGuide(g1) # set position in layout units (mm) guides.setGuideLayoutPosition(g1, 50) self.assertEqual(g1.position().length(), 5.0) self.assertEqual(g1.position().units(), QgsUnitTypes.LayoutCentimeters)
def testDataDefinedTitle(self): layout = QgsLayout(QgsProject.instance()) layout.initializeDefaults() legend = QgsLayoutItemLegend(layout) layout.addLayoutItem(legend) legend.setTitle('original') self.assertEqual(legend.title(), 'original') self.assertEqual(legend.legendSettings().title(), 'original') legend.dataDefinedProperties().setProperty(QgsLayoutObject.LegendTitle, QgsProperty.fromExpression("'new'")) legend.refreshDataDefinedProperty() self.assertEqual(legend.title(), 'original') self.assertEqual(legend.legendSettings().title(), 'new')
def testDataDefinedColumnCount(self): layout = QgsLayout(QgsProject.instance()) layout.initializeDefaults() legend = QgsLayoutItemLegend(layout) layout.addLayoutItem(legend) legend.setColumnCount(2) self.assertEqual(legend.columnCount(), 2) self.assertEqual(legend.legendSettings().columnCount(), 2) legend.dataDefinedProperties().setProperty(QgsLayoutObject.LegendColumnCount, QgsProperty.fromExpression("5")) legend.refreshDataDefinedProperty() self.assertEqual(legend.columnCount(), 2) self.assertEqual(legend.legendSettings().columnCount(), 5)
def testSnapRect(self): p = QgsProject() l = QgsLayout(p) page = QgsLayoutItemPage(l) page.setPageSize('A4') l.pageCollection().addPage(page) s = QgsLayoutSnapper(l) guides = l.guides() # first test snapping to grid l.gridSettings().setResolution(QgsLayoutMeasurement(5, QgsUnitTypes.LayoutMillimeters)) s.setSnapToItems(False) s.setSnapToGrid(True) s.setSnapTolerance(1) rect, snapped = s.snapRect(QRectF(1, 1, 2, 1), 1) self.assertTrue(snapped) self.assertEqual(rect, QRectF(0, 0, 2, 1)) rect, snapped = s.snapRect(QRectF(1, 1, 3.5, 3.5), 1) self.assertTrue(snapped) self.assertEqual(rect, QRectF(1.5, 1.5, 3.5, 3.5)) s.setSnapToItems(False) s.setSnapToGrid(False) rect, snapped = s.snapRect(QRectF(1, 1, 3.5, 3.5), 1) self.assertFalse(snapped) self.assertEqual(rect, QRectF(1, 1, 3.5, 3.5)) # test that guide takes precedence s.setSnapToGrid(True) s.setSnapToGuides(True) guides.addGuide(QgsLayoutGuide(Qt.Horizontal, QgsLayoutMeasurement(0.5), page)) rect, snapped = s.snapRect(QRectF(1, 1, 2, 3), 1) self.assertTrue(snapped) self.assertEqual(rect, QRectF(0.0, 0.5, 2.0, 3.0)) # add an item item1 = QgsLayoutItemMap(l) item1.attemptMove(QgsLayoutPoint(121, 1.1, QgsUnitTypes.LayoutMillimeters)) l.addItem(item1) # test that guide takes precedence over item s.setSnapToGrid(True) s.setSnapToGuides(True) s.setSnapToItems(True) rect, snapped = s.snapRect(QRectF(1, 1, 2, 3), 1) self.assertTrue(snapped) self.assertEqual(rect, QRectF(0.0, 0.5, 2.0, 3.0)) # but items take precedence over grid s.setSnapToGuides(False) rect, snapped = s.snapRect(QRectF(1, 1, 2, 3), 1) self.assertTrue(snapped) self.assertEqual(rect, QRectF(0.0, 1.1, 2.0, 3.0)) # ... unless item is ignored! rect, snapped = s.snapRect(QRectF(1, 1, 2, 3), 1, None, None, [item1]) self.assertTrue(snapped) self.assertEqual(rect, QRectF(0.0, 0.0, 2.0, 3.0))
def __init__(self, methodName): """Run once on class initialization.""" unittest.TestCase.__init__(self, methodName) myPath = os.path.join(TEST_DATA_DIR, 'rgb256x256.png') rasterFileInfo = QFileInfo(myPath) self.raster_layer = QgsRasterLayer(rasterFileInfo.filePath(), rasterFileInfo.completeBaseName()) rasterRenderer = QgsMultiBandColorRenderer( self.raster_layer.dataProvider(), 1, 2, 3) self.raster_layer.setRenderer(rasterRenderer) myPath = os.path.join(TEST_DATA_DIR, 'points.shp') vector_file_info = QFileInfo(myPath) self.vector_layer = QgsVectorLayer(vector_file_info.filePath(), vector_file_info.completeBaseName(), 'ogr') assert self.vector_layer.isValid() # pipe = mRasterLayer.pipe() # assert pipe.set(rasterRenderer), 'Cannot set pipe renderer' QgsProject.instance().addMapLayers([self.raster_layer, self.vector_layer]) # create layout with layout map self.layout = QgsLayout(QgsProject.instance()) self.layout.initializeDefaults() self.map = QgsLayoutItemMap(self.layout) self.map.attemptSetSceneRect(QRectF(20, 20, 200, 100)) self.map.setFrameEnabled(True) self.map.setLayers([self.raster_layer]) self.layout.addLayoutItem(self.map)
def __init__(self, methodName): """Run once on class initialization.""" unittest.TestCase.__init__(self, methodName) # create composition self.layout = QgsLayout(QgsProject.instance()) self.layout.initializeDefaults() # create polygon = QPolygonF() polygon.append(QPointF(0.0, 0.0)) polygon.append(QPointF(100.0, 0.0)) polygon.append(QPointF(200.0, 100.0)) polygon.append(QPointF(100.0, 200.0)) self.polyline = QgsLayoutItemPolyline( polygon, self.layout) self.layout.addLayoutItem(self.polyline) # style props = {} props["color"] = "0,0,0,255" props["width"] = "10.0" props["capstyle"] = "square" style = QgsLineSymbol.createSimple(props) self.polyline.setSymbol(style)
def __init__(self, methodName): """Run once on class initialization.""" unittest.TestCase.__init__(self, methodName) # create composition self.layout = QgsLayout(QgsProject.instance()) self.layout.initializeDefaults() # create polygon = QPolygonF() polygon.append(QPointF(0.0, 0.0)) polygon.append(QPointF(100.0, 0.0)) polygon.append(QPointF(200.0, 100.0)) polygon.append(QPointF(100.0, 200.0)) self.polygon = QgsLayoutItemPolygon(polygon, self.layout) self.layout.addLayoutItem(self.polygon) # style props = {} props["color"] = "green" props["style"] = "solid" props["style_border"] = "solid" props["color_border"] = "black" props["width_border"] = "10.0" props["joinstyle"] = "miter" style = QgsFillSymbol.createSimple(props) self.polygon.setSymbol(style)
def testResize(self): p = QgsProject() l = QgsLayout(p) # add some items item1 = QgsLayoutItemPicture(l) item1.attemptMove(QgsLayoutPoint(4, 8, QgsUnitTypes.LayoutMillimeters)) item1.attemptResize( QgsLayoutSize(18, 12, QgsUnitTypes.LayoutMillimeters)) l.addItem(item1) item2 = QgsLayoutItemPicture(l) item2.attemptMove(QgsLayoutPoint(7, 10, QgsUnitTypes.LayoutMillimeters)) item2.attemptResize( QgsLayoutSize(10, 9, QgsUnitTypes.LayoutMillimeters)) l.addItem(item2) item3 = QgsLayoutItemPicture(l) item3.attemptMove( QgsLayoutPoint(0.8, 1.2, QgsUnitTypes.LayoutCentimeters)) item3.attemptResize( QgsLayoutSize(1.8, 1.6, QgsUnitTypes.LayoutCentimeters)) l.addItem(item3) QgsLayoutAligner.resizeItems(l, [item1, item2, item3], QgsLayoutAligner.ResizeNarrowest) self.assertEqual(item1.sizeWithUnits(), QgsLayoutSize(10, 12, QgsUnitTypes.LayoutMillimeters)) self.assertEqual(item2.sizeWithUnits(), QgsLayoutSize(10, 9, QgsUnitTypes.LayoutMillimeters)) self.assertEqual( item3.sizeWithUnits(), QgsLayoutSize(1.0, 1.6, QgsUnitTypes.LayoutCentimeters)) l.undoStack().stack().undo() QgsLayoutAligner.resizeItems(l, [item1, item2, item3], QgsLayoutAligner.ResizeWidest) self.assertEqual(item1.sizeWithUnits(), QgsLayoutSize(18, 12, QgsUnitTypes.LayoutMillimeters)) self.assertEqual(item2.sizeWithUnits(), QgsLayoutSize(18, 9, QgsUnitTypes.LayoutMillimeters)) self.assertEqual( item3.sizeWithUnits(), QgsLayoutSize(1.8, 1.6, QgsUnitTypes.LayoutCentimeters)) l.undoStack().stack().undo() QgsLayoutAligner.resizeItems(l, [item1, item2, item3], QgsLayoutAligner.ResizeShortest) self.assertEqual(item1.sizeWithUnits(), QgsLayoutSize(18, 9, QgsUnitTypes.LayoutMillimeters)) self.assertEqual(item2.sizeWithUnits(), QgsLayoutSize(10, 9, QgsUnitTypes.LayoutMillimeters)) self.assertEqual( item3.sizeWithUnits(), QgsLayoutSize(1.8, 0.9, QgsUnitTypes.LayoutCentimeters)) l.undoStack().stack().undo() QgsLayoutAligner.resizeItems(l, [item1, item2, item3], QgsLayoutAligner.ResizeTallest) self.assertEqual(item1.sizeWithUnits(), QgsLayoutSize(18, 16, QgsUnitTypes.LayoutMillimeters)) self.assertEqual(item2.sizeWithUnits(), QgsLayoutSize(10, 16, QgsUnitTypes.LayoutMillimeters)) self.assertEqual( item3.sizeWithUnits(), QgsLayoutSize(1.8, 1.6, QgsUnitTypes.LayoutCentimeters)) l.undoStack().stack().undo() item2.attemptResize( QgsLayoutSize(10, 19, QgsUnitTypes.LayoutMillimeters)) QgsLayoutAligner.resizeItems(l, [item1, item2, item3], QgsLayoutAligner.ResizeToSquare) self.assertEqual(item1.sizeWithUnits(), QgsLayoutSize(18, 18, QgsUnitTypes.LayoutMillimeters)) self.assertEqual(item2.sizeWithUnits(), QgsLayoutSize(19, 19, QgsUnitTypes.LayoutMillimeters)) self.assertEqual( item3.sizeWithUnits(), QgsLayoutSize(1.8, 1.8, QgsUnitTypes.LayoutCentimeters)) l.undoStack().stack().undo() QgsLayoutAligner.resizeItems(l, [item1], QgsLayoutAligner.ResizeToSquare) self.assertEqual(item1.sizeWithUnits(), QgsLayoutSize(18, 18, QgsUnitTypes.LayoutMillimeters))
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 testSelectedItems(self): p = QgsProject() l = QgsLayout(p) # add some items item1 = QgsLayoutItemMap(l) l.addItem(item1) item2 = QgsLayoutItemMap(l) l.addItem(item2) item3 = QgsLayoutItemMap(l) l.addItem(item3) self.assertFalse(l.selectedLayoutItems()) item1.setSelected(True) self.assertEqual(set(l.selectedLayoutItems()), set([item1])) item2.setSelected(True) self.assertEqual(set(l.selectedLayoutItems()), set([item1, item2])) item3.setSelected(True) self.assertEqual(set(l.selectedLayoutItems()), set([item1, item2, item3])) item3.setLocked(True) self.assertEqual(set(l.selectedLayoutItems(False)), set([item1, item2])) self.assertEqual(set(l.selectedLayoutItems(True)), set([item1, item2, item3]))
def testLayoutItemAt(self): p = QgsProject() l = QgsLayout(p) # add some items item1 = QgsLayoutItemMap(l) item1.attemptMove(QgsLayoutPoint(4, 8, QgsUnitTypes.LayoutMillimeters)) item1.attemptResize( QgsLayoutSize(18, 12, QgsUnitTypes.LayoutMillimeters)) l.addItem(item1) item2 = QgsLayoutItemMap(l) item2.attemptMove(QgsLayoutPoint(6, 10, QgsUnitTypes.LayoutMillimeters)) item2.attemptResize( QgsLayoutSize(18, 12, QgsUnitTypes.LayoutMillimeters)) l.addItem(item2) item3 = QgsLayoutItemMap(l) item3.attemptMove(QgsLayoutPoint(8, 12, QgsUnitTypes.LayoutMillimeters)) item3.attemptResize( QgsLayoutSize(18, 12, QgsUnitTypes.LayoutMillimeters)) item3.setLocked(True) l.addItem(item3) self.assertIsNone(l.layoutItemAt(QPointF(0, 0))) self.assertIsNone(l.layoutItemAt(QPointF(100, 100))) self.assertEqual(l.layoutItemAt(QPointF(5, 9)), item1) self.assertEqual(l.layoutItemAt(QPointF(25, 23)), item3) self.assertIsNone(l.layoutItemAt(QPointF(25, 23), True)) self.assertEqual(l.layoutItemAt(QPointF(7, 11)), item2) self.assertEqual(l.layoutItemAt(QPointF(9, 13)), item3) self.assertEqual(l.layoutItemAt(QPointF(9, 13), True), item2) self.assertEqual(l.layoutItemAt(QPointF(9, 13), item3), item2) self.assertEqual(l.layoutItemAt(QPointF(9, 13), item2), item1) self.assertIsNone(l.layoutItemAt(QPointF(9, 13), item1)) item2.setLocked(True) self.assertEqual(l.layoutItemAt(QPointF(9, 13), item3, True), item1)
def testStacking(self): p = QgsProject() l = QgsLayout(p) # add some items item1 = QgsLayoutItemPicture(l) l.addLayoutItem(item1) item2 = QgsLayoutItemPicture(l) l.addLayoutItem(item2) item3 = QgsLayoutItemPicture(l) l.addLayoutItem(item3) view = QgsLayoutView() view.setCurrentLayout(l) self.assertEqual(item1.zValue(), 1) self.assertEqual(item2.zValue(), 2) self.assertEqual(item3.zValue(), 3) # no effect interactions view.raiseSelectedItems() view.lowerSelectedItems() view.moveSelectedItemsToTop() view.moveSelectedItemsToBottom() self.assertEqual(item1.zValue(), 1) self.assertEqual(item2.zValue(), 2) self.assertEqual(item3.zValue(), 3) # raising item3.setSelected(True) view.raiseSelectedItems() self.assertEqual(item1.zValue(), 1) self.assertEqual(item2.zValue(), 2) self.assertEqual(item3.zValue(), 3) item3.setSelected(False) item2.setSelected(True) view.raiseSelectedItems() self.assertEqual(item1.zValue(), 1) self.assertEqual(item2.zValue(), 3) self.assertEqual(item3.zValue(), 2) view.raiseSelectedItems() self.assertEqual(item1.zValue(), 1) self.assertEqual(item2.zValue(), 3) self.assertEqual(item3.zValue(), 2) item2.setSelected(False) item1.setSelected(True) view.raiseSelectedItems() self.assertEqual(item1.zValue(), 2) self.assertEqual(item2.zValue(), 3) self.assertEqual(item3.zValue(), 1) # lower item1.setSelected(False) item3.setSelected(True) view.lowerSelectedItems() self.assertEqual(item1.zValue(), 2) self.assertEqual(item2.zValue(), 3) self.assertEqual(item3.zValue(), 1) item3.setSelected(False) item2.setSelected(True) view.lowerSelectedItems() self.assertEqual(item1.zValue(), 3) self.assertEqual(item2.zValue(), 2) self.assertEqual(item3.zValue(), 1) view.lowerSelectedItems() self.assertEqual(item1.zValue(), 3) self.assertEqual(item2.zValue(), 1) self.assertEqual(item3.zValue(), 2) # raise to top item2.setSelected(False) item1.setSelected(True) view.moveSelectedItemsToTop() self.assertEqual(item1.zValue(), 3) self.assertEqual(item2.zValue(), 1) self.assertEqual(item3.zValue(), 2) item1.setSelected(False) item3.setSelected(True) view.moveSelectedItemsToTop() self.assertEqual(item1.zValue(), 2) self.assertEqual(item2.zValue(), 1) self.assertEqual(item3.zValue(), 3) item3.setSelected(False) item2.setSelected(True) view.moveSelectedItemsToTop() self.assertEqual(item1.zValue(), 1) self.assertEqual(item2.zValue(), 3) self.assertEqual(item3.zValue(), 2) # move to bottom item2.setSelected(False) item1.setSelected(True) view.moveSelectedItemsToBottom() self.assertEqual(item1.zValue(), 1) self.assertEqual(item2.zValue(), 3) self.assertEqual(item3.zValue(), 2) item1.setSelected(False) item3.setSelected(True) view.moveSelectedItemsToBottom() self.assertEqual(item1.zValue(), 2) self.assertEqual(item2.zValue(), 3) self.assertEqual(item3.zValue(), 1) item3.setSelected(False) item2.setSelected(True) view.moveSelectedItemsToBottom() self.assertEqual(item1.zValue(), 3) self.assertEqual(item2.zValue(), 1) self.assertEqual(item3.zValue(), 2)
def testInitialSizeSymbolMapUnits(self): """Test initial size of legend with a symbol size in map units""" point_path = os.path.join(TEST_DATA_DIR, 'points.shp') point_layer = QgsVectorLayer(point_path, 'points', 'ogr') QgsProject.instance().addMapLayers([point_layer]) marker_symbol = QgsMarkerSymbol.createSimple({ 'color': '#ff0000', 'outline_style': 'no', 'size': '5', 'size_unit': 'MapUnit' }) point_layer.setRenderer(QgsSingleSymbolRenderer(marker_symbol)) s = QgsMapSettings() s.setLayers([point_layer]) layout = QgsLayout(QgsProject.instance()) layout.initializeDefaults() map = QgsLayoutItemMap(layout) map.attemptSetSceneRect(QRectF(20, 20, 80, 80)) map.setFrameEnabled(True) map.setLayers([point_layer]) layout.addLayoutItem(map) map.setExtent(point_layer.extent()) legend = QgsLayoutItemLegend(layout) legend.setTitle("Legend") legend.attemptSetSceneRect(QRectF(120, 20, 80, 80)) legend.setFrameEnabled(True) legend.setFrameStrokeWidth(QgsLayoutMeasurement(2)) legend.setBackgroundColor(QColor(200, 200, 200)) legend.setTitle('') layout.addLayoutItem(legend) legend.setLinkedMap(map) checker = QgsLayoutChecker('composer_legend_mapunits', layout) checker.setControlPathPrefix("composer_legend") result, message = checker.testLayout() self.assertTrue(result, message) # resize with non-top-left reference point legend.setResizeToContents(False) legend.setReferencePoint(QgsLayoutItem.LowerRight) legend.attemptMove(QgsLayoutPoint(120, 90)) legend.attemptResize(QgsLayoutSize(50, 60)) self.assertEqual(legend.positionWithUnits().x(), 120.0) self.assertEqual(legend.positionWithUnits().y(), 90.0) self.assertAlmostEqual(legend.pos().x(), 70, -1) self.assertAlmostEqual(legend.pos().y(), 30, -1) legend.setResizeToContents(True) legend.updateLegend() self.assertEqual(legend.positionWithUnits().x(), 120.0) self.assertEqual(legend.positionWithUnits().y(), 90.0) self.assertAlmostEqual(legend.pos().x(), 91, -1) self.assertAlmostEqual(legend.pos().y(), 71, -1) QgsProject.instance().removeMapLayers([point_layer.id()])
def testPrint(self): l = QgsLayout(QgsProject.instance()) l.initializeDefaults() # add a second page page2 = QgsLayoutItemPage(l) page2.setPageSize('A5') l.pageCollection().addPage(page2) # add some items item1 = QgsLayoutItemShape(l) item1.attemptSetSceneRect(QRectF(10, 20, 100, 150)) fill = QgsSimpleFillSymbolLayer() fill_symbol = QgsFillSymbol() fill_symbol.changeSymbolLayer(0, fill) fill.setColor(Qt.green) fill.setStrokeStyle(Qt.NoPen) item1.setSymbol(fill_symbol) l.addItem(item1) item2 = QgsLayoutItemShape(l) item2.attemptSetSceneRect(QRectF(10, 20, 100, 150)) item2.attemptMove(QgsLayoutPoint(10, 20), page=1) fill = QgsSimpleFillSymbolLayer() fill_symbol = QgsFillSymbol() fill_symbol.changeSymbolLayer(0, fill) fill.setColor(Qt.cyan) fill.setStrokeStyle(Qt.NoPen) item2.setSymbol(fill_symbol) l.addItem(item2) exporter = QgsLayoutExporter(l) # setup settings settings = QgsLayoutExporter.PrintExportSettings() settings.dpi = 80 settings.rasterizeWholeImage = False pdf_file_path = os.path.join(self.basetestpath, 'test_printdpi.pdf') # make a qprinter directed to pdf printer = QPrinter() printer.setOutputFileName(pdf_file_path) printer.setOutputFormat(QPrinter.PdfFormat) self.assertEqual(exporter.print(printer, settings), QgsLayoutExporter.Success) self.assertTrue(os.path.exists(pdf_file_path)) rendered_page_1 = os.path.join(self.basetestpath, 'test_exporttopdfdpi.png') dpi = 80 pdfToPng(pdf_file_path, rendered_page_1, dpi=dpi, page=1) rendered_page_2 = os.path.join(self.basetestpath, 'test_exporttopdfdpi2.png') pdfToPng(pdf_file_path, rendered_page_2, dpi=dpi, page=2) self.assertTrue( self.checkImage('printdpi_page1', 'exporttopdfdpi_page1', rendered_page_1, size_tolerance=1)) self.assertTrue( self.checkImage('printdpi_page2', 'exporttopdfdpi_page2', rendered_page_2, size_tolerance=1))
def testIteration(self): p = QgsProject() r = QgsReport(p) # empty report self.assertTrue(r.beginRender()) self.assertFalse(r.next()) # add a header r.setHeaderEnabled(True) report_header = QgsLayout(p) r.setHeader(report_header) self.assertTrue(r.beginRender()) self.assertTrue(r.next()) self.assertEqual(r.layout(), report_header) self.assertFalse(r.next()) # add a footer r.setFooterEnabled(True) report_footer = QgsLayout(p) r.setFooter(report_footer) self.assertTrue(r.beginRender()) self.assertTrue(r.next()) self.assertEqual(r.layout(), report_header) self.assertTrue(r.next()) self.assertEqual(r.layout(), report_footer) self.assertFalse(r.next()) # add a child child1 = QgsReportSectionLayout() child1_body = QgsLayout(p) child1.setBody(child1_body) r.appendChild(child1) self.assertTrue(r.beginRender()) self.assertTrue(r.next()) self.assertEqual(r.layout(), report_header) self.assertTrue(r.next()) self.assertEqual(r.layout(), child1_body) self.assertTrue(r.next()) self.assertEqual(r.layout(), report_footer) self.assertFalse(r.next()) # header and footer on child child1_header = QgsLayout(p) child1.setHeader(child1_header) child1.setHeaderEnabled(True) child1_footer = QgsLayout(p) child1.setFooter(child1_footer) child1.setFooterEnabled(True) self.assertTrue(r.beginRender()) self.assertTrue(r.next()) self.assertEqual(r.layout(), report_header) self.assertTrue(r.next()) self.assertEqual(r.layout(), child1_header) self.assertTrue(r.next()) self.assertEqual(r.layout(), child1_body) self.assertTrue(r.next()) self.assertEqual(r.layout(), child1_footer) self.assertTrue(r.next()) self.assertEqual(r.layout(), report_footer) self.assertFalse(r.next()) # add another child child2 = QgsReportSectionLayout() child2_header = QgsLayout(p) child2.setHeader(child2_header) child2.setHeaderEnabled(True) child2_footer = QgsLayout(p) child2.setFooter(child2_footer) child2.setFooterEnabled(True) r.appendChild(child2) self.assertTrue(r.beginRender()) self.assertTrue(r.next()) self.assertEqual(r.layout(), report_header) self.assertTrue(r.next()) self.assertEqual(r.layout(), child1_header) self.assertTrue(r.next()) self.assertEqual(r.layout(), child1_body) self.assertTrue(r.next()) self.assertEqual(r.layout(), child1_footer) self.assertTrue(r.next()) self.assertEqual(r.layout(), child2_header) self.assertTrue(r.next()) self.assertEqual(r.layout(), child2_footer) self.assertTrue(r.next()) self.assertEqual(r.layout(), report_footer) self.assertFalse(r.next()) # add a child to child2 child2a = QgsReportSectionLayout() child2a_header = QgsLayout(p) child2a.setHeader(child2a_header) child2a.setHeaderEnabled(True) child2a_footer = QgsLayout(p) child2a.setFooter(child2a_footer) child2a.setFooterEnabled(True) child2.appendChild(child2a) self.assertTrue(r.beginRender()) self.assertTrue(r.next()) self.assertEqual(r.layout(), report_header) self.assertEqual(r.filePath('/tmp/myreport', 'png'), '/tmp/myreport_0001.png') self.assertTrue(r.next()) self.assertEqual(r.layout(), child1_header) self.assertEqual(r.filePath('/tmp/myreport', 'png'), '/tmp/myreport_0002.png') self.assertTrue(r.next()) self.assertEqual(r.layout(), child1_body) self.assertEqual(r.filePath('/tmp/myreport', '.png'), '/tmp/myreport_0003.png') self.assertTrue(r.next()) self.assertEqual(r.layout(), child1_footer) self.assertEqual(r.filePath('/tmp/myreport', 'jpg'), '/tmp/myreport_0004.jpg') self.assertTrue(r.next()) self.assertEqual(r.layout(), child2_header) self.assertEqual(r.filePath('/tmp/myreport', 'png'), '/tmp/myreport_0005.png') self.assertTrue(r.next()) self.assertEqual(r.layout(), child2a_header) self.assertEqual(r.filePath('/tmp/myreport', 'png'), '/tmp/myreport_0006.png') self.assertTrue(r.next()) self.assertEqual(r.layout(), child2a_footer) self.assertEqual(r.filePath('/tmp/myreport', 'png'), '/tmp/myreport_0007.png') self.assertTrue(r.next()) self.assertEqual(r.layout(), child2_footer) self.assertEqual(r.filePath('/tmp/myreport', 'png'), '/tmp/myreport_0008.png') self.assertTrue(r.next()) self.assertEqual(r.layout(), report_footer) self.assertEqual(r.filePath('/tmp/myreport', 'png'), '/tmp/myreport_0009.png') self.assertFalse(r.next())
def testReportSectionLayout(self): r = QgsReportSectionLayout() p = QgsProject() body = QgsLayout(p) r.setBody(body) self.assertEqual(r.body(), body)
def testFieldGroupMultiLayer(self): # create a layer states = QgsVectorLayer("Point?crs=epsg:4326&field=country:string(20)&field=state:string(20)", "points", "memory") attributes = [ ['Australia', 'QLD'], ['NZ', 'state1'], ['Australia', 'VIC'], ['NZ', 'state2'], ['PNG', 'state3'], ['Australia', 'NSW'] ] pr = states.dataProvider() for a in attributes: f = QgsFeature() f.initAttributes(2) f.setAttribute(0, a[0]) f.setAttribute(1, a[1]) self.assertTrue(pr.addFeature(f)) places = QgsVectorLayer("Point?crs=epsg:4326&field=state:string(20)&field=town:string(20)", "points", "memory") attributes = [ ['QLD', 'Brisbane'], ['QLD', 'Emerald'], ['state1', 'town1'], ['VIC', 'Melbourne'], ['state1', 'town2'], ['QLD', 'Beerburrum'], ['VIC', 'Geelong'], ['state3', 'town1'] ] pr = places.dataProvider() for a in attributes: f = QgsFeature() f.initAttributes(2) f.setAttribute(0, a[0]) f.setAttribute(1, a[1]) self.assertTrue(pr.addFeature(f)) p = QgsProject() r = QgsReport(p) # add a child child1 = QgsReportSectionFieldGroup() child1_body = QgsLayout(p) child1.setLayer(states) child1.setBody(child1_body) child1.setBodyEnabled(True) child1.setField('country') r.appendChild(child1) self.assertTrue(r.beginRender()) self.assertTrue(r.next()) self.assertEqual(r.layout(), child1_body) self.assertEqual(r.layout().reportContext().feature().attributes(), ['Australia', 'QLD']) self.assertTrue(r.next()) self.assertEqual(r.layout(), child1_body) self.assertEqual(r.layout().reportContext().feature().attributes(), ['Australia', 'VIC']) self.assertTrue(r.next()) self.assertEqual(r.layout(), child1_body) self.assertEqual(r.layout().reportContext().feature().attributes(), ['Australia', 'NSW']) self.assertTrue(r.next()) self.assertEqual(r.layout(), child1_body) self.assertEqual(r.layout().reportContext().feature().attributes(), ['NZ', 'state1']) self.assertTrue(r.next()) self.assertEqual(r.layout(), child1_body) self.assertEqual(r.layout().reportContext().feature().attributes(), ['NZ', 'state2']) self.assertTrue(r.next()) self.assertEqual(r.layout(), child1_body) self.assertEqual(r.layout().reportContext().feature().attributes(), ['PNG', 'state3']) self.assertFalse(r.next()) # another group # remove body from child1 child1.setBodyEnabled(False) child2 = QgsReportSectionFieldGroup() child2_body = QgsLayout(p) child2.setLayer(states) child2.setBody(child2_body) child2.setBodyEnabled(True) child2.setField('state') child1.appendChild(child2) self.assertTrue(r.beginRender()) self.assertTrue(r.next()) self.assertEqual(r.layout(), child2_body) self.assertEqual(r.layout().reportContext().feature().attributes(), ['Australia', 'NSW']) self.assertTrue(r.next()) self.assertEqual(r.layout(), child2_body) self.assertEqual(r.layout().reportContext().feature().attributes(), ['Australia', 'QLD']) self.assertTrue(r.next()) self.assertEqual(r.layout(), child2_body) self.assertEqual(r.layout().reportContext().feature().attributes(), ['Australia', 'VIC']) self.assertTrue(r.next()) self.assertEqual(r.layout(), child2_body) self.assertEqual(r.layout().reportContext().feature().attributes(), ['NZ', 'state1']) self.assertTrue(r.next()) self.assertEqual(r.layout(), child2_body) self.assertEqual(r.layout().reportContext().feature().attributes(), ['NZ', 'state2']) self.assertTrue(r.next()) self.assertEqual(r.layout(), child2_body) self.assertEqual(r.layout().reportContext().feature().attributes(), ['PNG', 'state3']) self.assertFalse(r.next()) # another group child3 = QgsReportSectionFieldGroup() child3_body = QgsLayout(p) child3.setLayer(places) child3.setBody(child3_body) child3.setBodyEnabled(True) child3.setField('town') child3.setSortAscending(False) child2.appendChild(child3) self.assertTrue(r.beginRender()) self.assertTrue(r.next()) self.assertEqual(r.layout(), child2_body) self.assertEqual(r.layout().reportContext().feature().attributes(), ['Australia', 'NSW']) self.assertTrue(r.next()) self.assertEqual(r.layout(), child2_body) self.assertEqual(r.layout().reportContext().feature().attributes(), ['Australia', 'QLD']) self.assertTrue(r.next()) self.assertEqual(r.layout(), child3_body) self.assertEqual(r.layout().reportContext().feature().attributes(), ['QLD', 'Emerald']) self.assertTrue(r.next()) self.assertEqual(r.layout(), child3_body) self.assertEqual(r.layout().reportContext().feature().attributes(), ['QLD', 'Brisbane']) self.assertTrue(r.next()) self.assertEqual(r.layout(), child3_body) self.assertEqual(r.layout().reportContext().feature().attributes(), ['QLD', 'Beerburrum']) self.assertTrue(r.next()) self.assertEqual(r.layout(), child2_body) self.assertEqual(r.layout().reportContext().feature().attributes(), ['Australia', 'VIC']) self.assertTrue(r.next()) self.assertEqual(r.layout(), child3_body) self.assertEqual(r.layout().reportContext().feature().attributes(), ['VIC', 'Melbourne']) self.assertTrue(r.next()) self.assertEqual(r.layout(), child3_body) self.assertEqual(r.layout().reportContext().feature().attributes(), ['VIC', 'Geelong']) self.assertTrue(r.next()) self.assertEqual(r.layout(), child2_body) self.assertEqual(r.layout().reportContext().feature().attributes(), ['NZ', 'state1']) self.assertTrue(r.next()) self.assertEqual(r.layout(), child3_body) self.assertEqual(r.layout().reportContext().feature().attributes(), ['state1', 'town2']) self.assertTrue(r.next()) self.assertEqual(r.layout(), child3_body) self.assertEqual(r.layout().reportContext().feature().attributes(), ['state1', 'town1']) self.assertTrue(r.next()) self.assertEqual(r.layout(), child2_body) self.assertEqual(r.layout().reportContext().feature().attributes(), ['NZ', 'state2']) self.assertTrue(r.next()) self.assertEqual(r.layout(), child2_body) self.assertEqual(r.layout().reportContext().feature().attributes(), ['PNG', 'state3']) self.assertTrue(r.next()) self.assertEqual(r.layout(), child3_body) self.assertEqual(r.layout().reportContext().feature().attributes(), ['state3', 'town1']) self.assertFalse(r.next()) # add headers/footers child3_header = QgsLayout(p) child3.setHeader(child3_header) child3.setHeaderEnabled(True) child3_footer = QgsLayout(p) child3.setFooter(child3_footer) child3.setFooterEnabled(True) self.assertTrue(r.beginRender()) self.assertTrue(r.next()) self.assertEqual(r.layout(), child2_body) self.assertEqual(r.layout().reportContext().feature().attributes(), ['Australia', 'NSW']) self.assertTrue(r.next()) self.assertEqual(r.layout(), child2_body) self.assertEqual(r.layout().reportContext().feature().attributes(), ['Australia', 'QLD']) self.assertTrue(r.next()) self.assertEqual(r.layout(), child3_header) self.assertEqual(r.layout().reportContext().feature().attributes(), ['QLD', 'Emerald']) self.assertTrue(r.next()) self.assertEqual(r.layout(), child3_body) self.assertEqual(r.layout().reportContext().feature().attributes(), ['QLD', 'Emerald']) self.assertTrue(r.next()) self.assertEqual(r.layout(), child3_body) self.assertEqual(r.layout().reportContext().feature().attributes(), ['QLD', 'Brisbane']) self.assertTrue(r.next()) self.assertEqual(r.layout(), child3_body) self.assertEqual(r.layout().reportContext().feature().attributes(), ['QLD', 'Beerburrum']) self.assertTrue(r.next()) self.assertEqual(r.layout(), child3_footer) self.assertEqual(r.layout().reportContext().feature().attributes(), ['QLD', 'Beerburrum']) self.assertTrue(r.next()) self.assertEqual(r.layout(), child2_body) self.assertEqual(r.layout().reportContext().feature().attributes(), ['Australia', 'VIC']) self.assertTrue(r.next()) self.assertEqual(r.layout(), child3_header) self.assertEqual(r.layout().reportContext().feature().attributes(), ['VIC', 'Melbourne']) self.assertTrue(r.next()) self.assertEqual(r.layout(), child3_body) self.assertEqual(r.layout().reportContext().feature().attributes(), ['VIC', 'Melbourne']) self.assertTrue(r.next()) self.assertEqual(r.layout(), child3_body) self.assertEqual(r.layout().reportContext().feature().attributes(), ['VIC', 'Geelong']) self.assertTrue(r.next()) self.assertEqual(r.layout(), child3_footer) self.assertEqual(r.layout().reportContext().feature().attributes(), ['VIC', 'Geelong']) self.assertTrue(r.next()) self.assertEqual(r.layout(), child2_body) self.assertEqual(r.layout().reportContext().feature().attributes(), ['NZ', 'state1']) self.assertTrue(r.next()) self.assertEqual(r.layout(), child3_header) self.assertEqual(r.layout().reportContext().feature().attributes(), ['state1', 'town2']) self.assertTrue(r.next()) self.assertEqual(r.layout(), child3_body) self.assertEqual(r.layout().reportContext().feature().attributes(), ['state1', 'town2']) self.assertTrue(r.next()) self.assertEqual(r.layout(), child3_body) self.assertEqual(r.layout().reportContext().feature().attributes(), ['state1', 'town1']) self.assertTrue(r.next()) self.assertEqual(r.layout(), child3_footer) self.assertEqual(r.layout().reportContext().feature().attributes(), ['state1', 'town1']) self.assertTrue(r.next()) self.assertEqual(r.layout(), child2_body) self.assertEqual(r.layout().reportContext().feature().attributes(), ['NZ', 'state2']) self.assertTrue(r.next()) self.assertEqual(r.layout(), child2_body) self.assertEqual(r.layout().reportContext().feature().attributes(), ['PNG', 'state3']) self.assertTrue(r.next()) self.assertEqual(r.layout(), child3_header) self.assertEqual(r.layout().reportContext().feature().attributes(), ['state3', 'town1']) self.assertTrue(r.next()) self.assertEqual(r.layout(), child3_body) self.assertEqual(r.layout().reportContext().feature().attributes(), ['state3', 'town1']) self.assertTrue(r.next()) self.assertEqual(r.layout(), child3_footer) self.assertEqual(r.layout().reportContext().feature().attributes(), ['state3', 'town1']) self.assertFalse(r.next())
def testReadWriteXml(self): p = QgsProject() ptLayer = QgsVectorLayer("Point?crs=epsg:4326&field=country:string(20)&field=state:string(20)&field=town:string(20)", "points", "memory") p.addMapLayer(ptLayer) r = QgsReport(p) r.setName('my report') # add a header r.setHeaderEnabled(True) report_header = QgsLayout(p) report_header.setUnits(QgsUnitTypes.LayoutInches) r.setHeader(report_header) # add a footer r.setFooterEnabled(True) report_footer = QgsLayout(p) report_footer.setUnits(QgsUnitTypes.LayoutMeters) r.setFooter(report_footer) # add some subsections child1 = QgsReportSectionLayout() child1_body = QgsLayout(p) child1_body.setUnits(QgsUnitTypes.LayoutPoints) child1.setBody(child1_body) child2 = QgsReportSectionLayout() child2_body = QgsLayout(p) child2_body.setUnits(QgsUnitTypes.LayoutPixels) child2.setBody(child2_body) child1.appendChild(child2) child2a = QgsReportSectionFieldGroup() child2a_body = QgsLayout(p) child2a_body.setUnits(QgsUnitTypes.LayoutInches) child2a.setBody(child2a_body) child2a.setField('my field') child2a.setLayer(ptLayer) child1.appendChild(child2a) r.appendChild(child1) doc = QDomDocument("testdoc") elem = r.writeLayoutXml(doc, QgsReadWriteContext()) r2 = QgsReport(p) self.assertTrue(r2.readLayoutXml(elem, doc, QgsReadWriteContext())) self.assertEqual(r2.name(), 'my report') self.assertTrue(r2.headerEnabled()) self.assertEqual(r2.header().units(), QgsUnitTypes.LayoutInches) self.assertTrue(r2.footerEnabled()) self.assertEqual(r2.footer().units(), QgsUnitTypes.LayoutMeters) self.assertEqual(r2.childCount(), 1) self.assertEqual(r2.childSection(0).body().units(), QgsUnitTypes.LayoutPoints) self.assertEqual(r2.childSection(0).childCount(), 2) self.assertEqual(r2.childSection(0).childSection(0).body().units(), QgsUnitTypes.LayoutPixels) self.assertEqual(r2.childSection(0).childSection(1).body().units(), QgsUnitTypes.LayoutInches) self.assertEqual(r2.childSection(0).childSection(1).field(), 'my field') self.assertEqual(r2.childSection(0).childSection(1).layer(), ptLayer)
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 testDistribute(self): p = QgsProject() l = QgsLayout(p) # add some items item1 = QgsLayoutItemPicture(l) item1.attemptMove(QgsLayoutPoint(4, 8, QgsUnitTypes.LayoutMillimeters)) item1.attemptResize( QgsLayoutSize(18, 12, QgsUnitTypes.LayoutMillimeters)) l.addItem(item1) item2 = QgsLayoutItemPicture(l) item2.attemptMove(QgsLayoutPoint(7, 10, QgsUnitTypes.LayoutMillimeters)) item2.attemptResize( QgsLayoutSize(10, 9, QgsUnitTypes.LayoutMillimeters)) l.addItem(item2) item3 = QgsLayoutItemPicture(l) item3.attemptMove( QgsLayoutPoint(0.8, 1.2, QgsUnitTypes.LayoutCentimeters)) item3.attemptResize( QgsLayoutSize(1.8, 1.6, QgsUnitTypes.LayoutCentimeters)) l.addItem(item3) QgsLayoutAligner.distributeItems(l, [item1, item2, item3], QgsLayoutAligner.DistributeLeft) self.assertEqual(item1.positionWithUnits(), QgsLayoutPoint(4, 8, QgsUnitTypes.LayoutMillimeters)) self.assertEqual(item1.sizeWithUnits(), QgsLayoutSize(18, 12, QgsUnitTypes.LayoutMillimeters)) self.assertAlmostEqual(item2.positionWithUnits().x(), 6.0, 3) self.assertEqual(item2.positionWithUnits().units(), QgsUnitTypes.LayoutMillimeters) self.assertEqual(item2.sizeWithUnits(), QgsLayoutSize(10, 9, QgsUnitTypes.LayoutMillimeters)) self.assertAlmostEqual(item3.positionWithUnits().x(), 0.8, 3) self.assertEqual(item3.positionWithUnits().units(), QgsUnitTypes.LayoutCentimeters) self.assertEqual( item3.sizeWithUnits(), QgsLayoutSize(1.8, 1.6, QgsUnitTypes.LayoutCentimeters)) QgsLayoutAligner.distributeItems(l, [item1, item2, item3], QgsLayoutAligner.DistributeHCenter) self.assertAlmostEqual(item1.positionWithUnits().x(), 5.0, 3) self.assertEqual(item1.positionWithUnits().units(), QgsUnitTypes.LayoutMillimeters) self.assertEqual(item1.sizeWithUnits(), QgsLayoutSize(18, 12, QgsUnitTypes.LayoutMillimeters)) self.assertAlmostEqual(item2.positionWithUnits().x(), 6.0, 3) self.assertEqual(item2.positionWithUnits().units(), QgsUnitTypes.LayoutMillimeters) self.assertEqual(item2.sizeWithUnits(), QgsLayoutSize(10, 9, QgsUnitTypes.LayoutMillimeters)) self.assertAlmostEqual(item3.positionWithUnits().x(), 0.8, 3) self.assertEqual(item3.positionWithUnits().units(), QgsUnitTypes.LayoutCentimeters) self.assertEqual( item3.sizeWithUnits(), QgsLayoutSize(1.8, 1.6, QgsUnitTypes.LayoutCentimeters)) QgsLayoutAligner.distributeItems(l, [item1, item2, item3], QgsLayoutAligner.DistributeRight) self.assertAlmostEqual(item1.positionWithUnits().x(), 3.0, 3) self.assertEqual(item1.positionWithUnits().units(), QgsUnitTypes.LayoutMillimeters) self.assertEqual(item1.sizeWithUnits(), QgsLayoutSize(18, 12, QgsUnitTypes.LayoutMillimeters)) self.assertAlmostEqual(item2.positionWithUnits().x(), 6.0, 3) self.assertEqual(item2.positionWithUnits().units(), QgsUnitTypes.LayoutMillimeters) self.assertEqual(item2.sizeWithUnits(), QgsLayoutSize(10, 9, QgsUnitTypes.LayoutMillimeters)) self.assertAlmostEqual(item3.positionWithUnits().x(), 0.8, 3) self.assertEqual(item3.positionWithUnits().units(), QgsUnitTypes.LayoutCentimeters) self.assertEqual( item3.sizeWithUnits(), QgsLayoutSize(1.8, 1.6, QgsUnitTypes.LayoutCentimeters)) QgsLayoutAligner.distributeItems(l, [item1, item2, item3], QgsLayoutAligner.DistributeTop) self.assertAlmostEqual(item1.positionWithUnits().y(), 8.0, 3) self.assertEqual(item1.positionWithUnits().units(), QgsUnitTypes.LayoutMillimeters) self.assertEqual(item1.sizeWithUnits(), QgsLayoutSize(18, 12, QgsUnitTypes.LayoutMillimeters)) self.assertAlmostEqual(item2.positionWithUnits().y(), 10.0, 3) self.assertEqual(item2.positionWithUnits().units(), QgsUnitTypes.LayoutMillimeters) self.assertEqual(item2.sizeWithUnits(), QgsLayoutSize(10, 9, QgsUnitTypes.LayoutMillimeters)) self.assertAlmostEqual(item3.positionWithUnits().y(), 1.2, 3) self.assertEqual(item3.positionWithUnits().units(), QgsUnitTypes.LayoutCentimeters) self.assertEqual( item3.sizeWithUnits(), QgsLayoutSize(1.8, 1.6, QgsUnitTypes.LayoutCentimeters)) QgsLayoutAligner.distributeItems(l, [item1, item2, item3], QgsLayoutAligner.DistributeVCenter) self.assertAlmostEqual(item1.positionWithUnits().y(), 8.0, 3) self.assertEqual(item1.positionWithUnits().units(), QgsUnitTypes.LayoutMillimeters) self.assertEqual(item1.sizeWithUnits(), QgsLayoutSize(18, 12, QgsUnitTypes.LayoutMillimeters)) self.assertAlmostEqual(item2.positionWithUnits().y(), 12.5, 3) self.assertEqual(item2.positionWithUnits().units(), QgsUnitTypes.LayoutMillimeters) self.assertEqual(item2.sizeWithUnits(), QgsLayoutSize(10, 9, QgsUnitTypes.LayoutMillimeters)) self.assertAlmostEqual(item3.positionWithUnits().y(), 1.2, 3) self.assertEqual(item3.positionWithUnits().units(), QgsUnitTypes.LayoutCentimeters) self.assertEqual( item3.sizeWithUnits(), QgsLayoutSize(1.8, 1.6, QgsUnitTypes.LayoutCentimeters)) QgsLayoutAligner.distributeItems(l, [item1, item2, item3], QgsLayoutAligner.DistributeBottom) self.assertAlmostEqual(item1.positionWithUnits().y(), 8.0, 3) self.assertEqual(item1.positionWithUnits().units(), QgsUnitTypes.LayoutMillimeters) self.assertEqual(item1.sizeWithUnits(), QgsLayoutSize(18, 12, QgsUnitTypes.LayoutMillimeters)) self.assertAlmostEqual(item2.positionWithUnits().y(), 15.0, 3) self.assertEqual(item2.positionWithUnits().units(), QgsUnitTypes.LayoutMillimeters) self.assertEqual(item2.sizeWithUnits(), QgsLayoutSize(10, 9, QgsUnitTypes.LayoutMillimeters)) self.assertAlmostEqual(item3.positionWithUnits().y(), 1.2, 3) self.assertEqual(item3.positionWithUnits().units(), QgsUnitTypes.LayoutCentimeters) self.assertEqual( item3.sizeWithUnits(), QgsLayoutSize(1.8, 1.6, QgsUnitTypes.LayoutCentimeters))
def testApplyToOtherPages(self): p = QgsProject() l = QgsLayout(p) l.initializeDefaults() page2 = QgsLayoutItemPage(l) page2.setPageSize('A6') l.pageCollection().addPage(page2) guides = l.guides() # add some guides g1 = QgsLayoutGuide(Qt.Horizontal, QgsLayoutMeasurement(5), l.pageCollection().page(0)) guides.addGuide(g1) g2 = QgsLayoutGuide(Qt.Vertical, QgsLayoutMeasurement(6), l.pageCollection().page(0)) guides.addGuide(g2) g3 = QgsLayoutGuide(Qt.Horizontal, QgsLayoutMeasurement(190), l.pageCollection().page(0)) guides.addGuide(g3) g4 = QgsLayoutGuide(Qt.Horizontal, QgsLayoutMeasurement(1), l.pageCollection().page(1)) guides.addGuide(g4) # apply guides from page 0 - should delete g4 guides.applyGuidesToAllOtherPages(0) self.assertEqual(guides.guides(Qt.Horizontal, 0), [g1, g3]) self.assertEqual(guides.guides(Qt.Vertical, 0), [g2]) self.assertTrue(sip.isdeleted(g4)) # g3 is outside of page 2 bounds - should not be copied self.assertEqual(len(guides.guides(Qt.Horizontal, 1)), 1) self.assertEqual( guides.guides(Qt.Horizontal, 1)[0].position().length(), 5) self.assertEqual(len(guides.guides(Qt.Vertical, 1)), 1) self.assertEqual( guides.guides(Qt.Vertical, 1)[0].position().length(), 6) # apply guides from page 1 to 0 guides.applyGuidesToAllOtherPages(1) self.assertTrue(sip.isdeleted(g1)) self.assertTrue(sip.isdeleted(g2)) self.assertTrue(sip.isdeleted(g3)) self.assertEqual(len(guides.guides(Qt.Horizontal, 0)), 1) self.assertEqual( guides.guides(Qt.Horizontal, 0)[0].position().length(), 5) self.assertEqual(len(guides.guides(Qt.Vertical, 0)), 1) self.assertEqual( guides.guides(Qt.Vertical, 0)[0].position().length(), 6)
def testUpdateGuide(self): p = QgsProject() l = QgsLayout(p) l.initializeDefaults() # add a page # add a second page page2 = QgsLayoutItemPage(l) page2.setPageSize('A5') l.pageCollection().addPage(page2) g = QgsLayoutGuide( Qt.Horizontal, QgsLayoutMeasurement(5, QgsUnitTypes.LayoutCentimeters), l.pageCollection().page(0)) g.setLayout(l) g.update() self.assertTrue(g.item().isVisible()) self.assertEqual(g.item().line().x1(), 0) self.assertEqual(g.item().line().y1(), 50) self.assertEqual(g.item().line().x2(), 297) self.assertEqual(g.item().line().y2(), 50) self.assertEqual(g.layoutPosition(), 50) g.setPosition(QgsLayoutMeasurement(15, QgsUnitTypes.LayoutMillimeters)) g.update() self.assertTrue(g.item().isVisible()) self.assertEqual(g.item().line().x1(), 0) self.assertEqual(g.item().line().y1(), 15) self.assertEqual(g.item().line().x2(), 297) self.assertEqual(g.item().line().y2(), 15) self.assertEqual(g.layoutPosition(), 15) # guide on page2 g1 = QgsLayoutGuide( Qt.Horizontal, QgsLayoutMeasurement(5, QgsUnitTypes.LayoutCentimeters), l.pageCollection().page(1)) g1.setLayout(l) g1.update() g1.setPosition(QgsLayoutMeasurement(15, QgsUnitTypes.LayoutMillimeters)) g1.update() self.assertTrue(g1.item().isVisible()) self.assertEqual(g1.item().line().x1(), 0) self.assertEqual(g1.item().line().y1(), 235) self.assertEqual(g1.item().line().x2(), 148) self.assertEqual(g1.item().line().y2(), 235) self.assertEqual(g1.layoutPosition(), 235) # vertical guide g2 = QgsLayoutGuide( Qt.Vertical, QgsLayoutMeasurement(5, QgsUnitTypes.LayoutCentimeters), l.pageCollection().page(0)) g2.setLayout(l) g2.update() self.assertTrue(g2.item().isVisible()) self.assertEqual(g2.item().line().x1(), 50) self.assertEqual(g2.item().line().y1(), 0) self.assertEqual(g2.item().line().x2(), 50) self.assertEqual(g2.item().line().y2(), 210) self.assertEqual(g2.layoutPosition(), 50) g.setPage(None) g.update() self.assertFalse(g.item().isVisible()) g.setPage(l.pageCollection().page(0)) g.update() self.assertTrue(g.item().isVisible()) #throw it off the bottom of the page g.setPosition( QgsLayoutMeasurement(1115, QgsUnitTypes.LayoutMillimeters)) g.update() self.assertFalse(g.item().isVisible()) # guide on page2 g3 = QgsLayoutGuide( Qt.Vertical, QgsLayoutMeasurement(5, QgsUnitTypes.LayoutCentimeters), l.pageCollection().page(1)) g3.setLayout(l) g3.update() self.assertTrue(g3.item().isVisible()) self.assertEqual(g3.item().line().x1(), 50) self.assertEqual(g3.item().line().y1(), 220) self.assertEqual(g3.item().line().x2(), 50) self.assertEqual(g3.item().line().y2(), 430) self.assertEqual(g3.layoutPosition(), 50)
class TestQgsLayoutPolyline(unittest.TestCase, LayoutItemTestCase): @classmethod def setUpClass(cls): cls.item_class = QgsLayoutItemPolyline def __init__(self, methodName): """Run once on class initialization.""" unittest.TestCase.__init__(self, methodName) # create composition self.layout = QgsLayout(QgsProject.instance()) self.layout.initializeDefaults() # create polygon = QPolygonF() polygon.append(QPointF(0.0, 0.0)) polygon.append(QPointF(100.0, 0.0)) polygon.append(QPointF(200.0, 100.0)) polygon.append(QPointF(100.0, 200.0)) self.polyline = QgsLayoutItemPolyline(polygon, self.layout) self.layout.addLayoutItem(self.polyline) # style props = {} props["color"] = "0,0,0,255" props["width"] = "10.0" props["capstyle"] = "square" style = QgsLineSymbol.createSimple(props) self.polyline.setSymbol(style) def testNodes(self): polygon = QPolygonF() polygon.append(QPointF(0.0, 0.0)) polygon.append(QPointF(100.0, 0.0)) polygon.append(QPointF(200.0, 100.0)) polygon.append(QPointF(100.0, 200.0)) p = QgsLayoutItemPolyline(polygon, self.layout) self.assertEqual(p.nodes(), polygon) polygon = QPolygonF() polygon.append(QPointF(0.0, 0.0)) polygon.append(QPointF(1000.0, 0.0)) polygon.append(QPointF(2000.0, 100.0)) polygon.append(QPointF(1000.0, 200.0)) p.setNodes(polygon) self.assertEqual(p.nodes(), polygon) def testDisplayName(self): """Test if displayName is valid""" self.assertEqual(self.polyline.displayName(), "<Polyline>") def testType(self): """Test if type is valid""" self.assertEqual(self.polyline.type(), QgsLayoutItemRegistry.LayoutPolyline) def testDefaultStyle(self): """Test polygon rendering with default style.""" self.polyline.setDisplayNodes(False) checker = QgsLayoutChecker('composerpolyline_defaultstyle', self.layout) checker.setControlPathPrefix("composer_polyline") myTestResult, myMessage = checker.testLayout() assert myTestResult, myMessage def testDisplayNodes(self): """Test displayNodes method""" self.polyline.setDisplayNodes(True) checker = QgsLayoutChecker('composerpolyline_displaynodes', self.layout) checker.setControlPathPrefix("composer_polyline") myTestResult, myMessage = checker.testLayout() assert myTestResult, myMessage self.polyline.setDisplayNodes(False) checker = QgsLayoutChecker('composerpolyline_defaultstyle', self.layout) checker.setControlPathPrefix("composer_polyline") myTestResult, myMessage = checker.testLayout() assert myTestResult, myMessage def testSelectedNode(self): """Test selectedNode and deselectNode methods""" self.polyline.setDisplayNodes(True) self.polyline.setSelectedNode(3) checker = QgsLayoutChecker('composerpolyline_selectednode', self.layout) checker.setControlPathPrefix("composer_polyline") myTestResult, myMessage = checker.testLayout() assert myTestResult, myMessage self.polyline.deselectNode() self.polyline.setDisplayNodes(False) checker = QgsLayoutChecker('composerpolyline_defaultstyle', self.layout) checker.setControlPathPrefix("composer_polyline") myTestResult, myMessage = checker.testLayout() assert myTestResult, myMessage def testRemoveNode(self): """Test removeNode method""" rc = self.polyline.removeNode(100) self.assertEqual(rc, False) checker = QgsLayoutChecker('composerpolyline_defaultstyle', self.layout) checker.setControlPathPrefix("composer_polyline") myTestResult, myMessage = checker.testLayout() assert myTestResult, myMessage self.assertEqual(self.polyline.nodesSize(), 4) rc = self.polyline.removeNode(3) self.assertEqual(rc, True) self.assertEqual(self.polyline.nodesSize(), 3) checker = QgsLayoutChecker('composerpolyline_removednode', self.layout) checker.setControlPathPrefix("composer_polyline") myTestResult, myMessage = checker.testLayout() assert myTestResult, myMessage def testAddNode(self): """Test addNode method""" # default searching radius is 10 self.assertEqual(self.polyline.nodesSize(), 4) rc = self.polyline.addNode(QPointF(50.0, 10.0)) self.assertEqual(rc, False) # default searching radius is 10 self.assertEqual(self.polyline.nodesSize(), 4) rc = self.polyline.addNode(QPointF(50.0, 9.99)) self.assertEqual(rc, True) self.assertEqual(self.polyline.nodesSize(), 5) def testAddNodeCustomRadius(self): """Test addNode with custom radius""" # default searching radius is 10 self.assertEqual(self.polyline.nodesSize(), 4) rc = self.polyline.addNode(QPointF(50.0, 8.1), True, 8.0) self.assertEqual(rc, False) self.assertEqual(self.polyline.nodesSize(), 4) # default searching radius is 10 rc = self.polyline.addNode(QPointF(50.0, 7.9), True, 8.0) self.assertEqual(rc, True) self.assertEqual(self.polyline.nodesSize(), 5) def testAddNodeWithoutCheckingArea(self): """Test addNode without checking the maximum distance allowed""" # default searching radius is 10 self.assertEqual(self.polyline.nodesSize(), 4) rc = self.polyline.addNode(QPointF(50.0, 20.0)) self.assertEqual(rc, False) self.assertEqual(self.polyline.nodesSize(), 4) # default searching radius is 10 self.assertEqual(self.polyline.nodesSize(), 4) rc = self.polyline.addNode(QPointF(50.0, 20.0), False) self.assertEqual(rc, True) self.assertEqual(self.polyline.nodesSize(), 5) checker = QgsLayoutChecker('composerpolyline_addnode', self.layout) checker.setControlPathPrefix("composer_polyline") myTestResult, myMessage = checker.testLayout() assert myTestResult, myMessage def testMoveNode(self): """Test moveNode method""" rc = self.polyline.moveNode(30, QPointF(100.0, 300.0)) self.assertEqual(rc, False) rc = self.polyline.moveNode(3, QPointF(100.0, 150.0)) self.assertEqual(rc, True) checker = QgsLayoutChecker('composerpolyline_movenode', self.layout) checker.setControlPathPrefix("composer_polyline") myTestResult, myMessage = checker.testLayout() assert myTestResult, myMessage def testNodeAtPosition(self): """Test nodeAtPosition method""" # default searching radius is 10 rc = self.polyline.nodeAtPosition(QPointF(100.0, 210.0)) self.assertEqual(rc, -1) # default searching radius is 10 rc = self.polyline.nodeAtPosition(QPointF(100.0, 210.0), False) self.assertEqual(rc, 3) # default searching radius is 10 rc = self.polyline.nodeAtPosition(QPointF(100.0, 210.0), True, 10.1) self.assertEqual(rc, 3) def testReadWriteXml(self): pr = QgsProject() l = QgsLayout(pr) p = QPolygonF() p.append(QPointF(0.0, 0.0)) p.append(QPointF(100.0, 0.0)) p.append(QPointF(200.0, 100.0)) shape = QgsLayoutItemPolyline(p, l) props = {} props["color"] = "255,0,0,255" props["width"] = "10.0" props["capstyle"] = "square" style = QgsLineSymbol.createSimple(props) shape.setSymbol(style) #save original item to xml doc = QDomDocument("testdoc") elem = doc.createElement("test") self.assertTrue(shape.writeXml(elem, doc, QgsReadWriteContext())) shape2 = QgsLayoutItemPolyline(l) self.assertTrue( shape2.readXml(elem.firstChildElement(), doc, QgsReadWriteContext())) self.assertEqual(shape2.nodes(), shape.nodes()) self.assertEqual(shape2.symbol().symbolLayer(0).color().name(), '#ff0000') def testBounds(self): pr = QgsProject() l = QgsLayout(pr) p = QPolygonF() p.append(QPointF(50.0, 30.0)) p.append(QPointF(100.0, 10.0)) p.append(QPointF(200.0, 100.0)) shape = QgsLayoutItemPolyline(p, l) props = {} props["color"] = "255,0,0,255" props["width"] = "6.0" props["capstyle"] = "square" style = QgsLineSymbol.createSimple(props) shape.setSymbol(style) # scene bounding rect should include symbol outline bounds = shape.sceneBoundingRect() self.assertEqual(bounds.left(), 47.0) self.assertEqual(bounds.right(), 203.0) self.assertEqual(bounds.top(), 7.0) self.assertEqual(bounds.bottom(), 103.0) # rectWithFrame should include symbol outline too bounds = shape.rectWithFrame() self.assertEqual(bounds.left(), -3.0) self.assertEqual(bounds.right(), 153.0) self.assertEqual(bounds.top(), -3.0) self.assertEqual(bounds.bottom(), 93.0) def testHorizontalLine(self): pr = QgsProject() l = QgsLayout(pr) l.initializeDefaults() p = QPolygonF() p.append(QPointF(50.0, 100.0)) p.append(QPointF(100.0, 100.0)) shape = QgsLayoutItemPolyline(p, l) l.addLayoutItem(shape) props = {} props["color"] = "0,0,0,255" props["width"] = "10.0" props["capstyle"] = "square" style = QgsLineSymbol.createSimple(props) shape.setSymbol(style) checker = QgsLayoutChecker('composerpolyline_hozline', l) checker.setControlPathPrefix("composer_polyline") myTestResult, myMessage = checker.testLayout() assert myTestResult, myMessage def testVerticalLine(self): pr = QgsProject() l = QgsLayout(pr) l.initializeDefaults() p = QPolygonF() p.append(QPointF(100.0, 50.0)) p.append(QPointF(100.0, 100.0)) shape = QgsLayoutItemPolyline(p, l) l.addLayoutItem(shape) props = {} props["color"] = "0,0,0,255" props["width"] = "10.0" props["capstyle"] = "square" style = QgsLineSymbol.createSimple(props) shape.setSymbol(style) checker = QgsLayoutChecker('composerpolyline_vertline', l) checker.setControlPathPrefix("composer_polyline") myTestResult, myMessage = checker.testLayout() assert myTestResult, myMessage
class TestQgsLayoutMap(unittest.TestCase, LayoutItemTestCase): @classmethod def setUpClass(cls): cls.item_class = QgsLayoutItemMap def setUp(self): self.report = "<h1>Python QgsLayoutItemMap 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 __init__(self, methodName): """Run once on class initialization.""" unittest.TestCase.__init__(self, methodName) myPath = os.path.join(TEST_DATA_DIR, 'rgb256x256.png') rasterFileInfo = QFileInfo(myPath) self.raster_layer = QgsRasterLayer(rasterFileInfo.filePath(), rasterFileInfo.completeBaseName()) rasterRenderer = QgsMultiBandColorRenderer( self.raster_layer.dataProvider(), 1, 2, 3) self.raster_layer.setRenderer(rasterRenderer) myPath = os.path.join(TEST_DATA_DIR, 'points.shp') vector_file_info = QFileInfo(myPath) self.vector_layer = QgsVectorLayer(vector_file_info.filePath(), vector_file_info.completeBaseName(), 'ogr') assert self.vector_layer.isValid() QgsProject.instance().addMapLayers( [self.raster_layer, self.vector_layer]) # create layout with layout map self.layout = QgsLayout(QgsProject.instance()) self.layout.initializeDefaults() self.map = QgsLayoutItemMap(self.layout) self.map.attemptSetSceneRect(QRectF(20, 20, 200, 100)) self.map.setFrameEnabled(True) self.map.setLayers([self.raster_layer]) self.layout.addLayoutItem(self.map) 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) self.assertTrue(myTestResult, myMessage) 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().setLinkedMap(self.map) overviewMap.overview().setBlendMode(QPainter.CompositionMode_Multiply) checker = QgsLayoutChecker('composermap_overview_blending', self.layout) checker.setControlPathPrefix("composer_mapoverview") myTestResult, myMessage = checker.testLayout() self.report += checker.report() self.layout.removeLayoutItem(overviewMap) self.assertTrue(myTestResult, myMessage) def testOverviewMapInvert(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) overviewMap.overview().setInverted(True) checker = QgsLayoutChecker('composermap_overview_invert', self.layout) checker.setControlPathPrefix("composer_mapoverview") myTestResult, myMessage = checker.testLayout() self.report += checker.report() self.layout.removeLayoutItem(overviewMap) 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().setLinkedMap(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.report += checker.report() self.layout.removeLayoutItem(overviewMap) self.assertTrue(myTestResult, myMessage) 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))' ]) 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 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 testRequiresRasterization(self): l = QgsLayout(QgsProject.instance()) item = self.make_item(l) self.assertFalse(item.requiresRasterization()) item.setBlendMode(QPainter.CompositionMode_SourceIn) self.assertTrue(item.requiresRasterization())
def testReadWriteXml(self): p = QgsProject() l = QgsLayout(p) l.initializeDefaults() guides = l.guides() # add some guides g1 = QgsLayoutGuide( Qt.Horizontal, QgsLayoutMeasurement(5, QgsUnitTypes.LayoutCentimeters), l.pageCollection().page(0)) guides.addGuide(g1) g2 = QgsLayoutGuide(Qt.Vertical, QgsLayoutMeasurement(6, QgsUnitTypes.LayoutInches), l.pageCollection().page(0)) guides.addGuide(g2) guides.setVisible(False) doc = QDomDocument("testdoc") elem = doc.createElement("test") self.assertTrue(guides.writeXml(elem, doc, QgsReadWriteContext())) l2 = QgsLayout(p) l2.initializeDefaults() guides2 = l2.guides() self.assertTrue( guides2.readXml(elem.firstChildElement(), doc, QgsReadWriteContext())) guide_list = guides2.guidesOnPage(0) self.assertEqual(len(guide_list), 2) self.assertEqual(guide_list[0].orientation(), Qt.Horizontal) self.assertEqual(guide_list[0].position().length(), 5.0) self.assertEqual(guide_list[0].position().units(), QgsUnitTypes.LayoutCentimeters) self.assertEqual(guide_list[1].orientation(), Qt.Vertical) self.assertEqual(guide_list[1].position().length(), 6.0) self.assertEqual(guide_list[1].position().units(), QgsUnitTypes.LayoutInches)
def testSelectNextByZOrder(self): p = QgsProject() l = QgsLayout(p) # add some items item1 = QgsLayoutItemPicture(l) l.addItem(item1) item2 = QgsLayoutItemPicture(l) l.addItem(item2) item3 = QgsLayoutItemPicture(l) item3.setLocked(True) l.addItem(item3) view = QgsLayoutView() # no layout, no crash view.selectNextItemAbove() view.selectNextItemBelow() view.setCurrentLayout(l) focused_item_spy = QSignalSpy(view.itemFocused) # no selection view.selectNextItemAbove() view.selectNextItemBelow() self.assertEqual(len(focused_item_spy), 0) l.setSelectedItem(item1) self.assertEqual(len(focused_item_spy), 1) # already bottom most view.selectNextItemBelow() self.assertTrue(item1.isSelected()) self.assertFalse(item2.isSelected()) self.assertFalse(item3.isSelected()) self.assertEqual(len(focused_item_spy), 1) view.selectNextItemAbove() self.assertFalse(item1.isSelected()) self.assertTrue(item2.isSelected()) self.assertFalse(item3.isSelected()) self.assertEqual(len(focused_item_spy), 2) view.selectNextItemAbove() self.assertFalse(item1.isSelected()) self.assertFalse(item2.isSelected()) self.assertTrue(item3.isSelected()) self.assertEqual(len(focused_item_spy), 3) view.selectNextItemAbove() # already top most self.assertFalse(item1.isSelected()) self.assertFalse(item2.isSelected()) self.assertTrue(item3.isSelected()) self.assertEqual(len(focused_item_spy), 3) view.selectNextItemBelow() self.assertFalse(item1.isSelected()) self.assertTrue(item2.isSelected()) self.assertFalse(item3.isSelected()) self.assertEqual(len(focused_item_spy), 4) view.selectNextItemBelow() self.assertTrue(item1.isSelected()) self.assertFalse(item2.isSelected()) self.assertFalse(item3.isSelected()) self.assertEqual(len(focused_item_spy), 5) view.selectNextItemBelow() # back to bottom most self.assertTrue(item1.isSelected()) self.assertFalse(item2.isSelected()) self.assertFalse(item3.isSelected()) self.assertEqual(len(focused_item_spy), 5)
def testCollection(self): p = QgsProject() l = QgsLayout(p) l.initializeDefaults() # add a page guides = l.guides() # no guides initially self.assertEqual(guides.rowCount(QModelIndex()), 0) self.assertFalse( guides.data(QModelIndex(), QgsLayoutGuideCollection.OrientationRole)) self.assertFalse(guides.guides(Qt.Horizontal)) self.assertFalse(guides.guides(Qt.Vertical)) # add a guide g1 = QgsLayoutGuide( Qt.Horizontal, QgsLayoutMeasurement(5, QgsUnitTypes.LayoutCentimeters), l.pageCollection().page(0)) guides.addGuide(g1) self.assertEqual(guides.rowCount(QModelIndex()), 1) self.assertEqual( guides.data(guides.index(0, 0), QgsLayoutGuideCollection.OrientationRole), Qt.Horizontal) self.assertEqual( guides.data(guides.index(0, 0), QgsLayoutGuideCollection.PositionRole), 5) self.assertEqual( guides.data(guides.index(0, 0), QgsLayoutGuideCollection.UnitsRole), QgsUnitTypes.LayoutCentimeters) self.assertEqual( guides.data(guides.index(0, 0), QgsLayoutGuideCollection.PageRole), 0) self.assertEqual(guides.guides(Qt.Horizontal), [g1]) self.assertFalse(guides.guides(Qt.Vertical)) self.assertEqual(guides.guidesOnPage(0), [g1]) self.assertEqual(guides.guidesOnPage(1), []) g2 = QgsLayoutGuide(Qt.Horizontal, QgsLayoutMeasurement(15), l.pageCollection().page(0)) guides.addGuide(g2) self.assertEqual(guides.rowCount(QModelIndex()), 2) self.assertEqual( guides.data(guides.index(1, 0), QgsLayoutGuideCollection.OrientationRole), Qt.Horizontal) self.assertEqual( guides.data(guides.index(1, 0), QgsLayoutGuideCollection.PositionRole), 15) self.assertEqual( guides.data(guides.index(1, 0), QgsLayoutGuideCollection.UnitsRole), QgsUnitTypes.LayoutMillimeters) self.assertEqual( guides.data(guides.index(1, 0), QgsLayoutGuideCollection.PageRole), 0) self.assertEqual(guides.guides(Qt.Horizontal), [g1, g2]) self.assertFalse(guides.guides(Qt.Vertical)) self.assertEqual(guides.guidesOnPage(0), [g1, g2]) page2 = QgsLayoutItemPage(l) page2.setPageSize('A3') l.pageCollection().addPage(page2) g3 = QgsLayoutGuide(Qt.Vertical, QgsLayoutMeasurement(35), l.pageCollection().page(1)) guides.addGuide(g3) self.assertEqual(guides.rowCount(QModelIndex()), 3) self.assertEqual( guides.data(guides.index(2, 0), QgsLayoutGuideCollection.OrientationRole), Qt.Vertical) self.assertEqual( guides.data(guides.index(2, 0), QgsLayoutGuideCollection.PositionRole), 35) self.assertEqual( guides.data(guides.index(2, 0), QgsLayoutGuideCollection.UnitsRole), QgsUnitTypes.LayoutMillimeters) self.assertEqual( guides.data(guides.index(2, 0), QgsLayoutGuideCollection.PageRole), 1) self.assertEqual(guides.guides(Qt.Horizontal), [g1, g2]) self.assertEqual(guides.guides(Qt.Horizontal, 0), [g1, g2]) self.assertEqual(guides.guides(Qt.Horizontal, 1), []) self.assertEqual(guides.guides(Qt.Vertical), [g3]) self.assertEqual(guides.guides(Qt.Vertical, 0), []) self.assertEqual(guides.guides(Qt.Vertical, 1), [g3]) self.assertEqual(guides.guides(Qt.Vertical, 2), []) self.assertEqual(guides.guidesOnPage(0), [g1, g2]) self.assertEqual(guides.guidesOnPage(1), [g3])
def testExportToSvg(self): md = QgsProject.instance().metadata() md.setTitle('proj title') md.setAuthor('proj author') md.setCreationDateTime( QDateTime(QDate(2011, 5, 3), QTime(9, 4, 5), QTimeZone(36000))) md.setIdentifier('proj identifier') md.setAbstract('proj abstract') md.setKeywords({'kw': ['kw1', 'kw2']}) QgsProject.instance().setMetadata(md) l = QgsLayout(QgsProject.instance()) l.initializeDefaults() # add a second page page2 = QgsLayoutItemPage(l) page2.setPageSize('A5') l.pageCollection().addPage(page2) # add some items item1 = QgsLayoutItemShape(l) item1.attemptSetSceneRect(QRectF(10, 20, 100, 150)) fill = QgsSimpleFillSymbolLayer() fill_symbol = QgsFillSymbol() fill_symbol.changeSymbolLayer(0, fill) fill.setColor(Qt.green) fill.setStrokeStyle(Qt.NoPen) item1.setSymbol(fill_symbol) l.addItem(item1) item2 = QgsLayoutItemShape(l) item2.attemptSetSceneRect(QRectF(10, 20, 100, 150)) item2.attemptMove(QgsLayoutPoint(10, 20), page=1) fill = QgsSimpleFillSymbolLayer() fill_symbol = QgsFillSymbol() fill_symbol.changeSymbolLayer(0, fill) fill.setColor(Qt.cyan) fill.setStrokeStyle(Qt.NoPen) item2.setSymbol(fill_symbol) l.addItem(item2) exporter = QgsLayoutExporter(l) # setup settings settings = QgsLayoutExporter.SvgExportSettings() settings.dpi = 80 settings.forceVectorOutput = False settings.exportMetadata = True svg_file_path = os.path.join(self.basetestpath, 'test_exporttosvgdpi.svg') svg_file_path_2 = os.path.join(self.basetestpath, 'test_exporttosvgdpi_2.svg') self.assertEqual(exporter.exportToSvg(svg_file_path, settings), QgsLayoutExporter.Success) self.assertTrue(os.path.exists(svg_file_path)) self.assertTrue(os.path.exists(svg_file_path_2)) # metadata def checkMetadata(f, expected): # ideally we'd check the path too - but that's very complex given that # the output from Qt svg generator isn't valid XML, and no Python standard library # xml parser handles invalid xml... self.assertEqual('proj title' in open(f).read(), expected) self.assertEqual('proj author' in open(f).read(), expected) self.assertEqual('proj identifier' in open(f).read(), expected) self.assertEqual('2011-05-03' in open(f).read(), expected) self.assertEqual('proj abstract' in open(f).read(), expected) self.assertEqual('kw1' in open(f).read(), expected) self.assertEqual('kw2' in open(f).read(), expected) for f in [svg_file_path, svg_file_path_2]: checkMetadata(f, True) rendered_page_1 = os.path.join(self.basetestpath, 'test_exporttosvgdpi.png') svgToPng(svg_file_path, rendered_page_1, width=936) rendered_page_2 = os.path.join(self.basetestpath, 'test_exporttosvgdpi2.png') svgToPng(svg_file_path_2, rendered_page_2, width=467) self.assertTrue( self.checkImage('exporttosvgdpi_page1', 'exporttopdfdpi_page1', rendered_page_1, size_tolerance=1)) self.assertTrue( self.checkImage('exporttosvgdpi_page2', 'exporttopdfdpi_page2', rendered_page_2, size_tolerance=1)) # no metadata settings.exportMetadata = False self.assertEqual(exporter.exportToSvg(svg_file_path, settings), QgsLayoutExporter.Success) for f in [svg_file_path, svg_file_path_2]: checkMetadata(f, False) # layered settings.exportAsLayers = True settings.exportMetadata = True svg_file_path = os.path.join(self.basetestpath, 'test_exporttosvglayered.svg') svg_file_path_2 = os.path.join(self.basetestpath, 'test_exporttosvglayered_2.svg') self.assertEqual(exporter.exportToSvg(svg_file_path, settings), QgsLayoutExporter.Success) self.assertTrue(os.path.exists(svg_file_path)) self.assertTrue(os.path.exists(svg_file_path_2)) rendered_page_1 = os.path.join(self.basetestpath, 'test_exporttosvglayered.png') svgToPng(svg_file_path, rendered_page_1, width=936) rendered_page_2 = os.path.join(self.basetestpath, 'test_exporttosvglayered2.png') svgToPng(svg_file_path_2, rendered_page_2, width=467) self.assertTrue( self.checkImage('exporttosvglayered_page1', 'exporttopdfdpi_page1', rendered_page_1, size_tolerance=1)) self.assertTrue( self.checkImage('exporttosvglayered_page2', 'exporttopdfdpi_page2', rendered_page_2, size_tolerance=1)) for f in [svg_file_path, svg_file_path_2]: checkMetadata(f, True) # layered no metadata settings.exportAsLayers = True settings.exportMetadata = False self.assertEqual(exporter.exportToSvg(svg_file_path, settings), QgsLayoutExporter.Success) for f in [svg_file_path, svg_file_path_2]: checkMetadata(f, False)
def testStacking(self): p = QgsProject() l = QgsLayout(p) # add some items item1 = QgsLayoutItemMap(l) l.addLayoutItem(item1) item2 = QgsLayoutItemMap(l) l.addLayoutItem(item2) item3 = QgsLayoutItemMap(l) l.addLayoutItem(item3) self.assertEqual(item1.zValue(), 1) self.assertEqual(item2.zValue(), 2) self.assertEqual(item3.zValue(), 3) # no effect interactions self.assertFalse(l.raiseItem(None)) self.assertFalse(l.lowerItem(None)) self.assertFalse(l.moveItemToTop(None)) self.assertFalse(l.moveItemToBottom(None)) self.assertEqual(item1.zValue(), 1) self.assertEqual(item2.zValue(), 2) self.assertEqual(item3.zValue(), 3) # raising self.assertFalse(l.raiseItem(item3)) self.assertEqual(item1.zValue(), 1) self.assertEqual(item2.zValue(), 2) self.assertEqual(item3.zValue(), 3) self.assertTrue(l.raiseItem(item2)) self.assertEqual(item1.zValue(), 1) self.assertEqual(item2.zValue(), 3) self.assertEqual(item3.zValue(), 2) self.assertFalse(l.raiseItem(item2)) self.assertEqual(item1.zValue(), 1) self.assertEqual(item2.zValue(), 3) self.assertEqual(item3.zValue(), 2) self.assertTrue(l.raiseItem(item1)) self.assertEqual(item1.zValue(), 2) self.assertEqual(item2.zValue(), 3) self.assertEqual(item3.zValue(), 1) # lower self.assertFalse(l.lowerItem(item3)) self.assertEqual(item1.zValue(), 2) self.assertEqual(item2.zValue(), 3) self.assertEqual(item3.zValue(), 1) self.assertTrue(l.lowerItem(item2)) self.assertEqual(item1.zValue(), 3) self.assertEqual(item2.zValue(), 2) self.assertEqual(item3.zValue(), 1) self.assertTrue(l.lowerItem(item2)) self.assertEqual(item1.zValue(), 3) self.assertEqual(item2.zValue(), 1) self.assertEqual(item3.zValue(), 2) # raise to top self.assertFalse(l.moveItemToTop(item1)) self.assertEqual(item1.zValue(), 3) self.assertEqual(item2.zValue(), 1) self.assertEqual(item3.zValue(), 2) self.assertTrue(l.moveItemToTop(item3)) self.assertEqual(item1.zValue(), 2) self.assertEqual(item2.zValue(), 1) self.assertEqual(item3.zValue(), 3) self.assertTrue(l.moveItemToTop(item2)) self.assertEqual(item1.zValue(), 1) self.assertEqual(item2.zValue(), 3) self.assertEqual(item3.zValue(), 2) # move to bottom self.assertFalse(l.moveItemToBottom(item1)) self.assertEqual(item1.zValue(), 1) self.assertEqual(item2.zValue(), 3) self.assertEqual(item3.zValue(), 2) self.assertTrue(l.moveItemToBottom(item3)) self.assertEqual(item1.zValue(), 2) self.assertEqual(item2.zValue(), 3) self.assertEqual(item3.zValue(), 1) self.assertTrue(l.moveItemToBottom(item2)) self.assertEqual(item1.zValue(), 3) self.assertEqual(item2.zValue(), 1) self.assertEqual(item3.zValue(), 2)
def testExportToPdf(self): md = QgsProject.instance().metadata() md.setTitle('proj title') md.setAuthor('proj author') md.setCreationDateTime( QDateTime(QDate(2011, 5, 3), QTime(9, 4, 5), QTimeZone(36000))) md.setIdentifier('proj identifier') md.setAbstract('proj abstract') md.setKeywords({'kw': ['kw1', 'kw2'], 'KWx': ['kw3', 'kw4']}) QgsProject.instance().setMetadata(md) l = QgsLayout(QgsProject.instance()) l.initializeDefaults() # add a second page page2 = QgsLayoutItemPage(l) page2.setPageSize('A5') l.pageCollection().addPage(page2) # add some items item1 = QgsLayoutItemShape(l) item1.attemptSetSceneRect(QRectF(10, 20, 100, 150)) fill = QgsSimpleFillSymbolLayer() fill_symbol = QgsFillSymbol() fill_symbol.changeSymbolLayer(0, fill) fill.setColor(Qt.green) fill.setStrokeStyle(Qt.NoPen) item1.setSymbol(fill_symbol) l.addItem(item1) item2 = QgsLayoutItemShape(l) item2.attemptSetSceneRect(QRectF(10, 20, 100, 150)) item2.attemptMove(QgsLayoutPoint(10, 20), page=1) fill = QgsSimpleFillSymbolLayer() fill_symbol = QgsFillSymbol() fill_symbol.changeSymbolLayer(0, fill) fill.setColor(Qt.cyan) fill.setStrokeStyle(Qt.NoPen) item2.setSymbol(fill_symbol) l.addItem(item2) exporter = QgsLayoutExporter(l) # setup settings settings = QgsLayoutExporter.PdfExportSettings() settings.dpi = 80 settings.rasterizeWholeImage = False settings.forceVectorOutput = False settings.exportMetadata = True pdf_file_path = os.path.join(self.basetestpath, 'test_exporttopdfdpi.pdf') self.assertEqual(exporter.exportToPdf(pdf_file_path, settings), QgsLayoutExporter.Success) self.assertTrue(os.path.exists(pdf_file_path)) rendered_page_1 = os.path.join(self.basetestpath, 'test_exporttopdfdpi.png') dpi = 80 pdfToPng(pdf_file_path, rendered_page_1, dpi=dpi, page=1) rendered_page_2 = os.path.join(self.basetestpath, 'test_exporttopdfdpi2.png') pdfToPng(pdf_file_path, rendered_page_2, dpi=dpi, page=2) self.assertTrue( self.checkImage('exporttopdfdpi_page1', 'exporttopdfdpi_page1', rendered_page_1, size_tolerance=1)) self.assertTrue( self.checkImage('exporttopdfdpi_page2', 'exporttopdfdpi_page2', rendered_page_2, size_tolerance=1)) d = gdal.Open(pdf_file_path) metadata = d.GetMetadata() self.assertEqual(metadata['AUTHOR'], 'proj author') self.assertEqual(metadata['CREATION_DATE'], "D:20110503090405+10'0'") self.assertEqual(metadata['KEYWORDS'], 'KWx: kw3,kw4;kw: kw1,kw2') self.assertEqual(metadata['SUBJECT'], 'proj abstract') self.assertEqual(metadata['TITLE'], 'proj title')
def testExportToImage(self): md = QgsProject.instance().metadata() md.setTitle('proj title') md.setAuthor('proj author') md.setCreationDateTime( QDateTime(QDate(2011, 5, 3), QTime(9, 4, 5), QTimeZone(36000))) md.setIdentifier('proj identifier') md.setAbstract('proj abstract') md.setKeywords({'kw': ['kw1', 'kw2'], 'KWx': ['kw3', 'kw4']}) QgsProject.instance().setMetadata(md) l = QgsLayout(QgsProject.instance()) l.initializeDefaults() # add a second page page2 = QgsLayoutItemPage(l) page2.setPageSize('A5') l.pageCollection().addPage(page2) # add some items item1 = QgsLayoutItemShape(l) item1.attemptSetSceneRect(QRectF(10, 20, 100, 150)) fill = QgsSimpleFillSymbolLayer() fill_symbol = QgsFillSymbol() fill_symbol.changeSymbolLayer(0, fill) fill.setColor(Qt.green) fill.setStrokeStyle(Qt.NoPen) item1.setSymbol(fill_symbol) l.addItem(item1) item2 = QgsLayoutItemShape(l) item2.attemptSetSceneRect(QRectF(10, 20, 100, 150)) item2.attemptMove(QgsLayoutPoint(10, 20), page=1) fill = QgsSimpleFillSymbolLayer() fill_symbol = QgsFillSymbol() fill_symbol.changeSymbolLayer(0, fill) fill.setColor(Qt.cyan) fill.setStrokeStyle(Qt.NoPen) item2.setSymbol(fill_symbol) l.addItem(item2) exporter = QgsLayoutExporter(l) # setup settings settings = QgsLayoutExporter.ImageExportSettings() settings.dpi = 80 rendered_file_path = os.path.join(self.basetestpath, 'test_exporttoimagedpi.png') self.assertEqual(exporter.exportToImage(rendered_file_path, settings), QgsLayoutExporter.Success) self.assertTrue( self.checkImage('exporttoimagedpi_page1', 'exporttoimagedpi_page1', rendered_file_path)) page2_path = os.path.join(self.basetestpath, 'test_exporttoimagedpi_2.png') self.assertTrue( self.checkImage('exporttoimagedpi_page2', 'exporttoimagedpi_page2', page2_path)) for f in (rendered_file_path, page2_path): d = gdal.Open(f) metadata = d.GetMetadata() self.assertEqual(metadata['Author'], 'proj author') self.assertEqual(metadata['Created'], '2011-05-03T09:04:05+10:00') self.assertEqual(metadata['Keywords'], 'KWx: kw3,kw4;kw: kw1,kw2') self.assertEqual(metadata['Subject'], 'proj abstract') self.assertEqual(metadata['Title'], 'proj title') # crop to contents settings.cropToContents = True settings.cropMargins = QgsMargins(10, 20, 30, 40) rendered_file_path = os.path.join(self.basetestpath, 'test_exporttoimagecropped.png') self.assertEqual(exporter.exportToImage(rendered_file_path, settings), QgsLayoutExporter.Success) self.assertTrue( self.checkImage('exporttoimagecropped_page1', 'exporttoimagecropped_page1', rendered_file_path)) page2_path = os.path.join(self.basetestpath, 'test_exporttoimagecropped_2.png') self.assertTrue( self.checkImage('exporttoimagecropped_page2', 'exporttoimagecropped_page2', page2_path)) # specific pages settings.cropToContents = False settings.pages = [1] rendered_file_path = os.path.join(self.basetestpath, 'test_exporttoimagepages.png') self.assertEqual(exporter.exportToImage(rendered_file_path, settings), QgsLayoutExporter.Success) self.assertFalse(os.path.exists(rendered_file_path)) page2_path = os.path.join(self.basetestpath, 'test_exporttoimagepages_2.png') self.assertTrue( self.checkImage('exporttoimagedpi_page2', 'exporttoimagedpi_page2', page2_path)) # image size settings.imageSize = QSize(600, 851) rendered_file_path = os.path.join(self.basetestpath, 'test_exporttoimagesize.png') self.assertEqual(exporter.exportToImage(rendered_file_path, settings), QgsLayoutExporter.Success) self.assertFalse(os.path.exists(rendered_file_path)) page2_path = os.path.join(self.basetestpath, 'test_exporttoimagesize_2.png') self.assertTrue( self.checkImage('exporttoimagesize_page2', 'exporttoimagesize_page2', page2_path)) # image size with incorrect aspect ratio # this can happen as a result of data defined page sizes settings.imageSize = QSize(851, 600) rendered_file_path = os.path.join( self.basetestpath, 'test_exporttoimagesizebadaspect.png') self.assertEqual(exporter.exportToImage(rendered_file_path, settings), QgsLayoutExporter.Success) page2_path = os.path.join(self.basetestpath, 'test_exporttoimagesizebadaspect_2.png') im = QImage(page2_path) self.assertTrue( self.checkImage('exporttoimagesize_badaspect', 'exporttoimagedpi_page2', page2_path), '{}x{}'.format(im.width(), im.height()))
def testExportReport(self): p = QgsProject() r = QgsReport(p) # add a header r.setHeaderEnabled(True) report_header = QgsLayout(p) report_header.initializeDefaults() item1 = QgsLayoutItemShape(report_header) item1.attemptSetSceneRect(QRectF(10, 20, 100, 150)) fill = QgsSimpleFillSymbolLayer() fill_symbol = QgsFillSymbol() fill_symbol.changeSymbolLayer(0, fill) fill.setColor(Qt.green) fill.setStrokeStyle(Qt.NoPen) item1.setSymbol(fill_symbol) report_header.addItem(item1) r.setHeader(report_header) # add a footer r.setFooterEnabled(True) report_footer = QgsLayout(p) report_footer.initializeDefaults() item2 = QgsLayoutItemShape(report_footer) item2.attemptSetSceneRect(QRectF(10, 20, 100, 150)) item2.attemptMove(QgsLayoutPoint(10, 20)) fill = QgsSimpleFillSymbolLayer() fill_symbol = QgsFillSymbol() fill_symbol.changeSymbolLayer(0, fill) fill.setColor(Qt.cyan) fill.setStrokeStyle(Qt.NoPen) item2.setSymbol(fill_symbol) report_footer.addItem(item2) r.setFooter(report_footer) # setup settings settings = QgsLayoutExporter.ImageExportSettings() settings.dpi = 80 report_path = os.path.join(self.basetestpath, 'test_report') result, error = QgsLayoutExporter.exportToImage( r, report_path, 'png', settings) self.assertEqual(result, QgsLayoutExporter.Success, error) page1_path = os.path.join(self.basetestpath, 'test_report_0001.png') self.assertTrue( self.checkImage('report_page1', 'report_page1', page1_path)) page2_path = os.path.join(self.basetestpath, 'test_report_0002.png') self.assertTrue( self.checkImage('report_page2', 'report_page2', page2_path))
def testSelections(self): p = QgsProject() l = QgsLayout(p) # add some items item1 = QgsLayoutItemMap(l) l.addItem(item1) item2 = QgsLayoutItemMap(l) l.addItem(item2) item3 = QgsLayoutItemMap(l) l.addItem(item3) select_changed_spy = QSignalSpy(l.selectedItemChanged) l.setSelectedItem(None) self.assertFalse(l.selectedLayoutItems()) self.assertEqual(len(select_changed_spy), 1) self.assertEqual(select_changed_spy[-1][0], None) l.setSelectedItem(item1) self.assertEqual(l.selectedLayoutItems(), [item1]) self.assertEqual(len(select_changed_spy), 2) self.assertEqual(select_changed_spy[-1][0], item1) l.setSelectedItem(None) self.assertFalse(l.selectedLayoutItems()) self.assertEqual(len(select_changed_spy), 3) self.assertEqual(select_changed_spy[-1][0], None) l.setSelectedItem(item2) self.assertEqual(l.selectedLayoutItems(), [item2]) self.assertEqual(len(select_changed_spy), 4) self.assertEqual(select_changed_spy[-1][0], item2) l.deselectAll() self.assertFalse(l.selectedLayoutItems()) self.assertEqual(len(select_changed_spy), 5) self.assertEqual(select_changed_spy[-1][0], None)
def testAlign(self): p = QgsProject() l = QgsLayout(p) # add some items item1 = QgsLayoutItemPicture(l) item1.attemptMove(QgsLayoutPoint(4, 8, QgsUnitTypes.LayoutMillimeters)) item1.attemptResize( QgsLayoutSize(18, 12, QgsUnitTypes.LayoutMillimeters)) l.addItem(item1) item2 = QgsLayoutItemPicture(l) item2.attemptMove(QgsLayoutPoint(6, 10, QgsUnitTypes.LayoutMillimeters)) item2.attemptResize( QgsLayoutSize(10, 9, QgsUnitTypes.LayoutMillimeters)) l.addItem(item2) item3 = QgsLayoutItemPicture(l) item3.attemptMove( QgsLayoutPoint(0.8, 1.2, QgsUnitTypes.LayoutCentimeters)) item3.attemptResize( QgsLayoutSize(1.8, 1.6, QgsUnitTypes.LayoutCentimeters)) l.addItem(item3) QgsLayoutAligner.alignItems(l, [item1, item2, item3], QgsLayoutAligner.AlignLeft) self.assertEqual(item1.positionWithUnits(), QgsLayoutPoint(4, 8, QgsUnitTypes.LayoutMillimeters)) self.assertEqual(item1.sizeWithUnits(), QgsLayoutSize(18, 12, QgsUnitTypes.LayoutMillimeters)) self.assertEqual(item2.positionWithUnits(), QgsLayoutPoint(4, 10, QgsUnitTypes.LayoutMillimeters)) self.assertEqual(item2.sizeWithUnits(), QgsLayoutSize(10, 9, QgsUnitTypes.LayoutMillimeters)) self.assertEqual( item3.positionWithUnits(), QgsLayoutPoint(0.4, 1.2, QgsUnitTypes.LayoutCentimeters)) self.assertEqual( item3.sizeWithUnits(), QgsLayoutSize(1.8, 1.6, QgsUnitTypes.LayoutCentimeters)) QgsLayoutAligner.alignItems(l, [item1, item2, item3], QgsLayoutAligner.AlignHCenter) self.assertEqual(item1.positionWithUnits(), QgsLayoutPoint(4, 8, QgsUnitTypes.LayoutMillimeters)) self.assertEqual(item1.sizeWithUnits(), QgsLayoutSize(18, 12, QgsUnitTypes.LayoutMillimeters)) self.assertEqual(item2.positionWithUnits(), QgsLayoutPoint(8, 10, QgsUnitTypes.LayoutMillimeters)) self.assertEqual(item2.sizeWithUnits(), QgsLayoutSize(10, 9, QgsUnitTypes.LayoutMillimeters)) self.assertEqual( item3.positionWithUnits(), QgsLayoutPoint(0.4, 1.2, QgsUnitTypes.LayoutCentimeters)) self.assertEqual( item3.sizeWithUnits(), QgsLayoutSize(1.8, 1.6, QgsUnitTypes.LayoutCentimeters)) QgsLayoutAligner.alignItems(l, [item1, item2, item3], QgsLayoutAligner.AlignRight) self.assertEqual(item1.positionWithUnits(), QgsLayoutPoint(4, 8, QgsUnitTypes.LayoutMillimeters)) self.assertEqual(item1.sizeWithUnits(), QgsLayoutSize(18, 12, QgsUnitTypes.LayoutMillimeters)) self.assertEqual( item2.positionWithUnits(), QgsLayoutPoint(12, 10, QgsUnitTypes.LayoutMillimeters)) self.assertEqual(item2.sizeWithUnits(), QgsLayoutSize(10, 9, QgsUnitTypes.LayoutMillimeters)) self.assertEqual( item3.positionWithUnits(), QgsLayoutPoint(0.4, 1.2, QgsUnitTypes.LayoutCentimeters)) self.assertEqual( item3.sizeWithUnits(), QgsLayoutSize(1.8, 1.6, QgsUnitTypes.LayoutCentimeters)) QgsLayoutAligner.alignItems(l, [item1, item2, item3], QgsLayoutAligner.AlignTop) self.assertEqual(item1.positionWithUnits(), QgsLayoutPoint(4, 8, QgsUnitTypes.LayoutMillimeters)) self.assertEqual(item1.sizeWithUnits(), QgsLayoutSize(18, 12, QgsUnitTypes.LayoutMillimeters)) self.assertEqual(item2.positionWithUnits(), QgsLayoutPoint(12, 8, QgsUnitTypes.LayoutMillimeters)) self.assertEqual(item2.sizeWithUnits(), QgsLayoutSize(10, 9, QgsUnitTypes.LayoutMillimeters)) self.assertEqual( item3.positionWithUnits(), QgsLayoutPoint(0.4, 0.8, QgsUnitTypes.LayoutCentimeters)) self.assertEqual( item3.sizeWithUnits(), QgsLayoutSize(1.8, 1.6, QgsUnitTypes.LayoutCentimeters)) QgsLayoutAligner.alignItems(l, [item1, item2, item3], QgsLayoutAligner.AlignVCenter) self.assertEqual(item1.positionWithUnits(), QgsLayoutPoint(4, 10, QgsUnitTypes.LayoutMillimeters)) self.assertEqual(item1.sizeWithUnits(), QgsLayoutSize(18, 12, QgsUnitTypes.LayoutMillimeters)) self.assertEqual( item2.positionWithUnits(), QgsLayoutPoint(12, 11.5, QgsUnitTypes.LayoutMillimeters)) self.assertEqual(item2.sizeWithUnits(), QgsLayoutSize(10, 9, QgsUnitTypes.LayoutMillimeters)) self.assertEqual( item3.positionWithUnits(), QgsLayoutPoint(0.4, 0.8, QgsUnitTypes.LayoutCentimeters)) self.assertEqual( item3.sizeWithUnits(), QgsLayoutSize(1.8, 1.6, QgsUnitTypes.LayoutCentimeters)) QgsLayoutAligner.alignItems(l, [item1, item2, item3], QgsLayoutAligner.AlignBottom) self.assertEqual(item1.positionWithUnits(), QgsLayoutPoint(4, 12, QgsUnitTypes.LayoutMillimeters)) self.assertEqual(item1.sizeWithUnits(), QgsLayoutSize(18, 12, QgsUnitTypes.LayoutMillimeters)) self.assertEqual( item2.positionWithUnits(), QgsLayoutPoint(12, 15, QgsUnitTypes.LayoutMillimeters)) self.assertEqual(item2.sizeWithUnits(), QgsLayoutSize(10, 9, QgsUnitTypes.LayoutMillimeters)) self.assertEqual( item3.positionWithUnits(), QgsLayoutPoint(0.4, 0.8, QgsUnitTypes.LayoutCentimeters)) self.assertEqual( item3.sizeWithUnits(), QgsLayoutSize(1.8, 1.6, QgsUnitTypes.LayoutCentimeters))
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 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))' ])