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()])
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)
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()])
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)