Coverage for gws-app/gws/base/layer/__init__.py: 100%

2 statements  

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

1"""Base classes and utilities for map layers. 

2 

3A layer is a node in the layer tree of a map. It knows its extent, the 

4resolutions it is visible at, its legend, metadata, templates, models and 

5search providers, and it can render itself as a box image, as tiles or as an 

6SVG fragment. Concrete layer types (QGIS, WMS, WFS, tile services, database 

7tables and so on) live in plugins and subclass the base classes here. 

8 

9Submodules: 

10 

11- ``core``: the base ``Object`` with the common ``Config`` and ``Props``. It 

12 defines the configuration protocol ``configure_layer``, which calls a fixed 

13 sequence of ``configure_*`` steps (provider, sources, group, models, extent, 

14 bounds, zoom bounds, resolutions, legend, metadata, templates, search, OWS). 

15 Each step returns ``True`` when it has set its value, so a subclass can 

16 override a step, call ``super()`` first and fill in a default only if the 

17 base step did nothing. 

18- ``group``: the ``group`` layer type, which holds child layers and derives 

19 its extent, resolutions, legend and render capabilities from them. Unless 

20 configured explicitly, the extent, zoom bounds and resolutions are the union 

21 of those of the children, and the legend is a ``combined`` legend of the 

22 children that have one. The group can render boxes, tiles or SVG if any 

23 child can, and is searchable if any child is. 

24- ``image``: base class for raster layers. It creates one grabber 

25 (see ``gws.base.grabber``) per CRS supported by the application and renders 

26 boxes and tiles through the grabber for the target CRS. Subclasses provide 

27 ``create_grabber`` and ``create_cache_name``. Rotated boxes are rendered as 

28 a larger square, then rotated and cropped. 

29- ``vector``: base class for vector layers. It finds features through the 

30 first model the user can read and renders them as SVG. 

31- ``ows``: the binding of a layer to OWS services (layer and feature names, 

32 XML namespace, allowed services, OWS models). Names may carry an XML 

33 namespace prefix (``prefix:name``), which then sets the XML namespace. 

34 Layer and feature names default to the layer title converted to a UID, the 

35 geometry name defaults to an empty string. 

36- ``tree``: builds child layer configurations from a hierarchy of source 

37 layers, for layer types that mirror an external layer tree (QGIS projects, 

38 WMS and WFS services). Its ``Config`` adds the ``rootLayers``, 

39 ``excludeLayers``, ``flattenLayers`` and ``autoLayers`` options. 

40 

41``Layer.render`` dispatches to ``render_box``, ``render_tile`` or 

42``render_svg`` by the input type. ``Layer.url_path_for`` builds the URLs of 

43the ``mapGetBox``, ``mapGetTile``, ``mapGetLegend`` and ``mapGetFeatures`` 

44commands of the map action. ``Layer.render_legend`` without arguments caches 

45the legend for the server lifetime. 

46 

47Child layers receive the parent's WGS extent, resolutions and the map CRS 

48through the internal config keys ``_parentWgsExtent``, ``_parentResolutions`` 

49and ``_mapCrs``; a layer's own extent is clipped to the parent extent. 

50 

51Example:: 

52 

53 map.layers+ { 

54 type "group" 

55 title "Base maps" 

56 layers+ { 

57 type "tile" 

58 title "OpenStreetMap" 

59 provider.url "https://tile.openstreetmap.org/{z}/{x}/{y}.png" 

60 } 

61 } 

62 

63A minimal raster layer type in a plugin:: 

64 

65 @gws.ext.object.layer('mytiles') 

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

67 def configure(self): 

68 self.configure_layer() 

69 

70 def create_cache_name(self, cache): 

71 return gws.u.sha256(self.uid)[: gws.base.layer.image.CACHE_NAME_LENGTH] 

72 

73 def create_grabber(self, opts): 

74 return MyGrabber(opts) 

75""" 

76 

77from .core import ( 

78 Object, 

79 Config, 

80 Props, 

81) 

82 

83from . import group, tree, image, vector