class OSMTileProvider(DynamicTileProvider): def __init__(self, tilecache): DynamicTileProvider.__init__(self, tilecache) def _load_dynamic(self, tile_id, outfile): media_id, tilelevel, row, col = tile_id if row < 0 or col < 0 or \ row > 2**tilelevel - 1 or col > 2**tilelevel - 1: ## row,col out of range return url = "http://tile.openstreetmap.org/%d/%d/%d.png" \ % (tilelevel, col, row) self._logger.info("downloading %s", url) try: urllib.urlretrieve(url, outfile) except IOError: self._logger.exception("cannot reach server") -- class DynamicTileProvider(TileProvider): def __init__(self, tilecache): TileProvider.__init__(self, tilecache) def _load_dynamic(self, tile_id, outfile): pass def _load(self, tile_id): filename = TileStore.get_tile_path( tile_id, True, filext=self.filext) if not os.path.exists(filename): ## tile has not been retrieved yet self._load_dynamic(tile_id, filename) try: tile = Image.open(filename) tile.load() return tile except Exception: self._logger.exception("error loading tile, " "assuming it is unavailable") return None -- class TileProvider(Thread): def __init__(self, tilecache): Thread.__init__(self) self.setDaemon(True) ... def _load(self, tile_id): pass def run(self): while True: self.__tasks_available.acquire() while not self.__tasks: self.__tasks_available.wait() tile_id = self.__tasks.pop() self.__tasks_available.release() if tile_id not in self.__tilecache: try: tile = self._load(tile_id) except Exception: self._logger.exception("error loading tile") tile = None if tile: self._logger.debug("loaded %s", str(tile_id)) self.__tilecache[tile_id] = Tile(tile) del tile else: self._logger.debug("unavailable %s", str(tile_id)) self.__tilecache[tile_id] = None -- class TileCache(object): ... def __setitem__(self, tile_id, tile): with self.__lock: if tile_id in self: if tile is None: ## don't replace an existing tile with a None tile return else: del self[tile_id] self.__d[tile_id] = tile if self.__mortal(tile_id, tile): self.__discard_queue.append(tile_id) self.__atime[tile_id] = int(time.time()) self.__num_tiles += 1 self.__clean() elif tile_id not in self.__d: self.__d[tile_id] = None