155 |
141 |
156 img_width = img_width, |
142 img_width = img_width, |
157 img_height = img_height, |
143 img_height = img_height, |
158 ) |
144 ) |
159 |
145 |
|
146 |
|
147 # threshold to cache images on - only images with a source data region *larger* than this are cached |
|
148 CACHE_THRESHOLD = 512 * 512 |
|
149 |
|
150 def scale_by_zoom (val, zoom) : |
|
151 """ |
|
152 Scale dimension by zoom factor |
|
153 """ |
|
154 |
|
155 if zoom > 0 : |
|
156 return val << zoom |
|
157 |
|
158 elif zoom > 0 : |
|
159 return val >> -zoom |
|
160 |
|
161 else : |
|
162 return val |
|
163 |
|
164 ### Image caching |
|
165 def check_cache_threshold (width, height, zl) : |
|
166 """ |
|
167 Checks if a tile with the given dimensions should be cached |
|
168 """ |
|
169 |
|
170 return (scale_by_zoom(width, -zl) * scale_by_zoom(height, -zl)) > CACHE_THRESHOLD |
|
171 |
|
172 def render_raw (image, width, height, x, y, zl) : |
|
173 """ |
|
174 Render and return tile |
|
175 """ |
|
176 |
|
177 return image.tile_mem( |
|
178 width, height, |
|
179 x, y, zl |
|
180 ) |
|
181 |
|
182 def render_cache (cache, image, width, height, x, y, zl) : |
|
183 """ |
|
184 Perform a cached render of the given tile |
|
185 """ |
|
186 |
|
187 if cache : |
|
188 # cache key |
|
189 # XXX: need a better id for the image.. |
|
190 key = "tl_%d:%d_%d:%d:%d_%s" % (x, y, width, height, zl, id(image)) |
|
191 |
|
192 # lookup |
|
193 data = cache.get(key) |
|
194 |
|
195 else : |
|
196 # oops, no cache |
|
197 data = None |
|
198 |
|
199 if not data : |
|
200 # cache miss, render |
|
201 data = render_raw(image, width, height, x, y, zl) |
|
202 |
|
203 if cache : |
|
204 # store |
|
205 cache.add(key, data) |
|
206 |
|
207 # ok |
|
208 return data |
|
209 |
160 ### Render PNG Data |
210 ### Render PNG Data |
161 def img_png_tile (image, x, y, zoom) : |
211 def img_png_tile (image, x, y, zoom, cache) : |
162 """ |
212 """ |
163 Render given tile, returning PNG data |
213 Render given tile, returning PNG data |
164 """ |
214 """ |
165 |
215 |
166 return image.tile_mem( |
216 # remap coordinates by zoom |
167 TILE_WIDTH, TILE_HEIGHT, |
217 x = scale_by_zoom(x, -zoom) |
168 scale_by_zoom(x, -zoom), scale_by_zoom(y, -zoom), |
218 y = scale_by_zoom(y, -zoom) |
169 zoom |
219 |
170 ) |
220 # do we want to cache this? |
171 |
221 if check_cache_threshold(TILE_WIDTH, TILE_HEIGHT, zoom) : |
172 def img_png_region (image, cx, cy, zoom, width, height) : |
222 # go via the cache |
|
223 return render_cache(cache, image, TILE_WIDTH, TILE_HEIGHT, x, y, zoom) |
|
224 |
|
225 else : |
|
226 # just go raw |
|
227 return render_raw(image, TILE_WIDTH, TILE_HEIGHT, x, y, zoom) |
|
228 |
|
229 def img_png_region (image, cx, cy, zoom, width, height, cache) : |
173 """ |
230 """ |
174 Render arbitrary tile, returning PNG data |
231 Render arbitrary tile, returning PNG data |
175 """ |
232 """ |
176 |
233 |
177 x = scale_by_zoom(cx - width / 2, -zoom) |
234 x = scale_by_zoom(cx - width / 2, -zoom) |
178 y = scale_by_zoom(cy - height / 2, -zoom) |
235 y = scale_by_zoom(cy - height / 2, -zoom) |
179 |
236 |
180 # safely limit |
237 # safely limit |
181 if width * height > MAX_PIXELS : |
238 if width * height > MAX_PIXELS : |
182 raise ValueError("Image size: %d * %d > %d" % (width, height, MAX_PIXELS)) |
239 raise ValueError("Image size: %d * %d > %d" % (width, height, MAX_PIXELS)) |
183 |
240 |
184 return image.tile_mem( |
241 # these images are always cached |
185 width, height, |
242 return render_cache(cache, image, width, height, x, y, zoom) |
186 x, y, |
243 |
187 zoom |
|
188 ) |
|
189 |
|