Coverage for gws-app/gws/plugin/ows_client/wms/flatlayer.py: 0%
96 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.base.legend
6import gws.base.model
7import gws.base.search
8import gws.base.template
9import gws.config.util
10import gws.lib.metadata
11import gws.gis.crs
12import gws.gis.source
13import gws.gis.zoom
14import gws.gis.bounds
15import gws.gis.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 self.configure_source_layers()
50 if not self.sourceLayers:
51 raise gws.Error(f'layer {self!r}: no source layers found for {self.serviceProvider.url!r}')
53 self.imageLayers = gws.gis.source.filter_layers(self.sourceLayers, is_image=True)
54 self.searchLayers = gws.gis.source.filter_layers(self.sourceLayers, is_queryable=True)
56 self.sourceCrs = self.serviceProvider.forceCrs or gws.gis.crs.best_match(
57 self.mapCrs,
58 gws.gis.source.combined_crs_list(self.sourceLayers))
60 def configure_source_layers(self):
61 return gws.config.util.configure_source_layers_for(self, self.serviceProvider.sourceLayers)
63 def configure_models(self):
64 return gws.config.util.configure_models_for(self, with_default=True)
66 def create_model(self, cfg):
67 return self.create_child(
68 gws.ext.object.model,
69 cfg,
70 type='wms',
71 _defaultProvider=self.serviceProvider,
72 _defaultSourceLayers=self.sourceLayers
73 )
75 def configure_bounds(self):
76 if super().configure_bounds():
77 return True
78 self.bounds = gws.gis.source.combined_bounds(self.imageLayers, self.mapCrs) or self.mapCrs.bounds
79 return True
81 def configure_resolutions(self):
82 if super().configure_resolutions():
83 return True
84 self.resolutions = gws.gis.zoom.resolutions_from_source_layers(
85 self.sourceLayers, self.cfg('_parentResolutions'))
86 if self.resolutions:
87 return True
88 raise gws.Error(f'layer {self!r}: no matching resolutions')
90 def configure_grid(self):
91 if super().configure_grid():
92 return True
93 self.grid = gws.TileGrid(
94 origin=gws.Origin.nw,
95 tileSize=256,
96 bounds=self.bounds,
97 resolutions=self.resolutions)
98 return True
100 def configure_legend(self):
101 if super().configure_legend():
102 return True
103 urls = gws.u.compact(sl.legendUrl for sl in self.imageLayers)
104 if urls:
105 self.legend = self.create_child(gws.ext.object.legend, type='remote', urls=urls)
106 return True
108 def configure_metadata(self):
109 if super().configure_metadata():
110 return True
111 if len(self.sourceLayers) == 1:
112 self.metadata = self.sourceLayers[0].metadata
113 return True
115 def configure_search(self):
116 if super().configure_search():
117 return True
118 if self.searchLayers:
119 self.finders.append(self.create_finder(None))
120 return True
122 def create_finder(self, cfg):
123 return self.create_child(
124 gws.ext.object.finder,
125 cfg,
126 type='wms',
127 _defaultProvider=self.serviceProvider,
128 _defaultSourceLayers=self.searchLayers
129 )
131 ##
133 def render(self, lri):
134 return gws.base.layer.util.mpx_raster_render(self, lri)
136 def mapproxy_config(self, mc, options=None):
137 # NB reversed: see the note in plugin/ows_client/wms/provider.py
138 layers = reversed([sl.name for sl in self.imageLayers])
139 op = self.serviceProvider.get_operation(gws.OwsVerb.GetMap)
140 args = self.serviceProvider.prepare_operation(op)
142 req = gws.u.merge(
143 args.params,
144 transparent=True,
145 layers=','.join(layers),
146 url=args.url,
147 )
149 src = gws.u.compact({
150 'type': 'wms',
151 'supported_srs': [self.sourceCrs.epsg],
152 'concurrent_requests': self.serviceProvider.maxRequests,
153 'req': req,
154 'wms_opts': {
155 'version': self.serviceProvider.version,
156 }
157 })
159 if args.headers:
160 src['http'] = {'headers': args.headers}
162 source_uid = mc.source(src)
164 gws.base.layer.util.mapproxy_layer_config(self, mc, source_uid)