def testReadWriteXml(self): p = QgsProject() l = QgsPrintLayout(p) l.setName('my layout') l.setUnits(QgsUnitTypes.LayoutInches) collection = l.pageCollection() # add a page page = QgsLayoutItemPage(l) page.setPageSize('A6') collection.addPage(page) grid = l.gridSettings() grid.setResolution(QgsLayoutMeasurement(5, QgsUnitTypes.LayoutPoints)) g1 = QgsLayoutGuide(Qt.Horizontal, QgsLayoutMeasurement(5, QgsUnitTypes.LayoutCentimeters), l.pageCollection().page(0)) l.guides().addGuide(g1) snapper = l.snapper() snapper.setSnapTolerance(7) # add some items item1 = QgsLayoutItemMap(l) item1.setId('xxyyxx') l.addItem(item1) item2 = QgsLayoutItemMap(l) item2.setId('zzyyzz') l.addItem(item2) l.setReferenceMap(item2) doc = QDomDocument("testdoc") elem = l.writeXml(doc, QgsReadWriteContext()) l2 = QgsPrintLayout(p) self.assertTrue(l2.readXml(elem, doc, QgsReadWriteContext())) self.assertEqual(l2.name(), 'my layout') self.assertEqual(l2.units(), QgsUnitTypes.LayoutInches) collection2 = l2.pageCollection() self.assertEqual(collection2.pageCount(), 1) self.assertAlmostEqual(collection2.page(0).pageSize().width(), 105, 4) self.assertEqual(collection2.page(0).pageSize().height(), 148) self.assertEqual(l2.gridSettings().resolution().length(), 5.0) self.assertEqual(l2.gridSettings().resolution().units(), QgsUnitTypes.LayoutPoints) self.assertEqual(l2.guides().guidesOnPage(0)[0].orientation(), Qt.Horizontal) self.assertEqual(l2.guides().guidesOnPage(0)[0].position().length(), 5.0) self.assertEqual(l2.guides().guidesOnPage(0)[0].position().units(), QgsUnitTypes.LayoutCentimeters) self.assertEqual(l2.snapper().snapTolerance(), 7) # check restored items new_item1 = l2.itemByUuid(item1.uuid()) self.assertTrue(new_item1) self.assertEqual(new_item1.id(), 'xxyyxx') new_item2 = l2.itemByUuid(item2.uuid()) self.assertTrue(new_item2) self.assertEqual(new_item2.id(), 'zzyyzz') self.assertEqual(l2.referenceMap().id(), 'zzyyzz')
def layoutLoader(self, template_source, layout_name, title_text): """ Generate the layout """ from qgis.core import (QgsProject, QgsPrintLayout, QgsReadWriteContext) from qgis.utils import iface from PyQt5.QtXml import QDomDocument #template_source = '/home/user/Document/Template.qpt' #layout_name = 'NewLayout' #title_text = 'New Title' # Create objects lm = layout manager, l = print layout lm = QgsProject.instance().layoutManager() l = QgsPrintLayout(QgsProject.instance()) l.initializeDefaults() # Load template file and load it into the layout (l) template_file = open(template_source, 'r+', encoding='utf-8') template_content = template_file.read() template_file.close() document = QDomDocument() document.setContent(template_content) context = QgsReadWriteContext() l.loadFromTemplate(document, context) # Give the layout a name (must be unique) l.setName(layout_name) # Get current canvas extent and apply that to all maps (items) in layout # Replace any text "{{title}}" in any layout label with the dialog Title text canvas = iface.mapCanvas() for item in l.items(): if item.type() == 65639: # Map item.zoomToExtent(canvas.extent()) if item.type() == 65641: # Label item.setText(item.text().replace('{{title}}', title_text)) # Add layout to layout manager l.refresh() lm.addLayout(l) # Open and show the layout in designer try: iface.openLayoutDesigner(l) except: oopsBox = QMessageBox() oopsBox.setIcon(QMessageBox.Warning) oopsBox.setText( self. tr('Ooops. Something went wrong. Trying to open the generated layout ({}) returned errors.' .format(l.name()))) oopsBox.setWindowTitle(self.tr('Layout Loader')) oopsBox.exec_()
class run(QObject): def __init__(self, id, gtotool, config, debug): super(run, self).__init__() try: self.debug = debug self.gtotool=gtotool self.gtomain = gtotool.gtomain self.info =gtotool.info self.metadata = self.gtomain.metadata templatedir = self.metadata.dirPrintLayouts self.iface = self.gtomain.iface #tool data template = config.get('template',None) activetool= config.get('active_tool',None) scale = config.get('scale',0) #init templatefile = None layoutname =config.get('layoutname', None) if template and layoutname is None: layoutname= os.path.splitext(template)[0]#default layoutname for template if self.debug:self.info.log("layoutname:",layoutname) prj = QgsProject.instance() projectLayoutManager = prj.layoutManager()#QgsLayoutManager self.layout = None if template is not None: templatefile = os.path.join(templatedir , template) if debug: self.info.log("template:",templatefile) if os.path.isfile(templatefile): f= open(templatefile, 'r') templateContent = f.read() f.close() doc=QDomDocument() doc.setContent(templateContent) pr = QgsPathResolver(templatefile) rwc = QgsReadWriteContext() rwc.setPathResolver(pr) self.layout = QgsPrintLayout(prj) self.layout.loadFromTemplate(doc,rwc) self.layout.setName(layoutname) projectLayoutManager.addLayout(self.layout) self.layout = projectLayoutManager.layoutByName(layoutname) if self.debug: self.info.log(type(self.layout)) if self.debug and self.layout:self.info.log("found layout:",self.layout.name()) if self.layout: result = self.iface.openLayoutDesigner(self.layout)#QgsLayoutDesignerInterface self.layoutview = result.view()#QgsLayoutView currenttool = self.layoutview.tool()#QgsLayoutViewTool if self.debug: self.info.log(currenttool.toolName()) if activetool: tool = QgsLayoutViewToolMoveItemContent(self.layoutview) self.layoutview.setTool(tool) #itemMap = QgsLayoutItemMap(self.layout) referencemap = self.layout.referenceMap() referencemap.zoomToExtent(self.iface.mapCanvas().extent()) if scale < 0: referencemap.setScale(self.iface.mapCanvas().scale()) elif scale > 0: referencemap.setScale(scale) referencemap.refresh() if activetool: menu = result.editMenu() for a in menu.actions(): if a.objectName() == activetool: if self.debug: self.info.log("set active tool:",activetool) a.trigger() break self.result = True else: self.result="Layout <%s> not found!" % layoutname except Exception as e: self.info.err(e)
def processAlgorithm(self, parameters, context, feedback): """This actually creates the print layout and exporting as .pdf document""" log = feedback.setProgressText input_title = self.parameterAsString(parameters, self.INPUT_TITLE, context) input_subtitle = self.parameterAsString(parameters, self.INPUT_SUBTITLE, context) input_credit_text = self.parameterAsString(parameters, self.INPUT_CREDIT_TEXT, context) output_pdf_path = self.parameterAsString(parameters, self.OUTPUT_PDF_PATH, context) log(f"Title: {input_title}") log(f"Subtitle: {input_subtitle}") log(f"Credit Text: {input_credit_text}") log(f"Output pdf path: {output_pdf_path}") #This creates a new print layout project = context.project() manager = project.layoutManager() layout = QgsPrintLayout(project) layoutName = 'EcoValuator Layout' #layoutName is going to be name of Title. Change this later layouts_list = manager.printLayouts() for layout in layouts_list: if layout.name() == layoutName: manager.removeLayout(layout) layout = QgsPrintLayout(project) layout.initializeDefaults() #create default map canvas layout.setName(layoutName) manager.addLayout(layout) #This adds a map item to the Print Layout map = QgsLayoutItemMap(layout) map.setRect(20, 20, 20, 20) #Set Extent canvas = iface.mapCanvas() map.setExtent(canvas.extent()) #sets map extent to current map canvas layout.addLayoutItem(map) #Move & Resize map.attemptMove(QgsLayoutPoint(5, 27, QgsUnitTypes.LayoutMillimeters)) map.attemptResize( QgsLayoutSize(218, 178, QgsUnitTypes.LayoutMillimeters)) #Gather visible layers in project layer tree and create a list of the map layer objects #Those which are not active (layers_to_remove) will subsequently remove from the legend model tree_layers = project.layerTreeRoot().children() active_layers = [ layer.name() for layer in tree_layers if layer.isVisible() ] layers_to_remove = [ layer for layer in project.mapLayers().values() if layer.name() not in active_layers ] #This adds a legend item to the Print Layout legend = QgsLayoutItemLegend(layout) layout.addLayoutItem(legend) legend.attemptMove( QgsLayoutPoint(219, 5, QgsUnitTypes.LayoutMillimeters)) #Get reference to existing legend model and root group then remove the unchecked layers legend.setAutoUpdateModel(False) #not sure if this line is required model = legend.model() group = model.rootGroup() for layer in layers_to_remove: group.removeLayer(layer) legend.adjustBoxSize() #This adds labels to the map title = QgsLayoutItemLabel(layout) title.setText(input_title) title.setFont(QFont("Arial", 28)) title.adjustSizeToText() layout.addLayoutItem(title) title.attemptMove(QgsLayoutPoint(10, 4, QgsUnitTypes.LayoutMillimeters)) subtitle = QgsLayoutItemLabel(layout) subtitle.setText(input_subtitle) subtitle.setFont(QFont("Arial", 17)) subtitle.adjustSizeToText() layout.addLayoutItem(subtitle) subtitle.attemptMove( QgsLayoutPoint(11, 20, QgsUnitTypes.LayoutMillimeters)) credit_text = QgsLayoutItemLabel(layout) credit_text.setText(input_credit_text) credit_text.setFont(QFont("Arial", 10)) credit_text.adjustSizeToText() layout.addLayoutItem(credit_text) credit_text.attemptMove( QgsLayoutPoint(219, 190, QgsUnitTypes.LayoutMillimeters)) #this creates credit text (line1) in bottom right corner of map layout giving credit to Key-Log Economics keylog_credits1 = QgsLayoutItemLabel(layout) keylog_credits1.setText("Created using EcoValuator Plugin") keylog_credits1.setFont(QFont("Arial", 10)) keylog_credits1.adjustSizeToText() layout.addLayoutItem(keylog_credits1) keylog_credits1.attemptMove( QgsLayoutPoint(219, 195, QgsUnitTypes.LayoutMillimeters)) #this creates credit text (line2) in bottom right corner of map layout giving credit to Key-Log Economics keylog_credits2 = QgsLayoutItemLabel(layout) keylog_credits2.setText("by Key-Log Economics") keylog_credits2.setFont(QFont("Arial", 10)) keylog_credits2.adjustSizeToText() layout.addLayoutItem(keylog_credits2) keylog_credits2.attemptMove( QgsLayoutPoint(219, 200, QgsUnitTypes.LayoutMillimeters)) #This exports a Print Layout as an image manager = QgsProject.instance().layoutManager( ) #this is a reference to the layout Manager, which contains a list of print layouts layout = manager.layoutByName( layoutName ) #this accesses a specific layout, by name (which is a string) exporter = QgsLayoutExporter( layout) #this creates a QgsLayoutExporter object exporter.exportToPdf(output_pdf_path, QgsLayoutExporter.PdfExportSettings()) log("Done!") result = { } #The processAlgorithm wants to return a dictionary. We don't actually need to do this so instead we return an empty one return result