Skip to content

Commit 1b2f69e

Browse files
authored
Merge pull request #4 from stocc/moving-v0
Moving v0
2 parents 5a1d2d5 + 2fbcdc4 commit 1b2f69e

File tree

18 files changed

+12941
-91
lines changed

18 files changed

+12941
-91
lines changed

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,4 +90,5 @@ ENV/
9090

9191
.idea/
9292

93-
.venv/
93+
.venv/
94+
.vl/

app.py

Lines changed: 28 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313

1414
from lookaround.lookaround.auth import Authenticator
1515
from lookaround.lookaround.geo import wgs84_to_tile_coord
16-
from lookaround.lookaround import get_coverage_tile, fetch_pano_segment, get_pano_segment_url
16+
from lookaround.lookaround import _get_coverage_tile_raw_json, get_coverage_tile, fetch_pano_segment, get_pano_segment_url
1717

1818
from util import CustomJSONEncoder
1919
from geo import haversine_distance
@@ -70,7 +70,7 @@ def relay_road_tile(tint, z, x, y):
7070
url = auth.authenticate_url(
7171
f"https://cdn3.apple-mapkit.com/ti/tile?style=0&size=1&x={x}&y={y}&z={z}&scale=1&lang=en"
7272
f"&poi=1&tint={tint_param}&emphasis=standard")
73-
print(url)
73+
#print(url)
7474
response = requests.get(url)
7575
return send_file(
7676
io.BytesIO(response.content),
@@ -91,7 +91,32 @@ def closest_pano_to_coord(lat, lon):
9191
if distance < smallest_distance:
9292
smallest_distance = distance
9393
closest = pano
94-
return jsonify(closest)
94+
#print(x,y)
95+
return jsonify(date=closest.date,lat = closest.lat, lon = closest.lon, panoid = str(closest.panoid), region_id = str(closest.region_id), unknown10 = closest.unknown10, unknown11 = closest.unknown11, heading = closest.heading)
96+
97+
98+
99+
@app.route("/tile/<float(signed=True):lat>/<float(signed=True):lon>/")
100+
def tile_of_coord(lat, lon):
101+
x, y = wgs84_to_tile_coord(lat, lon, 17)
102+
103+
return jsonify(x=x,y=y)
104+
105+
@app.route("/rawtile/<int:x>/<int:y>/")
106+
def rawtile(x, y):
107+
panos = _get_coverage_tile_raw_json(x, y)
108+
109+
return panos
110+
111+
@app.route("/fullTileInfo/<int:x>/<int:y>/")
112+
def full_tile_coverage_incl_neighbors(x, y):
113+
panos = get_coverage_tile(x, y)
114+
#print(panos)
115+
if len(panos) == 0:
116+
return jsonify(None)
117+
118+
return jsonify(panos)
119+
95120

96121
@app.route("/pano/<int:panoid>/<int:region_id>/<int:zoom>/")
97122
def relay_full_pano(panoid, region_id, zoom):
@@ -104,7 +129,6 @@ def relay_full_pano(panoid, region_id, zoom):
104129
image = None
105130

106131
TILE_SIZE = round(heic_array[0].width * (256 / 5632))
107-
print("TILE_SIZE:", TILE_SIZE)
108132
WIDTH_SIZE = round(heic_array[0].width * (1024 / 5632))
109133
widths, heights = zip(*(i.size for i in heic_array))
110134
total_width, max_height = (sum(widths)-WIDTH_SIZE), max(heights)
@@ -128,7 +152,6 @@ def relay_full_pano(panoid, region_id, zoom):
128152

129153
@app.route("/panodbg/<int:panoid>/<int:region_id>/<int:zoom>/")
130154
def relay_pano_dbg(panoid, region_id, zoom):
131-
print("Starting")
132155
heic_array = []
133156
for i in range(4):
134157
heic_bytes = fetch_pano_segment(panoid, region_id, i, zoom, auth)

lookaround/lookaround/__init__.py

Lines changed: 28 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,39 +2,57 @@
22
import requests
33

44
from .proto import MapTile_pb2
5-
from .geo import wgs84_to_tile_coord
5+
from .geo import wgs84_to_tile_coord, heading_from_unkown10_unknown11
66
from .panorama import LookaroundPanorama
77

8+
from google.protobuf.json_format import MessageToJson
89

9-
def get_coverage_tile_by_latlon(lat, lon):
10-
x, y = wgs84_to_tile_coord(lat, lon, 17)
10+
11+
def get_coverage_tile_by_latlon(lat, lon, tile_z = 17):
12+
x, y = wgs84_to_tile_coord(lat, lon, tile_z)
1113
return get_coverage_tile(x, y)
1214

1315

14-
def get_coverage_tile(tile_x, tile_y):
15-
tile = _get_coverage_tile_raw(tile_x, tile_y)
16+
def get_coverage_tile(tile_x, tile_y, tile_z = 17):
17+
tile = _get_coverage_tile_raw(tile_x, tile_y, tile_z)
1618
panos = []
1719
for pano in tile.pano:
1820
lat, lon = geo.protobuf_tile_offset_to_wgs84(
1921
pano.unknown4.longitude_offset,
2022
pano.unknown4.latitude_offset,
2123
tile_x,
22-
tile_y)
24+
tile_y,
25+
tile_z
26+
)
2327
pano_obj = LookaroundPanorama(
2428
pano.panoid,
2529
tile.unknown13[pano.region_id_idx].region_id,
26-
lat, lon)
30+
lat, lon, pano.unknown4.unknown10, pano.unknown4.unknown11, heading_from_unkown10_unknown11(pano.unknown4.unknown10, pano.unknown4.unknown11))
2731
pano_obj.date = datetime.fromtimestamp(int(pano.timestamp) / 1000.0)
2832
panos.append(pano_obj)
2933
return panos
3034

