2014/08/11

[google-places-api-nearby-bus_station] 如何用 Google Places API 取得附近公車站

http://stackoverflow.com/questions/9340800/detect-the-nearest-transit-stop-from-the-given-location

有人問說如何在一個給定的位址(或經緯度)抓取附近的公車站。解答者雖然能用google-place-api取得bus_station,但無法取得公車編號(bus service No, bus stop ID)。 其實仔細爬google place details,連到url還是可能抓到公車編號。
以下是python pseudocode,更詳細作法在https://github.com/MikimotoH/gisTools/blob/master/google_place.py


#!/usr/bin/env python3

def nearby_bus_stations(lat, lng, apikey=""):
    """ Return a list of nearby bus stations around the location
    Args:
        lat: (float) latitude in degrees
        lng: (float) longitude in degrees
        apikey: Google API Key which enables Place API
    Yields:
        tuple(station:str, latitude: float, longitude: float, list[bus: string])
    Example:
        >>> sts = list(nearby_bus_stations(25.021072,121.551788))
        >>> print sts[0]
        ("黎明社教中心", 25.019798, 121.551818, ["懷恩專車S32"])
    """
    places = get_web_json(
        'https://maps.googleapis.com/maps/api/place/nearbysearch/json?' +
        'key=%s&location=%f,%f' % (apikey, lat, lng) +
        '&rankby=distance&language=zh-TW&types=bus_station')
    if places['status'] == 'OK':
        for result in places['results']:
            placeid = result['place_id']
            detail = get_web_json(
                'https://maps.googleapis.com/maps/api/place/details/' +
                'json?key=%s&placeid=%s' % (apikey, placeid) +
                '&language=zh-TW')
            station = detail['result']['name']
            loc = detail['result']['geometry']['location']
            buspage = get_webpage(detail['result']['url'])
            tree = lxml.html.document_fromstring(buspage)
            bus_elm = tree.xpath("/html/body/div[1]/div/div[4]/div[4]/div/div/div[2]/div/div[2]/div[1]/div[2]/div/div/div[2]/div/table/tr/td")[0]
            buses = list(filter(lambda s: len(s.strip()) > 0,
                                bus_elm.text_content().strip().split()))
            yield (station, float(loc['lat']), float(loc['lat']), buses)