Coverage for gws-app/gws/gis/mpx/util.py: 0%

29 statements  

« prev     ^ index     » next       coverage.py v7.11.0, created at 2025-10-16 22:59 +0200

1"""Utility functions for MapProxy integration. 

2 

3This module provides utilities for annotating and decorating MapProxy images. 

4""" 

5 

6from typing import Any, Dict, List, Tuple, Optional 

7from PIL import ImageColor, ImageDraw, ImageFont 

8from mapproxy.image import ImageSource 

9 

10# see https://mapproxy.org/docs/nightly/decorate_img.html 

11 

12def annotate(image: Any, service: str, layers: List[str], environ: Dict[str, Any], 

13 query_extent: Tuple[Any, Any], **kw: Any) -> ImageSource: 

14 """Annotate a MapProxy image with request information. 

15 

16 This function is used as a callback for MapProxy's decorate_img middleware. 

17 It adds text information about the request to the image. 

18 

19 Args: 

20 image: The MapProxy image object to annotate. 

21 service: The OWS service name (WMS, WMTS, etc.). 

22 layers: List of requested layer names. 

23 environ: The WSGI environment dictionary. 

24 query_extent: A tuple containing SRS and coordinate information. 

25 **kw: Additional keyword arguments. 

26 

27 Returns: 

28 An ImageSource object with the annotated image. 

29 """ 

30 img = image.as_image().convert('RGBA') 

31 

32 text = [ 

33 'service: %s' % service, 

34 'layers: %s' % ', '.join(layers), 

35 'srs: %s' % query_extent[0] 

36 ] 

37 

38 try: 

39 args = environ['mapproxy.request'].args 

40 text.append('x=%s y=%s z=%s' % ( 

41 args['tilecol'], 

42 args['tilerow'], 

43 args['tilematrix'], 

44 )) 

45 except: 

46 pass 

47 

48 for coord in query_extent[1]: 

49 text.append(' %s' % coord) 

50 

51 draw = ImageDraw.Draw(img) 

52 font = ImageFont.load_default() 

53 clr = ImageColor.getrgb('#ff0000') 

54 

55 line_y = 10 

56 for line in text: 

57 line_w, line_h = font.getsize(line) 

58 draw.text((10, line_y), line, font=font, fill=clr) 

59 line_y = line_y + line_h 

60 

61 draw.rectangle((0, 0) + img.size, outline=clr) 

62 

63 return ImageSource(img, image.image_opts) 

64 

65 

66class AnnotationFilter(object): 

67 """Simple MapProxy decorate_img middleware. 

68 

69 This middleware annotates map images with information about the request. 

70 It can be used to debug MapProxy requests by adding visual information 

71 to the returned images. 

72 """ 

73 

74 def __init__(self, app: Any) -> None: 

75 """Initialize the filter with a WSGI application. 

76 

77 Args: 

78 app: The WSGI application to wrap. 

79 """ 

80 self.app = app 

81 

82 def __call__(self, environ: Dict[str, Any], start_response: Any) -> Any: 

83 """WSGI application interface. 

84 

85 Args: 

86 environ: The WSGI environment dictionary. 

87 start_response: The WSGI start_response callable. 

88 

89 Returns: 

90 The response from the wrapped application. 

91 """ 

92 # Add the callback to the WSGI environment 

93 environ['mapproxy.decorate_img'] = annotate 

94 

95 return self.app(environ, start_response)