3135

32-
def _get_coverage_tile_raw(tile_x, tile_y):
36+
def _get_coverage_tile_raw_json(tile_x, tile_y, tile_z = 17):
37+
headers = {
38+
"maps-tile-style": "style=57&size=2&scale=0&v=0&preflight=2",
39+
"maps-tile-x": str(tile_x),
40+
"maps-tile-y": str(tile_y),
41+
"maps-tile-z": str(tile_z),
42+
"maps-auth-token": "w31CPGRO/n7BsFPh8X7kZnFG0LDj9pAuR8nTtH3xhH8=",
43+
}
44+
response = requests.get("https://gspe76-ssl.ls.apple.com/api/tile?", headers=headers)
45+
tile = MapTile_pb2.MapTile()
46+
tile.ParseFromString(response.content)
47+
json_obj = MessageToJson(tile)
48+
return json_obj
49+
50+
def _get_coverage_tile_raw(tile_x, tile_y, tile_z = 17):
3351
headers = {
3452
"maps-tile-style": "style=57&size=2&scale=0&v=0&preflight=2",
3553
"maps-tile-x": str(tile_x),
3654
"maps-tile-y": str(tile_y),
37-
"maps-tile-z": "17",
55+
"maps-tile-z": str(tile_z),
3856
"maps-auth-token": "w31CPGRO/n7BsFPh8X7kZnFG0LDj9pAuR8nTtH3xhH8=",
3957
}
4058
response = requests.get("https://gspe76-ssl.ls.apple.com/api/tile?", headers=headers)
@@ -63,7 +81,7 @@ def get_pano_segment_url(panoid, region_id, segment, zoom, auth):
6381

6482
url = endpoint + f"{panoid_url}/{region_id_padded}/t/{segment}/{zoom}"
6583
url = auth.authenticate_url(url)
66-
print(url)
84+
#print(url)
6785
return url
6886

6987

lookaround/lookaround/geo.py

