Coverage for gws-app/gws/base/map/core.py: 0%

68 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.gis.crs 

6import gws.gis.bounds 

7import gws.gis.extent 

8import gws.gis.zoom 

9 

10gws.ext.new.map('default') 

11 

12 

13class Config(gws.Config): 

14 """Map configuration""" 

15 

16 center: Optional[gws.Point] 

17 """map center""" 

18 coordinatePrecision: Optional[int] 

19 """precision for coordinates""" 

20 crs: Optional[gws.CrsName] = 'EPSG:3857' 

21 """crs for this map""" 

22 extent: Optional[gws.Extent] 

23 """map extent""" 

24 extentBuffer: Optional[int] 

25 """extent buffer""" 

26 layers: list[gws.ext.config.layer] 

27 """collection of layers for this map""" 

28 title: str = '' 

29 """map title""" 

30 wrapX: bool = False 

31 """wrap the world horizontally""" 

32 zoom: Optional[gws.gis.zoom.Config] 

33 """map scales and resolutions""" 

34 

35 

36class Props(gws.Data): 

37 crs: str 

38 crsDef: Optional[str] 

39 coordinatePrecision: int 

40 extent: gws.Extent 

41 center: gws.Point 

42 initResolution: float 

43 rootLayer: gws.base.layer.Props 

44 resolutions: list[float] 

45 title: str = '' 

46 wrapX: bool 

47 

48 

49class _RootLayer(gws.base.layer.group.Object): 

50 parent: 'Object' 

51 

52 

53class Object(gws.Map): 

54 wrapX: bool 

55 

56 def configure(self): 

57 self.title = self.cfg('title') or self.cfg('_defaultTitle') or '' 

58 

59 p = self.cfg('crs') 

60 crs = gws.gis.crs.require(p) if p else gws.gis.crs.WEBMERCATOR 

61 

62 p = self.cfg('extent') 

63 if p: 

64 self.bounds = gws.Bounds( 

65 crs=crs, 

66 extent=gws.gis.extent.buffer(gws.gis.extent.from_list(p), self.cfg('extentBuffer') or 0) 

67 ) 

68 else: 

69 self.bounds = gws.Bounds(crs=crs, extent=crs.extent) 

70 

71 self.center = self.cfg('center') or gws.gis.extent.center(self.bounds.extent) 

72 self.wgsExtent = gws.gis.extent.transform_to_wgs(self.bounds.extent, self.bounds.crs) 

73 self.wrapX = self.cfg('wrapX', default=False) 

74 

75 p = self.cfg('zoom') 

76 if p: 

77 self.resolutions = gws.gis.zoom.resolutions_from_config(p) 

78 self.initResolution = gws.gis.zoom.init_resolution(p, self.resolutions) 

79 else: 

80 self.resolutions = gws.gis.zoom.OSM_RESOLUTIONS 

81 self.initResolution = self.resolutions[len(self.resolutions) >> 1] 

82 

83 p = self.cfg('coordinatePrecision') 

84 if p: 

85 self.coordinatePrecision = p 

86 else: 

87 self.coordinatePrecision = (2 if self.bounds.crs.uom == gws.Uom.m else 7) 

88 

89 self.rootLayer = self.create_child( 

90 gws.ext.object.layer, 

91 type='group', 

92 title=self.title, 

93 layers=self.cfg('layers'), 

94 _parentBounds=self.bounds, 

95 _parentResolutions=self.resolutions, 

96 ) 

97 

98 if not self.rootLayer: 

99 raise gws.Error(f'missing or invalid root layer in {self!r}') 

100 

101 def props(self, user): 

102 return gws.Data( 

103 crs=self.bounds.crs.epsg, 

104 crsDef=self.bounds.crs.proj4text, 

105 coordinatePrecision=self.coordinatePrecision, 

106 extent=self.bounds.extent, 

107 center=self.center, 

108 initResolution=self.initResolution, 

109 rootLayer=self.rootLayer, 

110 resolutions=sorted(self.resolutions, reverse=True), 

111 title=self.title, 

112 wrapX=self.wrapX, 

113 )