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

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 

8 

9 

10# http://portal.opengeospatial.org/files/?artifact_id=35326 

11 

12 

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')) 

25 

26 

27def _layer(layer_el: gws.XmlElement, tms_dct): 

28 # <Layer> 

29 # <ows:Title>... 

30 # <Style>... 

31 # <Format>... 

32 # <TileMatrixSetLink> 

33 # <TileMatrixSet>... 

34 

35 sl = gws.SourceLayer() 

36 

37 sl.metadata = u.element_metadata(layer_el) 

38 sl.name = sl.metadata.get('name', '') 

39 sl.title = sl.metadata.get('title', '') 

40 

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 

45 

46 sl.tileMatrixIds = [el.textof('TileMatrixSet') for el in layer_el.findall('TileMatrixSetLink')] 

47 sl.tileMatrixSets = [tms_dct[tid] for tid in sl.tileMatrixIds] 

48 

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) 

52 

53 sl.supportedCrs = crs_list or [gws.gis.crs.WGS84] 

54 sl.wgsExtent = wgs_extent or gws.gis.crs.WGS84.extent 

55 

56 sl.isImage = True 

57 sl.isVisible = True 

58 

59 sl.imageFormat = layer_el.textof('Format') 

60 

61 sl.resourceUrls = { 

62 e.get('resourceType'): e.get('template') 

63 for e in layer_el.findall('ResourceURL') 

64 } 

65 

66 return sl 

67 

68 

69def _tile_matrix_set(tms_el: gws.XmlElement): 

70 # <TileMatrixSet> 

71 # <ows:Identifier>... 

72 # <ows:SupportedCRS>... 

73 # <TileMatrix> 

74 # ... 

75 

76 tms = gws.TileMatrixSet() 

77 

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) 

83 

84 return tms 

85 

86 

87def _tile_matrix(tm_el: gws.XmlElement): 

88 # <TileMatrix> 

89 # <ows:Identifier> 

90 # <ScaleDenominator> 

91 # ... 

92 

93 tm = gws.TileMatrix() 

94 tm.uid = tm_el.textof('Identifier') 

95 tm.scale = u.to_float(tm_el.textof('ScaleDenominator')) 

96 

97 p = u.to_float_pair(tm_el.textof('TopLeftCorner')) 

98 tm.x = p[0] 

99 tm.y = p[1] 

100 

101 tm.width = u.to_int(tm_el.textof('MatrixWidth')) 

102 tm.height = u.to_int(tm_el.textof('MatrixHeight')) 

103 

104 tm.tileWidth = u.to_int(tm_el.textof('TileWidth')) 

105 tm.tileHeight = u.to_int(tm_el.textof('TileHeight')) 

106 

107 tm.extent = _extent_for_matrix(tm) 

108 

109 return tm 

110 

111 

112# compute a bbox for a TileMatrix 

113# see http://portal.opengeospatial.org/files/?artifact_id=35326 page 8 

114 

115def _extent_for_matrix(m: gws.TileMatrix): 

116 res = units.scale_to_res(m.scale) 

117 

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 ]