Lines changed: 51 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
TILE_SIZE = 256
55

66

7-
def protobuf_tile_offset_to_wgs84(x_offset, y_offset, tile_x, tile_y):
7+
def protobuf_tile_offset_to_wgs84(x_offset, y_offset, tile_x, tile_y, tile_z = 17):
88
"""
99
Calculates the absolute position of a pano from the tile offsets returned by the API.
1010
:param x_offset: The X coordinate of the raw tile offset returned by the API.
@@ -15,7 +15,7 @@ def protobuf_tile_offset_to_wgs84(x_offset, y_offset, tile_x, tile_y):
1515
"""
1616
pano_x = tile_x + (x_offset / 64.0) / (TILE_SIZE - 1)
1717
pano_y = tile_y + (255 - (y_offset / 64.0)) / (TILE_SIZE - 1)
18-
lat, lon = tile_coord_to_wgs84(pano_x, pano_y, 17)
18+
lat, lon = tile_coord_to_wgs84(pano_x, pano_y, tile_z)
1919
return lat, lon
2020

2121

@@ -48,3 +48,52 @@ def tile_coord_to_wgs84(x, y, zoom):
4848
world_coord = (pixel_coord[0] / scale, pixel_coord[1] / scale)
4949
lat_lon = mercator_to_wgs84(world_coord[0], world_coord[1])
5050
return lat_lon
51+
52+
53+
54+
'''
55+
Approximate heading of the panorama, assuming the POV is facing
56+
to the left of the Apple Car in cthe direction of driving.
57+
'''
58+
def heading_from_unkown10_unknown11(unknown10, unknown11):
59+
# Whatever is the logic behind this?
60+
# Who at Apple thought of these values?
61+
62+
# unknown10
63+
# These are the extreme values of unkown10 I have observed in a random selection of about 1000 tiles.
64+
# The values are in two clusters.
65+
# In the range [1,2159] you're looking more west than east.
66+
# In the range [14318,16383] you're looking more east than west.
67+
westmin = 1
68+
westmax = 2159
69+
eastmin = 16383 # looking (north/south) and very slightly east
70+
eastmax = 14318 # looking slightly (north/south) directly east
71+
72+
# unknown11
73+
# This is slightly more speculative
74+
northmin = 8204 # this is likely lower
75+
northmax = 6054
76+
southmin = 8204 # this is likely lower
77+
southmax = 10173
78+
79+
80+
ew=0
81+
if unknown10 < westmax:
82+
# Looking west
83+
ew = -(float(unknown10 - westmin) / float(westmax - westmin))
84+
elif unknown10 > eastmax:
85+
# Looking east
86+
ew = (float(unknown10 - eastmin) / float(eastmax - eastmin))
87+
88+
ns=0
89+
if unknown11 <= northmin:
90+
# Looking north
91+
ns = (float(unknown11 - northmin) / float(northmax - northmin))
92+
else:
93+
ns = -(float(unknown11 - southmin) / float(southmax - southmin))
94+
95+
96+
r = math.degrees(math.atan2(ew,ns))
97+
if r < 0:
98+
r += 360
99+
return r

lookaround/lookaround/panorama.py

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,19 @@
11
class LookaroundPanorama:
2-
def __init__(self, panoid, region_id, lat, lon):
2+
def __init__(self, panoid, region_id, lat, lon, unknown10, unknown11, heading):
33
self.panoid = panoid
44
self.region_id = region_id
55
self.lat = lat
66
self.lon = lon
7-
7+
self.unknown10 = unknown10
8+
self.unknown11 = unknown11
89
self.date = None
10+
self.heading = heading
11+
12+
913

1014
def __repr__(self):
1115
return str(self)
1216

