瓦片地图

瓦片地图

简介

瓦片地图金字塔模型是一种多分辨率层次模型,从瓦片金字塔的底层到顶层,分辨率越来越低,但表示的地理范围不变。

使用场景

在地图上叠加热力图

首先可以用如下函数进行坐标和瓦片的互相转化:

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
import math

TILE_SIZE = 256


def lon_to_pixel_x(lon, zoom):
pixel_x = (lon + 180) / 360 * (TILE_SIZE << zoom)
return pixel_x


def lat_to_pixel_y(lat, zoom):
sin_lat = math.sin(lat * math.pi / 180)
return (0.5 - math.log((1 + sin_lat) / (1 - sin_lat)) / (4 * math.pi)) * (TILE_SIZE << zoom)


def lat_lon_to_tile(lon, lat, zoom):
px = lon_to_pixel_x(lon, zoom)
py = lat_to_pixel_y(lat, zoom)
tx = int(px / TILE_SIZE)
ty = int(py / TILE_SIZE)
return tx, ty


def tile_to_latlon(x, y, z):
n = 2.0 ** z
lon_left = x / n * 360.0 - 180.0
lat_rad = math.atan(math.sinh(math.pi * (1 - 2 * y / n)))
lat_top = math.degrees(lat_rad)

lon_right = (x + 1) / n * 360.0 - 180.0
lat_rad = math.atan(math.sinh(math.pi * (1 - 2 * (y + 1) / n)))
lat_bottom = math.degrees(lat_rad)

return lat_top, lon_left, lat_bottom, lon_right


if __name__ == "__main__":
print(tile_to_latlon(14, 6, 4))
print(lat_lon_to_tile(135, 40.97, 4))

然后还可以使用如下代码的生成瓦片:

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
from PIL import Image


def interpolate_color(config: list, value: int) -> tuple:
if value is None:
return 0, 0, 0, 0
lower_entry = None
higher_entry = None
for entry in config:
if entry[0] <= value:
lower_entry = entry
if entry[0] >= value:
higher_entry = entry
break

if lower_entry is None:
return tuple(higher_entry[1])
elif higher_entry is None:
return tuple(lower_entry[1])

check = (higher_entry[0] - lower_entry[0])
if check == 0:
return lower_entry[1][0], lower_entry[1][1], lower_entry[1][2], 255
else:
ratio = (value - lower_entry[0]) / (higher_entry[0] - lower_entry[0])
result = interpolate_color_between(lower_entry[1], higher_entry[1], ratio)
return result


def interpolate_color_between(color1: tuple, color2: tuple, ratio: int) -> tuple:
r1, g1, b1 = color1
r2, g2, b2 = color2

r = int(r1 + (r2 - r1) * ratio)
g = int(g1 + (g2 - g1) * ratio)
b = int(b1 + (b2 - b1) * ratio)
a = 255
return r, g, b, a


def draw_image(rgba_array: list, width: int, height: int) -> Image:
image = Image.new("RGBA", (width, height))
image.putdata(rgba_array)
return image


def get_rgba_list(data: list, config: dict) -> list:
cache = []
for d in data:
cache.append(interpolate_color(config, d))
return cache


def fake_data_generator(x: int, y: int, value: int) -> list:
cache = []
for i in range(x * y):
cache.append(value)
return cache;


if __name__ == "__main__":
x = 45
y = 45
data = fake_data_generator(45, 45, 305)

config = [
[193, [255, 255, 255]],
[215, [237, 220, 237]],
[230, [227, 204, 229]],
[245, [206, 169, 212]],
[260, [139, 97, 184]],
[275, [51, 76, 160]],
[290, [76, 159, 199]],
[305, [211, 243, 149]],
[320, [248, 144, 43]],
[335, [148, 21, 50]],
[350, [44, 0, 15]],
]
rgba_list = get_rgba_list(data, config)
img = draw_image(rgba_list, y, x).resize((256, 256))
img.save("tile.webp", "WEBP")

瓦片地图
https://wangqian0306.github.io/2024/tile/
作者
WangQian
发布于
2024年4月19日
许可协议