end0tknr's kipple - web写経開発

太宰府天満宮の狛犬って、妙にカワイイ

Google Maps Platform Directions API + python による道路距離計測

以下を参考に、python による http request の練習

cloud.google.com

qiita.com

で、以下の通り

#!/usr/local/bin/python
# -*- coding: utf-8 -*-
import json
import urllib
import urllib.request
import urllib.parse
import sys

conf = \
    {"req_url" : "https://maps.googleapis.com/maps/api/directions/json",
     "req_opts": {"mode": "driving",
                  "avoid":"tolls|highways"},
#                  "avoid":"tolls|highways|ferries"},
     "api_key" : "ないしょ"}
origins = ["北海道札幌市北区北6条西4丁目",       #札幌駅
           "宮城県仙台市青葉区中央一丁目",       #仙台駅
           "東京都渋谷区道玄坂一丁目",            #渋谷駅
       "愛知県名古屋市中村区名駅1丁目1−4",#名古屋駅
           "大阪市北区芝田一丁目1番2号",         #大阪梅田駅
           "広島県広島市南区松原町2番37号",   #広島駅
           "福岡県福岡市博多区博多駅中央街1−1",#博多駅
           ]


def main():

    pref_cities = load_destinations( sys.argv[1] )
    
    # 出力先fileのopen
    out_f = open("distances.txt", 'w', encoding='utf-8', errors='replace')
    
    for to_pref_city in pref_cities:
        print("\t".join(to_pref_city))
        distances = to_pref_city
        for from_address in origins:
            if len(to_pref_city)<2 or not to_pref_city[1]:
                distances.append("")
            else:
                distance = calc_road_distance(from_address,to_pref_city)
                distances.append(str(distance))
        print("\t".join(distances), file=out_f)
        
    out_f.close()


def load_destinations(destinations_file):

    pref_cities = []
    f = open(destinations_file, mode='r',encoding='utf-8')
    for line in f:
        pref_city = line.split()
        pref_cities.append(pref_city)
    f.close()

    return pref_cities

def calc_road_distance(from_address,to_pref_city):
            
    req_params = conf["req_opts"]
    req_params["origin"] = from_address
    req_params["destination"] =  to_pref_city[0]+""+to_pref_city[1]
    req_params_str = urllib.parse.urlencode(req_params)
    req_url_0 = conf["req_url"] +"?"+ req_params_str
    req_url   = req_url_0 + "&key=" + conf["api_key"]

    req = urllib.request.Request(req_url)
    try:
        res = urllib.request.urlopen(req)
        # requestsモジュールでは、接続と読込両方のtimeout設定可のよう
        # https://blog.cosnomi.com/posts/1259/
#    except (urllib.error.HTTPError, urllib.error.URLError) as err:
    except urllib.error.HTTPError as err:
        print(err.code, req_url_0)
        return None
    except urllib.error.URLError as err:
        print(err.reason, req_url_0)
        return None
    except:
        print("unknown error", req_url_0)
        return None

    content_str = res.read()
    res.close()
    
    content = json.loads(content_str)
    if content['status'] != "OK":
        return None

    # 複数の経路が得られる場合がある為、最短距離を返す
    distances = []
    for routes in content['routes']:
        for legs in routes['legs']:
            distances.append(legs['distance']['value'])
    distance = sorted(distances)
    return distance[0]

            
if __name__ == '__main__':
    main()