Exemple #1
0
class PyMapper:
    
    def __init__(self):
        pygame.init()
        self.tileCache = TileCache()
        
        self.units = latlon2unit(45.547717, -73.55484) # position in google units
        self.zoom = 8 # current zoom level (0-16)
        
        self.window = pygame.display.set_mode((800, 480), pygame.FULLSCREEN) 
        self.clock = pygame.time.Clock()
        
    def shutdown(self):
        self.tileCache.shutdown()
        pygame.quit()
        sys.exit(0)
        
    def drawScreen(self):
        # coordinates of the center tile
        # our position in pixels on the center tile
        tilex, pixelx = unit2tilepixel(self.units[0], self.zoom)
        tiley, pixely = unit2tilepixel(self.units[1], self.zoom)
        
        screenSize = (800, 480)
        
        # need to cover the screen, number of tiles to surround the center tile with
        h = int(math.ceil(math.ceil((screenSize[0] / 256.0) / 2)))
        v = int(math.ceil(math.ceil((screenSize[1] / 256.0) / 2)))
        
        # clear the screen
        
        screen = pygame.display.get_surface()
        screen.fill((0,0,0))
        
        # compute list of all tiles we need and their position on the screen
        
        pos = [] # position of each tile on the screen in pixels
        tiles = [] # coordinates of each tile (x, y, zoom)
        
        for t in range(-v, v + 1):
            for s in range(-h, h + 1):
                
                tiles.append((tilex + s, tiley + t, self.zoom))
                
                posx = screenSize[0] / 2 - pixelx + s * 256
                posy = screenSize[1] / 2 - pixely + t * 256
                
                pos.append((posx, posy))
                
        # fetch the tiles from the tile server
        images = self.tileCache.getTiles(tiles)
        
        # draw the tiles to screen
        for i in range((h * 2 + 1) * (v * 2 + 1)):
            screen.blit(images.pop(), pos.pop())
            
        # draw our position on the screen
        pygame.draw.circle(screen, (255, 0, 0), (screenSize[0] / 2, screenSize[1] / 2), 2)
        
        # we're using double buffering
        pygame.display.flip()
        
    def doInput(self, events):
        for event in events:
            if event.type == pygame.QUIT:
                self.shutdown()
            
            elif event.type == pygame.KEYUP:
                
                if event.key == K_ZOOM_IN:
                    self.zoom -= 1
                elif event.key == K_ZOOM_OUT:
                    self.zoom += 1
                    
                elif event.key == K_LEFT:
                    self.units[0] -= panunits(self.zoom)
                elif event.key == K_RIGHT:
                    self.units[0] += panunits(self.zoom)
                elif event.key == K_UP:
                    self.units[1] -= panunits(self.zoom)
                elif event.key == K_DOWN:
                    self.units[1] += panunits(self.zoom)
                    
                elif event.key == K_BACK:
                    self.shutdown()
                
                
                self.zoom = min(MAX_ZOOM - 1, self.zoom)
                self.zoom = max(0, self.zoom)
                
                self.needsRefresh = True
            
            elif event.type == pygame.MOUSEMOTION:
                if event.buttons[0]:
                    dx = -pixel2unit(event.rel[0], self.zoom)
                    dy = -pixel2unit(event.rel[1], self.zoom)
                    
                    self.units = [self.units[0] + dx, self.units[1] + dy]
                    
                    self.needsRefresh = True
                    
    def run(self):
        self.needsRefresh = True
        
        while True:
            
            self.doInput(pygame.event.get())
            
            if self.tileCache.hasTiles():
                self.needsRefresh = True
            
            if self.needsRefresh:
                self.drawScreen()
                
            self.needsRefresh = False
            
            pygame.display.set_caption("%.1f fps" % self.clock.get_fps())
            self.clock.tick(20)
