import os os.environ['http_proxy'] = 'http://[proxy_host]:[proxy_port]/' import math import urllib import velocation from os.path import exists #------------------------ # S60 Specific Imports from appuifw import * from key_codes import * from graphics import Image import e32 #------------------------ ROAD = 0 AERIAL = 1 xfer_in_progress = 0 class Tile: cache = 'c:\\system\\temp\\' def __init__(self, x, y, zoom, mode): self.x = x self.y = y self.zoom = zoom self.mode = mode server = ((self.x & 1) + ((self.y & 1) << 1)) % 4 quadkey = self.__tileToQuadKey() if self.mode == ROAD: self.filename = 'r%s.png' % quadkey self.url = 'http://r%d.ortho.tiles.virtualearth.net/tiles/%s?g=22' % (server, self.filename) else: self.filename = 'h%s.jpeg' % quadkey self.url = 'http://h%d.ortho.tiles.virtualearth.net/tiles/%s?g=22' % (server, self.filename) def __tileToQuadKey(self): quad = '' for i in range(self.zoom, 0, -1): mask = 1 << (i - 1) cell = 0 if (self.x & mask) != 0: cell = cell + 1 if (self.y & mask) != 0: cell = cell + 2 quad = quad + str(cell) return quad def load(self): global xfer_in_progress if not exists(self.cache+self.filename): xfer_in_progress = 1 urllib.urlretrieve(self.url, self.cache+self.filename) xfer_in_progress = 0 def draw(self, x, y, c = None): if c is None: return #------------------------ # S60 Specific Code im = Image.open(self.cache+self.filename) rect = (x, y, x+256, y+256) c.blit(im, target=rect) #------------------------ class Map: earthRadius = 6378137 earthCircum = earthRadius * 2.0 * math.pi earthHalfCirc = earthCircum / 2.0 def __init__(self, width, height): self.width = width self.height = height self.maxTiles = (width/256 + 2)*(height/256 + 2); self.displayedTiles = 0 self.tiles = [] for i in range(self.maxTiles): self.tiles.append(0) self.x = 0 self.y = 0 self.zoom = 0 self.mode = ROAD self.drawing = 0 self.canvas = None def up(self): self.move(0, -1) def down(self): self.move(0, 1) def left(self): self.move(-1, 0) def right(self): self.move(1, 0) def move(self, dx, dy): self.x = self.x + 50*dx self.y = self.y + 50*dy self.draw() def zoomIn(self): if self.zoom == 18: return self.zoom = self.zoom + 1 self.x = self.x*2 + self.width/2 self.y = self.y*2 + self.height/2 self.draw() def zoomOut(self): if self.zoom == 1: return self.zoom = self.zoom - 1 self.x = self.x/2 - self.width/4 self.y = self.y/2 - self.height/4 self.draw() def toggleMode(self): if self.mode == ROAD: self.mode = AERIAL else: self.mode = ROAD self.draw() def gotoLocation(self, latitude, longitude, zoom = -1): if zoom != -1: self.zoom = zoom self.x = self.longitudeToXAtZoom(longitude, self.zoom) - self.width/2 self.y = self.latitudeToYAtZoom(latitude, self.zoom) - self.height/2 self.draw() def draw(self): if self.drawing == 1 or self.canvas is None: return self.drawing = 1 tilex = self.x / 256 tiley = self.y / 256 offsetx = -(self.x % 256) offsety = -(self.y % 256) for i in range(self.maxTiles): self.tiles[i] = None self.displayedTiles = 0 while offsety < self.height: tmpoffset = offsetx tmptilex = tilex while tmpoffset < self.width: t = Tile(tmptilex, tiley, self.zoom, self.mode) t.load() self.tiles[self.displayedTiles] = (tmpoffset, offsety, t) self.displayedTiles = self.displayedTiles + 1 tmpoffset = tmpoffset + 256 tmptilex = tmptilex + 1 offsety = offsety + 256 tiley = tiley + 1 for i in range(self.displayedTiles): self.tiles[i][2].draw(self.tiles[i][0], self.tiles[i][1], self.canvas) self.drawing = 0 def longitudeToXAtZoom(self, lon, zl): arc = self.earthCircum / ((1 << zl) * 256) metersX = self.earthRadius * self.degToRad(lon) return int(round((metersX + self.earthHalfCirc) / arc)) def latitudeToYAtZoom(self, lat, zl): arc = self.earthCircum / ((1 << zl) * 256) sinLat = math.sin(self.degToRad(lat)) metersY = self.earthRadius / 2 * math.log((1.0 + sinLat) / (1.0 - sinLat)) return int(round((self.earthHalfCirc - metersY) / arc)) def degToRad(self, d): return d * math.pi / 180.0 #------------------------------ # S60 Application Specific Code running = 1 def quit(): global running if xfer_in_progress == 1: return running = 0 app.exit_key_handler= quit # Main Loop m = None def draw(rect = None): if m is None: return m.draw() app.screen = 'full' app.body = c = Canvas(redraw_callback=draw) screensize = c.size m = Map(screensize[0], screensize[1]) m.canvas = c (initlat, initlon, initzoom) = velocation.locateMe() m.gotoLocation(initlat, initlon, initzoom) c.bind(EKeyRightArrow, m.right) c.bind(EKeyLeftArrow, m.left) c.bind(EKeyUpArrow, m.up) c.bind(EKeyDownArrow, m.down) c.bind(EKeySelect, m.zoomIn) c.bind(EKeyStar, m.zoomOut) c.bind(EKeyHash, m.toggleMode) while running: e32.ao_sleep(0.1) #------------------------------