Coverage for gws-app/gws/plugin/raster_layer/layer.py: 95%

41 statements  

« prev     ^ index     » next       coverage.py v7.16.2, created at 2026-10-05 13:35 +0200

1"""The ``raster`` layer.""" 

2 

3from typing import Optional 

4 

5import gws 

6import gws.base.layer 

7import gws.lib.shape 

8import gws.config.util 

9import gws.lib.bounds 

10import gws.lib.extent 

11 

12from . import grabber, provider 

13 

14 

15@gws.ext.config.layer('raster') 

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

17 """Layer that shows georeferenced image files, rendered with MapServer.""" 

18 

19 provider: provider.Config 

20 """Image files the layer is built from.""" 

21 processing: Optional[list[str]] 

22 """MapServer processing directives.""" 

23 transparentColor: Optional[str] 

24 """Color to treat as transparent in the layer.""" 

25 sldPath: Optional[gws.FilePath] 

26 """Path to SLD file for styling the layer.""" 

27 sldName: Optional[str] 

28 """Name of an SLD NamedLayer to apply.""" 

29 

30 

31@gws.ext.object.layer('raster') 

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

33 """Image layer that shows georeferenced image files, rendered with MapServer.""" 

34 

35 provider: provider.Object 

36 """Image set provider.""" 

37 msOptions: gws.MapServerLayerOptions 

38 """MapServer layer options.""" 

39 entries: list[provider.ImageEntry] 

40 """Images of the layer.""" 

41 

42 def configure(self): 

43 self.msOptions = gws.MapServerLayerOptions( 

44 type=gws.MapServerLayerType.raster, 

45 processing=self.cfg('processing', default=[]), 

46 transparentColor=self.cfg('transparentColor'), 

47 sldPath=self.cfg('sldPath'), 

48 sldName=self.cfg('sldName'), 

49 ) 

50 self.configure_layer() 

51 

52 def create_cache_name(self, cache): 

53 return gws.u.sha256([ 

54 self.provider.cache_hash(), 

55 [e.path for e in self.entries], 

56 self.cfg('processing', default=[]), 

57 self.cfg('transparentColor') or '', 

58 self.cfg('sldPath') or '', 

59 self.cfg('sldName') or '', 

60 vars(self.imageFormat), 

61 list(self.wgsExtent), 

62 cache.requestBuffer, 

63 cache.requestTiles, 

64 ])[: gws.base.layer.image.CACHE_NAME_LENGTH] 

65 

66 def create_grabber(self, opts): 

67 return grabber.Object(opts, msOptions=self.msOptions) 

68 

69 def configure_provider(self): 

70 gws.config.util.configure_provider_for(self, provider.Object) 

71 

72 default_crs = self.provider.crs or self.mapCrs 

73 self.entries = self.provider.enumerate_images(default_crs) 

74 if not self.entries: 

75 raise gws.ConfigurationError('no images found') 

76 

77 self.msOptions.crs = self.entries[0].bounds.crs 

78 self.msOptions.tileIndex = self.provider.make_tile_index( 

79 self.entries, 

80 file_name=f'raster_layer_{self.uid}', 

81 ) 

82 # self.msOptions.path = self.entries[0].path 

83 

84 def configure_extent(self): 

85 if super().configure_extent(): 

86 return True 

87 b = gws.lib.bounds.union([e.bounds for e in self.entries]) 

88 self.wgsExtent = gws.lib.extent.transform_to_wgs(b.extent, b.crs) 

89 return True