整體思路
- 首先线召,將目標地點轉換為相應的經(jīng)緯度。
- 然后以經(jīng)緯度查詢附近的摩拜單車赤炒,將其標記在地圖上。
- 接著亏较,用起始位置與距離最近的單車位置調用導航API獲取路徑莺褒。
- 最后將路線繪制在地圖上。
使用庫與資源
效果圖
代碼
import folium
import subprocess
import requests
from requests.packages.urllib3.exceptions import InsecureRequestWarning
requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
key = 'efb66f1d0e0a897af3702fdb233c0812'
def geoMap(address=u'北京市', city=''):
'''
由地名獲得對應經(jīng)緯度
'''
geoMapUrl = ('http://restapi.amap.com/v3/geocode/geo?'
'key={key}&address={address}&city={city}')
geo_map_url = geoMapUrl.format(key=key, address=address, city=city)
r = requests.get(geo_map_url)
try:
locat = r.json()['geocodes'][0]['location']
lng, lat = locat.split(',')
return lat, lng # 緯度本今,經(jīng)度拆座!
except:
raise Exception(u'無法找到該位置, 請嘗試更詳細的地址, 如添加省市限定')
def get_nearby_bikes(lat, lng):
'''
獲取附近的摩拜單車,參考http://www.reibang.com/p/8662de6f0d7a
'''
mobike_url = "https://mwx.mobike.com/mobike-api/rent/nearbyBikesInfo.do"
headers = {
'referer': "https://servicewechat.com/",
# 'host': "mwx.mobike.com", # host和agent暫時來看沒有影響
# 'user-agent': "MicroMessenger/6.5.4.1000 NetType/WIFI Language/zh_CN"
}
data = { # 請求參數(shù): 緯度冠息,經(jīng)度挪凑!
'latitude': lat,
'longitude': lng,
}
r = requests.post(mobike_url, data=data, headers=headers,
timeout=5, verify=False)
return r.json()
def routeMap(origin, destination):
'''
以經(jīng)緯度起點和終點獲取導航路徑json數(shù)據(jù)
'''
routeMapUrl = ('http://restapi.amap.com/v3/direction/walking?'
'key={key}&'
'origin={origin[1]},{origin[0]}&'
'destination={destination[1]},{destination[0]}')
route_map_url = routeMapUrl.format(key=key,
origin=origin, destination=destination)
r = requests.get(route_map_url)
return r.json()
def json_to_line(json_):
'''
將獲取的導航json數(shù)據(jù)轉換為[[int, int], [int, int]]形式的經(jīng)緯度列表
'''
if json_.get('route', None):
line = []
route = json_['route']
dest = route['destination']
ori = route['origin']
line.append(ori)
for step in route['paths'][0]['steps']:
line.extend(step['polyline'].split(';'))
line.append(dest)
line = [lnglat.split(',')[::-1] for lnglat in line]
line = [[float(lat), float(lng)] for lat, lng in line]
return line
return None
def display_map(where, whereLatLng, markers, html_name):
'''
顯示所有摩拜單車的地點,并畫出從當前點到最近的摩拜的導航路線
'''
tileset = ('https://webrd01.is.autonavi.com/appmaptile?'
'lang=zh_cn&size=1&scale=1&style=8&x={x}&y={y}&z={z}')
# colors = ['green', 'red', 'blue']
map = folium.Map(location=whereLatLng,
zoom_start=7,
tiles=tileset,
attr='附近摩拜單車分布 @ Mobike & Gaode')
for marker in markers:
# import random
# color = random.choice(colors)
folium.Marker(marker,
popup=where,
icon=folium.Icon(color='green')).add_to(map)
json_ = routeMap(whereLatLng, markers[0])
line = json_to_line(json_)
folium.PolyLine(line, color='red').add_to(map)
map.fit_bounds(markers)
map.save(html_name)
command = ['start', html_name]
subprocess.run(command, shell=True)
where = u'西安市鐘樓公交站'
whereLatLng = geoMap(where)
json_ = get_nearby_bikes(*whereLatLng)
if json_.get('object', None):
bikes = json_['object']
markers = [(bike['distY'], bike['distX']) for bike in bikes]
html_name = 'mapBike.html'
display_map(where, whereLatLng, markers, html_name)