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

52 statements  

« prev     ^ index     » next       coverage.py v7.15.4, created at 2026-08-24 12:46 +0200

1"""Raster image layer.""" 

2 

3from typing import Optional 

4 

5import gws 

6import gws.base.layer 

7import gws.base.shape 

8import gws.config.util 

9import gws.lib.gdalx 

10import gws.lib.mapserver 

11import gws.gis.zoom 

12import gws.lib.bounds 

13import gws.lib.crs 

14import gws.lib.osx 

15 

16from . import provider 

17 

18gws.ext.new.layer('raster') 

19 

20 

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

22 """Raster layer""" 

23 

24 provider: provider.Config 

25 """Raster provider""" 

26 processing: Optional[list[str]] 

27 """Processing directives.""" 

28 transparentColor: Optional[str] 

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

30 sldPath: Optional[gws.FilePath] 

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

32 sldName: Optional[str] 

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

34 

35 

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

37 serviceProvider: provider.Object 

38 entries: list[provider.ImageEntry] 

39 

40 def configure(self): 

41 self.msOptions = gws.MapServerLayerOptions( 

42 type=gws.MapServerLayerType.raster, 

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

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

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

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

47 ) 

48 self.configure_layer() 

49 

50 def configure_provider(self): 

51 gws.config.util.configure_service_provider_for(self, provider.Object) 

52 

53 default_crs = self.serviceProvider.crs or self.parentBounds.crs 

54 self.entries = self.serviceProvider.enumerate_images(default_crs) 

55 if not self.entries: 

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

57 

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

59 self.msOptions.tileIndex = self.serviceProvider.make_tile_index( 

60 self.entries, 

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

62 ) 

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

64 

65 def configure_bounds(self): 

66 if super().configure_bounds(): 

67 return True 

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

69 self.bounds = gws.lib.bounds.transform(b, self.parentBounds.crs) 

70 return True 

71 

72 def configure_grid(self): 

73 p = self.cfg('grid') or gws.base.layer.GridConfig() 

74 

75 self.grid = gws.TileGrid( 

76 origin=p.origin or gws.Origin.nw, 

77 tileSize=p.tileSize or 256, 

78 bounds=self.bounds, 

79 ) 

80 

81 if p.resolutions: 

82 self.grid.resolutions = p.resolutions 

83 else: 

84 self.grid.resolutions = gws.gis.zoom.resolutions_from_bounds(self.grid.bounds, self.grid.tileSize) 

85 

86 def render(self, lri): 

87 return gws.lib.mapserver.util.raster_render(self, lri)