示例#1
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()])
示例#2
0
def deduplicate_legend_entries(iface,
                               raster_layer,
                               criteria,
                               unique_class_row_indexes=None,
                               expand=None):
    """Remove duplicate entries from layer legend.

    :param iface: QGIS interface
    :type iface: QgisInterface
    :param raster_layer: raster layer
    :type raster_layer: QgsRasterLayer
    :param criteria: classification criteria: label for the legend band
    :type criteria: str
    :param unique_class_row_indexes: list of 1-indexed unique entries, defaults to None
    :type unique_class_row_indexes: list, optional
    :param expand: whether to expand the legend, defaults to None
    :type expand: any, optional
    """

    assert iface is not None
    model = iface.layerTreeView().layerTreeModel()
    root = QgsProject.instance().layerTreeRoot()
    node = root.findLayer(raster_layer.id())

    if unique_class_row_indexes is None:
        unique_class_row_indexes = [0]
        renderer = raster_layer.renderer()
        unique_labels = []
        idx = 1

        # Get classes from renderer
        if isinstance(raster_layer.renderer(), QgsPalettedRasterRenderer):
            classes = renderer.classes()
        elif isinstance(raster_layer.renderer(),
                        QgsSingleBandPseudoColorRenderer):
            shader = raster_layer.renderer().shader()
            if shader:
                colorRampShaderFcn = shader.rasterShaderFunction()
                if colorRampShaderFcn:
                    classes = colorRampShaderFcn.colorRampItemList()
        else:
            rat_log('Unsupported renderer for layer %s' % raster_layer,
                    Qgis.Critical)
            return

        for klass in classes:
            if klass.label not in unique_labels:
                unique_labels.append(klass.label)
                unique_class_row_indexes.append(idx)
            idx += 1

    rat_log(
        f'Deduplicating legend entries for layer {raster_layer.name()}: {unique_class_row_indexes}'
    )
    QgsMapLayerLegendUtils.setLegendNodeOrder(node, unique_class_row_indexes)
    QgsMapLayerLegendUtils.setLegendNodeUserLabel(node, 0, criteria)
    model.refreshLayerLegend(node)
    if expand is not None:
        node.setExpanded(True)
示例#3
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()])
示例#4
0
def set_legend(layout: QgsPrintLayout, tree: QgsLayerTree, layer: QgsLayer, item_id: str):
  '''Sets the Legend items'''
  logging.info(f'setting legend: {item_id}')
  item = layout.itemById(item_id)

  # set layer as root for legend
  tree.addLayer(layer)
  model = item.model()
  model.setRootGroup(tree)
  root = model.rootGroup().findLayer(layer)
  
  # hide the node title
  QgsLegendRenderer.setNodeLegendStyle(root, QgsLegendStyle.Hidden)

  # hide the node with label: Band 1 (Gray)
  if isinstance(layer, QgsRasterLayer):
    nodes = model.layerLegendNodes(root)
    if nodes[0].data(0) == 'Band 1 (Gray)':
      indexes = list(range(1, len(nodes)))
      QgsMapLayerLegendUtils.setLegendNodeOrder(root, indexes)
      model.refreshLayerLegend(root)