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 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 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 testExportToPdf(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.PdfExportSettings() settings.dpi = 80 settings.rasterizeWholeImage = False settings.forceVectorOutput = False 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))
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 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 exportCompo(self, cView, folder, title, extension): """Function that sets how to export files. Returns a file :param cView: The print layout to export :param folder: The folder in which to store the output file :param title: The print layout name :param extension: The file extension to use for the output :return: A file representing the layout in the selected format """ #self.msgWMSWarning(cView) myAtlas = cView.atlas() #Let's use custom export properties if there are exportSettings = self.overrideExportSettings(cView, extension) # Do the export process exporter = QgsLayoutExporter(cView) # Allow export cancelation #QCoreApplication.processEvents() #self.buttonBox.rejected.connect(self.stopProcessing) if myAtlas.enabled(): # for i in range(0, myAtlas.count()): feedback = QgsFeedback() # Allow to listen to changes and increase progressbar # or abort the operation # with process input events #QCoreApplication.processEvents() #self.buttonBox.rejected.connect(feedback.cancel) #feedback.progressChanged.connect(self.pageProcessed) # if single file export is required (only compatible with pdf, yet) # singleFile can be true and None in that case if cView.customProperty( 'singleFile') is not False and extension == '.pdf': result, error = exporter.exportToPdf( myAtlas, os.path.join(folder, title + '.pdf'), exportSettings, feedback) else: #If instead multiple files will be output # Check if there's a valid expression for filenames, # and otherwise inform that a default one will be used and set it using the layout name. # replacement in the GUI is failing at the moment # if len(myAtlas.filenameExpression()) == 0: # self.iface.messageBar().pushMessage( # self.tr(u'Empty filename expression'), # self.tr(u'The print layout "{}" has an empty output filename expression. {}_@atlas_pagename is used as default.').format(title, title), # level = Qgis.Warning # ) # myAtlas.setFilenameExpression(u"'{}_'||@atlas_pagename".format(title)) current_fileName = myAtlas.filenameExpression() #export atlas to multiple pdfs if extension == '.pdf': result, error = exporter.exportToPdfs( myAtlas, os.path.join(folder, current_fileName), exportSettings, feedback) # export atlas to svg format elif extension == '.svg': result, error = exporter.exportToSvg( myAtlas, os.path.join(folder, current_fileName), exportSettings, feedback) # export atlas to image format else: result, error = exporter.exportToImage( myAtlas, os.path.join(folder, current_fileName), extension, exportSettings, feedback) myAtlas.endRender() # if the composition has no atlas else: if extension == '.pdf': result = exporter.exportToPdf( os.path.join(folder, title + '.pdf'), exportSettings) elif extension == '.svg': result = exporter.exportToSvg( os.path.join(folder, title + '.svg'), exportSettings) else: result = exporter.exportToImage( os.path.join(folder, title + extension), exportSettings) # When the export fails (eg it's aborted) # if not result == QgsLayoutExporter.Success: # #print( 'noresult') # self.stopProcessing() return result == QgsLayoutExporter.Success
def testExportToPdf(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.PdfExportSettings() settings.dpi = 80 settings.rasterizeWholeImage = False settings.forceVectorOutput = False 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))
def TOMsExportAtlas(self, printProposalObject): # TH (180608): Export function to deal with atlases settings = QSettings() format = self.dialogui.comboBox_fileformat.itemData(self.dialogui.comboBox_fileformat.currentIndex()) # TH (180608): Check to see whether or not the Composer is an Atlas currPrintLayout = self.layoutView currLayoutAtlas = currPrintLayout.atlas() success = False # https://gis.stackexchange.com/questions/77848/programmatically-load-composer-from-template-and-generate-atlas-using-pyqgis?utm_medium=organic&utm_source=google_rich_qa&utm_campaign=google_rich_qa self.TOMsSetAtlasValues(currPrintLayout) currRevisionDate = self.proposalsManager.date() # get the map tiles that are affected by the Proposal # self.getProposalTileList(currProposalID, currRevisionDate) proposalTileDictionaryForDate = printProposalObject.getProposalTileDictionaryForDate(currRevisionDate) """self.tileSet = set( proposalTileDictionaryForDate)""" # TODO: Change around use of tileSet - also might be good to have a current proposal as an object in proposalManager... # Now check which tiles to use self.tilesToPrint = self.TOMsChooseTiles(proposalTileDictionaryForDate) if len(self.tilesToPrint) == 0: return # get the output location dirName = QFileDialog.getExistingDirectory( self.iface.mainWindow(), self.tr("Export Composition"), settings.value("/instantprint/lastdir", ""), QFileDialog.ShowDirsOnly ) if not dirName: return settings.setValue("/instantprint/lastdir", dirName) tileIDList = "" firstTile = True for tile in self.tilesToPrint: if firstTile: tileIDList = str(tile.attribute("id")) firstTile = False else: tileIDList = tileIDList + ',' + str(tile.attribute("id")) currLayoutAtlas.setFilterFeatures(True) currLayoutAtlas.setFilterExpression(' "id" in ({tileList})'.format(tileList=tileIDList)) composerRevisionNr = currPrintLayout.itemById('revisionNr') composerEffectiveDate = currPrintLayout.itemById('effectiveDate') composerProposalStatus = currPrintLayout.itemById('proposalStatus') if composerProposalStatus is not None: composerProposalStatus.setText(self.proposalForPrintingStatusText) else: QMessageBox.warning(self.iface.mainWindow(), self.tr("Missing label in Layout"), self.tr("Missing label 'proposalStatus'")) composerPrintTypeDetails = currPrintLayout.itemById('printTypeDetails') if composerPrintTypeDetails is not None: composerPrintTypeDetails.setText(self.proposalPrintTypeDetails) else: QMessageBox.warning(self.iface.mainWindow(), self.tr("Missing label in Layout"), self.tr("Missing label 'printTypeDetails'")) # currProposalTitle, currProposalOpenDate = self.getProposalTitle(currProposalID) #printProposal = printProposalObject currProposalTitle = printProposalObject.getProposalTitle() currProposalOpenDate = printProposalObject.getProposalOpenDate() if printProposalObject.thisProposalNr == 0: currProposalTitle = "CurrentRestrictions_({date})".format( date=self.proposalsManager.date().toString('yyyyMMMdd')) TOMsMessageLog.logMessage("In TOMsExportAtlas. Now printing " + str(currLayoutAtlas.count()) + " items ....", level=Qgis.Info) currLayoutAtlas.setEnabled(True) currLayoutAtlas.updateFeatures() currLayoutAtlas.beginRender() altasFeatureFound = currLayoutAtlas.first() while altasFeatureFound: currTileNr = int(currLayoutAtlas.nameForPage(currLayoutAtlas.currentFeatureNumber())) currLayoutAtlas.refreshCurrentFeature() #tileWithDetails = self.tileFromTileSet(currTileNr) tileWithDetails = proposalTileDictionaryForDate[currTileNr] if tileWithDetails == None: TOMsMessageLog.logMessage("In TOMsExportAtlas. Tile with details not found ....", level=Qgis.Info) QMessageBox.warning(self.iface.mainWindow(), self.tr("Print Failed"), self.tr("Could not find details for " + str(currTileNr))) break TOMsMessageLog.logMessage("In TOMsExportAtlas. tile nr: " + str(currTileNr) + " RevisionNr: " + str( tileWithDetails["RevisionNr"]) + " RevisionDate: " + str(tileWithDetails["LastRevisionDate"]), level=Qgis.Info) if self.proposalForPrintingStatusText == "CONFIRMED": composerRevisionNr.setText(str(tileWithDetails["RevisionNr"])) composerEffectiveDate.setText( '{date}'.format(date=tileWithDetails["LastRevisionDate"].toString('dd-MMM-yyyy'))) else: composerRevisionNr.setText(str(tileWithDetails["RevisionNr"] + 1)) # For the Proposal, use the current view date composerEffectiveDate.setText( '{date}'.format(date=self.openDateForPrintProposal.toString('dd-MMM-yyyy'))) filename = currProposalTitle + "_" + str( currTileNr) + "." + self.dialogui.comboBox_fileformat.currentText().lower() outputFile = os.path.join(dirName, filename) exporter = QgsLayoutExporter(currLayoutAtlas.layout()) if self.dialogui.comboBox_fileformat.currentText().lower() == u"pdf": result = exporter.exportToPdf(outputFile, QgsLayoutExporter.PdfExportSettings()) # success = currLayoutAtlas.composition().exportAsPDF(outputFile) else: result = exporter.exportToImage(outputFile, 'png', QgsLayoutExporter.ImageExportSettings()) """image = currLayoutAtlas.composition().printPageAsRaster(0) if not image.isNull(): success = image.save(outputFile)""" if result != QgsLayoutExporter.Success: QMessageBox.warning(self.iface.mainWindow(), self.tr("Print Failed"), self.tr("Failed to print " + exporter.errorFile())) break altasFeatureFound = currLayoutAtlas.next() currLayoutAtlas.endRender() QMessageBox.information(self.iface.mainWindow(), "Information", ("Printing completed"))
def print_atlas(self, project_path, composer_name, predefined_scales, feature_filter=None, page_name_expression=None ): if not feature_filter: QgsMessageLog.logMessage("atlasprint: NO feature_filter provided !", 'atlasprint', Qgis.Info) return None # Get composer from project # in QGIS 2, canno get composers without iface # so we reading project xml and extract composer # in QGIS 3.0, we will use project layoutManager() from xml.etree import ElementTree as ET composer_xml = None with open(project_path, 'r') as f: tree = ET.parse(f) for elem in tree.findall('.//Composer[@title="%s"]' % composer_name): composer_xml = ET.tostring( elem, encoding='utf8', method='xml' ) if not composer_xml: for elem in tree.findall('.//Layout[@name="%s"]' % composer_name): composer_xml = ET.tostring( elem, encoding='utf8', method='xml' ) if not composer_xml: QgsMessageLog.logMessage("atlasprint: Composer XML not parsed !", 'atlasprint', Qgis.Info) return None document = QDomDocument() document.setContent(composer_xml) # Get canvas, map setting & instantiate composition canvas = QgsMapCanvas() project = QgsProject() project.read(project_path) bridge = QgsLayerTreeMapCanvasBridge( project.layerTreeRoot(), canvas ) bridge.setCanvasLayers() layout = QgsPrintLayout(project) # Load content from XML layout.loadFromTemplate( document, QgsReadWriteContext(), ) atlas = layout.atlas() atlas.setEnabled(True) atlas_map = layout.referenceMap() atlas_map.setAtlasDriven(True) atlas_map.setAtlasScalingMode( QgsLayoutItemMap.Predefined ) layout.reportContext().setPredefinedScales(predefined_scales) if page_name_expression: atlas.setPageNameExpression(page_name_expression) # Filter feature here to avoid QGIS looping through every feature when doing : composition.setAtlasMode(QgsComposition.ExportAtlas) coverageLayer = atlas.coverageLayer() # Filter by FID as QGIS cannot compile expressions with $id or other $ vars # which leads to bad perfs for big datasets useFid = None if '$id' in feature_filter: import re ids = list(map(int, re.findall(r'\d+', feature_filter))) if len(ids) > 0: useFid = ids[0] if useFid: qReq = QgsFeatureRequest().setFilterFid(useFid) else: qReq = QgsFeatureRequest().setFilterExpression(feature_filter) # Change feature_filter in order to improve perfs pks = coverageLayer.dataProvider().pkAttributeIndexes() if useFid and len(pks) == 1: pk = coverageLayer.dataProvider().fields()[pks[0]].name() feature_filter = '"%s" IN (%s)' % (pk, useFid) QgsMessageLog.logMessage("atlasprint: feature_filter changed into: %s" % feature_filter, 'atlasprint', Qgis.Info) qReq = QgsFeatureRequest().setFilterExpression(feature_filter) atlas.setFilterFeatures(True) atlas.setFilterExpression(feature_filter) uid = uuid4() i = 0 atlas.beginRender() atlas.seekTo(i) # setup settings settings = QgsLayoutExporter.PdfExportSettings() export_path = os.path.join( tempfile.gettempdir(), '%s_%s.pdf' % (atlas.nameForPage(i), uid) ) exporter = QgsLayoutExporter(layout) result = exporter.exportToPdf(export_path, settings) atlas.endRender() if result != QgsLayoutExporter.Success: QgsMessageLog.logMessage("atlasprint: export not generated %s" % export_path, 'atlasprint', Qgis.Info) return None if not os.path.isfile(export_path): QgsMessageLog.logMessage("atlasprint: export not generated %s" % export_path, 'atlasprint', Qgis.Info) return None QgsMessageLog.logMessage("atlasprint: path generated %s" % export_path, 'atlasprint', Qgis.Info) return export_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 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 export_atlas(qgs_project_path, layout_name, filepath): imageExtension = os.path.splitext(filepath)[1] imageExtension = imageExtension.lower() # Open existing project project = QgsProject.instance() print(os.path.abspath(os.path.dirname(qgs_project_path))) os.chdir(os.path.abspath(os.path.dirname(qgs_project_path))) project.read(os.path.abspath(qgs_project_path)) project.readPath(os.path.abspath(os.path.dirname(qgs_project_path))) #print(f'Project in "{project.fileName()} loaded successfully') print('Project in "{fn} loaded successfully'.format(fn=project.fileName())) # Open prepared layout that as atlas enabled and set layout = project.layoutManager().layoutByName(layout_name) # Export atlas exporter = QgsLayoutExporter(layout) settings = QgsLayoutExporter.ImageExportSettings() img_path = os.path.dirname(filepath) filename = os.path.basename(filepath) myAtlas = layout.atlas() myAtlasMap = myAtlas.layout() myAtlas.setFilenameExpression(img_path) pdf_settings = QgsLayoutExporter(myAtlasMap).PdfExportSettings() image_settings = QgsLayoutExporter(myAtlasMap).ImageExportSettings() image_settings.dpi = 96 svg_settings = QgsLayoutExporter(myAtlasMap).SvgExportSettings( ) #https://qgis.org/api/structQgsLayoutExporter_1_1SvgExportSettings.html print('layout_name= {layout_name} '.format(layout_name=layout_name)) print('try export to {img_path} '.format(img_path=img_path)) if imageExtension == '.jpg': if os.path.isfile(os.path.join(img_path, 'output_0.jpg')): os.unlink(os.path.join(img_path, 'output_0.jpg')) for layout in QgsProject.instance().layoutManager().printLayouts(): if myAtlas.enabled(): print('signal') result, error = QgsLayoutExporter.exportToImage( myAtlas, baseFilePath=img_path + '//', extension=imageExtension, settings=image_settings) if not result == QgsLayoutExporter.Success: print(error) os.rename(os.path.join(img_path, 'output_0.jpg'), os.path.join(img_path, filename)) if imageExtension == '.png': if os.path.isfile(os.path.join(img_path, 'output_0.png')): os.unlink(os.path.join(img_path, 'output_0.png')) for layout in QgsProject.instance().layoutManager().printLayouts(): if myAtlas.enabled(): print('signal') result, error = QgsLayoutExporter.exportToImage( myAtlas, baseFilePath=img_path + '//', extension=imageExtension, settings=image_settings) if not result == QgsLayoutExporter.Success: print(error) os.rename(os.path.join(img_path, 'output_0.png'), os.path.join(img_path, filename)) if imageExtension == '.pdf': #if os.path.isfile(os.path.join(img_path,'output_0.jpg')): # os.unlink(os.path.join(img_path,'output_0.jpg')) for layout in QgsProject.instance().layoutManager().printLayouts(): if myAtlas.enabled(): result, error = QgsLayoutExporter.exportToPdf( myAtlas, img_path + '//output_0.pdf', settings=pdf_settings) if not result == QgsLayoutExporter.Success: print(error) os.rename(os.path.join(img_path, 'output_0.pdf'), os.path.join(img_path, filename)) if imageExtension == '.svg': for layout in QgsProject.instance().layoutManager().printLayouts(): if myAtlas.enabled(): result, error = QgsLayoutExporter.exportToSvg( myAtlas, img_path + '//output_0.svg', settings=svg_settings) if not result == QgsLayoutExporter.Success: print(error) os.rename(os.path.join(img_path, 'output_0.svg'), os.path.join(img_path, filename))
def print_layout(project, layout_name, feature_filter: str = None, scales=None, scale=None, **kwargs): """Generate a PDF for an atlas or a report. :param project: The QGIS project. :type project: QgsProject :param layout_name: Name of the layout of the atlas or report. :type layout_name: basestring :param feature_filter: QGIS Expression to use to select the feature. It can return many features, a multiple pages PDF will be returned. This is required to print atlas, not report :type feature_filter: basestring :param scale: A scale to force in the atlas context. Default to None. :type scale: int :param scales: A list of predefined list of scales to force in the atlas context. Default to None. :type scales: list :return: Path to the PDF. :rtype: basestring """ canvas = QgsMapCanvas() bridge = QgsLayerTreeMapCanvasBridge(project.layerTreeRoot(), canvas) bridge.setCanvasLayers() manager = project.layoutManager() master_layout = manager.layoutByName(layout_name) settings = QgsLayoutExporter.PdfExportSettings() atlas = None atlas_layout = None report_layout = None logger = Logger() if not master_layout: raise AtlasPrintException('Layout `{}` not found'.format(layout_name)) if master_layout.layoutType() == QgsMasterLayoutInterface.PrintLayout: for _print_layout in manager.printLayouts(): if _print_layout.name() == layout_name: atlas_layout = _print_layout break atlas = atlas_layout.atlas() if not atlas.enabled(): raise AtlasPrintException('The layout is not enabled for an atlas') layer = atlas.coverageLayer() if feature_filter is None: raise AtlasPrintException( 'EXP_FILTER is mandatory to print an atlas layout') feature_filter = optimize_expression(layer, feature_filter) expression = QgsExpression(feature_filter) if expression.hasParserError(): raise AtlasPrintException( 'Expression is invalid, parser error: {}'.format( expression.parserErrorString())) context = QgsExpressionContext() context.appendScope(QgsExpressionContextUtils.globalScope()) context.appendScope(QgsExpressionContextUtils.projectScope(project)) context.appendScope( QgsExpressionContextUtils.layoutScope(atlas_layout)) context.appendScope(QgsExpressionContextUtils.atlasScope(atlas)) context.appendScope(QgsExpressionContextUtils.layerScope(layer)) expression.prepare(context) if expression.hasEvalError(): raise AtlasPrintException( 'Expression is invalid, eval error: {}'.format( expression.evalErrorString())) atlas.setFilterFeatures(True) atlas.setFilterExpression(feature_filter) if scale: atlas_layout.referenceMap().setAtlasScalingMode( QgsLayoutItemMap.Fixed) atlas_layout.referenceMap().setScale(scale) if scales: atlas_layout.referenceMap().setAtlasScalingMode( QgsLayoutItemMap.Predefined) if Qgis.QGIS_VERSION_INT >= 30900: settings.predefinedMapScales = scales else: atlas_layout.reportContext().setPredefinedScales(scales) if not scales and atlas_layout.referenceMap().atlasScalingMode( ) == QgsLayoutItemMap.Predefined: if Qgis.QGIS_VERSION_INT >= 30900: use_project = project.useProjectScales() map_scales = project.mapScales() else: map_scales = project_scales(project) use_project = len(map_scales) == 0 if not use_project or len(map_scales) == 0: logger.info( 'Map scales not found in project, fetching predefined map scales in global config' ) map_scales = global_scales() if Qgis.QGIS_VERSION_INT >= 30900: settings.predefinedMapScales = map_scales else: atlas_layout.reportContext().setPredefinedScales(map_scales) elif master_layout.layoutType() == QgsMasterLayoutInterface.Report: report_layout = master_layout else: raise AtlasPrintException('The layout is not supported by the plugin') for key, value in kwargs.items(): found = False if atlas_layout: item = atlas_layout.itemById(key.lower()) if isinstance(item, QgsLayoutItemLabel): item.setText(value) found = True logger.info( 'Additional parameters: {} found in layout {}, value {}'.format( key, found, value)) export_path = os.path.join( tempfile.gettempdir(), '{}_{}.pdf'.format(clean_string(layout_name), uuid4())) result, error = QgsLayoutExporter.exportToPdf(atlas or report_layout, export_path, settings) if result != QgsLayoutExporter.Success: raise Exception('Export not generated in QGIS exporter {} : {}'.format( export_path, error)) if not os.path.isfile(export_path): raise Exception( 'Export OK from QGIS, but file not found on the file system : {}'. format(export_path)) return export_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 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()