Package viewer :: Package lib :: Module tileloader2
[hide private]
[frames] | no frames]

Source Code for Module viewer.lib.tileloader2

  1  #!/usr/bin/env python 
  2  """Loads OSM tiles from the Web using threading and urllib3""" 
  3   
  4  import os 
  5  import sys 
  6  import random 
  7  import threading 
  8   
  9  from Queue import Queue 
 10  import urllib3 
 11   
 12  import pyglet.image as pygletimage 
 13   
 14  __author__ = "B. Henne" 
 15  __maintainer__ = "B. Henne" 
 16  __contact__ = "henne@dcsec.uni-hannover.de" 
 17  __copyright__ = "(c) 2012, DCSec, Leibniz Universitaet Hannover, Germany" 
 18  __license__ = "GPLv3" 
 19   
 20   
 21  LAYERS = {"tah": ["cassini.toolserver.org:8080", "/http://a.tile.openstreetmap.org/+http://toolserver.org/~cmarqu/hill/"], 
 22            "oam": ["oam1.hypercube.telascience.org", "/tiles/1.0.0/openaerialmap-900913/"], 
 23            "mapnikold": ["tile.openstreetmap.org", "/mapnik/"], 
 24            "mapnik": [["a.tile.openstreetmap.org", "b.tile.openstreetmap.org", "c.tile.openstreetmap.org"], "/"], 
 25  } 
 26   
 27   
28 -class TileLoader(object):
29 """A tile downloader using threads for downloads""" 30
31 - def __init__(self, tile_list={}, cache_dir='.cache', NUM_WORKER=1, NUM_SOCKETS=3):
32 """Inits the TileLoader with its threads""" 33 34 self.dl_queue = Queue() 35 self.load_queue = Queue() 36 self.data_dir = os.path.join(os.path.dirname(os.path.abspath(sys.modules[self.__module__].__file__)), '..', 'data') 37 self.cache_dir = cache_dir 38 self.tile_list = tile_list 39 self.loading_image = pygletimage.load(os.path.join(self.data_dir, 'loading.png')) 40 self.NUM_SOCKETS = NUM_SOCKETS 41 self.t = [] 42 for w in xrange(0, NUM_WORKER): 43 self.t.append(threading.Thread(target=self.worker)) 44 for t in self.t: 45 t.setDaemon(True) 46 t.start()
47
48 - def worker(self):
49 """Thread worker""" 50 51 http = urllib3.PoolManager(maxsize=self.NUM_SOCKETS) 52 while True: 53 tile = self.dl_queue.get() 54 ok = False 55 tries = 3 56 while (ok == False) and (tries > 0): 57 tries -= 1 58 r = http.request('GET', tile[0]) 59 ok = self.handle_response(r.data, tile[1], tile[2], tile[3], tile[4], tile[5]) 60 self.load_queue.put((tile[1], tile[2], tile[3], tile[4], tile[5])) 61 self.dl_queue.task_done()
62
63 - def handle_response(self, r, x, y, z, layer, file_extension):
64 """Handles download responses, writes images to files""" 65 66 if '<html>' in r: 67 # something went wrong...mostlikely a 404 error 68 return False 69 elements = [self.cache_dir, layer, str(z), str(x)] 70 path = '' 71 for element in elements: 72 path = os.path.join(path, element) 73 try: 74 os.mkdir(path) 75 except OSError: 76 #folder exists, no need to create 77 pass 78 path = os.path.join(path, str(y) + file_extension) 79 image_file = open(path, 'wb') 80 image_file.write(r) 81 image_file.flush() 82 image_file.close() 83 return True
84
85 - def load_images(self):
86 """Loads images downloaded by workers to tile_list""" 87 88 for i in xrange(0, self.load_queue.qsize()): 89 x, y, z, layer, file_extension = self.load_queue.get() 90 path = os.path.join(self.cache_dir, layer, str(z), str(x), str(y) + file_extension) 91 image = pygletimage.load(path) 92 image.anchor_x = image.width / 2 93 image.anchor_y = image.height / 2 94 self.tile_list[(x, y, z)] = image 95 self.load_queue.task_done()
96
97 - def enqueue_tile(self, x, y, z, layer='mapnik'):
98 """Enqueues a tile to be downloaded""" 99 100 if type(LAYERS[layer][0]) == str: 101 host = LAYERS[layer][0] 102 elif type(LAYERS[layer][0]) == list: 103 host = random.choice(LAYERS[layer][0]) 104 layer = layer 105 106 base_url_extension = LAYERS[layer][1] 107 file_extension = '.jpg' if layer == 'oam' else '.png' 108 109 #path = os.path.join(self.cache_dir, layer, str(z), str(x), str(y) + file_extension) 110 #assert os.path.isfile(path) == False 111 self.tile_list[(x, y, z)] = self.loading_image 112 113 url = 'http://' + host + base_url_extension + str(z) + '/' + str(x) + '/' + str(y) + file_extension 114 self.dl_queue.put((url, x, y, z, layer, file_extension)) 115 return True
116 117
118 -def test():
119 myApp = wx.App() 120 t = TileLoader() 121 import time 122 x=40 123 while 1: 124 if x < 50: 125 for i in xrange(0,20): 126 t.enqueue_tile(34, x, 16) 127 if t.dl_queue.qsize() <= 0: 128 break 129 print "Queue size: %s" % t.dl_queue.qsize() 130 time.sleep(1) 131 t.load_images() 132 x += 1
133 134 135 if __name__ == '__main__': 136 test() 137