def fetch_style_images(self, city, zoom=16, hq=True): city_polygon = utils.polygon_union(city['features']) city_bounds = city_polygon.bounds all_style_imgs = [] fetcher = MapBoxFetcher() lat = city_bounds[3] lon = city_bounds[0] while lat >= city_bounds[1]: while lon <= city_bounds[2]: numx, numy = utils.deg2num(lat, lon, zoom) style_img = fetcher.style(lat, lon, zoom, hq=hq) all_style_imgs.append(style_img.bw_array()) lon = utils.num2deg( utils.deg2num(lat, lon, zoom)[0] + 1, utils.deg2num(lat, lon, zoom)[1], zoom)[1] lon = city_bounds[0] lat = utils.num2deg( utils.deg2num(lat, lon, zoom)[0], utils.deg2num(lat, lon, zoom)[1] + 1, zoom)[0] return all_style_imgs
def bbox2tiles(bbox, zoom): """ Return the tile coordinates that forms a bounding box. """ upper_left_tile = deg2num(bbox['upper_left'][0], bbox['upper_left'][1], zoom) lower_right_tile = deg2num(bbox['lower_right'][0], bbox['lower_right'][1], zoom) tile_coords = [] for i in range(upper_left_tile[0], lower_right_tile[0]+1): for j in range(upper_left_tile[1], lower_right_tile[1]+1): tile_coords.append((zoom, i,j)) return tile_coords
def write_josm_file(self, filename, tilezoom=14): """ create a osm file for the editor JOSM, that only contains the download boundary information. Load the file in JOSM and update the data. Note: Please do not missuse this function to download large areas with josm """ from shapely.geometry import LineString, Polygon f_out = open(filename, 'w') f_out.write("<?xml version='1.0' encoding='UTF-8'?>\n") f_out.write("<osm version='0.6' upload='true' generator='JOSM'>\n") for i, op in enumerate(self.outer_polygons): # create coordinate list and then a polygon plist = [(node.lat, node.lon) for node in op] outer_polygon = Polygon(LineString(plist)) if not outer_polygon.is_valid: raise ValueError('outer polygon no %i is not valid' % (i + 1)) (minlat, minlon, maxlat, maxlon) = outer_polygon.bounds (x1, y2) = deg2num(minlat, minlon, tilezoom) (x2, y1) = deg2num(maxlat, maxlon, tilezoom) for ty in range(y1, y2 + 1): for tx in range(x1, x2 + 1): tile_rectangle = [ num2deg(tx, ty, tilezoom), num2deg(tx + 1, ty, tilezoom), num2deg(tx + 1, ty + 1, tilezoom), num2deg(tx, ty + 1, tilezoom), num2deg(tx, ty, tilezoom) ] tile_polygon = Polygon(tile_rectangle) if outer_polygon.contains( tile_polygon) or outer_polygon.intersects( tile_polygon): minlat = tile_rectangle[3][0] minlon = tile_rectangle[3][1] maxlat = tile_rectangle[1][0] maxlon = tile_rectangle[1][1] f_out.write(' <bounds minlat="%.7f" minlon="%.7f" maxlat="%.7f" maxlon="%.7f" />\n' \ % (minlat-0.0000001, minlon-0.0000001, maxlat+0.0000001, maxlon+0.0000001)) f_out.write("</osm>\n") f_out.close
def import_gpx(self, gpx): """Import GPX track""" def add_middle_points(): """Add middle points for sections skipping tiles""" dx = x - lon[-1] dy = y - lat[-1] if abs(dx) >= 1 or abs(dy) >= 1: nx = int(abs(dx)) ny = int(abs(dy)) n = max(nx, ny) for _ in range(n): lon.append(lon[-1] + dx / (n + 1)) lat.append(lat[-1] + dy / (n + 1)) lat = [] lon = [] gpx_track = gpxpy.parse(open(gpx, 'r')) for track in gpx_track.tracks: for segment in track.segments: for point in segment.points: x, y = utils.deg2num(point.latitude, point.longitude, zoom=self.zoom) # Add middle points in case abs diff >= 1 if len(lat) > 1: add_middle_points() lon.append(x) lat.append(y) return (lon, lat)
def write_josm_file(self, filename, tilezoom=14): """ create a osm file for the editor JOSM, that only contains the download boundary information. Load the file in JOSM and update the data. Note: Please do not missuse this function to download large areas with josm """ from shapely.geometry import LineString, Polygon f_out = open(filename,'w') f_out.write("<?xml version='1.0' encoding='UTF-8'?>\n") f_out.write("<osm version='0.6' upload='true' generator='JOSM'>\n") for i, op in enumerate(self.outer_polygons): # create coordinate list and then a polygon plist = [(node.lat, node.lon) for node in op] outer_polygon = Polygon(LineString(plist)) if not outer_polygon.is_valid: raise ValueError('outer polygon no %i is not valid' % (i+1)) (minlat, minlon, maxlat, maxlon) = outer_polygon.bounds (x1, y2) = deg2num(minlat, minlon, tilezoom) (x2, y1) = deg2num(maxlat, maxlon, tilezoom) for ty in range(y1, y2 + 1): for tx in range(x1, x2 + 1): tile_rectangle = [num2deg(tx, ty, tilezoom), num2deg(tx+1, ty, tilezoom), num2deg(tx+1, ty+1, tilezoom), num2deg(tx, ty+1, tilezoom), num2deg(tx, ty, tilezoom)] tile_polygon = Polygon(tile_rectangle) if outer_polygon.contains(tile_polygon) or outer_polygon.intersects(tile_polygon): minlat = tile_rectangle[3][0] minlon = tile_rectangle[3][1] maxlat = tile_rectangle[1][0] maxlon = tile_rectangle[1][1] f_out.write(' <bounds minlat="%.7f" minlon="%.7f" maxlat="%.7f" maxlon="%.7f" />\n' \ % (minlat-0.0000001, minlon-0.0000001, maxlat+0.0000001, maxlon+0.0000001)) f_out.write("</osm>\n") f_out.close
def test_deg2num(self): x, y, z = utils.deg2num(30, -40, 14) self.assertEqual((x, y, z), (6371, 6759, 14))