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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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