Skip to content

Commit

Permalink
Use namedTuple instead of dictionary, it is more Pythonic
Browse files Browse the repository at this point in the history
  • Loading branch information
Gustry committed Apr 4, 2024
1 parent f729a9d commit e589449
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 32 deletions.
55 changes: 31 additions & 24 deletions lizmap_server/get_legend_graphic.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -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

Expand All @@ -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():
Expand All @@ -174,24 +181,24 @@ 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 = ''

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
16 changes: 8 additions & 8 deletions test/test_legend_without_server.py
Original file line number Diff line number Diff line change
Expand Up @@ -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'))

0 comments on commit e589449

Please sign in to comment.