Exemple #2
0
class PyMapper:
	
	def __init__(self):
		pygame.init()
		self.tileCache = TileCache()
		
		# Fix starting coordinates to Brisbane, Australia (Jerry])
		#self.units = latlon2unit(45.547717, -73.55484) # position in google units
		self.units = latlon2unit(-27.493210, 153.003387)
		self.zoom = DEFAULT_ZOOM # current zoom level (0-16)
		
		# Draw as decorated window (Jerry])
		if scanner.config.EnableHildon:
			self.window = pygame.display.set_mode((800, 480), pygame.FULLSCREEN)
		else:
			self.window = pygame.display.set_mode((800, 480))
		self.clock = pygame.time.Clock()
		
		# image store (Jerry])
		self.images = []
		
	def shutdown(self):
		self.tileCache.shutdown()
		pygame.quit()
		sys.exit(0)
		
	def drawScreen(self):
		# coordinates of the center tile
		# our position in pixels on the center tile
		tilex, pixelx = unit2tilepixel(self.units[0], self.zoom)
		tiley, pixely = unit2tilepixel(self.units[1], self.zoom)
		
		#print 'tilex', tilex, 'tiley', tiley
		#print 'pixelx', pixelx, 'pixely', pixely
		
		screenSize = (800, 480)
		
		# need to cover the screen, number of tiles to surround the center tile with
		h = int(math.ceil(math.ceil((screenSize[0] / 256.0) / 2)))
		v = int(math.ceil(math.ceil((screenSize[1] / 256.0) / 2)))
		
		# clear the screen
		
		screen = pygame.display.get_surface()
		screen.fill((0,0,0))
		
		# compute list of all tiles we need and their position on the screen
		
		pos = [] # position of each tile on the screen in pixels
		tiles = [] # coordinates of each tile (x, y, zoom)
		
		for t in range(-v, v + 1):
			for s in range(-h, h + 1):
				
				tiles.append((tilex + s, tiley + t, self.zoom))
				
				posx = screenSize[0] / 2 - pixelx + s * 256
				posy = screenSize[1] / 2 - pixely + t * 256
				
				pos.append((posx, posy))
				
		# fetch the tiles from the tile server
		images = self.tileCache.getTiles(tiles)
		
		# draw the tiles to screen
		for i in range((h * 2 + 1) * (v * 2 + 1)):
			screen.blit(images.pop(), pos.pop())
			
		# Check for hooked images (Jerry])
		for image in self.images:
			# skip image if zoom level is different
			if image['zoom'] != self.zoom:
				continue
			# calculate absolute position onscreen to draw image
			x = (screenSize[0] / 2 - pixelx) + (image['x'] - tilex) * 256
			y = (screenSize[1] / 2 - pixely) + (image['y'] - tiley) * 256
			screen.blit(pygame.image.load(image['file']), (x, y))
			
		# draw our position on the screen
		pygame.draw.circle(screen, (255, 0, 0), (screenSize[0] / 2, screenSize[1] / 2), 2)
		
		# we're using double buffering
		pygame.display.flip()
		
	def add_image(self, file, tilex, tiley, zoom):
		"""Hook the image onto fixed tiles on the map. (Jerry])
			:param file: Path to image file
			:param tilex: X coordinate in tiles to attach
			:param tiley: Y coordinate in tiles to attach
			:param zoom: The zoom level to display. If the zoom level is not
				the same as 'zoom', added images will be skipped."""
		image = {
				'x': tilex,
				'y': tiley,
				'zoom': zoom,
				'file': file
		}
		self.images.append(image)
		
	def doInput(self, events):
		for event in events:
			if event.type == pygame.QUIT:
				self.shutdown()
			
			elif event.type == pygame.KEYUP:
				
				if event.key == K_ZOOM_IN:
					self.zoom -= 1
				elif event.key == K_ZOOM_OUT:
					self.zoom += 1
					
				elif event.key == K_LEFT:
					self.units[0] -= panunits(self.zoom)
				elif event.key == K_RIGHT:
					self.units[0] += panunits(self.zoom)
				elif event.key == K_UP:
					self.units[1] -= panunits(self.zoom)
				elif event.key == K_DOWN:
					self.units[1] += panunits(self.zoom)
					
				elif event.key == K_BACK:
					self.shutdown()
				
				
				self.zoom = min(MAX_ZOOM - 1, self.zoom)
				self.zoom = max(0, self.zoom)
				
				self.needsRefresh = True
			
			elif event.type == pygame.MOUSEMOTION:
				if event.buttons[0]:
					dx = -pixel2unit(event.rel[0], self.zoom)
					dy = -pixel2unit(event.rel[1], self.zoom)
					
					self.units = [self.units[0] + dx, self.units[1] + dy]
					
					self.needsRefresh = True
					
	def run(self):
		self.needsRefresh = True
		
		while True:
			
			self.doInput(pygame.event.get())
			
			if self.tileCache.hasTiles():
				self.needsRefresh = True
			
			if self.needsRefresh:
				self.drawScreen()
				
			self.needsRefresh = False
			
			pygame.display.set_caption("%.1f fps" % self.clock.get_fps())
			self.clock.tick(20)