找到最近的摩拜单车——高德地图API的应用

整体思路

  • 首先,将目标地点转换为相应的经纬度。
  • 然后以经纬度查询附近的摩拜单车,将其标记在地图上。
  • 接着,用起始位置与距离最近的单车位置调用导航API获取路径。
  • 最后将路线绘制在地图上。

使用库与资源

  • 利用现成的API和python简便的网络请求功能以及广泛的第三方库,可以实现很多功能。同理可见一个简单的github 500+赞的python项目分析。
  • 基于高德地图提供的API,我们可以做地理/逆地理编码,路径规划,行政区域查询,搜索,IP定位,抓路服务,批量请求接口,静态地图,坐标转换,天气查询,输入提示,交通态势等等。
  • 本文中,简单调用了地理编码(将详细的结构化地址转换为高德经纬度坐标)和路径规划(导航)API。
  • 并且使用了python封装的基于leaflet的地图库folium快速绘制地图。
  • 此外,摩拜单车位置信息的获取参考思聪前辈的摩拜单车爬虫源码及解析,既然被大神破解了,使用就很简单,返回的单车列表已经是按距离远近排序过的。

效果图

找到最近的摩拜单车——高德地图API的应用_第1张图片
找到最近的摩拜单车——高德地图API的应用_第2张图片

代码

  • 先将key换成你自己的,也可直接使用我的尝试
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=''):
    '''
    由地名获得对应经纬度
    '''
    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  # 纬度,经度!
    except:
        raise Exception(u'无法找到该位置, 请尝试更详细的地址, 如添加省市限定')


def get_nearby_bikes(lat, lng):
    '''
    获取附近的摩拜单车,参考http://www.jianshu.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 = {  # 请求参数: 纬度,经度!
        'latitude': lat,
        'longitude': lng,
    }

    r = requests.post(mobike_url, data=data, headers=headers,
                      timeout=5, verify=False)
    return r.json()


def routeMap(origin, destination):
    '''
    以经纬度起点和终点获取导航路径json数据
    '''
    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数据转换为[[int, int], [int, int]]形式的经纬度列表
    '''
    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)

你可能感兴趣的:(找到最近的摩拜单车——高德地图API的应用)