Coverage for gws-app/gws/plugin/qgis/layer.py: 0%
84 statements
« prev ^ index » next coverage.py v7.11.0, created at 2025-10-16 22:59 +0200
« prev ^ index » next coverage.py v7.11.0, created at 2025-10-16 22:59 +0200
1"""qgis layer.
3"qgis" layers display QGIS layers as WebSuite layers, keeping the tree structure.
4"""
6from typing import Optional, cast
8import gws
9import gws.base.layer
10import gws.config.util
12from . import provider, flatlayer
14gws.ext.new.layer('qgis')
17class Config(gws.base.layer.Config, gws.base.layer.tree.Config):
18 """QGIS Tree layer configuration."""
20 provider: Optional[provider.Config]
21 """Qgis provider."""
22 compositeRender: bool = False
23 """If true, the layer will be rendered as a single image. (added in 8.2)"""
24 sqlFilters: Optional[dict]
25 """Per-layer sql filters. (added in 8.2)"""
28class Object(gws.base.layer.group.Object):
29 serviceProvider: provider.Object
30 compositeRender: bool = False
31 sqlFilters: dict
33 def configure(self):
34 self.compositeRender = self.cfg('compositeRender', default=False)
35 self.sqlFilters = self.cfg('sqlFilters', default={})
37 def configure_group(self):
38 gws.config.util.configure_service_provider_for(self, provider.Object)
40 configs = gws.base.layer.tree.layer_configs_from_layer(
41 self,
42 self.serviceProvider.sourceLayers,
43 self.serviceProvider.leaf_config,
44 )
46 self.configure_group_layers(configs)
48 def configure_metadata(self):
49 if super().configure_metadata():
50 return True
51 self.metadata = self.serviceProvider.metadata
52 return True
54 def post_configure(self):
55 if self.compositeRender:
56 self.canRenderBox = True
58 def props(self, user):
59 p = super().props(user)
60 if not self.compositeRender:
61 return p
63 def _to_leaf(la):
64 pla = la.props(user)
65 if not pla:
66 return pla
67 if pla.get('type') == 'group':
68 pla['layers'] = [_to_leaf(la) for la in pla['layers']]
69 elif pla.get('type') == 'box':
70 pla['type'] = 'compositeLeaf'
71 return pla
73 return gws.u.merge(
74 p,
75 type='compositeTree',
76 layers=[_to_leaf(la) for la in p['layers']],
77 )
79 def render(self, lri):
80 if not self.compositeRender:
81 return super().render(lri)
83 if lri.type != gws.LayerRenderInputType.box:
84 return
86 params = self.get_render_params(lri)
87 if not params:
88 return
90 def get_box(bounds, width, height):
91 return self.serviceProvider.get_map(self, bounds, width, height, params)
93 content = gws.base.layer.util.generic_render_box(self, lri, get_box)
94 return gws.LayerRenderOutput(content=content)
96 def get_render_params(self, lri: gws.LayerRenderInput) -> Optional[dict]:
97 leaves = dict(lri.extraParams or {}).get('compositeLayerUids', [])
98 if not leaves:
99 return
101 layers = []
102 filters = []
104 for la in self.descendants():
105 if la.uid not in leaves:
106 continue
107 if la.extType != 'qgisflat':
108 gws.log.debug(f'skipping {la.uid=} {la.extType=}')
109 continue
110 p = cast(flatlayer.Object, la).get_render_params(lri, self.sqlFilters)
111 if not p:
112 gws.log.debug(f'skipping {la.uid=} no params')
113 layers.extend(reversed(p.get('LAYERS', [])))
114 f = p.get('FILTER')
115 if f:
116 filters.append(f)
118 if not layers:
119 gws.log.debug(f'no layers')
121 params = {}
122 params['LAYERS'] = list(reversed(layers))
123 if filters:
124 params['FILTER'] = ';'.join(filters)
126 return params