Coverage for gws-app/gws/base/legend/core.py: 94%
34 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"""Base legend object."""
3from typing import Optional
5import gws
6import gws.lib.image
9class Props(gws.Props):
10 type: str
13class Config(gws.ConfigWithAccess):
14 """Layer legend confuguration."""
16 cacheMaxAge: gws.Duration = '1d'
17 """How long legend images from remote sources are cached."""
18 options: Optional[dict]
19 """Provider-specific legend options."""
22class Object(gws.Legend):
23 """Base legend object.
25 Reads the common ``cacheMaxAge`` and ``options`` settings. Subclasses
26 implement ``render`` and can stack several legend images into one with
27 ``combine_outputs``.
28 """
30 cacheMaxAge: int
31 """How long legend images from remote sources are cached, in seconds."""
32 options: dict
33 """Provider-specific legend options."""
35 def configure(self):
36 self.options = self.cfg('options', default={})
37 self.cacheMaxAge = self.cfg('cacheMaxAge', default=3600 * 24)
40def combine_outputs(lro_list: list[gws.LegendRenderOutput], options: dict = None) -> Optional[gws.LegendRenderOutput]:
41 """Combine several legend outputs into one image.
43 The images are stacked vertically, aligned to the left. Outputs without an
44 image are skipped.
46 Args:
47 lro_list: Legend outputs to combine; ``None`` entries are allowed.
48 options: Legend options, currently unused.
50 Returns:
51 A new legend output with the combined image, or ``None`` if there are
52 no images.
53 """
54 imgs = []
55 for lro in lro_list:
56 if lro and lro.image:
57 imgs.append(lro.image)
58 if not imgs:
59 return
60 img = _combine_images(imgs, options)
61 return gws.LegendRenderOutput(image=img, size=img.size())
64def _combine_images(images: list[gws.Image], options: dict = None):
65 """Combine images into one."""
66 return _combine_vertically(images)
69def _combine_vertically(images: list[gws.Image]):
70 """Stack images vertically on a transparent canvas."""
71 ws = [img.size()[0] for img in images]
72 hs = [img.size()[1] for img in images]
74 comp = gws.lib.image.from_size((max(ws), sum(hs)))
75 y = 0
76 for img in images:
77 comp.paste(img, (0, y))
78 y += img.size()[1]
80 return comp