1317
def __str__(self):
14-
return f"{self.panoid}/{self.region_id} ({self.lat:.6}, {self.lon:.6}) " \
18+
return f"{self.panoid}/{self.region_id} ({self.lat:.6}, {self.lon:.6}) {self.heading}" \
1519
f"[{self.date.strftime('%Y-%m-%d')}]"
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
import json, numpy
2+
from matplotlib import pyplot as plt
3+
4+
unknown_10s = {}
5+
unknown_11s = {}
6+
7+
for fn in ["eastwestAutobahn.json"]: #, "eow.json"]:
8+
9+
with open(fn, "r") as f:
10+
# import as json
11+
panos = json.load(f)["pano"]
12+
13+
u10 = []
14+
u11 = []
15+
for p in panos:
16+
try:
17+
u10.append(p["unknown4"]["unknown10"])
18+
u11.append(p["unknown4"]["unknown11"])
19+
except:
20+
print(p)
21+
unknown_10s[fn] = u10
22+
unknown_11s[fn] = u11
23+
24+
25+
#print(min(unknown_10s["random.json"]), max(unknown_10s["random.json"]))
26+
#print(min(unknown_11s["random.json"]), max(unknown_11s["random.json"]))
27+
28+
plt.figure(figsize=(20,10))
29+
plt.subplot(2,1,1)
30+
plt.title("unknown10")
31+
#plt.hlines(1,1,20) # Draw a horizontal line
32+
colors=["red", "blue", "green", "black"]
33+
i = 0
34+
for k,v in unknown_10s.items():
35+
plt.eventplot(v, label=k, orientation='horizontal', colors=colors[i], linewidths=0.1)
36+
i += 1
37+
plt.legend()
38+
#plt.axis('off')
39+
plt.subplot(2,1,2)
40+
plt.title("unknown11")
41+
#plt.hlines(1,1,20) # Draw a horizontal line
42+
i = 0
43+
for k,v in unknown_11s.items():
44+
plt.eventplot(v, label=k, orientation='horizontal', colors=colors[i], linewidths=0.1)
45+
i += 1
46+
plt.legend()
47+
#plt.axis('off')
48+
plt.show()
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
import json, numpy
2+
from matplotlib import pyplot as plt
3+
4+
unknown_10s = {}
5+
unknown_11s = {}
6+
7+
for fn in ["random.json"]: #, "eow.json"]:
8+
9+
with open(fn, "r") as f:
10+
# import as json
11+
panos = json.load(f)#["pano"]
12+
13+
u10 = []
14+
u11 = []
15+
for p in panos:
16+
try:
17+
u10.append(p["unknown4"]["unknown10"])
18+
u11.append(p["unknown4"]["unknown11"])
19+
except:
20+
print(p)
21+
unknown_10s[fn] = u10
22+
unknown_11s[fn] = u11
23+
24+
25+
print(min(unknown_10s["random.json"]), max(unknown_10s["random.json"]))
26+
print(min(unknown_11s["random.json"]), max(unknown_11s["random.json"]))
27+
28+
plt.figure(figsize=(20,10))
29+
plt.subplot(2,1,1)
30+
plt.title("unknown10")
31+
#plt.hlines(1,1,20) # Draw a horizontal line
32+
colors=["red", "blue", "green", "black"]
33+
i = 0
34+
for k,v in unknown_10s.items():
35+
plt.eventplot(v, label=k, orientation='horizontal', colors=colors[i], linewidths=0.1)
36+
i += 1
37+
plt.legend()
38+
#plt.axis('off')
39+
plt.subplot(2,1,2)
40+
plt.title("unknown11")
41+
#plt.hlines(1,1,20) # Draw a horizontal line
42+
i = 0
43+
for k,v in unknown_11s.items():
44+
plt.eventplot(v, label=k, orientation='horizontal', colors=colors[i], linewidths=0.1)
45+
i += 1
46+
plt.legend()
47+
#plt.axis('off')
48+
plt.show()
49+
print(numpy.average(unknown_10s["random.json"]))

0 commit comments

Comments
 (0)