Coverage for gws-app/gws/plugin/qgis/flatlayer.py: 0%
110 statements
« prev ^ index » next coverage.py v7.8.0, created at 2025-04-17 01:37 +0200
« prev ^ index » next coverage.py v7.8.0, created at 2025-04-17 01:37 +0200
1from typing import Optional
3import gws
4import gws.base.layer
5import gws.config.util
6import gws.gis.crs
7import gws.gis.bounds
8import gws.gis.extent
9import gws.gis.source
10import gws.gis.zoom
11import gws.lib.metadata
12import gws.lib.osx
14from . import provider
16gws.ext.new.layer('qgisflat')
19class Config(gws.base.layer.Config):
20 """Flat Qgis layer"""
22 provider: Optional[provider.Config]
23 """qgis provider"""
24 sourceLayers: Optional[gws.gis.source.LayerFilter]
25 """source layers to use"""
28class Object(gws.base.layer.image.Object):
29 serviceProvider: provider.Object
30 sqlFilters: dict
31 imageLayers: list[gws.SourceLayer]
32 searchLayers: list[gws.SourceLayer]
34 def configure(self):
35 self.sqlFilters = self.cfg('sqlFilters', default={})
36 self.configure_layer()
38 def configure_provider(self):
39 return gws.config.util.configure_service_provider_for(self, provider.Object)
41 def configure_sources(self):
42 if super().configure_sources():
43 return True
44 self.configure_source_layers()
45 self.imageLayers = gws.gis.source.filter_layers(self.sourceLayers, is_image=True)
46 self.searchLayers = gws.gis.source.filter_layers(self.sourceLayers, is_queryable=True)
48 def configure_source_layers(self):
49 return gws.config.util.configure_source_layers_for(
50 self,
51 self.serviceProvider.sourceLayers,
52 is_image=True,
53 is_visible=True
54 )
56 def configure_models(self):
57 return gws.config.util.configure_models_for(self, with_default=True)
59 def create_model(self, cfg):
60 return self.create_child(
61 gws.ext.object.model,
62 cfg,
63 type='qgis',
64 _defaultProvider=self.serviceProvider,
65 _defaultSourceLayers=self.searchLayers
66 )
68 def configure_bounds(self):
69 if super().configure_bounds():
70 return True
71 self.bounds = gws.gis.bounds.transform(self.serviceProvider.bounds, self.mapCrs)
72 return True
74 def configure_zoom_bounds(self):
75 if super().configure_zoom_bounds():
76 return True
77 b = gws.gis.source.combined_bounds(self.sourceLayers, self.mapCrs)
78 if b:
79 self.zoomBounds = b
80 return True
82 def configure_resolutions(self):
83 if super().configure_resolutions():
84 return True
85 self.resolutions = gws.gis.zoom.resolutions_from_source_layers(self.sourceLayers, self.cfg('_parentResolutions'))
86 if not self.resolutions:
87 raise gws.Error(f'layer {self.uid!r}: no matching resolutions')
89 def configure_grid(self):
90 if super().configure_grid():
91 return True
92 self.grid = gws.TileGrid(
93 origin=gws.Origin.nw,
94 tileSize=256,
95 bounds=self.bounds,
96 resolutions=self.resolutions)
97 return True
99 def configure_legend(self):
100 # cannot use super() here, because the config must be extended with defaults
101 if not self.cfg('withLegend'):
102 return True
103 cc = self.cfg('legend')
104 options = gws.u.merge(self.serviceProvider.defaultLegendOptions, cc.options if cc else {})
105 self.legend = self.create_child(
106 gws.ext.object.legend,
107 cc,
108 type='qgis',
109 options=options,
110 _defaultProvider=self.serviceProvider,
111 _defaultSourceLayers=self.imageLayers,
112 )
113 return True
115 def configure_metadata(self):
116 if super().configure_metadata():
117 return True
118 if len(self.sourceLayers) == 1:
119 self.metadata = self.sourceLayers[0].metadata
120 return True
122 def configure_templates(self):
123 return gws.config.util.configure_templates_for(self)
125 def configure_search(self):
126 if super().configure_search():
127 return True
128 if self.searchLayers:
129 self.finders.append(self.create_finder(None))
130 return True
132 def create_finder(self, cfg):
133 return self.create_child(
134 gws.ext.object.finder,
135 cfg,
136 type='qgis',
137 _defaultProvider=self.serviceProvider,
138 _defaultSourceLayers=self.searchLayers
139 )
141 ##
143 def render(self, lri):
144 if lri.type != gws.LayerRenderInputType.box:
145 return
147 params = dict(lri.extraParams or {})
148 all_names = [sl.name for sl in self.imageLayers]
149 req_names = params.pop('layers', all_names)
150 req_filters = params.pop('filters', self.sqlFilters)
152 layers = []
153 filters = []
155 for name in req_names:
156 if name not in all_names:
157 gws.log.warning(f'invalid layer name {name!r}')
158 continue
159 layers.append(name)
160 flt = req_filters.get(name) or req_filters.get('*')
161 if flt:
162 filters.append(name + ': ' + flt)
164 # NB reversed: see the note in plugin/ows_client/wms/provider.py
165 params['LAYERS'] = list(reversed(layers))
166 if filters:
167 params['FILTER'] = ';'.join(filters)
169 def get_box(bounds, width, height):
170 return self.serviceProvider.get_map(self, bounds, width, height, params)
172 content = gws.base.layer.util.generic_render_box(self, lri, get_box)
173 return gws.LayerRenderOutput(content=content)