def change_zoom(self, zoom): '''zoom in or out by zoom factor, keeping centered''' state = self.state if self.mouse_pos: (x, y) = (self.mouse_pos.x, self.mouse_pos.y) else: (x, y) = (state.width / 2, state.height / 2) (lat, lon) = self.coordinates(x, y) lat = mp_util.constrain(lat, -85, 85) lon = mp_util.constrain(lon, -180, 180) state.ground_width *= zoom # limit ground_width to sane values state.ground_width = max(state.ground_width, 2) state.ground_width = min(state.ground_width, 20000000) self.re_center(x, y, lat, lon)
def draw(self, img, pixmapper, bounds): '''draw a polygon on the image''' if self.hidden: return (lat,lon,w,h) = bounds # note that w and h are in degrees spacing = 1000 while True: start = mp_util.latlon_round((lat,lon), spacing) lat2 = mp_util.constrain(lat+h*0.5,-85,85) lon2 = mp_util.wrap_180(lon+w) dist = mp_util.gps_distance(lat2,lon,lat2,lon2) count = int(dist / spacing) if count < 2: spacing /= 10 elif count > 50: spacing *= 10 else: break count += 10 for i in range(count): # draw vertical lines of constant longitude pos1 = mp_util.gps_newpos(start[0], start[1], 90, i*spacing) pos3 = (pos1[0]+h*2, pos1[1]) self.draw_line(img, pixmapper, pos1, pos3, self.colour, self.linewidth) # draw horizontal lines of constant latitude pos1 = mp_util.gps_newpos(start[0], start[1], 0, i*spacing) pos3 = (pos1[0], pos1[1]+w*2) self.draw_line(img, pixmapper, pos1, pos3, self.colour, self.linewidth)
def coord_to_tile(self, lat, lon, zoom): '''convert lat/lon/zoom to a TileInfo''' world_tiles = 1<<zoom lon = mp_util.wrap_180(lon) x = world_tiles / 360.0 * (lon + 180.0) tiles_pre_radian = world_tiles / (2 * pi) e = sin(radians(lat)) e = mp_util.constrain(e, -1+1.0e-15, 1-1.0e-15) y = world_tiles/2 + 0.5*log((1+e)/(1-e)) * (-tiles_pre_radian) offsetx = int((x - int(x)) * TILES_WIDTH) offsety = int((y - int(y)) * TILES_HEIGHT) return TileInfo((int(x) % world_tiles, int(y) % world_tiles), zoom, self.service, offset=(offsetx, offsety))
def coord_from_area(self, x, y, lat, lon, width, ground_width): '''return (lat,lon) for a pixel in an area image x is pixel coord to the right from top,left y is pixel coord down from top left ''' scale1 = mp_util.constrain(cos(radians(lat)), 1.0e-15, 1) pixel_width = ground_width / float(width) pixel_width_equator = (ground_width / float(width)) / cos(radians(lat)) latr = radians(lat) y0 = abs(1.0/cos(latr) + tan(latr)) lat2 = 2 * atan(y0 * exp(-(y * pixel_width_equator) / mp_util.radius_of_earth)) - pi/2.0 lat2 = degrees(lat2) dx = pixel_width_equator * cos(radians(lat2)) * x (lat2,lon2) = mp_util.gps_offset(lat2, lon, dx, 0) return (lat2,lon2)
def constrain_latlon(self): self.state.lat = mp_util.constrain(self.state.lat, -85, 85) self.state.lon = mp_util.wrap_180(self.state.lon)