Coverage for gws-app/gws/plugin/ows_client/wmts/caps.py: 0%
56 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
1import gws
2import gws.base.ows.client
3import gws.gis.crs
4import gws.gis.source
5import gws.lib.uom as units
6import gws.lib.xmlx as xmlx
7import gws.base.ows.client.parseutil as u
10# http://portal.opengeospatial.org/files/?artifact_id=35326
13def parse(xml: str) -> gws.OwsCapabilities:
14 caps_el = xmlx.from_string(xml, compact_whitespace=True, remove_namespaces=True)
15 tms_lst = [_tile_matrix_set(el) for el in caps_el.findall('Contents/TileMatrixSet')]
16 tms_dct = {tms.uid: tms for tms in tms_lst}
17 sls = gws.gis.source.check_layers(
18 _layer(el, tms_dct) for el in caps_el.findall('Contents/Layer'))
19 return gws.OwsCapabilities(
20 tileMatrixSets=tms_lst,
21 metadata=u.service_metadata(caps_el),
22 operations=u.service_operations(caps_el),
23 sourceLayers=sls,
24 version=caps_el.get('version'))
27def _layer(layer_el: gws.XmlElement, tms_dct):
28 # <Layer>
29 # <ows:Title>...
30 # <Style>...
31 # <Format>...
32 # <TileMatrixSetLink>
33 # <TileMatrixSet>...
35 sl = gws.SourceLayer()
37 sl.metadata = u.element_metadata(layer_el)
38 sl.name = sl.metadata.get('name', '')
39 sl.title = sl.metadata.get('title', '')
41 sl.styles = [u.parse_style(e) for e in layer_el.findall('Style')]
42 sl.defaultStyle = u.default_style(sl.styles)
43 if sl.defaultStyle:
44 sl.legendUrl = sl.defaultStyle.legendUrl
46 sl.tileMatrixIds = [el.textof('TileMatrixSet') for el in layer_el.findall('TileMatrixSetLink')]
47 sl.tileMatrixSets = [tms_dct[tid] for tid in sl.tileMatrixIds]
49 extra_crsids = [tms.crs.srid for tms in sl.tileMatrixSets]
50 wgs_extent = u.wgs_extent(layer_el)
51 crs_list = u.supported_crs(layer_el, extra_crsids)
53 sl.supportedCrs = crs_list or [gws.gis.crs.WGS84]
54 sl.wgsExtent = wgs_extent or gws.gis.crs.WGS84.extent
56 sl.isImage = True
57 sl.isVisible = True
59 sl.imageFormat = layer_el.textof('Format')
61 sl.resourceUrls = {
62 e.get('resourceType'): e.get('template')
63 for e in layer_el.findall('ResourceURL')
64 }
66 return sl
69def _tile_matrix_set(tms_el: gws.XmlElement):
70 # <TileMatrixSet>
71 # <ows:Identifier>...
72 # <ows:SupportedCRS>...
73 # <TileMatrix>
74 # ...
76 tms = gws.TileMatrixSet()
78 tms.uid = tms_el.textof('Identifier')
79 tms.crs = gws.gis.crs.require(tms_el.textof('SupportedCRS'))
80 tms.matrices = sorted(
81 [_tile_matrix(e) for e in tms_el.findall('TileMatrix')],
82 key=lambda m: -m.scale)
84 return tms
87def _tile_matrix(tm_el: gws.XmlElement):
88 # <TileMatrix>
89 # <ows:Identifier>
90 # <ScaleDenominator>
91 # ...
93 tm = gws.TileMatrix()
94 tm.uid = tm_el.textof('Identifier')
95 tm.scale = u.to_float(tm_el.textof('ScaleDenominator'))
97 p = u.to_float_pair(tm_el.textof('TopLeftCorner'))
98 tm.x = p[0]
99 tm.y = p[1]
101 tm.width = u.to_int(tm_el.textof('MatrixWidth'))
102 tm.height = u.to_int(tm_el.textof('MatrixHeight'))
104 tm.tileWidth = u.to_int(tm_el.textof('TileWidth'))
105 tm.tileHeight = u.to_int(tm_el.textof('TileHeight'))
107 tm.extent = _extent_for_matrix(tm)
109 return tm
112# compute a bbox for a TileMatrix
113# see http://portal.opengeospatial.org/files/?artifact_id=35326 page 8
115def _extent_for_matrix(m: gws.TileMatrix):
116 res = units.scale_to_res(m.scale)
118 return [
119 m.x,
120 m.y - res * m.height * m.tileHeight,
121 m.x + res * m.width * m.tileWidth,
122 m.y,
123 ]