def testRenderPage(self): l = QgsLayout(QgsProject.instance()) l.initializeDefaults() # add some items item1 = QgsLayoutItemShape(l) item1.attemptSetSceneRect(QRectF(10, 20, 100, 150)) fill = QgsSimpleFillSymbolLayer() fill_symbol = QgsFillSymbol() fill_symbol.changeSymbolLayer(0, fill) fill.setColor(Qt.green) fill.setStrokeStyle(Qt.NoPen) item1.setSymbol(fill_symbol) l.addItem(item1) # get width/height, create image and render the composition to it size = QSize(1122, 794) output_image = QImage(size, QImage.Format_RGB32) output_image.setDotsPerMeterX(self.dots_per_meter) output_image.setDotsPerMeterY(self.dots_per_meter) QgsMultiRenderChecker.drawBackground(output_image) painter = QPainter(output_image) exporter = QgsLayoutExporter(l) # valid page exporter.renderPage(painter, 0) painter.end() rendered_file_path = os.path.join(self.basetestpath, 'test_renderpage.png') output_image.save(rendered_file_path, "PNG") self.assertTrue(self.checkImage('renderpage', 'renderpage', rendered_file_path))
def testRenderRegion(self): l = QgsLayout(QgsProject.instance()) l.initializeDefaults() # add a guide, to ensure it is not included in export g1 = QgsLayoutGuide(Qt.Horizontal, QgsLayoutMeasurement(15, QgsUnitTypes.LayoutMillimeters), l.pageCollection().page(0)) l.guides().addGuide(g1) # add some items item1 = QgsLayoutItemShape(l) item1.attemptSetSceneRect(QRectF(10, 20, 100, 150)) fill = QgsSimpleFillSymbolLayer() fill_symbol = QgsFillSymbol() fill_symbol.changeSymbolLayer(0, fill) fill.setColor(Qt.green) fill.setStrokeStyle(Qt.NoPen) item1.setSymbol(fill_symbol) l.addItem(item1) # get width/height, create image and render the composition to it size = QSize(560, 509) output_image = QImage(size, QImage.Format_RGB32) output_image.setDotsPerMeterX(self.dots_per_meter) output_image.setDotsPerMeterY(self.dots_per_meter) QgsMultiRenderChecker.drawBackground(output_image) painter = QPainter(output_image) exporter = QgsLayoutExporter(l) exporter.renderRegion(painter, QRectF(5, 10, 110, 100)) painter.end() rendered_file_path = os.path.join(self.basetestpath, 'test_renderregion.png') output_image.save(rendered_file_path, "PNG") self.assertTrue(self.checkImage('renderregion', 'renderregion', rendered_file_path))
def testRenderPageToImage(self): l = QgsLayout(QgsProject.instance()) l.initializeDefaults() # add some items item1 = QgsLayoutItemShape(l) item1.attemptSetSceneRect(QRectF(10, 20, 100, 150)) fill = QgsSimpleFillSymbolLayer() fill_symbol = QgsFillSymbol() fill_symbol.changeSymbolLayer(0, fill) fill.setColor(Qt.green) fill.setStrokeStyle(Qt.NoPen) item1.setSymbol(fill_symbol) l.addItem(item1) exporter = QgsLayoutExporter(l) size = QSize(1122, 794) # bad page numbers image = exporter.renderPageToImage(-1, size) self.assertTrue(image.isNull()) image = exporter.renderPageToImage(1, size) self.assertTrue(image.isNull()) # good page image = exporter.renderPageToImage(0, size) self.assertFalse(image.isNull()) rendered_file_path = os.path.join(self.basetestpath, 'test_rendertoimagepage.png') image.save(rendered_file_path, "PNG") self.assertTrue(self.checkImage('rendertoimagepage', 'rendertoimagepage', rendered_file_path))
def testLayout(self, page=0, pixelDiff=0): if self.layout is None: myMessage = "Layout not valid" return False, myMessage # load expected image self.setControlName("expected_" + self.test_name) # get width/height, create image and render the composition to it outputImage = QImage(self.size, QImage.Format_RGB32) outputImage.setDotsPerMeterX(self.dots_per_meter) outputImage.setDotsPerMeterY(self.dots_per_meter) QgsMultiRenderChecker.drawBackground(outputImage) p = QPainter(outputImage) exporter = QgsLayoutExporter(self.layout) exporter.renderPage(p, page) p.end() renderedFilePath = QDir.tempPath() + QDir.separator() + QFileInfo(self.test_name).baseName() + "_rendered.png" outputImage.save(renderedFilePath, "PNG") self.setRenderedImage(renderedFilePath) testResult = self.runTest(self.test_name, pixelDiff) return testResult, self.report()
def _get_layout_image(self, width, height, dpi): image = QImage(QSize(width, height), self._TestMapSettings.outputImageFormat()) image.fill(QColor(152, 219, 249).rgb()) image.setDotsPerMeterX(dpi / 25.4 * 1000) image.setDotsPerMeterY(dpi / 25.4 * 1000) p = QPainter(image) p.setRenderHint( QPainter.Antialiasing, self._TestMapSettings.testFlag(QgsMapSettings.Antialiasing) ) exporter = QgsLayoutExporter(self._c) exporter.renderPage(p, 0) p.end() # image = self._c.printPageAsRaster(0) # """:type: QImage""" if image.isNull(): return False, '' filepath = getTempfilePath('png') res = image.save(filepath, 'png') if not res: os.unlink(filepath) filepath = '' return res, filepath
def exportItemAsPdf(self, comptecommunal, suffix=None): ''' Export one PDF file using the template composer filled with appropriate data for one "compte communal" ''' temppath = None # print("export pour le cc %s" % comptecommunal) # Set configuration self.setComposerTemplates(comptecommunal) # Create the composition self.createComposition() if self.currentComposition: # Populate composition for all pages # print("numpage %s" % self.numPages) for i in range(self.numPages): j=i+1 self.addPageContent(j) # Add map in first page if export parcelle if self.etype == 'parcelle' and self.print_parcelle_page: self.addParcelleMap() # Create the pdf output path from time import time temp = "releve_%s_%s_%s.pdf" % ( self.etype, comptecommunal.replace('+', 'plus').replace('*', 'fois'), #.replace('¤', 'plus'), int(time()*100) ) # Create regexp to remove all non ascii chars import re r = re.compile(r"[^ -~]") temp = r.sub('', temp) #print temp temppath = os.path.join(self.targetDir, temp) temppath = os.path.normpath(temppath) # print("export temppath %s" % temppath) # Export as pdf exportersettings=QgsLayoutExporter.PdfExportSettings() exportersettings.dpi=300 exportersettings.forceVectorOutput = True exportersettings.rasterizeWholeImage = False exporter = QgsLayoutExporter(self.currentComposition) exporter.exportToPdf(temppath, exportersettings) # Remove redline layer if self.redlineLayer: self.mProject.removeMapLayer(self.redlineLayer.id()) return temppath
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 testPageFileName(self): l = QgsLayout(QgsProject.instance()) exporter = QgsLayoutExporter(l) details = QgsLayoutExporter.PageExportDetails() details.directory = '/tmp/output' details.baseName = 'my_maps' details.extension = 'png' details.page = 0 self.assertEqual(exporter.generateFileName(details), '/tmp/output/my_maps.png') details.page = 1 self.assertEqual(exporter.generateFileName(details), '/tmp/output/my_maps_2.png') details.page = 2 self.assertEqual(exporter.generateFileName(details), '/tmp/output/my_maps_3.png')
def export_view(self): ''' Export current view to PDF ''' # Load template from file s = QSettings() f = s.value("cadastre/composerTemplateFile", '', type=str) if not os.path.exists(f): f = os.path.join(str(Path(__file__).resolve().parent), 'composers', 'paysage_a4.qpt') s.setValue("cadastre/composerTemplateFile", f) QApplication.setOverrideCursor(Qt.WaitCursor) template_content = None with open(f, 'rt', encoding="utf-8") as ff: template_content = ff.read() if not template_content: return d = QDomDocument() d.setContent(template_content) c = QgsPrintLayout(QgsProject.instance()) c.loadFromTemplate(d, QgsReadWriteContext() ) # Set scale and extent cm=c.referenceMap() canvas = self.iface.mapCanvas() extent = canvas.extent() scale = canvas.scale() if extent: cm.zoomToExtent(extent) if scale: cm.setScale(scale) # Export tempDir = s.value("cadastre/tempDir", '%s' % tempfile.gettempdir(), type=str) self.targetDir = tempfile.mkdtemp('', 'cad_export_', tempDir) temp = int(time()*100) temppath = os.path.join(tempDir, 'export_cadastre_%s.pdf' % temp) exporter = QgsLayoutExporter(c) exportersettings = QgsLayoutExporter.PdfExportSettings() exportersettings.dpi = 300 exportersettings.forceVectorOutput = True exportersettings.rasterizeWholeImage = False #rasterizeWholeImage = false exporter.exportToPdf(temppath, exportersettings ) QApplication.restoreOverrideCursor() if os.path.exists(temppath): cadastre_common.openFile(temppath)
def testIteratorToPdfs(self): project, layout = self.prepareIteratorLayout() atlas = layout.atlas() atlas.setFilenameExpression("'test_exportiteratortopdf_' || \"NAME_1\"") # setup settings settings = QgsLayoutExporter.PdfExportSettings() settings.dpi = 80 settings.rasterizeWholeImage = False settings.forceVectorOutput = False result, error = QgsLayoutExporter.exportToPdfs(atlas, self.basetestpath + '/', settings) self.assertEqual(result, QgsLayoutExporter.Success, error) page1_path = os.path.join(self.basetestpath, 'test_exportiteratortopdf_Basse-Normandie.pdf') rendered_page_1 = os.path.join(self.basetestpath, 'test_exportiteratortopdf_Basse-Normandie.png') pdfToPng(page1_path, rendered_page_1, dpi=80, page=1) self.assertTrue(self.checkImage('iteratortopdf1', 'iteratortoimage1', rendered_page_1, size_tolerance=2)) page2_path = os.path.join(self.basetestpath, 'test_exportiteratortopdf_Bretagne.pdf') rendered_page_2 = os.path.join(self.basetestpath, 'test_exportiteratortopdf_Bretagne.png') pdfToPng(page2_path, rendered_page_2, dpi=80, page=1) self.assertTrue(self.checkImage('iteratortopdf2', 'iteratortoimage2', rendered_page_2, size_tolerance=2)) page3_path = os.path.join(self.basetestpath, 'test_exportiteratortopdf_Centre.pdf') self.assertTrue(os.path.exists(page3_path)) page4_path = os.path.join(self.basetestpath, 'test_exportiteratortopdf_Pays de la Loire.pdf') self.assertTrue(os.path.exists(page4_path))
def testIteratorToPdf(self): project, layout = self.prepareIteratorLayout() atlas = layout.atlas() # setup settings settings = QgsLayoutExporter.PdfExportSettings() settings.dpi = 80 settings.rasterizeWholeImage = False settings.forceVectorOutput = False pdf_path = os.path.join(self.basetestpath, 'test_exportiteratortopdf_single.pdf') result, error = QgsLayoutExporter.exportToPdf(atlas, pdf_path, settings) self.assertEqual(result, QgsLayoutExporter.Success, error) rendered_page_1 = os.path.join(self.basetestpath, 'test_exportiteratortopdf_single1.png') pdfToPng(pdf_path, rendered_page_1, dpi=80, page=1) self.assertTrue(self.checkImage('iteratortopdfsingle1', 'iteratortoimage1', rendered_page_1, size_tolerance=2)) rendered_page_2 = os.path.join(self.basetestpath, 'test_exportiteratortopdf_single2.png') pdfToPng(pdf_path, rendered_page_2, dpi=80, page=2) self.assertTrue(self.checkImage('iteratortopdfsingle2', 'iteratortoimage2', rendered_page_2, size_tolerance=2)) rendered_page_3 = os.path.join(self.basetestpath, 'test_exportiteratortopdf_single3.png') pdfToPng(pdf_path, rendered_page_3, dpi=80, page=3) self.assertTrue(os.path.exists(rendered_page_3)) rendered_page_4 = os.path.join(self.basetestpath, 'test_exportiteratortopdf_single4.png') pdfToPng(pdf_path, rendered_page_4, dpi=80, page=4) self.assertTrue(os.path.exists(rendered_page_4))
def testPrintIterator(self): project, layout = self.prepareIteratorLayout() atlas = layout.atlas() # setup settings settings = QgsLayoutExporter.PrintExportSettings() settings.dpi = 80 settings.rasterizeWholeImage = False pdf_path = os.path.join(self.basetestpath, 'test_printiterator.pdf') # make a qprinter directed to pdf printer = QPrinter() printer.setOutputFileName(pdf_path) printer.setOutputFormat(QPrinter.PdfFormat) result, error = QgsLayoutExporter.print(atlas, printer, settings) self.assertEqual(result, QgsLayoutExporter.Success, error) rendered_page_1 = os.path.join(self.basetestpath, 'test_printiterator1.png') pdfToPng(pdf_path, rendered_page_1, dpi=80, page=1) self.assertTrue(self.checkImage('printeriterator1', 'iteratortoimage1', rendered_page_1, size_tolerance=2)) rendered_page_2 = os.path.join(self.basetestpath, 'test_printiterator2.png') pdfToPng(pdf_path, rendered_page_2, dpi=80, page=2) self.assertTrue(self.checkImage('printiterator2', 'iteratortoimage2', rendered_page_2, size_tolerance=2)) rendered_page_3 = os.path.join(self.basetestpath, 'test_printiterator3.png') pdfToPng(pdf_path, rendered_page_3, dpi=80, page=3) self.assertTrue(os.path.exists(rendered_page_3)) rendered_page_4 = os.path.join(self.basetestpath, 'test_printiterator4.png') pdfToPng(pdf_path, rendered_page_4, dpi=80, page=4) self.assertTrue(os.path.exists(rendered_page_4))
def testExportToSvgTextRenderFormat(self): l = QgsLayout(QgsProject.instance()) l.initializeDefaults() # add a map and scalebar mapitem = QgsLayoutItemMap(l) mapitem.attemptSetSceneRect(QRectF(110, 120, 200, 250)) mapitem.zoomToExtent(QgsRectangle(1, 1, 10, 10)) mapitem.setScale(666) # unlikely to appear in the SVG by accident... unless... oh no! RUN! l.addItem(mapitem) item1 = QgsLayoutItemScaleBar(l) item1.attemptSetSceneRect(QRectF(10, 20, 100, 150)) item1.setLinkedMap(mapitem) item1.setStyle('Numeric') l.addItem(item1) exporter = QgsLayoutExporter(l) # setup settings settings = QgsLayoutExporter.SvgExportSettings() settings.dpi = 80 settings.forceVectorOutput = False settings.exportMetadata = True settings.textRenderFormat = QgsRenderContext.TextFormatAlwaysText svg_file_path = os.path.join(self.basetestpath, 'test_exporttosvgtextformattext.svg') self.assertEqual(exporter.exportToSvg(svg_file_path, settings), QgsLayoutExporter.Success) self.assertTrue(os.path.exists(svg_file_path)) # expect svg to contain a text object with the scale with open(svg_file_path, 'r') as f: lines = ''.join(f.readlines()) self.assertIn('<text', lines) self.assertIn('>1:666<', lines) # force use of outlines os.unlink(svg_file_path) settings.textRenderFormat = QgsRenderContext.TextFormatAlwaysOutlines self.assertEqual(exporter.exportToSvg(svg_file_path, settings), QgsLayoutExporter.Success) self.assertTrue(os.path.exists(svg_file_path)) # expect svg NOT to contain a text object with the scale with open(svg_file_path, 'r') as f: lines = ''.join(f.readlines()) self.assertNotIn('<text', lines) self.assertNotIn('>1:666<', lines)
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 _get_layout_svg_image(self, width, height, dpi): svgpath = getTempfilePath('svg') temp_size = os.path.getsize(svgpath) svg_g = QSvgGenerator() # noinspection PyArgumentList svg_g.setTitle(QgsProject.instance().title()) svg_g.setFileName(svgpath) svg_g.setSize(QSize(width, height)) svg_g.setViewBox(QRect(0, 0, width, height)) svg_g.setResolution(dpi) sp = QPainter(svg_g) exporter = QgsLayoutExporter(self._c) exporter.renderPage(sp, 0) sp.end() if temp_size == os.path.getsize(svgpath): return False, '' image = QImage(width, height, self._TestMapSettings.outputImageFormat()) image.fill(QColor(152, 219, 249).rgb()) image.setDotsPerMeterX(dpi / 25.4 * 1000) image.setDotsPerMeterY(dpi / 25.4 * 1000) svgr = QSvgRenderer(svgpath) p = QPainter(image) p.setRenderHint( QPainter.Antialiasing, self._TestMapSettings.testFlag(QgsMapSettings.Antialiasing) ) p.setRenderHint(QPainter.TextAntialiasing) svgr.render(p) p.end() filepath = getTempfilePath('png') res = image.save(filepath, 'png') if not res: os.unlink(filepath) filepath = '' # TODO: remove .svg file as well? return res, filepath
def testRenderRegionToImage(self): l = QgsLayout(QgsProject.instance()) l.initializeDefaults() # add some items item1 = QgsLayoutItemShape(l) item1.attemptSetSceneRect(QRectF(10, 20, 100, 150)) fill = QgsSimpleFillSymbolLayer() fill_symbol = QgsFillSymbol() fill_symbol.changeSymbolLayer(0, fill) fill.setColor(Qt.green) fill.setStrokeStyle(Qt.NoPen) item1.setSymbol(fill_symbol) l.addItem(item1) exporter = QgsLayoutExporter(l) size = QSize(560, 509) image = exporter.renderRegionToImage(QRectF(5, 10, 110, 100), size) self.assertFalse(image.isNull()) rendered_file_path = os.path.join(self.basetestpath, 'test_rendertoimageregionsize.png') image.save(rendered_file_path, "PNG") self.assertTrue(self.checkImage('rendertoimageregionsize', 'rendertoimageregionsize', rendered_file_path)) # using layout dpi l.renderContext().setDpi(40) image = exporter.renderRegionToImage(QRectF(5, 10, 110, 100)) self.assertFalse(image.isNull()) rendered_file_path = os.path.join(self.basetestpath, 'test_rendertoimageregiondpi.png') image.save(rendered_file_path, "PNG") self.assertTrue(self.checkImage('rendertoimageregiondpi', 'rendertoimageregiondpi', rendered_file_path)) # overriding dpi image = exporter.renderRegionToImage(QRectF(5, 10, 110, 100), QSize(), 80) self.assertFalse(image.isNull()) rendered_file_path = os.path.join(self.basetestpath, 'test_rendertoimageregionoverridedpi.png') image.save(rendered_file_path, "PNG") self.assertTrue(self.checkImage('rendertoimageregionoverridedpi', 'rendertoimageregionoverridedpi', rendered_file_path))
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 testExportWorldFile(self): l = QgsLayout(QgsProject.instance()) l.initializeDefaults() # add some items map = QgsLayoutItemMap(l) map.attemptSetSceneRect(QRectF(30, 60, 200, 100)) extent = QgsRectangle(2000, 2800, 2500, 2900) map.setExtent(extent) l.addLayoutItem(map) exporter = QgsLayoutExporter(l) # setup settings settings = QgsLayoutExporter.ImageExportSettings() settings.dpi = 80 settings.generateWorldFile = False rendered_file_path = os.path.join(self.basetestpath, 'test_exportwithworldfile.png') world_file_path = os.path.join(self.basetestpath, 'test_exportwithworldfile.pgw') self.assertEqual(exporter.exportToImage(rendered_file_path, settings), QgsLayoutExporter.Success) self.assertTrue(os.path.exists(rendered_file_path)) self.assertFalse(os.path.exists(world_file_path)) # with world file settings.generateWorldFile = True rendered_file_path = os.path.join(self.basetestpath, 'test_exportwithworldfile.png') self.assertEqual(exporter.exportToImage(rendered_file_path, settings), QgsLayoutExporter.Success) self.assertTrue(os.path.exists(rendered_file_path)) self.assertTrue(os.path.exists(world_file_path)) lines = tuple(open(world_file_path, 'r')) values = [float(f) for f in lines] self.assertAlmostEqual(values[0], 0.794117647059, 2) self.assertAlmostEqual(values[1], 0.0, 2) self.assertAlmostEqual(values[2], 0.0, 2) self.assertAlmostEqual(values[3], -0.794251134644, 2) self.assertAlmostEqual(values[4], 1925.000000000000, 2) self.assertAlmostEqual(values[5], 3050.000000000000, 2)
def testExportReport(self): p = QgsProject() r = QgsReport(p) # add a header r.setHeaderEnabled(True) report_header = QgsLayout(p) report_header.initializeDefaults() item1 = QgsLayoutItemShape(report_header) item1.attemptSetSceneRect(QRectF(10, 20, 100, 150)) fill = QgsSimpleFillSymbolLayer() fill_symbol = QgsFillSymbol() fill_symbol.changeSymbolLayer(0, fill) fill.setColor(Qt.green) fill.setStrokeStyle(Qt.NoPen) item1.setSymbol(fill_symbol) report_header.addItem(item1) r.setHeader(report_header) # add a footer r.setFooterEnabled(True) report_footer = QgsLayout(p) report_footer.initializeDefaults() item2 = QgsLayoutItemShape(report_footer) item2.attemptSetSceneRect(QRectF(10, 20, 100, 150)) item2.attemptMove(QgsLayoutPoint(10, 20)) fill = QgsSimpleFillSymbolLayer() fill_symbol = QgsFillSymbol() fill_symbol.changeSymbolLayer(0, fill) fill.setColor(Qt.cyan) fill.setStrokeStyle(Qt.NoPen) item2.setSymbol(fill_symbol) report_footer.addItem(item2) r.setFooter(report_footer) # setup settings settings = QgsLayoutExporter.ImageExportSettings() settings.dpi = 80 report_path = os.path.join(self.basetestpath, 'test_report') result, error = QgsLayoutExporter.exportToImage(r, report_path, 'png', settings) self.assertEqual(result, QgsLayoutExporter.Success, error) page1_path = os.path.join(self.basetestpath, 'test_report_0001.png') self.assertTrue(self.checkImage('report_page1', 'report_page1', page1_path)) page2_path = os.path.join(self.basetestpath, 'test_report_0002.png') self.assertTrue(self.checkImage('report_page2', 'report_page2', page2_path))
def testIteratorToImages(self): project, layout = self.prepareIteratorLayout() atlas = layout.atlas() atlas.setFilenameExpression("'test_exportiteratortoimage_' || \"NAME_1\"") # setup settings settings = QgsLayoutExporter.ImageExportSettings() settings.dpi = 80 result, error = QgsLayoutExporter.exportToImage(atlas, self.basetestpath + '/', 'png', settings) self.assertEqual(result, QgsLayoutExporter.Success, error) page1_path = os.path.join(self.basetestpath, 'test_exportiteratortoimage_Basse-Normandie.png') self.assertTrue(self.checkImage('iteratortoimage1', 'iteratortoimage1', page1_path)) page2_path = os.path.join(self.basetestpath, 'test_exportiteratortoimage_Bretagne.png') self.assertTrue(self.checkImage('iteratortoimage2', 'iteratortoimage2', page2_path)) page3_path = os.path.join(self.basetestpath, 'test_exportiteratortoimage_Centre.png') self.assertTrue(os.path.exists(page3_path)) page4_path = os.path.join(self.basetestpath, 'test_exportiteratortoimage_Pays de la Loire.png') self.assertTrue(os.path.exists(page4_path))
def _get_layout_pdf_image(self, width, height, dpi): pdfpath = getTempfilePath('pdf') temp_size = os.path.getsize(pdfpath) p = QPrinter() p.setOutputFormat(QPrinter.PdfFormat) p.setOutputFileName(pdfpath) p.setPaperSize(QSizeF(self._c.pageCollection().page(0).sizeWithUnits().width(), self._c.pageCollection().page(0).sizeWithUnits().height()), QPrinter.Millimeter) p.setFullPage(True) p.setColorMode(QPrinter.Color) p.setResolution(self._c.renderContext().dpi()) pdf_p = QPainter(p) # page_mm = p.pageRect(QPrinter.Millimeter) # page_px = p.pageRect(QPrinter.DevicePixel) # self._c.render(pdf_p, page_px, page_mm) exporter = QgsLayoutExporter(self._c) exporter.renderPage(pdf_p, 0) pdf_p.end() if temp_size == os.path.getsize(pdfpath): return False, '' filepath = getTempfilePath('png') # Poppler (pdftocairo or pdftoppm): # PDFUTIL -png -singlefile -r 72 -x 0 -y 0 -W 420 -H 280 in.pdf pngbase # muPDF (mudraw): # PDFUTIL -c rgb[a] -r 72 -w 420 -h 280 -o out.png in.pdf if PDFUTIL.strip().endswith('pdftocairo'): filebase = os.path.join( os.path.dirname(filepath), os.path.splitext(os.path.basename(filepath))[0] ) call = [ PDFUTIL, '-png', '-singlefile', '-r', str(dpi), '-x', '0', '-y', '0', '-W', str(width), '-H', str(height), pdfpath, filebase ] elif PDFUTIL.strip().endswith('mudraw'): call = [ PDFUTIL, '-c', 'rgba', '-r', str(dpi), '-w', str(width), '-h', str(height), # '-b', '8', '-o', filepath, pdfpath ] else: return False, '' qDebug("_get_layout_pdf_image call: {0}".format(' '.join(call))) res = False try: subprocess.check_call(call) res = True except subprocess.CalledProcessError as e: qDebug("_get_layout_pdf_image failed!\n" "cmd: {0}\n" "returncode: {1}\n" "message: {2}".format(e.cmd, e.returncode, e.message)) if not res: os.unlink(filepath) filepath = '' return res, filepath
def create_qgis_pdf_output( impact_report, output_path, layout, file_format, metadata): """Produce PDF output using QgsLayout. :param output_path: The output path. :type output_path: str :param layout: QGIS Layout object. :type layout: qgis.core.QgsPrintLayout :param qgis_composition_context: QGIS Composition context used by renderer. :type qgis_composition_context: safe.report.impact_report. QgsLayoutContext :param file_format: file format of map output, PDF or PNG. :type file_format: 'pdf', 'png' :param metadata: The component metadata. :type metadata: QgisComposerComponentsMetadata :return: Generated output path. :rtype: str """ # make sure directory is created dirname = os.path.dirname(output_path) if not os.path.exists(dirname): os.makedirs(dirname) qgis_composition_context = impact_report.qgis_composition_context aggregation_summary_layer = ( impact_report.impact_function.aggregation_summary) # process atlas generation print_atlas = setting('print_atlas_report', False, bool) if layout.atlas().enabled() and ( print_atlas and aggregation_summary_layer): output_path = atlas_renderer( layout, aggregation_summary_layer, output_path, file_format) # for QGIS layout only pdf and png output are available elif file_format == QgisComposerComponentsMetadata.OutputFormat.PDF: try: exporter = QgsLayoutExporter(layout) settings = QgsLayoutExporter.PdfExportSettings() settings.dpi = metadata.page_dpi settings.rasterizeWholeImage = \ qgis_composition_context.save_as_raster # settings.forceVectorOutput = False # settings.exportMetadata = True # TODO: ABP: check that page size is set on the pages res = exporter.exportToPdf(output_path, settings) if res != QgsLayoutExporter.Success: LOGGER.error('Error exporting to {}'.format( exporter.errorFile())) return None except Exception as exc: LOGGER.error(exc) return None elif file_format == QgisComposerComponentsMetadata.OutputFormat.PNG: # TODO: implement PNG generation raise Exception('Not yet supported') return output_path
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 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 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 run(self): """Run method that performs all the real work""" # Create the dialog with elements (after translation) and keep reference # Only create GUI ONCE in callback, so that it will only load when the plugin is started if self.first_start == True: self.first_start = False self.dlg = massprintlabDialog() # задание списка возможных форматов вывода на печать format_list = ['png', 'pdf'] # задание списка масштабного ранжирования scalerange_rule_list = ['линейная шкала', 'логарифмическая шкала'] # задание операторов для фильтра filter_operators = [ 'None', '=', '!=', '<', '<=', '>', '>=', 'LIKE', 'ILIKE', '%', 'IN', 'NOT IN' ] # словарь единиц измерения UnitsPerSegment_dict = {'метры': 0, 'километры': 1} # получение списка макетов в проекте curLayouts = QgsProject.instance().layoutManager().layouts() layout_list = [] for layout in curLayouts: layout_list.append(layout.name()) def select_output_file(): file_path = QtWidgets.QFileDialog.getExistingDirectory( self.dlg, "Выбери папку для записи ", "") self.dlg.lineEdit_saver.setText(f'{file_path}') def defQuery(): layer = self.dlg.mMapLayerComboBox_mf_lay.currentLayer() iface.setActiveLayer(layer) iface.zoomToActiveLayer() field_1 = self.dlg.mFieldComboBox_mf_lay.currentField() layer_dp = layer.dataProvider() layer_unique = list( layer_dp.uniqueValues(layer_dp.fieldNameIndex(field_1))) return layer_unique, layer, field_1 def namer(): #надо переписать, сейчас в качестве примера имени выводится любое уникальное значение из определённого столбца слоя #надо, чтобы выводилось значения полей от одной строки (объекта) self.dlg.lineEdit_namer.clear() layer = self.dlg.mMapLayerComboBox_namer.currentLayer() layer_dp = layer.dataProvider() field_namer_1 = self.dlg.mFieldComboBox_namer_1.currentField() field_namer_2 = self.dlg.mFieldComboBox_namer_2.currentField() field_namer_3 = self.dlg.mFieldComboBox_namer_3.currentField() field_namer_4 = self.dlg.mFieldComboBox_namer_4.currentField() try: field_namer_1_value = list( layer_dp.uniqueValues( layer_dp.fieldNameIndex(field_namer_1)))[0] except: field_namer_1_value = '' try: field_namer_2_value = list( layer_dp.uniqueValues( layer_dp.fieldNameIndex(field_namer_2)))[0] except: field_namer_2_value = '' try: field_namer_3_value = list( layer_dp.uniqueValues( layer_dp.fieldNameIndex(field_namer_3)))[0] except: field_namer_3_value = '' try: field_namer_4_value = list( layer_dp.uniqueValues( layer_dp.fieldNameIndex(field_namer_4)))[0] except: field_namer_4_value = '' list_values = np.array([ field_namer_1_value, field_namer_2_value, field_namer_3_value, field_namer_4_value ]) list_values = list_values[list_values != ''] self.dlg.lineEdit_namer.setText('_'.join(list_values)) return '_'.join(list_values) def scale_range_selector(): scale_step = self.dlg.mQgsSpinBox_scale.value() max_scale = int(self.dlg.mScaleRangeWidget.maximumScale()) min_scale = int(self.dlg.mScaleRangeWidget.minimumScale()) scale_range = [ i for i in range(max_scale, min_scale + scale_step, scale_step) ] if self.dlg.comboBox_range_rule.currentIndex() == 0: self.dlg.lineEdit_scalerange.setText(str(scale_range)) else: base = max_scale end_scale = min_scale stop = math.log(end_scale, base) num = self.dlg.mQgsSpinBox_scale_2.value() scale_range = np.logspace(1, stop=stop, num=num, endpoint=True, base=base, dtype=int, axis=0) scale_range = np.around(scale_range, -2) self.dlg.lineEdit_scalerange.setText(str(scale_range)) return scale_range # filter function def filt_by_iddb(layer, filter_field, value): layer.setSubsetString(f'"{filter_field}" = {value}') iface.setActiveLayer(layer) iface.zoomToActiveLayer() return layer.extent() def scale_setter(max_scale, min_scale, cur_scale_value, scale_range): if (np.array(scale_range) >= cur_scale_value ).all(): # если все значения масштаба больше текущего масштаба return max_scale elif (np.array(scale_range) <= cur_scale_value).all( ): # если все значения масштаба меньше текущего масштаба return min_scale return np.array(scale_range)[ np.array(scale_range) >= cur_scale_value][0] def aux_filter(layer, field, operator, link_lay, link_lay_field): link_lay_dp = link_lay.dataProvider() if link_lay_dp.featureCount() > 1: linked_layer_field_values = str( link_lay_dp.uniqueValues( link_lay_dp.fieldNameIndex(link_lay_field))).replace( '{', '(').replace('}', ')') else: linked_layer_field_index = link_lay_dp.fieldNameIndex( link_lay_field) linked_layer_field_values = \ [feature.attributes()[linked_layer_field_index] for feature in link_lay_dp.getFeatures()][0] if linked_layer_field_values == '': linked_layer_field_values = "('zero_value')" print(f"linked_layer_field_values {linked_layer_field_values}") print(f'"{field}" {operator} {linked_layer_field_values}') layer.setSubsetString( f'"{field}" {operator} {linked_layer_field_values}') self.dlg.lineEdit_saver.clear() self.dlg.toolButton_saver.clicked.connect(select_output_file) self.dlg.comboBox_layout.clear() self.dlg.comboBox_layout.addItems(layout_list) self.dlg.comboBox_saver.clear() self.dlg.comboBox_saver.addItems(format_list) self.dlg.comboBox_range_rule.clear() self.dlg.comboBox_range_rule.addItems(scalerange_rule_list) # show the dialog self.dlg.show() #main_filter self.dlg.mMapLayerComboBox_mf_lay.layerChanged.connect( self.dlg.mFieldComboBox_mf_lay.setLayer) # auxiliary_filter self.dlg.mMapLayerComboBox_layer_1.layerChanged.connect( self.dlg.mFieldComboBox_layer_1.setLayer) self.dlg.comboBox_operator_1.addItems(filter_operators) self.dlg.mMapLayerComboBox_l_lay_1.layerChanged.connect( self.dlg.mFieldComboBox_l_lay_1.setLayer) self.dlg.mMapLayerComboBox_layer_2.layerChanged.connect( self.dlg.mFieldComboBox_layer_2.setLayer) self.dlg.comboBox_operator_2.addItems(filter_operators) self.dlg.mMapLayerComboBox_l_lay_2.layerChanged.connect( self.dlg.mFieldComboBox_l_lay_2.setLayer) self.dlg.mMapLayerComboBox_layer_3.layerChanged.connect( self.dlg.mFieldComboBox_layer_3.setLayer) self.dlg.comboBox_operator_3.addItems(filter_operators) self.dlg.mMapLayerComboBox_l_lay_3.layerChanged.connect( self.dlg.mFieldComboBox_l_lay_3.setLayer) # namer self.dlg.pushButton_namer.clicked.connect(namer) self.dlg.mMapLayerComboBox_namer.layerChanged.connect( self.dlg.mFieldComboBox_namer_1.setLayer) self.dlg.mMapLayerComboBox_namer.layerChanged.connect( self.dlg.mFieldComboBox_namer_2.setLayer) self.dlg.mMapLayerComboBox_namer.layerChanged.connect( self.dlg.mFieldComboBox_namer_3.setLayer) self.dlg.mMapLayerComboBox_namer.layerChanged.connect( self.dlg.mFieldComboBox_namer_4.setLayer) self.dlg.pushButton_scale.clicked.connect(scale_range_selector) self.dlg.comboBox_ruler_units.clear() self.dlg.comboBox_ruler_units.addItems(UnitsPerSegment_dict.keys()) # Run the dialog event loop result = self.dlg.exec_() max_scale = int(self.dlg.mScaleRangeWidget.maximumScale()) min_scale = int(self.dlg.mScaleRangeWidget.minimumScale()) scale_range = scale_range_selector() ruler_min = self.dlg.mQgsSpinBox_ruler_min.value() / (2 * 10**6) ruler_max = self.dlg.mQgsSpinBox_ruler_max.value() / (2 * 10**6) units_per_segment = np.array([0.1, 0.25, 0.5, 1, 2, 2.5, 5, 10, 20]) # See if OK was pressed if result: selected_layout = curLayouts[ self.dlg.comboBox_layout.currentIndex()] referencemap = selected_layout.referenceMap() referencebar = selected_layout.itemById("scalebar") layer_unique, layer, filter_field = defQuery() base_path = self.dlg.lineEdit_saver.text() file_ext = format_list[self.dlg.comboBox_saver.currentIndex()] try: os.mkdir( os.path.join(base_path, str(date.today()).replace('-', '_'))) write_path = os.path.join(base_path, str(date.today()).replace('-', '_')) except FileExistsError: write_path = os.path.join(base_path, str(date.today()).replace('-', '_')) print(write_path) os.mkdir( os.path.join( write_path, datetime.now().strftime('%H:%M').replace(':', '_'))) write_path = os.path.join( write_path, datetime.now().strftime('%H:%M').replace(':', '_')) file = open(write_path + '/log.txt', 'w') file.write( f'ЭТО ЛОГ ФАЙЛ, в папке должно быть {len(layer_unique)} файлов' ) file.close() if self.dlg.comboBox_ruler_units.currentIndex() == 0: units_per_segment = units_per_segment * 1000 ruler_max = ruler_max * 1000 ruler_min = ruler_min * 1000 for value in layer_unique: extent = filt_by_iddb(layer, filter_field, value) if filter_operators[ self.dlg.comboBox_operator_1.currentIndex()] != 'None': aux_filter( self.dlg.mMapLayerComboBox_layer_1.currentLayer(), self.dlg.mFieldComboBox_layer_1.currentField(), filter_operators[ self.dlg.comboBox_operator_1.currentIndex()], self.dlg.mMapLayerComboBox_l_lay_1.currentLayer(), self.dlg.mFieldComboBox_l_lay_1.currentField()) if filter_operators[ self.dlg.comboBox_operator_2.currentIndex()] != 'None': aux_filter( self.dlg.mMapLayerComboBox_layer_2.currentLayer(), self.dlg.mFieldComboBox_layer_2.currentField(), filter_operators[ self.dlg.comboBox_operator_2.currentIndex()], self.dlg.mMapLayerComboBox_l_lay_2.currentLayer(), self.dlg.mFieldComboBox_l_lay_2.currentField()) if filter_operators[ self.dlg.comboBox_operator_3.currentIndex()] != 'None': aux_filter( self.dlg.mMapLayerComboBox_layer_3.currentLayer(), self.dlg.mFieldComboBox_layer_3.currentField(), filter_operators[ self.dlg.comboBox_operator_3.currentIndex()], self.dlg.mMapLayerComboBox_l_lay_3.currentLayer(), self.dlg.mFieldComboBox_l_lay_3.currentField()) full_file_path = f"{write_path}/{namer()}.{file_ext}" iface.openLayoutDesigner(selected_layout) selected_layout.refresh() referencemap.zoomToExtent(extent) cur_scale_value = referencemap.scale() cur_scale_value = scale_setter(max_scale, min_scale, cur_scale_value, scale_range) referencemap.setScale(cur_scale_value) units_per_segment_value = units_per_segment[ np.where((units_per_segment / cur_scale_value >= ruler_min) & \ (units_per_segment / cur_scale_value <= ruler_max))].max() referencebar.setUnitsPerSegment(units_per_segment_value) exporter = QgsLayoutExporter(selected_layout) if format_list[ self.dlg.comboBox_saver.currentIndex()] == 'png': exporter.exportToImage( full_file_path, QgsLayoutExporter.ImageExportSettings()) elif format_list[ self.dlg.comboBox_saver.currentIndex()] == 'pdf': exporter.exportToPdf(full_file_path, QgsLayoutExporter.PdfExportSettings()) else: print('Неизвестный формат') break
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 create_qgis_pdf_output(impact_report, output_path, layout, file_format, metadata): """Produce PDF output using QgsLayout. :param output_path: The output path. :type output_path: str :param layout: QGIS Layout object. :type layout: qgis.core.QgsPrintLayout :param qgis_composition_context: QGIS Composition context used by renderer. :type qgis_composition_context: safe.report.impact_report. QgsLayoutContext :param file_format: file format of map output, PDF or PNG. :type file_format: 'pdf', 'png' :param metadata: The component metadata. :type metadata: QgisComposerComponentsMetadata :return: Generated output path. :rtype: str """ # make sure directory is created dirname = os.path.dirname(output_path) if not os.path.exists(dirname): os.makedirs(dirname) qgis_composition_context = impact_report.qgis_composition_context aggregation_summary_layer = ( impact_report.impact_function.aggregation_summary) # process atlas generation print_atlas = setting('print_atlas_report', False, bool) if layout.atlas().enabled() and (print_atlas and aggregation_summary_layer): output_path = atlas_renderer(layout, aggregation_summary_layer, output_path, file_format) # for QGIS layout only pdf and png output are available elif file_format == QgisComposerComponentsMetadata.OutputFormat.PDF: try: exporter = QgsLayoutExporter(layout) settings = QgsLayoutExporter.PdfExportSettings() settings.dpi = metadata.page_dpi settings.rasterizeWholeImage = \ qgis_composition_context.save_as_raster # settings.forceVectorOutput = False # settings.exportMetadata = True # TODO: ABP: check that page size is set on the pages res = exporter.exportToPdf(output_path, settings) if res != QgsLayoutExporter.Success: LOGGER.error('Error exporting to {}'.format( exporter.errorFile())) return None except Exception as exc: LOGGER.error(exc) return None elif file_format == QgisComposerComponentsMetadata.OutputFormat.PNG: # TODO: implement PNG generation raise Exception('Not yet supported') return output_path
def atlas_renderer(layout, coverage_layer, output_path, file_format): """Extract composition using atlas generation. :param layout: QGIS Print Layout object used for producing the report. :type layout: qgis.core.QgsPrintLayout :param coverage_layer: Coverage Layer used for atlas map. :type coverage_layer: QgsMapLayer :param output_path: The output path of the product. :type output_path: str :param file_format: File format of map output, 'pdf' or 'png'. :type file_format: str :return: Generated output path(s). :rtype: str, list """ # set the composer map to be atlas driven composer_map = layout_item( layout, 'impact-map', QgsLayoutItemMap) composer_map.setAtlasDriven(True) composer_map.setAtlasScalingMode(QgsLayoutItemMap.Auto) # setup the atlas composition and composition atlas mode atlas_composition = layout.atlas() atlas_composition.setCoverageLayer(coverage_layer) atlas_on_single_file = layout.customProperty('singleFile', True) if file_format == QgisComposerComponentsMetadata.OutputFormat.PDF: if not atlas_composition.filenameExpression(): atlas_composition.setFilenameExpression( "'output_'||@atlas_featurenumber") output_directory = os.path.dirname(output_path) # we need to set the predefined scales for atlas project_scales = [] scales = QgsProject.instance().readListEntry( "Scales", "/ScalesList")[0] has_project_scales = QgsProject.instance().readBoolEntry( "Scales", "/useProjectScales")[0] if not has_project_scales or not scales: scales_string = str(general_setting("Map/scales", PROJECT_SCALES)) scales = scales_string.split(',') for scale in scales: parts = scale.split(':') if len(parts) == 2: project_scales.append(float(parts[1])) layout.reportContext().setPredefinedScales(project_scales) settings = QgsLayoutExporter.PdfExportSettings() LOGGER.info('Exporting Atlas') atlas_output = [] if atlas_on_single_file: res, error = QgsLayoutExporter.exportToPdf( atlas_composition, output_path, settings) atlas_output.append(output_path) else: res, error = QgsLayoutExporter.exportToPdfs( atlas_composition, output_directory, settings) if res != QgsLayoutExporter.Success: LOGGER.error(error) return atlas_output
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 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']}) 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.assertIn(metadata['KEYWORDS'], ('kw1,kw2', 'kw2,kw1')) self.assertEqual(metadata['SUBJECT'], 'proj abstract') self.assertEqual(metadata['TITLE'], 'proj title')
def atlas_renderer(layout, coverage_layer, output_path, file_format): """Extract composition using atlas generation. :param layout: QGIS Print Layout object used for producing the report. :type layout: qgis.core.QgsPrintLayout :param coverage_layer: Coverage Layer used for atlas map. :type coverage_layer: QgsMapLayer :param output_path: The output path of the product. :type output_path: str :param file_format: File format of map output, 'pdf' or 'png'. :type file_format: str :return: Generated output path(s). :rtype: str, list """ # set the composer map to be atlas driven composer_map = layout_item(layout, 'impact-map', QgsLayoutItemMap) composer_map.setAtlasDriven(True) composer_map.setAtlasScalingMode(QgsLayoutItemMap.Auto) # setup the atlas composition and composition atlas mode atlas_composition = layout.atlas() atlas_composition.setCoverageLayer(coverage_layer) atlas_on_single_file = layout.customProperty('singleFile', True) if file_format == QgisComposerComponentsMetadata.OutputFormat.PDF: if not atlas_composition.filenameExpression(): atlas_composition.setFilenameExpression( "'output_'||@atlas_featurenumber") output_directory = os.path.dirname(output_path) # we need to set the predefined scales for atlas project_scales = [] scales = QgsProject.instance().readListEntry("Scales", "/ScalesList")[0] has_project_scales = QgsProject.instance().readBoolEntry( "Scales", "/useProjectScales")[0] if not has_project_scales or not scales: scales_string = str(general_setting("Map/scales", PROJECT_SCALES)) scales = scales_string.split(',') for scale in scales: parts = scale.split(':') if len(parts) == 2: project_scales.append(float(parts[1])) layout.reportContext().setPredefinedScales(project_scales) settings = QgsLayoutExporter.PdfExportSettings() LOGGER.info('Exporting Atlas') atlas_output = [] if atlas_on_single_file: res, error = QgsLayoutExporter.exportToPdf(atlas_composition, output_path, settings) atlas_output.append(output_path) else: res, error = QgsLayoutExporter.exportToPdfs( atlas_composition, output_directory, settings) if res != QgsLayoutExporter.Success: LOGGER.error(error) return atlas_output
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']}) 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.assertIn(metadata['Keywords'], ('kw1,kw2', 'kw2,kw1')) 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))
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 exportLayout(self, cView, folder, title): """Function that sets how to export files.""" currProject = QgsProject.instance() printer = QPrinter() painter = QPainter() exporter = QgsLayoutExporter(cView) # Set page progressbar maximum value self.dlg.pageBar.setValue(0) self.dlg.pageBar.setMaximum(11) # Do the export process if not os.path.exists(os.path.join(folder, title)): os.makedirs(os.path.join(folder, title)) exporter.exportToPdf(os.path.join(folder, title, title + '.pdf'), QgsLayoutExporter.PdfExportSettings()) exporter.exportToImage(os.path.join(folder, title, title + '.jpg'), QgsLayoutExporter.ImageExportSettings()) # read CSV file & load into list with open(os.path.join(self.plugin_dir, "input/metadata_items.csv"), 'r') as metadata_file: reader = csv.reader(metadata_file, delimiter=',') metadata_list = list(reader) settings = ET.Element("mapdoc") mapdata = ET.SubElement(settings, "mapdata") # output fixed QGIS variables to XML """ACTION?""" # output project variables listed in CSV to XML for x in metadata_list[1:]: ma_variable = str(x[0]) elem_name = str(x[1]) elem_name = elem_name.strip() ma_level = str(x[2]) ma_level = ma_level.strip() if (ma_level == 'project') and (elem_name != 'no_xml'): elem_value = str( QgsExpressionContextUtils.projectScope( currProject).variable(ma_variable)) ET.SubElement(mapdata, elem_name).text = elem_value self.dlg.pageBar.setValue(self.dlg.pageBar.value() + 1) if elem_value.strip(): QgsMessageLog.logMessage( ma_variable + ' exported as ' + elem_value, 'MapExport', Qgis.Info) else: msgBar.pushMessage( 'Warning: missing value for ' + ma_variable, 5) QgsMessageLog.logMessage( 'Warning: missing value for ' + ma_variable, 'MapExport') themes = ET.SubElement(mapdata, "themes") for theme in self.dlg.themeBox.findChildren(QCheckBox): if theme.isChecked(): ET.SubElement(themes, 'theme').text = theme.text() for layout in QgsProject.instance().layoutManager().printLayouts(): # Set values of internal variables if layout.name() == self.dlg.layoutSelect.currentText(): date_now = datetime.date.today().strftime("%B %d, %Y") ET.SubElement(mapdata, 'lastUpdated').text = date_now title = layout.name() ET.SubElement(mapdata, 'jpgfilename').text = layout.name() + '.jpg' ET.SubElement(mapdata, 'pdffilename').text = layout.name() + '.pdf' # Action: Which map is selected by this? item = layout.referenceMap() # item = layout.itemById('main') # Get the attr by name and call map_scale = getattr(item, 'scale')() ET.SubElement(mapdata, 'scale').text = str(round(map_scale)) map_extent = item.extent() map_xmin = map_extent.xMinimum() map_xmax = map_extent.xMaximum() map_ymin = map_extent.yMinimum() map_ymax = map_extent.yMaximum() QgsMessageLog.logMessage('Scale ' + str(map_xmin), 'MapExport', Qgis.Info) ET.SubElement(mapdata, 'xmin').text = str(round(map_xmin)) ET.SubElement(mapdata, 'xmax').text = str(round(map_xmax)) ET.SubElement(mapdata, 'ymin').text = str(round(map_ymin)) ET.SubElement(mapdata, 'ymax').text = str(round(map_ymax)) for x in metadata_list[1:]: ma_variable = str(x[0]) elem_name = str(x[1]) elem_name = elem_name.strip() ma_level = str(x[2]) ma_level = ma_level.strip() if ma_level == 'layout': elem_value = str( QgsExpressionContextUtils.layoutScope( layout).variable(ma_variable)) ET.SubElement(mapdata, elem_name).text = elem_value self.dlg.pageBar.setValue(self.dlg.pageBar.value() + 1) if elem_value.strip(): QgsMessageLog.logMessage( ma_variable + ' exported as ' + elem_value, 'MapExport', Qgis.Info) else: msgBar.pushMessage( 'Warning: missing value for ' + ma_variable, 5) QgsMessageLog.logMessage( 'Warning: missing value for ' + ma_variable, 'MapExport') tree = ET.ElementTree(settings) tree.write(os.path.join(folder, title, title + '.xml')) # Set the location and the file name of the zip zippath = os.path.join(folder, title) zf = zipfile.ZipFile( os.path.abspath(folder) + os.sep + title + ".zip", "w") for dirnames, folders, files in os.walk(os.path.join(folder, title)): # for root, dirs, files in os.walk(folder): for file in files: zf.write(os.path.join(os.path.join(folder, title), file), file) zf.close() self.pageProcessed()