Esempio n. 1
0
    def testExpressionInText(self):
        """Test expressions embedded in legend node text"""

        point_path = os.path.join(TEST_DATA_DIR, 'points.shp')
        point_layer = QgsVectorLayer(point_path, 'points', 'ogr')

        layout = QgsPrintLayout(QgsProject.instance())
        layout.setName('LAYOUT')
        layout.initializeDefaults()

        map = QgsLayoutItemMap(layout)
        map.attemptSetSceneRect(QRectF(20, 20, 80, 80))
        map.setFrameEnabled(True)
        map.setLayers([point_layer])
        layout.addLayoutItem(map)
        map.setExtent(point_layer.extent())

        legend = QgsLayoutItemLegend(layout)
        legend.setTitle("Legend")
        legend.attemptSetSceneRect(QRectF(120, 20, 100, 100))
        legend.setFrameEnabled(True)
        legend.setFrameStrokeWidth(QgsLayoutMeasurement(2))
        legend.setBackgroundColor(QColor(200, 200, 200))
        legend.setTitle('')
        legend.setLegendFilterByMapEnabled(False)
        legend.setStyleFont(QgsLegendStyle.Title, QgsFontUtils.getStandardTestFont('Bold', 16))
        legend.setStyleFont(QgsLegendStyle.Group, QgsFontUtils.getStandardTestFont('Bold', 16))
        legend.setStyleFont(QgsLegendStyle.Subgroup, QgsFontUtils.getStandardTestFont('Bold', 16))
        legend.setStyleFont(QgsLegendStyle.Symbol, QgsFontUtils.getStandardTestFont('Bold', 16))
        legend.setStyleFont(QgsLegendStyle.SymbolLabel, QgsFontUtils.getStandardTestFont('Bold', 16))

        legend.setAutoUpdateModel(False)

        QgsProject.instance().addMapLayers([point_layer])
        s = QgsMapSettings()
        s.setLayers([point_layer])

        group = legend.model().rootGroup().addGroup("Group [% 1 + 5 %] [% @layout_name %]")
        layer_tree_layer = group.addLayer(point_layer)
        layer_tree_layer.setCustomProperty("legend/title-label", 'bbbb [% 1+2 %] xx [% @layout_name %] [% @layer_name %]')
        QgsMapLayerLegendUtils.setLegendNodeUserLabel(layer_tree_layer, 0, 'xxxx')
        legend.model().refreshLayerLegend(layer_tree_layer)
        legend.model().layerLegendNodes(layer_tree_layer)[0].setUserLabel('bbbb [% 1+2 %] xx [% @layout_name %] [% @layer_name %]')

        layout.addLayoutItem(legend)
        legend.setLinkedMap(map)

        map.setExtent(QgsRectangle(-102.51, 41.16, -102.36, 41.30))

        checker = QgsLayoutChecker(
            'composer_legend_expressions', layout)
        checker.setControlPathPrefix("composer_legend")
        result, message = checker.testLayout()
        self.assertTrue(result, message)

        QgsProject.instance().removeMapLayers([point_layer.id()])
