Coverage for gws-app/gws/plugin/ows_client/wms/flatlayer.py: 0%
97 statements
« prev ^ index » next coverage.py v7.15.4, created at 2026-08-24 12:46 +0200
« prev ^ index » next coverage.py v7.15.4, created at 2026-08-24 12:46 +0200
1from typing import Optional
3import gws
4import gws.base.layer
5import gws.base.legend
6import gws.base.model
7import gws.base.search
8import gws.base.template
9import gws.config.util
10import gws.base.metadata
11import gws.lib.crs
12import gws.gis.source
13import gws.gis.zoom
14import gws.lib.bounds
15import gws.lib.extent
17from . import provider
19gws.ext.new.layer('wmsflat')
22class Config(gws.base.layer.Config):
23 """Flat WMS layer."""
25 provider: Optional[provider.Config]
26 """WMS provider."""
27 sourceLayers: Optional[gws.gis.source.LayerFilter]
28 """Source layers to use."""
31class Object(gws.base.layer.image.Object):
32 serviceProvider: provider.Object
33 sourceLayers: list[gws.SourceLayer]
34 sourceCrs: gws.Crs
36 imageLayers: list[gws.SourceLayer]
37 searchLayers: list[gws.SourceLayer]
39 def configure(self):
40 self.configure_layer()
42 def configure_provider(self):
43 return gws.config.util.configure_service_provider_for(self, provider.Object)
45 def configure_sources(self):
46 if super().configure_sources():
47 return True
49 gws.u.require(self.serviceProvider, 'failed to configure service provider')
51 self.configure_source_layers()
52 if not self.sourceLayers:
53 raise gws.Error(f'layer {self!r}: no source layers found for {self.serviceProvider.url!r}')
55 self.imageLayers = gws.gis.source.filter_layers(self.sourceLayers, is_image=True)
56 self.searchLayers = gws.gis.source.filter_layers(self.sourceLayers, is_queryable=True)
58 self.sourceCrs = self.serviceProvider.forceCrs or gws.lib.crs.best_match(
59 self.mapCrs,
60 gws.gis.source.combined_crs_list(self.sourceLayers))
62 def configure_source_layers(self):
63 return gws.config.util.configure_source_layers_for(self, self.serviceProvider.sourceLayers)
65 def configure_models(self):
66 return gws.config.util.configure_models_for(self, with_default=True)
68 def create_model(self, cfg):
69 return self.create_child(
70 gws.ext.object.model,
71 cfg,
72 type='wms',
73 _defaultProvider=self.serviceProvider,
74 _defaultSourceLayers=self.sourceLayers
75 )
77 def configure_bounds(self):
78 if super().configure_bounds():
79 return True
80 self.bounds = gws.gis.source.combined_bounds(self.imageLayers, self.mapCrs) or self.mapCrs.bounds
81 return True
83 def configure_resolutions(self):
84 if super().configure_resolutions():
85 return True
86 self.resolutions = gws.gis.zoom.resolutions_from_source_layers(
87 self.sourceLayers, self.cfg('_parentResolutions'))
88 if self.resolutions:
89 return True
90 raise gws.Error(f'layer {self!r}: no matching resolutions')
92 def configure_grid(self):
93 if super().configure_grid():
94 return True
95 self.grid = gws.TileGrid(
96 origin=gws.Origin.nw,
97 tileSize=256,
98 bounds=self.bounds,
99 resolutions=self.resolutions)
100 return True
102 def configure_legend(self):
103 if super().configure_legend():
104 return True
105 urls = gws.u.compact(sl.legendUrl for sl in self.imageLayers)
106 if urls:
107 self.legend = self.create_child(gws.ext.object.legend, type='remote', urls=urls)
108 return True
110 def configure_metadata(self):
111 if super().configure_metadata():
112 return True
113 if len(self.sourceLayers) == 1:
114 self.metadata = self.sourceLayers[0].metadata
115 return True
117 def configure_search(self):
118 if super().configure_search():
119 return True
120 if self.searchLayers:
121 self.finders.append(self.create_finder(None))
122 return True
124 def create_finder(self, cfg):
125 return self.create_child(
126 gws.ext.object.finder,
127 cfg,
128 type='wms',
129 _defaultProvider=self.serviceProvider,
130 _defaultSourceLayers=self.searchLayers
131 )
133 ##
135 def render(self, lri):
136 return gws.base.layer.util.mpx_raster_render(self, lri)
138 def mapproxy_config(self, mc, options=None):
139 # NB reversed: see the note in plugin/ows_client/wms/provider.py
140 layers = reversed([sl.name for sl in self.imageLayers])
141 op = self.serviceProvider.get_operation(gws.OwsVerb.GetMap)
142 args = self.serviceProvider.prepare_operation(op)
144 req = gws.u.merge(
145 args.params,
146 transparent=True,
147 layers=','.join(layers),
148 url=args.url,
149 )
151 src = gws.u.compact({
152 'type': 'wms',
153 'supported_srs': [self.sourceCrs.epsg],
154 'concurrent_requests': self.serviceProvider.maxRequests,
155 'req': req,
156 'wms_opts': {
157 'version': self.serviceProvider.version,
158 }
159 })
161 if args.headers:
162 src['http'] = {'headers': args.headers}
164 source_uid = mc.source(src)
166 gws.base.layer.util.mapproxy_layer_config(self, mc, source_uid)