예제 #1
0
    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')
예제 #2
0
    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')
예제 #3
0
    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_()
예제 #4
0
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