Esempio n. 2
0
    def testSymbolExpressionRender(self):
        """Test expressions embedded in legend node text"""
        point_path = os.path.join(TEST_DATA_DIR, 'points.shp')
        point_layer = QgsVectorLayer(point_path, 'points', 'ogr')
        layout = QgsPrintLayout(QgsProject.instance())
        layout.setName('LAYOUT')
        layout.initializeDefaults()

        map = QgsLayoutItemMap(layout)
        map.attemptSetSceneRect(QRectF(20, 20, 80, 80))
        map.setFrameEnabled(True)
        map.setLayers([point_layer])
        layout.addLayoutItem(map)
        map.setExtent(point_layer.extent())

        legend = QgsLayoutItemLegend(layout)
        legend.setTitle("Legend")
        legend.attemptSetSceneRect(QRectF(120, 20, 100, 100))
        legend.setFrameEnabled(True)
        legend.setFrameStrokeWidth(QgsLayoutMeasurement(2))
        legend.setBackgroundColor(QColor(200, 200, 200))
        legend.setTitle('')
        legend.setLegendFilterByMapEnabled(False)
        legend.setStyleFont(QgsLegendStyle.Title, QgsFontUtils.getStandardTestFont('Bold', 16))
        legend.setStyleFont(QgsLegendStyle.Group, QgsFontUtils.getStandardTestFont('Bold', 16))
        legend.setStyleFont(QgsLegendStyle.Subgroup, QgsFontUtils.getStandardTestFont('Bold', 16))
        legend.setStyleFont(QgsLegendStyle.Symbol, QgsFontUtils.getStandardTestFont('Bold', 16))
        legend.setStyleFont(QgsLegendStyle.SymbolLabel, QgsFontUtils.getStandardTestFont('Bold', 16))

        legend.setAutoUpdateModel(False)

        QgsProject.instance().addMapLayers([point_layer])
        s = QgsMapSettings()
        s.setLayers([point_layer])

        group = legend.model().rootGroup().addGroup("Group [% 1 + 5 %] [% @layout_name %]")
        layer_tree_layer = group.addLayer(point_layer)
        counterTask = point_layer.countSymbolFeatures()
        counterTask.waitForFinished()
        layer_tree_layer.setCustomProperty("legend/title-label",
                                           'bbbb [% 1+2 %] xx [% @layout_name %] [% @layer_name %]')
        QgsMapLayerLegendUtils.setLegendNodeUserLabel(layer_tree_layer, 0, 'xxxx')
        legend.model().refreshLayerLegend(layer_tree_layer)
        layer_tree_layer.setLabelExpression('Concat(@symbol_id, @symbol_label, count("Class"))')
        legend.model().layerLegendNodes(layer_tree_layer)[0].setUserLabel(' sym 1')
        legend.model().layerLegendNodes(layer_tree_layer)[1].setUserLabel('[%@symbol_count %]')
        legend.model().layerLegendNodes(layer_tree_layer)[2].setUserLabel('[% count("Class") %]')
        layout.addLayoutItem(legend)
        legend.setLinkedMap(map)
        legend.updateLegend()
        print(layer_tree_layer.labelExpression())
        map.setExtent(QgsRectangle(-102.51, 41.16, -102.36, 41.30))
        checker = QgsLayoutChecker(
            'composer_legend_symbol_expression', layout)
        checker.setControlPathPrefix("composer_legend")
        sleep(4)
        result, message = checker.testLayout()
        self.assertTrue(result, message)

        QgsProject.instance().removeMapLayers([point_layer.id()])
Esempio n. 3
0
    def testSymbolExpressions(self):
        "Test expressions embedded in legend node text"
        QgsProject.instance().clear()
        point_path = os.path.join(TEST_DATA_DIR, 'points.shp')
        point_layer = QgsVectorLayer(point_path, 'points', 'ogr')

        layout = QgsPrintLayout(QgsProject.instance())
        layout.initializeDefaults()

        map = QgsLayoutItemMap(layout)
        map.setLayers([point_layer])
        layout.addLayoutItem(map)
        map.setExtent(point_layer.extent())

        legend = QgsLayoutItemLegend(layout)

        layer = QgsProject.instance().addMapLayer(point_layer)
        legendlayer = legend.model().rootGroup().addLayer(point_layer)

        counterTask = point_layer.countSymbolFeatures()
        counterTask.waitForFinished()
        TM = QgsApplication.taskManager()
        actask = TM.activeTasks()
        print(TM.tasks(), actask)
        count = actask[0]
        legend.model().refreshLayerLegend(legendlayer)
        legendnodes = legend.model().layerLegendNodes(legendlayer)
        legendnodes[0].setUserLabel('[% @symbol_id %]')
        legendnodes[1].setUserLabel('[% @symbol_count %]')
        legendnodes[2].setUserLabel('[% sum("Pilots") %]')
        label1 = legendnodes[0].evaluateLabel()
        label2 = legendnodes[1].evaluateLabel()
        label3 = legendnodes[2].evaluateLabel()
        count.waitForFinished()
        self.assertEqual(label1, '0')
        #self.assertEqual(label2, '5')
        #self.assertEqual(label3, '12')

        legendlayer.setLabelExpression("Concat(@symbol_label, @symbol_id)")

        label1 = legendnodes[0].evaluateLabel()
        label2 = legendnodes[1].evaluateLabel()
        label3 = legendnodes[2].evaluateLabel()

        self.assertEqual(label1, ' @symbol_id 0')
        #self.assertEqual(label2, '@symbol_count 1')
        #self.assertEqual(label3, 'sum("Pilots") 2')

        QgsProject.instance().clear()
    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