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

1from typing import Optional 

2 

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 

13 

14from . import provider 

15 

16gws.ext.new.layer('qgisflat') 

17 

18 

19class Config(gws.base.layer.Config): 

20 """Flat Qgis layer""" 

21 

22 provider: Optional[provider.Config] 

23 """qgis provider""" 

24 sourceLayers: Optional[gws.gis.source.LayerFilter] 

25 """source layers to use""" 

26 

27 

28class Object(gws.base.layer.image.Object): 

29 serviceProvider: provider.Object 

30 sqlFilters: dict 

31 imageLayers: list[gws.SourceLayer] 

32 searchLayers: list[gws.SourceLayer] 

33 

34 def configure(self): 

35 self.sqlFilters = self.cfg('sqlFilters', default={}) 

36 self.configure_layer() 

37 

38 def configure_provider(self): 

39 return gws.config.util.configure_service_provider_for(self, provider.Object) 

40 

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) 

47 

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 ) 

55 

56 def configure_models(self): 

57 return gws.config.util.configure_models_for(self, with_default=True) 

58 

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 ) 

67 

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 

73 

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 

81 

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

88 

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 

98 

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 

114 

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 

121 

122 def configure_templates(self): 

123 return gws.config.util.configure_templates_for(self) 

124 

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 

131 

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 ) 

140 

141 ## 

142 

143 def render(self, lri): 

144 if lri.type != gws.LayerRenderInputType.box: 

145 return 

146 

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) 

151 

152 layers = [] 

153 filters = [] 

154 

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) 

163 

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) 

168 

169 def get_box(bounds, width, height): 

170 return self.serviceProvider.get_map(self, bounds, width, height, params) 

171 

172 content = gws.base.layer.util.generic_render_box(self, lri, get_box) 

173 return gws.LayerRenderOutput(content=content)