source: subversion/applications/routing/pyroute/tiles.py @ 5722

Last change on this file since 5722 was 5722, checked in by ojw, 12 years ago

first draft of separate thread for downloading tiles in background

File size: 3.3 KB
Line 
1#!/usr/bin/python
2#-----------------------------------------------------------------------------
3# Tile image handler (download, cache, and display tiles)
4#
5# Usage:
6#   (library code for pyroute GUI, not for direct use)
7#-----------------------------------------------------------------------------
8# Copyright 2007, Oliver White
9#
10# This program is free software: you can redistribute it and/or modify
11# it under the terms of the GNU General Public License as published by
12# the Free Software Foundation, either version 3 of the License, or
13# (at your option) any later version.
14#
15# This program is distributed in the hope that it will be useful,
16# but WITHOUT ANY WARRANTY; without even the implied warranty of
17# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18# GNU General Public License for more details.
19#
20# You should have received a copy of the GNU General Public License
21# along with this program.  If not, see <http://www.gnu.org/licenses/>.
22#-----------------------------------------------------------------------------
23from base import pyrouteModule
24from tilenames import *
25import urllib
26import os
27import cairo
28from threading import Thread
29
30class tileLoader(Thread):
31  def __init__(self, x,y,z,filename):
32    self.url = tileURL(x,y,z)
33    self.filename = filename
34    Thread.__init__(self)
35    self.run()
36   
37  def run(self):
38    print "downloading %s" % self.filename
39    urllib.urlretrieve(self.url, self.filename)
40   
41   
42class tileHandler(pyrouteModule):
43  def __init__(self, modules):
44    pyrouteModule.__init__(self, modules)
45    self.images = {}
46    self.threads = {}
47   
48  def imageName(self,x,y,z):
49    return("%d_%d_%d" % (z,x,y))
50 
51  def startDownloading(self,x,y,z,filename):
52    name = self.imageName(x,y,z)
53    if name in self.threads.keys():
54      return
55    print "Starting to download %s" % name
56    self.threads[name] = tileLoader(x,y,z,filename)
57   
58  def loadImage(self,x,y,z):
59    name = self.imageName(x,y,z)
60    if name in self.images.keys():
61      return
62    # TODO: actually check if a thread is handling this already
63    filename = "cache/%s.png" % name
64    if not os.path.exists(filename):
65      self.startDownloading(x,y,z,filename)
66      return
67    print "loading %s from cache"%name
68    self.images[name]  = cairo.ImageSurface.create_from_png(filename)
69   
70  def drawImage(self,cr, tile, bbox):
71    name = self.imageName(tile[0],tile[1],tile[2])
72    if not name in self.images.keys():
73      return
74    cr.save()
75    cr.translate(bbox[0],bbox[1])
76    cr.scale((bbox[2] - bbox[0]) / 256.0, (bbox[3] - bbox[1]) / 256.0)
77    cr.set_source_surface(self.images[name],0,0)
78    cr.paint()
79    cr.restore()
80   
81  def zoomFromScale(self,scale):
82    if(scale > 0.046):
83      return(10)
84    if(scale > 0.0085):
85      return(13)
86    if(scale > 0.0026):
87      return(15)
88    return(17)
89   
90  def tileZoom(self):
91    return(self.zoomFromScale(self.m['projection'].scale))
92 
93  def draw(self, cr):
94    proj = self.m['projection']
95    z = self.tileZoom()
96    view_x1,view_y1 = latlon2xy(proj.N, proj.W, z)
97    view_x2,view_y2 = latlon2xy(proj.S, proj.E, z)
98    for x in range(int(floor(view_x1)), int(ceil(view_x2))):
99      for y in range(int(floor(view_y1)), int(ceil(view_y2))):
100        S,W,N,E = tileEdges(x,y,z) 
101        x1,y1 = proj.ll2xy(N,W)
102        x2,y2 = proj.ll2xy(S,E)
103        self.loadImage(x,y,z)
104        self.drawImage(cr,(x,y,z),(x1,y1,x2,y2))
Note: See TracBrowser for help on using the repository browser.