Index: trunk/tools/osm-tools/cgi-bin/export |
— | — | @@ -16,8 +16,10 @@ |
17 | 17 | import yaml |
18 | 18 | import md5 |
19 | 19 | import datetime |
| 20 | +import math |
| 21 | +import socket |
| 22 | +import struct |
20 | 23 | |
21 | | - |
22 | 24 | # |
23 | 25 | # Config data |
24 | 26 | # |
— | — | @@ -83,6 +85,45 @@ |
84 | 86 | print "</body>" |
85 | 87 | print "</html>" |
86 | 88 | |
| 89 | +# When generating a static map, also insert the relevant tiles into |
| 90 | +# the rendering queue, as one might want to view the static map in a |
| 91 | +# slippy map afterwards |
| 92 | +def expire_tiles(bbox, zoom,renderd_xmlname): |
| 93 | + width = bbox[2] - bbox[0] |
| 94 | + height = bbox[3] - bbox[1] |
| 95 | + # Add a 10% margin around the bounding box |
| 96 | + bbox_bigger = [(bbox[0] - 0.10*width), (bbox[1] - 0.10*height), (bbox[2] + 0.10*width), (bbox[3] + 0.10*height)] |
| 97 | + notiles = math.pow(2,zoom) |
| 98 | + # Calculate the x/y coordinates of the tiles corresponding to the bbox |
| 99 | + mix = int(1 + math.floor((bbox_bigger[0] + 180.0) / (360.0 / notiles))) |
| 100 | + max = int(1 + math.ceil((bbox_bigger[2] + 180) / (360.0 / notiles))) |
| 101 | + |
| 102 | + # The tiles are merkator projected, so calculating y coordinates from the bbox is a little more |
| 103 | + # complicated. The formula was taken from http://wiki.openstreetmap.org/wiki/Slippy_map_tilenames#X_and_Y |
| 104 | + merc_miy = math.log(math.tan(bbox_bigger[1]/180*math.pi) + 1/math.cos(bbox_bigger[1]/180*math.pi)) |
| 105 | + may = int(1 + math.floor(((1 - merc_miy/math.pi) / 2)*notiles)) |
| 106 | + merc_may = math.log(math.tan(bbox_bigger[3]/180*math.pi) + 1/math.cos(bbox_bigger[3]/180*math.pi)) |
| 107 | + miy = int(1 + math.floor(((1 - merc_may/math.pi) / 2)*notiles)) |
| 108 | + |
| 109 | + CMD_DIRT = 2 |
| 110 | + RENDERD_PROTOCOL_VER = 2 |
| 111 | + |
| 112 | + # Open a socket to renderd |
| 113 | + for x in range(mix, max): |
| 114 | + for y in range(miy, may): |
| 115 | + try: |
| 116 | + # TODO: It would be better to reuse the socket rather than |
| 117 | + # creating a new one everytime. |
| 118 | + s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) |
| 119 | + s.connect(config['renderd']['socket']) |
| 120 | + s.send(struct.pack("iiiii44s",RENDERD_PROTOCOL_VER,CMD_DIRT,x,y,zoom,renderd_xmlname)) |
| 121 | + s.close() |
| 122 | + except: |
| 123 | + # If we have an error here, just continue with the next one |
| 124 | + # and hope that works better. |
| 125 | + continue |
| 126 | + return |
| 127 | + |
87 | 128 | # Parse CGI parameters |
88 | 129 | form = cgi.FieldStorage() |
89 | 130 | |
— | — | @@ -123,6 +164,7 @@ |
124 | 165 | # Bogus bounding box |
125 | 166 | output_error("Invalid bounding box") |
126 | 167 | else: |
| 168 | + bbox_coords = bbox |
127 | 169 | # Project the bounds to the map projection |
128 | 170 | bbox = mapnik.forward_(mapnik.Envelope(*bbox), prj) |
129 | 171 | |
— | — | @@ -157,6 +199,15 @@ |
158 | 200 | if (os.environ['HTTP_IF_NONE_MATCH'] == etagquotes): |
159 | 201 | print "Status: 304 Not Modified" |
160 | 202 | exit |
| 203 | + |
| 204 | + # Also make sure that the corresponding slippy map tiles exist |
| 205 | + # and are up to date The magic number of 2132 is taken from |
| 206 | + # http://lists.openstreetmap.org/pipermail/talk/2007-January/010349.html |
| 207 | + zoom = math.ceil(18 - math.log(map.scale_denominator()/2132.72958385,2)) |
| 208 | + renderd_xmlname = form.getvalue('locale') |
| 209 | + expire_tiles(bbox_coords, zoom, renderd_xmlname) |
| 210 | + expire_tiles(bbox_coords, zoom - 1, renderd_xmlname) |
| 211 | + expire_tiles(bbox_coords, zoom + 1, renderd_xmlname) |
161 | 212 | |
162 | 213 | output_headers("image/png", len(png),etag.hexdigest()) |
163 | 214 | print png |
Index: trunk/tools/osm-tools/cgi-bin/export-config.yml |
— | — | @@ -23,3 +23,7 @@ |
24 | 24 | |
25 | 25 | # Where to read our list of languages from |
26 | 26 | locales: /sql/misc-data/wikipedia-languages.yml |
| 27 | + |
| 28 | +# Interface with renderd |
| 29 | +renderd: |
| 30 | + socket: /var/run/renderd/renderd.sock |