Old tiles.ttss.pl backed using MapProxy
Jacek Kowalski
2020-06-09 a32ed5ec142a74385fe24f9e1adecfc86847f543
commit | author | age
d1e1f5 1 # This file is part of the MapProxy project.
JK 2 # Modified for https://github.com/jacekkow/mpk-ttss-osm project.
3 # Copyright (C) 2011 Omniscale <http://omniscale.de>
4 #
5 # Licensed under the Apache License, Version 2.0 (the "License");
6 # you may not use this file except in compliance with the License.
7 # You may obtain a copy of the License at
8 #
9 #    http://www.apache.org/licenses/LICENSE-2.0
10 #
11 # Unless required by applicable law or agreed to in writing, software
12 # distributed under the License is distributed on an "AS IS" BASIS,
13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 # See the License for the specific language governing permissions and
15 # limitations under the License.
16
17 from __future__ import absolute_import
18
19 import sys
20 import time
21 import threading
22
23 from mapproxy.image import ImageSource
24 from mapproxy.image.opts import ImageOptions
25 from mapproxy.layer import MapExtent, DefaultMapExtent, BlankImage, MapLayer
26 from mapproxy.source import  SourceError
27 from mapproxy.client.log import log_request
28 from mapproxy.util.py import reraise_exception
29 from mapproxy.util.async_ import run_non_blocking
30 from mapproxy.compat import BytesIO
31
32 try:
33     import mapnik
34     mapnik
35 except ImportError:
36     try:
37         # for 2.0 alpha/rcs and first 2.0 release
38         import mapnik2 as mapnik
39     except ImportError:
40         mapnik = None
41
42 # fake 2.0 API for older versions
43 if mapnik and not hasattr(mapnik, 'Box2d'):
44     mapnik.Box2d = mapnik.Envelope
45
46 import logging
47 log = logging.getLogger(__name__)
48
49 class MapnikSource(MapLayer):
50     supports_meta_tiles = True
51     def __init__(self, mapfile, layers=None, image_opts=None, coverage=None,
52         res_range=None, lock=None, reuse_map_objects=None, scale_factor=None):
53         MapLayer.__init__(self, image_opts=image_opts)
54         self.mapfile = mapfile
55         self.coverage = coverage
56         self.res_range = res_range
57         self.layers = set(layers) if layers else None
58         self.scale_factor = scale_factor
59         self.lock = lock
60         self._map_holder = threading.local()
61         self._map_holder.__dict__.setdefault('map', None)
62         if self.coverage:
63             self.extent = MapExtent(self.coverage.bbox, self.coverage.srs)
64         else:
65             self.extent = DefaultMapExtent()
66         # initialize map object
67         self.map_obj()
68
69     def get_map(self, query):
70         if self.res_range and not self.res_range.contains(query.bbox, query.size,
71                                                           query.srs):
72             raise BlankImage()
73         if self.coverage and not self.coverage.intersects(query.bbox, query.srs):
74             raise BlankImage()
75
76         try:
77             resp = self.render(query)
78         except RuntimeError as ex:
79             log.error('could not render Mapnik map: %s', ex)
80             reraise_exception(SourceError(ex.args[0]), sys.exc_info())
81         resp.opacity = self.opacity
82         return resp
83
84     def render(self, query):
85         if self.lock:
86             with self.lock():
87                 return self.render_mapfile(query)
88         else:
89             return self.render_mapfile(query)
90
91     def map_obj(self):
92         if not self._map_holder.map:
93             m = mapnik.Map(0, 0)
94             mapnik.load_map(m, str(self.mapfile))
95             self._map_holder.map = m
96         return self._map_holder.map
97
98     def render_mapfile(self, query):
99         return run_non_blocking(self._render_mapfile, (query,))
100
101     def _render_mapfile(self, query):
102         start_time = time.time()
103
104         m = self.map_obj()
105         m.resize(query.size[0], query.size[1])
106         m.srs = '+init=%s' % str(query.srs.srs_code.lower())
107         envelope = mapnik.Box2d(*query.bbox)
108         m.zoom_to_box(envelope)
109         data = None
110
111         try:
112             if self.layers:
113                 i = 0
114                 for layer in m.layers[:]:
115                     if layer.name != 'Unkown' and layer.name not in self.layers:
116                         del m.layers[i]
117                     else:
118                         i += 1
119
120             img = mapnik.Image(query.size[0], query.size[1])
121             if self.scale_factor:
122                 mapnik.render(m, img, self.scale_factor)
123             else:
124                 mapnik.render(m, img)
125             data = img.tostring(str(query.format))
126         finally:
127             size = None
128             if data:
129                 size = len(data)
130             log_request('%s:%s:%s:%s' % (self.mapfile, query.bbox, query.srs.srs_code, query.size),
131                 status='200' if data else '500', size=size, method='API', duration=time.time()-start_time)
132
133         return ImageSource(BytesIO(data), size=query.size,
134             image_opts=ImageOptions(format=query.format))