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 _set_up_composition(self, width, height, dpi, engine_settings): # set up layout and add map self._c = QgsLayout(QgsProject.instance()) """:type: QgsLayout""" # self._c.setUseAdvancedEffects(False) self._c.renderContext().setDpi(dpi) # 600 x 400 px = 211.67 x 141.11 mm @ 72 dpi paperw = width * 25.4 / dpi paperh = height * 25.4 / dpi page = QgsLayoutItemPage(self._c) page.attemptResize(QgsLayoutSize(paperw, paperh)) self._c.pageCollection().addPage(page) # NOTE: do not use QgsLayoutItemMap(self._c, 0, 0, paperw, paperh) since # it only takes integers as parameters and the composition will grow # larger based upon union of item scene rectangles and a slight buffer # see end of QgsComposition::compositionBounds() # add map as small graphics item first, then set its scene QRectF later self._cmap = QgsLayoutItemMap(self._c) self._cmap.attemptSetSceneRect(QRectF(10, 10, 10, 10)) """:type: QgsLayoutItemMap""" self._cmap.setFrameEnabled(False) self._cmap.setLayers(self._TestMapSettings.layers()) if self._TestMapSettings.labelingEngineSettings().flags() & QgsLabelingEngineSettings.UsePartialCandidates: self._cmap.setMapFlags(QgsLayoutItemMap.ShowPartialLabels) self._c.addLayoutItem(self._cmap) # now expand map to fill page and set its extent self._cmap.attemptSetSceneRect(QRectF(0, 0, paperw, paperw)) self._cmap.setExtent(self.aoiExtent()) # self._cmap.updateCachedImage() # composition takes labeling engine settings from project QgsProject.instance().setLabelingEngineSettings(engine_settings)
def testSnapPoint(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.setSnapToGrid(True) s.setSnapTolerance(1) point, snapped = s.snapPoint(QPointF(1, 1), 1) self.assertTrue(snapped) self.assertEqual(point, QPointF(0, 0)) s.setSnapToGrid(False) point, snapped = s.snapPoint(QPointF(1, 1), 1) self.assertFalse(snapped) self.assertEqual(point, QPointF(1, 1)) # test that guide takes precedence s.setSnapToGrid(True) s.setSnapToGuides(True) guides.addGuide(QgsLayoutGuide(QgsLayoutGuide.Horizontal, QgsLayoutMeasurement(0.5), page)) point, snapped = s.snapPoint(QPointF(1, 1), 1) self.assertTrue(snapped) self.assertEqual(point, QPointF(0, 0.5))
def testReadWriteXml(self): p = QgsProject() l = QgsPrintLayout(p) l.setName('my layout') l.setUnits(QgsUnitTypes.LayoutInches) collection = l.pageCollection() # add a page page = QgsLayoutItemPage(l) page.setPageSize('A6') collection.addPage(page) grid = l.gridSettings() grid.setResolution(QgsLayoutMeasurement(5, QgsUnitTypes.LayoutPoints)) g1 = QgsLayoutGuide(Qt.Horizontal, QgsLayoutMeasurement(5, QgsUnitTypes.LayoutCentimeters), l.pageCollection().page(0)) l.guides().addGuide(g1) snapper = l.snapper() snapper.setSnapTolerance(7) # add some items item1 = QgsLayoutItemMap(l) item1.setId('xxyyxx') l.addItem(item1) item2 = QgsLayoutItemMap(l) item2.setId('zzyyzz') l.addItem(item2) l.setReferenceMap(item2) doc = QDomDocument("testdoc") elem = l.writeXml(doc, QgsReadWriteContext()) l2 = QgsPrintLayout(p) self.assertTrue(l2.readXml(elem, doc, QgsReadWriteContext())) self.assertEqual(l2.name(), 'my layout') self.assertEqual(l2.units(), QgsUnitTypes.LayoutInches) collection2 = l2.pageCollection() self.assertEqual(collection2.pageCount(), 1) self.assertAlmostEqual(collection2.page(0).pageSize().width(), 105, 4) self.assertEqual(collection2.page(0).pageSize().height(), 148) self.assertEqual(l2.gridSettings().resolution().length(), 5.0) self.assertEqual(l2.gridSettings().resolution().units(), QgsUnitTypes.LayoutPoints) self.assertEqual(l2.guides().guidesOnPage(0)[0].orientation(), Qt.Horizontal) self.assertEqual(l2.guides().guidesOnPage(0)[0].position().length(), 5.0) self.assertEqual(l2.guides().guidesOnPage(0)[0].position().units(), QgsUnitTypes.LayoutCentimeters) self.assertEqual(l2.snapper().snapTolerance(), 7) # check restored items new_item1 = l2.itemByUuid(item1.uuid()) self.assertTrue(new_item1) self.assertEqual(new_item1.id(), 'xxyyxx') new_item2 = l2.itemByUuid(item2.uuid()) self.assertTrue(new_item2) self.assertEqual(new_item2.id(), 'zzyyzz') self.assertEqual(l2.referenceMap().id(), 'zzyyzz')
def testSnapPointsToGrid(self): p = QgsProject() l = QgsLayout(p) # need a page to snap to grid page = QgsLayoutItemPage(l) page.setPageSize('A4') l.pageCollection().addPage(page) s = QgsLayoutSnapper(l) l.gridSettings().setResolution(QgsLayoutMeasurement(5, QgsUnitTypes.LayoutMillimeters)) s.setSnapToGrid(True) s.setSnapTolerance(1) delta, snappedX, snappedY = s.snapPointsToGrid([QPointF(1, 0.5)], 1) self.assertTrue(snappedX) self.assertTrue(snappedY) self.assertEqual(delta, QPointF(-1, -0.5)) point, snappedX, snappedY = s.snapPointsToGrid([QPointF(9, 2), QPointF(12, 6)], 1) self.assertTrue(snappedX) self.assertTrue(snappedY) self.assertEqual(point, QPointF(1, -1)) point, snappedX, snappedY = s.snapPointsToGrid([QPointF(9, 2), QPointF(12, 7)], 1) self.assertTrue(snappedX) self.assertFalse(snappedY) self.assertEqual(point, QPointF(1, 0)) point, snappedX, snappedY = s.snapPointsToGrid([QPointF(8, 2), QPointF(12, 6)], 1) self.assertFalse(snappedX) self.assertTrue(snappedY) self.assertEqual(point, QPointF(0, -1)) # grid disabled s.setSnapToGrid(False) point, snappedX, snappedY = s.snapPointsToGrid([QPointF(1, 1)], 1) self.assertFalse(snappedX) self.assertFalse(snappedY) self.assertEqual(point, QPointF(0, 0)) s.setSnapToGrid(True) # with different pixel scale point, snappedX, snappedY = s.snapPointsToGrid([QPointF(0.5, 0.5)], 1) self.assertTrue(snappedX) self.assertTrue(snappedY) self.assertEqual(point, QPointF(-.5, -.5)) point, snappedX, snappedY = s.snapPointsToGrid([QPointF(0.5, 0.5)], 3) self.assertFalse(snappedX) self.assertFalse(snappedY) self.assertEqual(point, QPointF(0, 0)) # with offset grid l.gridSettings().setOffset(QgsLayoutPoint(2, 0)) point, snappedX, snappedY = s.snapPointsToGrid([QPointF(13, 23)], 1) self.assertTrue(snappedX) self.assertFalse(snappedY) self.assertEqual(point, QPointF(-1, 0))
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 page_evaluation_test(self, layout, label, mVectorLayer): page = QgsLayoutItemPage(layout) page.setPageSize('A4') layout.pageCollection().addPage(page) label.setText("[%@layout_page||'/'||@layout_numpages%]") assert label.currentText() == "1/2" # move the the second page and re-evaluate label.attemptMove(QgsLayoutPoint(0, 320)) assert label.currentText() == "2/2"
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 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 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 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 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 testExcludePagesImage(self): l = QgsLayout(QgsProject.instance()) l.initializeDefaults() # add a second page page2 = QgsLayoutItemPage(l) page2.setPageSize('A5') l.pageCollection().addPage(page2) exporter = QgsLayoutExporter(l) # setup settings settings = QgsLayoutExporter.ImageExportSettings() settings.dpi = 80 settings.generateWorldFile = False rendered_file_path = os.path.join(self.basetestpath, 'test_exclude_export.png') details = QgsLayoutExporter.PageExportDetails() details.directory = self.basetestpath details.baseName = 'test_exclude_export' details.extension = 'png' details.page = 0 self.assertEqual(exporter.exportToImage(rendered_file_path, settings), QgsLayoutExporter.Success) self.assertTrue(os.path.exists(exporter.generateFileName(details))) details.page = 1 self.assertTrue(os.path.exists(exporter.generateFileName(details))) # exclude a page l.pageCollection().page(0).setExcludeFromExports(True) rendered_file_path = os.path.join(self.basetestpath, 'test_exclude_export_excluded.png') details.baseName = 'test_exclude_export_excluded' details.page = 0 self.assertEqual(exporter.exportToImage(rendered_file_path, settings), QgsLayoutExporter.Success) self.assertFalse(os.path.exists(exporter.generateFileName(details))) details.page = 1 self.assertTrue(os.path.exists(exporter.generateFileName(details))) # exclude second page l.pageCollection().page(1).setExcludeFromExports(True) rendered_file_path = os.path.join(self.basetestpath, 'test_exclude_export_excluded_all.png') details.baseName = 'test_exclude_export_excluded_all' details.page = 0 self.assertEqual(exporter.exportToImage(rendered_file_path, settings), QgsLayoutExporter.Success) self.assertFalse(os.path.exists(exporter.generateFileName(details))) details.page = 1 self.assertFalse(os.path.exists(exporter.generateFileName(details)))
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 testSnapPointToGuides(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 point, snapped = s.snapPointToGuides(0.5, QgsLayoutGuide.Vertical, 1) self.assertFalse(snapped) guides.addGuide(QgsLayoutGuide(QgsLayoutGuide.Vertical, QgsLayoutMeasurement(1), page)) point, snapped = s.snapPointToGuides(0.5, QgsLayoutGuide.Vertical, 1) self.assertTrue(snapped) self.assertEqual(point, 1) # outside tolerance point, snapped = s.snapPointToGuides(5.5, QgsLayoutGuide.Vertical, 1) self.assertFalse(snapped) # snapping off s.setSnapToGuides(False) point, snapped = s.snapPointToGuides(0.5, QgsLayoutGuide.Vertical, 1) self.assertFalse(snapped) s.setSnapToGuides(True) # snap to hoz point, snapped = s.snapPointToGuides(0.5, QgsLayoutGuide.Horizontal, 1) self.assertFalse(snapped) guides.addGuide(QgsLayoutGuide(QgsLayoutGuide.Horizontal, QgsLayoutMeasurement(1), page)) point, snapped = s.snapPointToGuides(0.5, QgsLayoutGuide.Horizontal, 1) self.assertTrue(snapped) self.assertEqual(point, 1) # with different pixel scale point, snapped = s.snapPointToGuides(0.5, QgsLayoutGuide.Horizontal, 3) self.assertFalse(snapped)
def testExportToPdfSkipFirstPage(self): l = QgsLayout(QgsProject.instance()) l.initializeDefaults() # page 1 is excluded from export page1 = l.pageCollection().page(0) page1.setExcludeFromExports(True) # add a second page page2 = QgsLayoutItemPage(l) page2.setPageSize('A5') l.pageCollection().addPage(page2) 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_skip_first.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_skip_first.png') dpi = 80 pdfToPng(pdf_file_path, rendered_page_1, dpi=dpi, page=1) self.assertTrue(self.checkImage('test_exporttopdfdpi_skip_first', 'exporttopdfdpi_page2', rendered_page_1, size_tolerance=1))
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 testQgsLayoutGuideProxyModel(self): p = QgsProject() l = QgsLayout(p) l.initializeDefaults() # add a page page2 = QgsLayoutItemPage(l) page2.setPageSize('A3') l.pageCollection().addPage(page2) guides = l.guides() hoz_filter = QgsLayoutGuideProxyModel(None, Qt.Horizontal, 0) hoz_filter.setSourceModel(guides) hoz_page_1_filter = QgsLayoutGuideProxyModel(None, Qt.Horizontal, 1) hoz_page_1_filter.setSourceModel(guides) vert_filter = QgsLayoutGuideProxyModel(None, Qt.Vertical, 0) vert_filter.setSourceModel(guides) # no guides initially self.assertEqual(hoz_filter.rowCount(QModelIndex()), 0) self.assertEqual(hoz_page_1_filter.rowCount(QModelIndex()), 0) self.assertEqual(vert_filter.rowCount(QModelIndex()), 0) # add some guides g1 = QgsLayoutGuide(Qt.Horizontal, QgsLayoutMeasurement(5, QgsUnitTypes.LayoutCentimeters), l.pageCollection().page(0)) guides.addGuide(g1) g2 = QgsLayoutGuide(Qt.Horizontal, QgsLayoutMeasurement(15), l.pageCollection().page(1)) guides.addGuide(g2) g3 = QgsLayoutGuide(Qt.Vertical, QgsLayoutMeasurement(35), l.pageCollection().page(0)) guides.addGuide(g3) self.assertEqual(hoz_filter.rowCount(QModelIndex()), 1) self.assertEqual(hoz_filter.data(hoz_filter.index(0, 0), QgsLayoutGuideCollection.PositionRole), 5) self.assertEqual(hoz_page_1_filter.rowCount(QModelIndex()), 1) self.assertEqual(hoz_page_1_filter.data(hoz_page_1_filter.index(0, 0), QgsLayoutGuideCollection.PositionRole), 15) self.assertEqual(vert_filter.rowCount(QModelIndex()), 1) self.assertEqual(vert_filter.data(vert_filter.index(0, 0), QgsLayoutGuideCollection.PositionRole), 35) # change page hoz_page_1_filter.setPage(0) self.assertEqual(hoz_page_1_filter.rowCount(QModelIndex()), 1) self.assertEqual(hoz_page_1_filter.data(hoz_page_1_filter.index(0, 0), QgsLayoutGuideCollection.PositionRole), 5)
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 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 createComposition(self): ''' Create a print Layout ''' c = QgsPrintLayout(self.mProject) c.initializeDefaults() c.setUnits(QgsUnitTypes.LayoutMillimeters) g=QgsLayoutGridSettings(c) g.setOffset( QgsLayoutPoint(3.5, 0, QgsUnitTypes.LayoutMillimeters) ) g.setResolution( QgsLayoutMeasurement(2.5) ) # Set page number self.getPageNumberNeeded() # Set main properties for i in range(1, self.numPages): p=QgsLayoutItemPage(c) #page.setPageSize('A6') p.setPageSize( QgsLayoutSize(self.pageWidth, self.pageHeight, QgsUnitTypes.LayoutMillimeters) ) c.pageCollection().addPage(p) # Set the global currentComposition self.currentComposition = c
def testDeletePageWithItems2(self): p = QgsProject() l = QgsLayout(p) collection = l.pageCollection() # add a page page = QgsLayoutItemPage(l) page.setPageSize('A4') collection.addPage(page) page2 = QgsLayoutItemPage(l) page2.setPageSize('A4') collection.addPage(page2) page3 = QgsLayoutItemPage(l) page3.setPageSize('A4') collection.addPage(page3) # item on pages shape1 = QgsLayoutItemShape(l) shape1.attemptResize(QgsLayoutSize(90, 50)) shape1.attemptMove(QgsLayoutPoint(90, 50), page=0) l.addLayoutItem(shape1) shape2 = QgsLayoutItemShape(l) shape2.attemptResize(QgsLayoutSize(110, 50)) shape2.attemptMove(QgsLayoutPoint(100, 150), page=2) l.addLayoutItem(shape2) self.assertEqual(shape1.page(), 0) self.assertEqual(shape2.page(), 2) collection.deletePage(page2) # check item position self.assertEqual(shape1.page(), 0) self.assertEqual(shape1.pagePositionWithUnits(), QgsLayoutPoint(90, 50)) self.assertEqual(shape2.page(), 1) self.assertEqual(shape2.pagePositionWithUnits(), QgsLayoutPoint(100, 150))
def testUndoRedo(self): p = QgsProject() l = QgsLayout(p) collection = l.pageCollection() # add a page page = QgsLayoutItemPage(l) page.setPageSize('A4') collection.addPage(page) self.assertEqual(collection.pageCount(), 1) l.undoStack().stack().undo() self.assertEqual(collection.pageCount(), 0) l.undoStack().stack().redo() self.assertEqual(collection.pageCount(), 1) # make sure page is accessible self.assertEqual(collection.page(0).pageSize().width(), 210) # add a second page page2 = QgsLayoutItemPage(l) page2.setPageSize('A5') collection.addPage(page2) # delete page collection.deletePage(collection.page(0)) self.assertEqual(collection.pageCount(), 1) l.undoStack().stack().undo() self.assertEqual(collection.pageCount(), 2) # make sure pages are accessible self.assertEqual(collection.page(0).pageSize().width(), 210) self.assertEqual(collection.page(1).pageSize().width(), 148) l.undoStack().stack().undo() self.assertEqual(collection.pageCount(), 1) l.undoStack().stack().undo() self.assertEqual(collection.pageCount(), 0) l.undoStack().stack().redo() self.assertEqual(collection.pageCount(), 1) self.assertEqual(collection.page(0).pageSize().width(), 210) l.undoStack().stack().redo() self.assertEqual(collection.pageCount(), 2) self.assertEqual(collection.page(0).pageSize().width(), 210) self.assertEqual(collection.page(1).pageSize().width(), 148) l.undoStack().stack().redo() self.assertEqual(collection.pageCount(), 1) self.assertEqual(collection.page(0).pageSize().width(), 148)
def testDeletePages(self): """ Test deleting pages from the collection """ p = QgsProject() l = QgsLayout(p) collection = l.pageCollection() # 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) # delete page collection.deletePage(None) self.assertEqual(collection.pageCount(), 2) self.assertEqual(len(page_about_to_be_removed_spy), 0) page3 = QgsLayoutItemPage(l) # try deleting a page not in collection collection.deletePage(page3) QCoreApplication.sendPostedEvents(None, QEvent.DeferredDelete) self.assertFalse(sip.isdeleted(page3)) self.assertEqual(collection.pageCount(), 2) self.assertEqual(len(page_about_to_be_removed_spy), 0) collection.deletePage(page) self.assertEqual(collection.pageCount(), 1) self.assertFalse(page in collection.pages()) QCoreApplication.sendPostedEvents(None, QEvent.DeferredDelete) self.assertTrue(sip.isdeleted(page)) self.assertEqual(len(page_about_to_be_removed_spy), 1) self.assertEqual(page_about_to_be_removed_spy[-1][0], 0) collection.deletePage(page2) self.assertEqual(collection.pageCount(), 0) self.assertFalse(collection.pages()) QCoreApplication.sendPostedEvents(None, QEvent.DeferredDelete) self.assertTrue(sip.isdeleted(page2)) self.assertEqual(len(page_about_to_be_removed_spy), 2) self.assertEqual(page_about_to_be_removed_spy[-1][0], 0)
def testReadWriteXml(self): p = QgsProject() l = QgsLayout(p) collection = l.pageCollection() fill = QgsSimpleFillSymbolLayer() fill_symbol = QgsFillSymbol() fill_symbol.changeSymbolLayer(0, fill) fill.setColor(Qt.green) fill.setStrokeColor(Qt.red) fill.setStrokeWidth(6) collection.setPageStyleSymbol(fill_symbol) # add a page page = QgsLayoutItemPage(l) page.setPageSize('A4') self.assertEqual(collection.pageNumber(page), -1) collection.addPage(page) # add a second page page2 = QgsLayoutItemPage(l) page2.setPageSize('A5') collection.addPage(page2) doc = QDomDocument("testdoc") elem = doc.createElement("test") self.assertTrue(collection.writeXml(elem, doc, QgsReadWriteContext())) l2 = QgsLayout(p) collection2 = l2.pageCollection() self.assertTrue(collection2.readXml(elem.firstChildElement(), doc, QgsReadWriteContext())) self.assertEqual(collection2.pageCount(), 2) self.assertEqual(collection2.page(0).pageSize().width(), 210) self.assertEqual(collection2.page(0).pageSize().height(), 297) self.assertEqual(collection2.page(1).pageSize().width(), 148) self.assertEqual(collection2.page(1).pageSize().height(), 210) self.assertEqual(collection2.pageStyleSymbol().symbolLayer(0).color().name(), '#00ff00') self.assertEqual(collection2.pageStyleSymbol().symbolLayer(0).strokeColor().name(), '#ff0000')
def testPositionOnPage(self): """ Test pageNumberForPoint and positionOnPage """ p = QgsProject() l = QgsLayout(p) collection = l.pageCollection() # add a page page = QgsLayoutItemPage(l) page.setPageSize('A4') collection.addPage(page) self.assertEqual(collection.pageNumberForPoint(QPointF(-100, -100)), 0) self.assertEqual(collection.pageNumberForPoint(QPointF(-100, -1)), 0) self.assertEqual(collection.pageNumberForPoint(QPointF(-100, 1)), 0) self.assertEqual(collection.pageNumberForPoint(QPointF(-100, 270)), 0) self.assertEqual(collection.pageNumberForPoint(QPointF(-100, 1270)), 0) self.assertEqual(collection.positionOnPage(QPointF(-100, -100)), QPointF(-100, -100)) self.assertEqual(collection.positionOnPage(QPointF(-100, -1)), QPointF(-100, -1)) self.assertEqual(collection.positionOnPage(QPointF(-100, 1)), QPointF(-100, 1)) self.assertEqual(collection.positionOnPage(QPointF(-100, 270)), QPointF(-100, 270)) self.assertEqual(collection.positionOnPage(QPointF(-100, 1270)), QPointF(-100, 973)) page2 = QgsLayoutItemPage(l) page2.setPageSize('A5') collection.addPage(page2) self.assertEqual(collection.pageNumberForPoint(QPointF(-100, -100)), 0) self.assertEqual(collection.pageNumberForPoint(QPointF(-100, -1)), 0) self.assertEqual(collection.pageNumberForPoint(QPointF(-100, 1)), 0) self.assertEqual(collection.pageNumberForPoint(QPointF(-100, 270)), 0) self.assertEqual(collection.pageNumberForPoint(QPointF(-100, 370)), 1) self.assertEqual(collection.pageNumberForPoint(QPointF(-100, 1270)), 1) self.assertEqual(collection.positionOnPage(QPointF(-100, -100)), QPointF(-100, -100)) self.assertEqual(collection.positionOnPage(QPointF(-100, -1)), QPointF(-100, -1)) self.assertEqual(collection.positionOnPage(QPointF(-100, 1)), QPointF(-100, 1)) self.assertEqual(collection.positionOnPage(QPointF(-100, 270)), QPointF(-100, 270)) self.assertEqual(collection.positionOnPage(QPointF(-100, 370)), QPointF(-100, 63)) self.assertEqual(collection.positionOnPage(QPointF(-100, 1270)), QPointF(-100, 753))
def testPagePositionToAbsolute(self): """ Test pagePositionToAbsolute """ p = QgsProject() l = QgsLayout(p) collection = l.pageCollection() # invalid pages self.assertEqual(collection.pagePositionToAbsolute(-1, QgsLayoutPoint(1, 1)), QgsLayoutPoint(1, 1)) self.assertEqual(collection.pagePositionToAbsolute(0, QgsLayoutPoint(1, 1)), QgsLayoutPoint(1, 1)) self.assertEqual(collection.pagePositionToAbsolute(100, QgsLayoutPoint(1, 1)), QgsLayoutPoint(1, 1)) # add a page page = QgsLayoutItemPage(l) page.setPageSize('A4') collection.addPage(page) #invalid pages self.assertEqual(collection.pagePositionToAbsolute(-1, QgsLayoutPoint(1, 1)), QgsLayoutPoint(1, 1)) self.assertEqual(collection.pagePositionToAbsolute(1, QgsLayoutPoint(1, 1)), QgsLayoutPoint(1, 1)) #valid page self.assertEqual(collection.pagePositionToAbsolute(0, QgsLayoutPoint(1, 1)), QgsLayoutPoint(1, 1)) self.assertEqual(collection.pagePositionToAbsolute(0, QgsLayoutPoint(5, 6)), QgsLayoutPoint(5, 6)) self.assertEqual(collection.pagePositionToAbsolute(0, QgsLayoutPoint(5, 6, QgsUnitTypes.LayoutCentimeters)), QgsLayoutPoint(5, 6, QgsUnitTypes.LayoutCentimeters)) page2 = QgsLayoutItemPage(l) page2.setPageSize('A5') collection.addPage(page2) #invalid pages self.assertEqual(collection.pagePositionToAbsolute(-1, QgsLayoutPoint(1, 1)), QgsLayoutPoint(1, 1)) self.assertEqual(collection.pagePositionToAbsolute(3, QgsLayoutPoint(1, 1)), QgsLayoutPoint(1, 1)) #valid pages self.assertEqual(collection.pagePositionToAbsolute(0, QgsLayoutPoint(1, 1)), QgsLayoutPoint(1, 1)) self.assertEqual(collection.pagePositionToAbsolute(0, QgsLayoutPoint(5, 6)), QgsLayoutPoint(5, 6)) self.assertEqual(collection.pagePositionToAbsolute(0, QgsLayoutPoint(5, 6, QgsUnitTypes.LayoutCentimeters)), QgsLayoutPoint(5, 6, QgsUnitTypes.LayoutCentimeters)) self.assertEqual(collection.pagePositionToAbsolute(1, QgsLayoutPoint(1, 1)), QgsLayoutPoint(1, 308.0)) self.assertEqual(collection.pagePositionToAbsolute(1, QgsLayoutPoint(5, 6)), QgsLayoutPoint(5, 313.0)) self.assertEqual(collection.pagePositionToAbsolute(1, QgsLayoutPoint(0.5, 0.6, QgsUnitTypes.LayoutCentimeters)), QgsLayoutPoint(0.5, 31.3, QgsUnitTypes.LayoutCentimeters))
def testVisiblePages(self): p = QgsProject() l = QgsLayout(p) collection = l.pageCollection() self.assertFalse(collection.visiblePages(QRectF(0, 0, 10, 10))) self.assertFalse(collection.visiblePageNumbers(QRectF(0, 0, 10, 10))) # add a page page = QgsLayoutItemPage(l) page.setPageSize('A4') collection.addPage(page) self.assertFalse(collection.visiblePages(QRectF(-10, -10, 5, 5))) self.assertFalse(collection.visiblePageNumbers(QRectF(-10, -10, 5, 5))) self.assertEqual(collection.visiblePages(QRectF(-10, -10, 15, 15)), [page]) self.assertEqual(collection.visiblePageNumbers(QRectF(-10, -10, 15, 15)), [0]) self.assertEqual(collection.visiblePages(QRectF(200, 200, 115, 115)), [page]) self.assertEqual(collection.visiblePageNumbers(QRectF(200, 200, 115, 115)), [0]) page2 = QgsLayoutItemPage(l) page2.setPageSize('A5') collection.addPage(page2) self.assertFalse(collection.visiblePages(QRectF(-10, -10, 5, 5))) self.assertFalse(collection.visiblePageNumbers(QRectF(-10, -10, 5, 5))) self.assertEqual(collection.visiblePages(QRectF(-10, -10, 15, 15)), [page]) self.assertEqual(collection.visiblePageNumbers(QRectF(-10, -10, 15, 15)), [0]) self.assertEqual(collection.visiblePages(QRectF(200, 200, 115, 115)), [page]) self.assertEqual(collection.visiblePageNumbers(QRectF(200, 200, 115, 115)), [0]) self.assertEqual(collection.visiblePages(QRectF(200, 200, 115, 615)), [page]) self.assertEqual(collection.visiblePageNumbers(QRectF(200, 200, 115, 115)), [0]) self.assertEqual(collection.visiblePages(QRectF(100, 200, 115, 615)), [page, page2]) self.assertEqual(collection.visiblePageNumbers(QRectF(100, 200, 115, 115)), [0, 1]) self.assertEqual(collection.visiblePages(QRectF(100, 310, 115, 615)), [page2]) self.assertEqual(collection.visiblePageNumbers(QRectF(100, 310, 115, 115)), [1])
def testPageAtPoint(self): """ Test pageAtPoint """ p = QgsProject() l = QgsLayout(p) collection = l.pageCollection() self.assertFalse(collection.pageAtPoint(QPointF(0, 0))) self.assertFalse(collection.pageAtPoint(QPointF(10, 10))) # add a page page = QgsLayoutItemPage(l) page.setPageSize('A4') collection.addPage(page) self.assertFalse(collection.pageAtPoint(QPointF(10, -1))) self.assertEqual(collection.pageAtPoint(QPointF(1, 1)), page) self.assertEqual(collection.pageAtPoint(QPointF(10, 10)), page) self.assertFalse(collection.pageAtPoint(QPointF(-10, 10))) self.assertFalse(collection.pageAtPoint(QPointF(1000, 10))) self.assertFalse(collection.pageAtPoint(QPointF(10, -10))) self.assertFalse(collection.pageAtPoint(QPointF(10, 1000))) page2 = QgsLayoutItemPage(l) page2.setPageSize('A5') collection.addPage(page2) self.assertEqual(collection.pageAtPoint(QPointF(1, 1)), page) self.assertEqual(collection.pageAtPoint(QPointF(10, 10)), page) self.assertFalse(collection.pageAtPoint(QPointF(-10, 10))) self.assertFalse(collection.pageAtPoint(QPointF(1000, 10))) self.assertFalse(collection.pageAtPoint(QPointF(10, -10))) self.assertEqual(collection.pageAtPoint(QPointF(10, 330)), page2) self.assertEqual(collection.pageAtPoint(QPointF(10, 500)), page2) self.assertFalse(collection.pageAtPoint(QPointF(10, 600)))
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 testExportToImage(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.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)) # 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))
def testPagePositionToAbsolute(self): """ Test pagePositionToAbsolute """ p = QgsProject() l = QgsLayout(p) collection = l.pageCollection() # invalid pages self.assertEqual( collection.pagePositionToAbsolute(-1, QgsLayoutPoint(1, 1)), QgsLayoutPoint(1, 1)) self.assertEqual( collection.pagePositionToAbsolute(0, QgsLayoutPoint(1, 1)), QgsLayoutPoint(1, 1)) self.assertEqual( collection.pagePositionToAbsolute(100, QgsLayoutPoint(1, 1)), QgsLayoutPoint(1, 1)) # add a page page = QgsLayoutItemPage(l) page.setPageSize('A4') collection.addPage(page) #invalid pages self.assertEqual( collection.pagePositionToAbsolute(-1, QgsLayoutPoint(1, 1)), QgsLayoutPoint(1, 1)) self.assertEqual( collection.pagePositionToAbsolute(1, QgsLayoutPoint(1, 1)), QgsLayoutPoint(1, 1)) #valid page self.assertEqual( collection.pagePositionToAbsolute(0, QgsLayoutPoint(1, 1)), QgsLayoutPoint(1, 1)) self.assertEqual( collection.pagePositionToAbsolute(0, QgsLayoutPoint(5, 6)), QgsLayoutPoint(5, 6)) self.assertEqual( collection.pagePositionToAbsolute( 0, QgsLayoutPoint(5, 6, QgsUnitTypes.LayoutCentimeters)), QgsLayoutPoint(5, 6, QgsUnitTypes.LayoutCentimeters)) page2 = QgsLayoutItemPage(l) page2.setPageSize('A5') collection.addPage(page2) #invalid pages self.assertEqual( collection.pagePositionToAbsolute(-1, QgsLayoutPoint(1, 1)), QgsLayoutPoint(1, 1)) self.assertEqual( collection.pagePositionToAbsolute(3, QgsLayoutPoint(1, 1)), QgsLayoutPoint(1, 1)) #valid pages self.assertEqual( collection.pagePositionToAbsolute(0, QgsLayoutPoint(1, 1)), QgsLayoutPoint(1, 1)) self.assertEqual( collection.pagePositionToAbsolute(0, QgsLayoutPoint(5, 6)), QgsLayoutPoint(5, 6)) self.assertEqual( collection.pagePositionToAbsolute( 0, QgsLayoutPoint(5, 6, QgsUnitTypes.LayoutCentimeters)), QgsLayoutPoint(5, 6, QgsUnitTypes.LayoutCentimeters)) self.assertEqual( collection.pagePositionToAbsolute(1, QgsLayoutPoint(1, 1)), QgsLayoutPoint(1, 308.0)) self.assertEqual( collection.pagePositionToAbsolute(1, QgsLayoutPoint(5, 6)), QgsLayoutPoint(5, 313.0)) self.assertEqual( collection.pagePositionToAbsolute( 1, QgsLayoutPoint(0.5, 0.6, QgsUnitTypes.LayoutCentimeters)), QgsLayoutPoint(0.5, 31.3, QgsUnitTypes.LayoutCentimeters))
def testDataDefinedSize(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) page3 = QgsLayoutItemPage(l) page3.setPageSize('A5') collection.addPage(page3) self.assertEqual(page.pos().x(), 0) self.assertEqual(page.pos().y(), 0) self.assertEqual(page2.pos().x(), 0) self.assertEqual(page2.pos().y(), 307) self.assertEqual(page3.pos().x(), 0) self.assertEqual(page3.pos().y(), 527) page.dataDefinedProperties().setProperty( QgsLayoutObject.ItemHeight, QgsProperty.fromExpression('50*3')) page.refresh() 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(), 160) self.assertEqual(page3.pos().x(), 0) self.assertEqual(page3.pos().y(), 380) page2.dataDefinedProperties().setProperty( QgsLayoutObject.ItemHeight, QgsProperty.fromExpression('50-20')) page2.refresh() 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(), 160) self.assertEqual(page3.pos().x(), 0) self.assertEqual(page3.pos().y(), 200)
def testSnapPointToGrid(self): p = QgsProject() l = QgsLayout(p) # need a page to snap to grid page = QgsLayoutItemPage(l) page.setPageSize('A4') l.pageCollection().addPage(page) s = QgsLayoutSnapper(l) l.gridSettings().setResolution( QgsLayoutMeasurement(5, QgsUnitTypes.LayoutMillimeters)) s.setSnapToGrid(True) s.setSnapTolerance(1) point, snappedX, snappedY = s.snapPointToGrid(QPointF(1, 1), 1) self.assertTrue(snappedX) self.assertTrue(snappedY) self.assertEqual(point, QPointF(0, 0)) point, snappedX, snappedY = s.snapPointToGrid(QPointF(9, 1), 1) self.assertTrue(snappedX) self.assertTrue(snappedY) self.assertEqual(point, QPointF(10, 0)) point, snappedX, snappedY = s.snapPointToGrid(QPointF(1, 11), 1) self.assertTrue(snappedX) self.assertTrue(snappedY) self.assertEqual(point, QPointF(0, 10)) point, snappedX, snappedY = s.snapPointToGrid(QPointF(13, 11), 1) self.assertFalse(snappedX) self.assertTrue(snappedY) self.assertEqual(point, QPointF(13, 10)) point, snappedX, snappedY = s.snapPointToGrid(QPointF(11, 13), 1) self.assertTrue(snappedX) self.assertFalse(snappedY) self.assertEqual(point, QPointF(10, 13)) point, snappedX, snappedY = s.snapPointToGrid(QPointF(13, 23), 1) self.assertFalse(snappedX) self.assertFalse(snappedY) self.assertEqual(point, QPointF(13, 23)) # grid disabled s.setSnapToGrid(False) point, nappedX, snappedY = s.snapPointToGrid(QPointF(1, 1), 1) self.assertFalse(nappedX) self.assertFalse(snappedY) self.assertEqual(point, QPointF(1, 1)) s.setSnapToGrid(True) # with different pixel scale point, snappedX, snappedY = s.snapPointToGrid(QPointF(0.5, 0.5), 1) self.assertTrue(snappedX) self.assertTrue(snappedY) self.assertEqual(point, QPointF(0, 0)) point, snappedX, snappedY = s.snapPointToGrid(QPointF(0.5, 0.5), 3) self.assertFalse(snappedX) self.assertFalse(snappedY) self.assertEqual(point, QPointF(0.5, 0.5)) # with offset grid l.gridSettings().setOffset(QgsLayoutPoint(2, 0)) point, snappedX, snappedY = s.snapPointToGrid(QPointF(13, 23), 1) self.assertTrue(snappedX) self.assertFalse(snappedY) self.assertEqual(point, QPointF(12, 23))
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 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 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 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 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)
def testReadWriteXml(self): p = QgsProject() l = QgsPrintLayout(p) l.setName('my layout') l.setUnits(QgsUnitTypes.LayoutInches) collection = l.pageCollection() # add a page page = QgsLayoutItemPage(l) page.setPageSize('A6') collection.addPage(page) grid = l.gridSettings() grid.setResolution(QgsLayoutMeasurement(5, QgsUnitTypes.LayoutPoints)) g1 = QgsLayoutGuide( Qt.Horizontal, QgsLayoutMeasurement(5, QgsUnitTypes.LayoutCentimeters), l.pageCollection().page(0)) l.guides().addGuide(g1) snapper = l.snapper() snapper.setSnapTolerance(7) # add some items item1 = QgsLayoutItemMap(l) item1.setId('xxyyxx') l.addItem(item1) item2 = QgsLayoutItemMap(l) item2.setId('zzyyzz') l.addItem(item2) l.setReferenceMap(item2) doc = QDomDocument("testdoc") elem = l.writeXml(doc, QgsReadWriteContext()) l2 = QgsPrintLayout(p) self.assertTrue(l2.readXml(elem, doc, QgsReadWriteContext())) self.assertEqual(l2.name(), 'my layout') self.assertEqual(l2.units(), QgsUnitTypes.LayoutInches) collection2 = l2.pageCollection() self.assertEqual(collection2.pageCount(), 1) self.assertAlmostEqual(collection2.page(0).pageSize().width(), 105, 4) self.assertEqual(collection2.page(0).pageSize().height(), 148) self.assertEqual(l2.gridSettings().resolution().length(), 5.0) self.assertEqual(l2.gridSettings().resolution().units(), QgsUnitTypes.LayoutPoints) self.assertEqual(l2.guides().guidesOnPage(0)[0].orientation(), Qt.Horizontal) self.assertEqual(l2.guides().guidesOnPage(0)[0].position().length(), 5.0) self.assertEqual(l2.guides().guidesOnPage(0)[0].position().units(), QgsUnitTypes.LayoutCentimeters) self.assertEqual(l2.snapper().snapTolerance(), 7) # check restored items new_item1 = l2.itemByUuid(item1.uuid()) self.assertTrue(new_item1) self.assertEqual(new_item1.id(), 'xxyyxx') new_item2 = l2.itemByUuid(item2.uuid()) self.assertTrue(new_item2) self.assertEqual(new_item2.id(), 'zzyyzz') self.assertEqual(l2.referenceMap().id(), 'zzyyzz')
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 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 testExportToSvg(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.SvgExportSettings() settings.dpi = 80 settings.forceVectorOutput = False 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)) 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)) # layered settings.exportAsLayers = 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))
def testSnapPointsToItems(self): p = QgsProject() l = QgsLayout(p) page = QgsLayoutItemPage(l) page.setPageSize('A4') #l.pageCollection().addPage(page) s = QgsLayoutSnapper(l) guides = l.guides() s.setSnapToItems(True) s.setSnapTolerance(1) # no items point, snapped = s.snapPointsToItems([0.5], Qt.Horizontal, 1, []) self.assertFalse(snapped) line = QGraphicsLineItem() line.setVisible(True) point, snapped = s.snapPointsToItems([0.5], Qt.Horizontal, 1, [], line) self.assertFalse(line.isVisible()) guides.addGuide( QgsLayoutGuide(Qt.Vertical, QgsLayoutMeasurement(1), page)) # add an item item1 = QgsLayoutItemMap(l) item1.attemptMove(QgsLayoutPoint(4, 8, QgsUnitTypes.LayoutMillimeters)) item1.attemptResize( QgsLayoutSize(18, 12, QgsUnitTypes.LayoutMillimeters)) l.addItem(item1) point, snapped = s.snapPointsToItems([3.5], Qt.Horizontal, 1, [], line) self.assertTrue(snapped) self.assertEqual(point, 0.5) self.assertTrue(line.isVisible()) point, snapped = s.snapPointsToItems([4.5], Qt.Horizontal, 1, []) self.assertTrue(snapped) self.assertEqual(point, -0.5) point, snapped = s.snapPointsToItems([4.6, 4.5], Qt.Horizontal, 1, []) self.assertTrue(snapped) self.assertEqual(point, -0.5) point, snapped = s.snapPointsToItems([4.6, 4.5, 3.7], Qt.Horizontal, 1, []) self.assertTrue(snapped) self.assertAlmostEqual(point, 0.3, 5) # ignoring item point, snapped = s.snapPointsToItems([4.5], Qt.Horizontal, 1, [item1]) self.assertFalse(snapped) # outside tolerance point, snapped = s.snapPointsToItems([5.5], Qt.Horizontal, 1, [], line) self.assertFalse(snapped) self.assertFalse(line.isVisible()) # snap to center point, snapped = s.snapPointsToItems([12.5], Qt.Horizontal, 1, []) self.assertTrue(snapped) self.assertEqual(point, 0.5) # snap to right point, snapped = s.snapPointsToItems([22.5], Qt.Horizontal, 1, []) self.assertTrue(snapped) self.assertEqual(point, -0.5) #snap to top point, snapped = s.snapPointsToItems([7.5], Qt.Vertical, 1, [], line) self.assertTrue(snapped) self.assertEqual(point, 0.5) self.assertTrue(line.isVisible()) point, snapped = s.snapPointsToItems([8.5], Qt.Vertical, 1, []) self.assertTrue(snapped) self.assertEqual(point, -0.5) # outside tolerance point, snapped = s.snapPointsToItems([5.5], Qt.Vertical, 1, [], line) self.assertFalse(snapped) self.assertFalse(line.isVisible()) # snap to center point, snapped = s.snapPointsToItems([13.5], Qt.Vertical, 1, []) self.assertTrue(snapped) self.assertEqual(point, 0.5) # snap to bottom point, snapped = s.snapPointsToItems([20.5], Qt.Vertical, 1, []) self.assertTrue(snapped) self.assertEqual(point, -0.5) # snapping off s.setSnapToItems(False) line.setVisible(True) point, snapped = s.snapPointsToItems([20.5], Qt.Vertical, 1, [], line) self.assertFalse(snapped) self.assertFalse(line.isVisible()) # with different pixel scale s.setSnapToItems(True) point, snapped = s.snapPointsToItems([20.5], Qt.Vertical, 3, []) self.assertFalse(snapped)
def testResizeToContents(self): p = QgsProject() l = QgsLayout(p) shape1 = QgsLayoutItemShape(l) shape1.attemptResize(QgsLayoutSize(90, 50)) shape1.attemptMove(QgsLayoutPoint(90, 50)) shape1.setItemRotation(45, False) l.addLayoutItem(shape1) shape2 = QgsLayoutItemShape(l) shape2.attemptResize(QgsLayoutSize(110, 50)) shape2.attemptMove(QgsLayoutPoint(100, 150), True, False, 0) l.addLayoutItem(shape2) shape3 = QgsLayoutItemShape(l) l.addLayoutItem(shape3) shape3.attemptResize(QgsLayoutSize(50, 100)) shape3.attemptMove(QgsLayoutPoint(210, 250), True, False, 0) shape4 = QgsLayoutItemShape(l) l.addLayoutItem(shape4) shape4.attemptResize(QgsLayoutSize(50, 30)) shape4.attemptMove(QgsLayoutPoint(10, 340), True, False, 0) shape4.setVisibility(False) # resize with no existing pages l.pageCollection().resizeToContents(QgsMargins(1, 2, 3, 4), QgsUnitTypes.LayoutCentimeters) self.assertEqual(l.pageCollection().pageCount(), 1) self.assertAlmostEqual( l.pageCollection().page(0).sizeWithUnits().width(), 290.3, 2) self.assertAlmostEqual( l.pageCollection().page(0).sizeWithUnits().height(), 380.36, 2) self.assertAlmostEqual( l.pageCollection().page(0).sizeWithUnits().units(), QgsUnitTypes.LayoutMillimeters) self.assertAlmostEqual(shape1.positionWithUnits().x(), 90.15, 2) self.assertAlmostEqual(shape1.positionWithUnits().y(), 20.21, 2) self.assertAlmostEqual(shape2.positionWithUnits().x(), 100.15, 2) self.assertAlmostEqual(shape2.positionWithUnits().y(), 120.21, 2) self.assertAlmostEqual(shape3.positionWithUnits().x(), 210.15, 2) self.assertAlmostEqual(shape3.positionWithUnits().y(), 220.21, 2) self.assertAlmostEqual(shape4.positionWithUnits().x(), 10.15, 2) self.assertAlmostEqual(shape4.positionWithUnits().y(), 310.21, 2) # add a second page page2 = QgsLayoutItemPage(l) page2.setPageSize("A4", QgsLayoutItemPage.Landscape) l.pageCollection().addPage(page2) # add some guides g1 = QgsLayoutGuide( Qt.Horizontal, QgsLayoutMeasurement(2.5, QgsUnitTypes.LayoutCentimeters), l.pageCollection().page(0)) l.guides().addGuide(g1) g2 = QgsLayoutGuide( Qt.Vertical, QgsLayoutMeasurement(4.5, QgsUnitTypes.LayoutCentimeters), l.pageCollection().page(0)) l.guides().addGuide(g2) # second page should be removed l.pageCollection().resizeToContents(QgsMargins(0, 0, 0, 0), QgsUnitTypes.LayoutCentimeters) self.assertEqual(l.pageCollection().pageCount(), 1) self.assertAlmostEqual( l.pageCollection().page(0).sizeWithUnits().width(), 250.3, 2) self.assertAlmostEqual( l.pageCollection().page(0).sizeWithUnits().height(), 320.36, 2) self.assertAlmostEqual( l.pageCollection().page(0).sizeWithUnits().units(), QgsUnitTypes.LayoutMillimeters) self.assertAlmostEqual(g1.position().length(), 0.5, 2) self.assertAlmostEqual(g2.position().length(), 3.5, 2)
def testAddItemsFromXml(self): p = QgsProject() l = QgsLayout(p) # add some items item1 = QgsLayoutItemLabel(l) item1.setId('xxyyxx') item1.attemptMove(QgsLayoutPoint(4, 8, QgsUnitTypes.LayoutMillimeters)) item1.attemptResize( QgsLayoutSize(18, 12, QgsUnitTypes.LayoutMillimeters)) l.addItem(item1) item2 = QgsLayoutItemLabel(l) item2.setId('zzyyzz') item2.attemptMove( QgsLayoutPoint(1.4, 1.8, QgsUnitTypes.LayoutCentimeters)) item2.attemptResize( QgsLayoutSize(2.8, 2.2, QgsUnitTypes.LayoutCentimeters)) l.addItem(item2) doc = QDomDocument("testdoc") # store in xml elem = l.writeXml(doc, QgsReadWriteContext()) l2 = QgsLayout(p) new_items = l2.addItemsFromXml(elem, doc, QgsReadWriteContext()) self.assertEqual(len(new_items), 2) items = l2.items() self.assertTrue([i for i in items if i.id() == 'xxyyxx']) self.assertTrue([i for i in items if i.id() == 'zzyyzz']) self.assertTrue(new_items[0] in l2.items()) self.assertTrue(new_items[1] in l2.items()) new_item1 = [i for i in items if i.id() == 'xxyyxx'][0] new_item2 = [i for i in items if i.id() == 'zzyyzz'][0] self.assertEqual(new_item1.positionWithUnits(), QgsLayoutPoint(4, 8, QgsUnitTypes.LayoutMillimeters)) self.assertEqual(new_item1.sizeWithUnits(), QgsLayoutSize(18, 12, QgsUnitTypes.LayoutMillimeters)) self.assertEqual( new_item2.positionWithUnits(), QgsLayoutPoint(1.4, 1.8, QgsUnitTypes.LayoutCentimeters)) self.assertEqual( new_item2.sizeWithUnits(), QgsLayoutSize(2.8, 2.2, QgsUnitTypes.LayoutCentimeters)) # test with a group group = QgsLayoutItemGroup(l) group.addItem(item1) group.addItem(item2) l.addLayoutItem(group) elem = l.writeXml(doc, QgsReadWriteContext()) l3 = QgsLayout(p) new_items = l3.addItemsFromXml(elem, doc, QgsReadWriteContext()) self.assertEqual(len(new_items), 3) items = l3.items() self.assertTrue([i for i in items if i.id() == 'xxyyxx']) self.assertTrue([i for i in items if i.id() == 'zzyyzz']) self.assertTrue(new_items[0] in l3.items()) self.assertTrue(new_items[1] in l3.items()) self.assertTrue(new_items[2] in l3.items()) # f*** you sip, I'll just manually cast new_group = sip.cast(l3.itemByUuid(group.uuid()), QgsLayoutItemGroup) self.assertIsNotNone(new_group) other_items = [i for i in new_items if i.type() != new_group.type()] self.assertCountEqual(new_group.items(), other_items) # test restoring at set position l3 = QgsLayout(p) new_items = l3.addItemsFromXml(elem, doc, QgsReadWriteContext(), QPointF(10, 30)) self.assertEqual(len(new_items), 3) items = l3.items() new_item1 = [i for i in items if i.id() == 'xxyyxx'][0] new_item2 = [i for i in items if i.id() == 'zzyyzz'][0] self.assertEqual( new_item1.positionWithUnits(), QgsLayoutPoint(10, 30, QgsUnitTypes.LayoutMillimeters)) self.assertEqual(new_item1.sizeWithUnits(), QgsLayoutSize(18, 12, QgsUnitTypes.LayoutMillimeters)) self.assertEqual( new_item2.positionWithUnits(), QgsLayoutPoint(2.0, 4.0, QgsUnitTypes.LayoutCentimeters)) self.assertEqual( new_item2.sizeWithUnits(), QgsLayoutSize(2.8, 2.2, QgsUnitTypes.LayoutCentimeters)) # paste in place l4 = QgsLayout(p) page = QgsLayoutItemPage(l) page.setPageSize('A3') l4.pageCollection().addPage(page) page = QgsLayoutItemPage(l) page.setPageSize('A6') l4.pageCollection().addPage(page) new_items = l4.addItemsFromXml(elem, doc, QgsReadWriteContext(), QPointF(10, 30), True) self.assertEqual(len(new_items), 3) new_item1 = [i for i in new_items if i.id() == 'xxyyxx'][0] new_item2 = [i for i in new_items if i.id() == 'zzyyzz'][0] self.assertEqual(new_item1.pagePositionWithUnits(), QgsLayoutPoint(4, 8, QgsUnitTypes.LayoutMillimeters)) self.assertEqual(new_item1.sizeWithUnits(), QgsLayoutSize(18, 12, QgsUnitTypes.LayoutMillimeters)) self.assertEqual(new_item1.page(), 0) self.assertEqual( new_item2.pagePositionWithUnits(), QgsLayoutPoint(1.4, 1.8, QgsUnitTypes.LayoutCentimeters)) self.assertEqual( new_item2.sizeWithUnits(), QgsLayoutSize(2.8, 2.2, QgsUnitTypes.LayoutCentimeters)) self.assertEqual(new_item2.page(), 0) # paste in place, page 2 new_items = l4.addItemsFromXml(elem, doc, QgsReadWriteContext(), QPointF(10, 550), True) self.assertEqual(len(new_items), 3) new_item1 = [i for i in new_items if i.id() == 'xxyyxx'][0] new_item2 = [i for i in new_items if i.id() == 'zzyyzz'][0] self.assertEqual(new_item1.pagePositionWithUnits(), QgsLayoutPoint(4, 8, QgsUnitTypes.LayoutMillimeters)) self.assertEqual(new_item1.page(), 1) self.assertEqual(new_item1.sizeWithUnits(), QgsLayoutSize(18, 12, QgsUnitTypes.LayoutMillimeters)) self.assertEqual( new_item2.pagePositionWithUnits(), QgsLayoutPoint(1.4, 1.8, QgsUnitTypes.LayoutCentimeters)) self.assertEqual(new_item2.page(), 1) self.assertEqual( new_item2.sizeWithUnits(), QgsLayoutSize(2.8, 2.2, QgsUnitTypes.LayoutCentimeters))
def 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 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 testPages(self): """ Test adding/retrieving/deleting pages from the collection """ p = QgsProject() l = QgsLayout(p) collection = l.pageCollection() self.assertEqual(collection.pageCount(), 0) self.assertFalse(collection.pages()) self.assertFalse(collection.page(-1)) self.assertFalse(collection.page(0)) self.assertFalse(collection.page(1)) # add a page page = QgsLayoutItemPage(l) page.setPageSize('A4') self.assertEqual(collection.pageNumber(page), -1) collection.addPage(page) self.assertTrue(page in l.items()) self.assertEqual(collection.pageCount(), 1) self.assertEqual(collection.pages(), [page]) self.assertFalse(collection.page(-1)) self.assertEqual(collection.page(0), page) self.assertFalse(collection.page(1)) self.assertEqual(collection.pageNumber(page), 0) # add a second page page2 = QgsLayoutItemPage(l) page2.setPageSize('A5') collection.addPage(page2) self.assertEqual(collection.pageCount(), 2) self.assertEqual(collection.pages(), [page, page2]) self.assertFalse(collection.page(-1)) self.assertEqual(collection.page(0), page) self.assertEqual(collection.page(1), page2) self.assertEqual(collection.pageNumber(page2), 1) # insert a page page3 = QgsLayoutItemPage(l) page3.setPageSize('A3') collection.insertPage(page3, 1) self.assertTrue(page3 in l.items()) self.assertEqual(collection.pageCount(), 3) self.assertEqual(collection.pages(), [page, page3, page2]) self.assertEqual(collection.page(0), page) self.assertEqual(collection.page(1), page3) self.assertEqual(collection.page(2), page2) self.assertEqual(collection.pageNumber(page3), 1) # delete page collection.deletePage(-1) self.assertEqual(collection.pageCount(), 3) self.assertEqual(collection.pages(), [page, page3, page2]) collection.deletePage(100) self.assertEqual(collection.pageCount(), 3) self.assertEqual(collection.pages(), [page, page3, page2]) collection.deletePage(1) self.assertEqual(collection.pageCount(), 2) self.assertEqual(collection.pages(), [page, page2]) # make sure page was deleted QCoreApplication.sendPostedEvents(None, QEvent.DeferredDelete) self.assertTrue(sip.isdeleted(page3)) del l QCoreApplication.sendPostedEvents(None, QEvent.DeferredDelete) self.assertTrue(sip.isdeleted(page)) self.assertTrue(sip.isdeleted(page2))
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)
def qgis_composer_html_renderer(impact_report, component): """HTML to PDF renderer using QGIS Composer. Render using qgis composer for a given impact_report data and component context for html input. :param impact_report: ImpactReport contains data about the report that is going to be generated. :type impact_report: safe.report.impact_report.ImpactReport :param component: Contains the component metadata and context for rendering the output. :type component: safe.report.report_metadata.QgisComposerComponentsMetadata :return: Whatever type of output the component should be. .. versionadded:: 4.0 """ context = component.context # QGIS3: not used # qgis_composition_context = impact_report.qgis_composition_context # create new layout with A4 portrait page layout = QgsPrintLayout(QgsProject.instance()) page = QgsLayoutItemPage(layout) page.setPageSize('A4', orientation=QgsLayoutItemPage.Portrait) layout.pageCollection().addPage(page) if not context.html_frame_elements: # if no html frame elements at all, do not generate empty report. component.output = '' return component.output # Add HTML Frame for html_el in context.html_frame_elements: mode = html_el.get('mode') html_element = QgsLayoutItemHtml(layout) margin_left = html_el.get('margin_left', 10) margin_top = html_el.get('margin_top', 10) width = html_el.get('width', component.page_width - 2 * margin_left) height = html_el.get('height', component.page_height - 2 * margin_top) html_frame = QgsLayoutFrame(layout, html_element) html_frame.attemptSetSceneRect( QRectF(margin_left, margin_top, width, height)) html_element.addFrame(html_frame) if html_element: if mode == 'text': text = html_el.get('text') text = text if text else '' html_element.setContentMode(QgsLayoutItemHtml.ManualHtml) html_element.setResizeMode( QgsLayoutItemHtml.RepeatUntilFinished) html_element.setHtml(text) html_element.loadHtml() elif mode == 'url': url = html_el.get('url') html_element.setContentMode(QgsLayoutItemHtml.Url) html_element.setResizeMode( QgsLayoutItemHtml.RepeatUntilFinished) qurl = QUrl.fromLocalFile(url) html_element.setUrl(qurl) # Attempt on removing blank page. Notes: We assume that the blank page # will always appears in the last x page(s), not in the middle. pc = layout.pageCollection() index = pc.pageCount() while pc.pageIsEmpty(index): pc.deletePage(index) index -= 1 # process to output # in case output folder not specified if impact_report.output_folder is None: impact_report.output_folder = mkdtemp(dir=temp_dir()) component_output_path = impact_report.component_absolute_output_path( component.key) component_output = None output_format = component.output_format doc_format = QgisComposerComponentsMetadata.OutputFormat.DOC_OUTPUT template_format = QgisComposerComponentsMetadata.OutputFormat.QPT if isinstance(output_format, list): component_output = [] for i in range(len(output_format)): each_format = output_format[i] each_path = component_output_path[i] if each_format in doc_format: result_path = create_qgis_pdf_output(impact_report, each_path, layout, each_format, component) component_output.append(result_path) elif each_format == template_format: result_path = create_qgis_template_output(each_path, layout) component_output.append(result_path) elif isinstance(output_format, dict): component_output = {} for key, each_format in list(output_format.items()): each_path = component_output_path[key] if each_format in doc_format: result_path = create_qgis_pdf_output(impact_report, each_path, layout, each_format, component) component_output[key] = result_path elif each_format == template_format: result_path = create_qgis_template_output(each_path, layout) component_output[key] = result_path elif (output_format in QgisComposerComponentsMetadata.OutputFormat.SUPPORTED_OUTPUT): component_output = None if output_format in doc_format: result_path = create_qgis_pdf_output(impact_report, component_output_path, layout, output_format, component) component_output = result_path elif output_format == template_format: result_path = create_qgis_template_output(component_output_path, layout) component_output = result_path component.output = component_output return component.output