diff --git a/lizmap_server/get_legend_graphic.py b/lizmap_server/get_legend_graphic.py index 77462d2b..e6a03792 100644 --- a/lizmap_server/get_legend_graphic.py +++ b/lizmap_server/get_legend_graphic.py @@ -3,11 +3,12 @@ __license__ = "GPL version 3" __copyright__ = 'Copyright 2022, Gis3w' -# File adapted by @rldhont, 3Liz +# File adapted by @rldhont and @Gustry, 3Liz import json import re +from collections import namedtuple from typing import Optional from qgis.core import Qgis, QgsProject, QgsVectorLayer @@ -17,6 +18,10 @@ from lizmap_server.logger import Logger, exception_handler from lizmap_server.tools import to_bool +Category = namedtuple( + 'Category', + ['ruleKey', 'checked', 'parentRuleKey', 'scaleMaxDenom', 'scaleMinDenom', 'expression', 'title']) + class GetLegendGraphicFilter(QgsServerFilter): """ Add "ruleKey" to GetLegendGraphic for categorized and rule-based @@ -115,20 +120,20 @@ def responseComplete(self): self.FEATURE_COUNT_REGEXP, symbol['title'])) try: category = categories[symbol_label] - symbol['ruleKey'] = category['ruleKey'] - symbol['checked'] = category['checked'] - symbol['parentRuleKey'] = category['parentRuleKey'] + symbol['ruleKey'] = category.ruleKey + symbol['checked'] = category.checked + symbol['parentRuleKey'] = category.parentRuleKey # TODO remove when QGIS 3.28 will be the minimum version # https://github.com/qgis/QGIS/pull/53738 3.34, 3.32.1, 3.28.10 - if 'scaleMaxDenom' not in symbol and category['scaleMaxDenom'] > 0: - symbol['scaleMaxDenom'] = category['scaleMaxDenom'] - if 'scaleMinDenom' not in symbol and category['scaleMinDenom'] > 0: - symbol['scaleMinDenom'] = category['scaleMinDenom'] - - symbol['expression'] = category['expression'] - if symbol['title'] != category['title']: - symbol['title'] = category['title'] + if 'scaleMaxDenom' not in symbol and category.scaleMaxDenom > 0: + symbol['scaleMaxDenom'] = category.scaleMaxDenom + if 'scaleMinDenom' not in symbol and category.scaleMinDenom > 0: + symbol['scaleMinDenom'] = category.scaleMinDenom + + symbol['expression'] = category.expression + if symbol['title'] != category.title: + symbol['title'] = category.title except (IndexError, KeyError): pass @@ -151,8 +156,10 @@ def responseComplete(self): @classmethod def _extract_categories( - cls, layer: QgsVectorLayer, show_feature_count: bool = False, project_path: str = "") -> dict: + cls, layer: QgsVectorLayer, show_feature_count: bool = False, project_path: str = "" + ) -> dict: """ Extract categories from the layer legend. """ + # TODO Annotations QGIS 3.22 [str, Category] renderer = layer.renderer() categories = {} for item in renderer.legendSymbolItems(): @@ -174,7 +181,7 @@ def _extract_categories( expression, result = renderer.legendKeyToExpression(item.ruleKey(), layer) if not result: Logger.warning( - f"The expression in the project {project_path}, layer {layer.name()} has not " + f"The expression in the project '{project_path}', layer '{layer.name()}' has not " f"been generated correctly, setting the expression to an empty string" ) expression = '' @@ -182,16 +189,16 @@ def _extract_categories( if item.label() in categories.keys(): Logger.warning( f"The label key '{item.label()}' is not unique, expect the legend to be broken in the project " - f"{project_path}, layer {layer.name()}." + f"'{project_path}', layer '{layer.name()}'." ) - categories[item.label()] = { - 'ruleKey': item.ruleKey(), - 'checked': renderer.legendSymbolItemChecked(item.ruleKey()), - 'parentRuleKey': item.parentRuleKey(), - 'scaleMaxDenom': item.scaleMaxDenom(), - 'scaleMinDenom': item.scaleMinDenom(), - 'expression': expression, - 'title': title, - } + categories[item.label()] = Category( + ruleKey=item.ruleKey(), + checked=renderer.legendSymbolItemChecked(item.ruleKey()), + parentRuleKey=item.parentRuleKey(), + scaleMaxDenom=item.scaleMaxDenom(), + scaleMinDenom=item.scaleMinDenom(), + expression=expression, + title=title, + ) return categories diff --git a/test/test_legend_without_server.py b/test/test_legend_without_server.py index 286e8ee0..58187d31 100644 --- a/test/test_legend_without_server.py +++ b/test/test_legend_without_server.py @@ -63,14 +63,14 @@ def test_duplicated_labels(self): self.assertEqual(3, len(list(result.keys()))) for symbol in result.values(): - self.assertGreaterEqual(len(symbol['ruleKey']), 1) - self.assertTrue(symbol['checked']) - self.assertGreaterEqual(len(symbol['parentRuleKey']), 1) - self.assertEqual(0, symbol['scaleMaxDenom']) - self.assertEqual(0, symbol['scaleMinDenom']) + self.assertGreaterEqual(len(symbol.ruleKey), 1) + self.assertTrue(symbol.checked) + self.assertGreaterEqual(len(symbol.parentRuleKey), 1) + self.assertEqual(0, symbol.scaleMaxDenom) + self.assertEqual(0, symbol.scaleMinDenom) if Qgis.QGIS_VERSION_INT >= 32800: # I'm not sure since when, just looking at CI results - self.assertEqual('TRUE', symbol['expression']) + self.assertEqual('TRUE', symbol.expression) else: - self.assertEqual('', symbol['expression']) - self.assertIn(symbol['title'], ('rule-1', 'same-label', 'rule-2')) + self.assertEqual('', symbol.expression) + self.assertIn(symbol.title, ('rule-1', 'same-label', 'rule-2'))