forked from Hagellach37/tile-downloader
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathlat_long_zoom_to_tile_URL.py
104 lines (87 loc) · 3.32 KB
/
lat_long_zoom_to_tile_URL.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
import os, sys
import math
class Point:
def __init__(self, x=0.0, y=0.0):
self.x = x
self.y = y
class Tile:
def __init__(self, x=0, y=0):
self.x = x
self.y = y
def lat_long_zoom_to_pixel_coords(lat, lon, zoom):
p = Point()
sinLat = math.sin(lat * math.pi/180.0)
x = ((lon + 180) / 360) * 256 * math.pow(2,zoom)
y = (0.5 - math.log((1 + sinLat) / (1 - sinLat)) /
(4 * math.pi)) * 256 * math.pow(2,zoom)
p.x = int(math.floor(x))
p.y = int(math.floor(y))
print("\nThe pixel coordinates are x = {} and y = {}".format(p.x, p.y))
return p
# NOTE - lat_long_zoom_to_pixel_coords and then to a tile will find the tile that
# contains that coordinate - going from tile back to lat long will not (typically)
# return that same coordinate
# I'm unclear if this returns the center of the tile or the top left corner.
def pixel_coords_to_lat_long(p, zoom):
mapsize = 256 * math.pow(2, zoom)
x = (min(max(p.x, 0), mapsize - 1) / mapsize) - 0.5
lon = 360 * x
y = 0.5 - (min(max(p.y, 0), mapsize - 1) / mapsize)
lat = 90 - 360 * math.atan(math.exp(-y * 2 * math.pi)) / math.pi
return lat, lon
def pixel_coords_to_tile_address(x,y):
t = Tile()
t.x = int(math.floor(x / 256))
t.y = int(math.floor(y / 256))
print("\nThe tile coordinates are x = {} and y = {}".format(t.x, t.y))
return t
def tile_address_to_pixel_coords(t):
p = Point()
p.x = t.x * 256
p.y = t.y * 256
return p
def tile_coords_and_zoom_to_quadKey(x, y, zoom):
quadKey = ''
for i in range(zoom, 0, -1):
digit = 0
mask = 1 << (i - 1)
if(x & mask) != 0:
digit += 1
if(y & mask) != 0:
digit += 2
quadKey += str(digit)
print("\nThe quadkey is {}".format(quadKey))
return quadKey
def quadKey_to_url(quadKey):
try:
f = open('cfg/api_key')
api_key = f.read()
except:
print("Something is wrong with your API key.\n"
"Do you even have an API key?")
#TODO get this into a config file, and set up others (Google, OSM, etc)
tile_url = ("http://t0.tiles.virtualearth.net/tiles/a{}.jpeg?"
"g=854&mkt=en-US&token={}".format(quadKey, api_key))
print("\nThe tile URL is: {}".format(tile_url))
return tile_url
def lat_long_zoom_to_quadKey(lat, lon, zoom):
pixel = lat_long_zoom_to_pixel_coords(lat, lon, zoom)
tile = pixel_coords_to_tile_address(pixel.x, pixel.y)
quadKey = tile_coords_and_zoom_to_quadKey(tile.x, tile.y, zoom)
return quadKey
def lat_long_zoom_to_URL(lat, lon, zoom):
pixel = lat_long_zoom_to_pixel_coords(lat, lon, zoom)
tile = pixel_coords_to_tile_address(pixel.x, pixel.y)
quadKey = tile_coords_and_zoom_to_quadKey(tile.x, tile.y, zoom)
tile_url = quadKey_to_url(quadKey)
return tile_url
if __name__ == "__main__":
# This script is intended to provide functions to another script.
# The __main__ function here is for testing and convenience;
# it accepts a latitude, longitude, and zoom level as arguments and
# calls the functions that translate those inputs into a tile URL, which
# is printed to the console along with the pixel and tile coordinates.
lat = float(sys.argv[1])
lon = float(sys.argv[2])
zoom = int(sys.argv[3])
URL = lat_long_zoom_to_URL(lat, lon, zoom)