Coverage for gws-app/gws/plugin/qgis/legend.py: 0%
39 statements
« prev ^ index » next coverage.py v7.16.2, created at 2026-10-05 13:35 +0200
« prev ^ index » next coverage.py v7.16.2, created at 2026-10-05 13:35 +0200
1"""QGIS legend."""
3from typing import Optional
5import gws
6import gws.base.legend
7import gws.config.util
8import gws.lib.mime
9import gws.gis.source
10import gws.lib.image
13from . import provider
16# see https://docs.qgis.org/3.22/de/docs/server_manual/services/wms.html#getlegendgraphics
18_DEFAULT_LEGEND_PARAMS = {
19 'BOXSPACE': 2,
20 'ICONLABELSPACE': 2,
21 'ITEMFONTBOLD': False,
22 'ITEMFONTCOLOR': '#000000',
23 'ITEMFONTFAMILY': 'DejaVuSans',
24 'ITEMFONTITALIC': False,
25 'ITEMFONTSIZE': 9,
26 'LAYERFONTBOLD': True,
27 'LAYERFONTCOLOR': '#000000',
28 'LAYERFONTFAMILY': 'DejaVuSans',
29 'LAYERFONTITALIC': False,
30 'LAYERFONTSIZE': 9,
31 'LAYERSPACE': 4,
32 'LAYERTITLE': True,
33 'LAYERTITLESPACE': 4,
34 'RULELABEL': True,
35 'SYMBOLHEIGHT': 8,
36 'SYMBOLSPACE': 2,
37 'SYMBOLWIDTH': 8,
38}
41@gws.ext.config.legend('qgis')
42class Config(gws.base.legend.Config):
43 """Legend for QGIS project layers, rendered by QGIS Server."""
45 provider: Optional[provider.Config]
46 """QGIS project the legend is rendered from."""
47 sourceLayers: Optional[gws.gis.source.LayerFilter]
48 """Source layers to include in the legend."""
51@gws.ext.object.legend('qgis')
52class Object(gws.base.legend.Object):
53 """Legend rendered by QGIS Server with GetLegendGraphic."""
55 provider: provider.Object
56 """QGIS provider."""
57 sourceLayers: list[gws.SourceLayer]
58 """Source layers in the legend."""
59 params: dict
60 """GetLegendGraphic request parameters."""
62 def configure(self):
63 self.configure_provider()
64 self.configure_sources()
65 self.configure_params()
67 def configure_provider(self):
68 """Set the QGIS provider.
70 Returns:
71 ``True`` if a provider was set.
73 Raises:
74 ``gws.Error``: If no provider is found.
75 """
76 return gws.config.util.configure_provider_for(self, provider.Object)
78 def configure_sources(self):
79 """Select the source layers of the legend.
81 Raises:
82 ``gws.Error``: If the provider is not set.
83 """
84 gws.u.require(self.provider, 'failed to configure service provider')
85 self.configure_source_layers()
87 def configure_source_layers(self):
88 """Select the source layers from the provider layers.
90 Returns:
91 Always ``True``.
92 """
93 return gws.config.util.configure_source_layers_for(self, self.provider.sourceLayers)
95 def configure_params(self):
96 """Build the GetLegendGraphic parameters.
98 Configured ``options`` override the default legend parameters.
99 """
100 defaults = dict(
101 DPI=96,
102 FORMAT=gws.lib.mime.PNG,
103 # qgis legends are rendered bottom-up (rightmost first)
104 # we need the straight order (leftmost first), like in the config
105 LAYER=','.join(sl.name for sl in reversed(self.sourceLayers)),
106 REQUEST=gws.OwsVerb.GetLegendGraphic,
107 STYLE='',
108 TRANSPARENT=True,
109 )
110 opts = gws.u.to_upper_dict(self.cfg('options', default={}))
111 self.params = self.provider.server_params(gws.u.merge(_DEFAULT_LEGEND_PARAMS, defaults, opts))
113 ##
115 def render(self, args=None):
116 def _get():
117 return self.provider.call_server(self.params).content
119 content = gws.u.get_cached_object(
120 f'legend_{gws.u.sha256([self.provider.url, self.params])}',
121 self.cacheMaxAge,
122 _get,
123 )
124 img = gws.lib.image.from_bytes(content)
125 return gws.LegendRenderOutput(image=img, size=img.size())