-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathreq_osm.py
More file actions
160 lines (141 loc) · 5.59 KB
/
req_osm.py
File metadata and controls
160 lines (141 loc) · 5.59 KB
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
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
import random
from overpy import Element
import requests as req
import global_params as gp
def check_key_exist(dict, key):
try:
value = dict[key]
return True
except KeyError:
return False
def get_bbox(city='Irvine', state='ca', country='usa'):
"""
returns a bbox of a certain area (bbox of Irvine, CA by default) \\
bbox is the bounding box arranged in [minLat, maxLat, minLon, maxLon] order \\
user can pass different parameters to get wanted bbox
"""
req_params = {'city':city, 'state':state, 'country':country, 'format':'jsonv2'}
url = 'https://nominatim.openstreetmap.org/search.php'
out = req.get(url, params=req_params)
js = out.json()
return (js[0])['boundingbox'] # a list with 4 strings
def gen_rand_loc(bbox):
"""
return the [lat,lon] of a random location within the bbox \\
Eg: generate a random location on the world: gen_rand_loc([-90, 90, -180, 180])
"""
minLat = float(bbox[0])
maxLat = float(bbox[1])
minLon = float(bbox[2])
maxLon = float(bbox[3])
latRange = maxLat - minLat
latMid = (maxLat+minLat) / 2
lonRange = maxLon - minLon
lonMid = (maxLon+minLon) / 2
lat = random.random()*latRange - latRange/2 + latMid
lon = random.random()*lonRange - lonRange/2 + lonMid
return [lat, lon]
def get_osm_id(lat, lon):
"""
return the osm_id according to the given [lat,lon]
"""
osm_type = ''
osm_id = 0
req_params = {'lat':lat, 'lon':lon, 'zoom':18,'format':'jsonv2'}
# req_params = {'format':'json', 'lat':MYLAT, 'lon':MYLON, 'zoom':18}
# req_params = {'format':'json', 'lat':lat, 'lon':lon, 'zoom':18}
url = 'https://nominatim.openstreetmap.org/reverse.php'
out = req.get(url, params=req_params)
js = out.json()
# print(js)
if(check_key_exist(js, 'osm_type')):
if(js['osm_type'] == 'way'):
# print(out.url)
# print(js)
osm_type = js['osm_type']
osm_id = js['osm_id']
# print(osm_id)
return osm_type, osm_id
def get_roads_query(osm_type, osm_id):
"""
return a "way" query for overpass API based on the osm_id (method 1);
need to get the osm_id first
"""
head = """[out:json][timeout:50];"""
body = osm_type + "(" + str(osm_id)
tail = """);out;"""
built_query = head + body + tail
# print(built_query)
return built_query
def get_way_around_query(lat, lon):
"""
return a "way around" query for overpass API based on the [lat,lon] (method 2)
"""
radius = 20 # unit: meter
head = """[out:json][timeout:50];way[highway](around:"""
body = str(radius) + "," + str(lat) + "," + str(lon)
tail = """);out;"""
built_query = head + body + tail
# print(built_query)
return built_query
def get_maxspeed(lat, lon):
status_code = 999
url_overpass = 'http://overpass-api.de/api/interpreter'
while (status_code >= 400): # try again if client/server error
# osm_id = 0
# osm_type = ''
# # osm_id = 173862443
# while(osm_id == 0 and (not osm_type == 'way')):
# # [lat, lon] = gen_rand_loc(get_bbox())
# [osm_type, osm_id] = get_osm_id(lat, lon)
# built_query = get_roads_query(osm_type, osm_id) # use osm_id
built_query = get_way_around_query(lat, lon) # use [lat,lon]
out = req.get(url_overpass, params={'data':built_query})
status_code = out.status_code
# print(out.url)
# print(out.content)
js = out.json() # this json file is complex, not simply dict
road_name = ''
maxspeed = -1
try:
e = (js['elements'])[0]
# print(e)
if(check_key_exist(e['tags'], 'name')): #
road_name = (e['tags'])['name']
if(check_key_exist(e['tags'], 'maxspeed')): # if maxspeed exist, use this value
maxSpeedStr = ((e['tags'])['maxspeed']).split()
# gp.maxSpeed = maxSpeedStr[0]
# return int(maxSpeedStr[0])
maxspeed = int(maxSpeedStr[0])
elif(check_key_exist(e['tags'], 'highway')): # else if maxspeed not exist
way_type = (e['tags'])['highway']
# refer to https://wiki.openstreetmap.org/wiki/Key:highway for different kinds of road (3.1.1)
# refer to https://en.wikipedia.org/wiki/Speed_limits_in_the_United_States for general speed limitation (see CA)
if(way_type in ['motorway', 'trunk']):
# gp.maxSpeed = 65
# return 65
maxspeed = 65
elif(way_type == 'residential'):
# gp.maxSpeed = 25
maxspeed = 25
elif(way_type in ['primary', 'secondary', 'tertiary', 'unclassified']):
# gp.maxSpeed = 55
maxspeed = 55
else:
print("highway type not specified")
# maxspeed = None
else:
print("not a highway")
# maxspeed = None # use the current speed limit
return [road_name, maxspeed]
except IndexError: # when use "way around" query, the js["elements"] may be empty
print('no way around found')
return [road_name, maxspeed]
if __name__=="__main__":
# simulate the route from my home to UCI (route data in .csv)
# fetch real-time max_speed
route_file = open('./home2uci_route.csv', 'r')
for line in route_file.readlines():
[lat, lon] = line.strip('\n').split(',')
gp.maxSpeed = get_maxspeed(gp.lat, gp.lon)
print('[lat, lon] = [' + lat + ',' + lon + '], current_max_speed = ' + gp.maxSpeed)