Help us understand the problem. What is going on with this article?

Google Map Directions API で日本国内の路線検索はできない

More than 1 year has passed since last update.

概要

最近、帰宅報告なんかを色々なサービス使って作ってる記事が多いじゃないですか。
そういうのの一環で、帰宅報告のついでに帰宅予想時間とか書けると面白そうじゃないかと考えてみたわけですよ。

今から帰ります!
20時25分ぐらいに着くので、よろしくね!

みたいなのですよ。

それで Google Map Directions API 使ってみたんですけど、思ったのじゃなかったですの記事です。

Google Map Directions API

簡単に説明すると、Google Mapの経路検索をAPI化したサービスです。
https://developers.google.com/maps/documentation/directions/?hl=ja

到着時間とかルートを取得できます。
経由地や避けたい場所を指定することも可能なようです。

説明では、使用できる経路が、
- driving (車)
- transit(電車)
- walking(徒歩)
- bicycling (自転車)
となってたので、こいつは使えるはずだ、と意気揚々でしたね。

基本的な使用は無料ですが、使用制限が以下に載ってます。
https://developers.google.com/maps/documentation/directions/usage-limits?hl=ja
1日2500回のリクエストまで無料なので、テスト程度では余裕で使えると思います。

APIキーの取得

使うにはAPIキーが必要です。
上記説明ページ内のキーの取得をクリックしますが、プロジェクト選べ、となります。

project_select.png

Googleの環境にプロジェクトがないと使わせてくれないようです。
+ Create a new project を選択して適当にプロジェクト名を入力します。
NEXTを押すと作成処理が開始、APIキーが生成されます。

スクリーンショット 2018-04-18 0.56.16.png

YOUR API KEY をメモってやってください。

使い方

ここに書いてある通りです。
https://developers.google.com/maps/documentation/directions/start?hl=ja

https://maps.googleapis.com/maps/api/directions/json?origin=Disneyland&destination=Universal+Studios+Hollywood4&key=YOUR_API_KEY

とりあえずサンプル通り上記URLの YOUR_API_KEY を変更すると使えます。

代表的なパラメータは以下でしょうか。

パラメータ名 内容 セットする値
origin 開始地点 エスケープした住所の文字列か、緯度経度の数字をカンマで繋ぐか
destination 到着地点 同上
mode 移動方法 driving、transit、walking、bicycling
units 使用する単位 metric(メートル)、imperial(ヤード)
region 優先する地域コード us、jaなど
departure_time 出発時刻 指定しない場合は現在時刻
arrival_time 到着予定時刻 指定しないとなし

jsonで結果が返ってきます。こんなの。

{
   "geocoded_waypoints" : [
      {
         "geocoder_status" : "OK",
         "place_id" : "ChIJRVY_etDX3IARGYLVpoq7f68",
         "types" : [
            "bus_station",
            "transit_station",
            "point_of_interest",
            "establishment"
         ]
      },
      {
         "geocoder_status" : "OK",
         "partial_match" : true,
         "place_id" : "ChIJp2Mn4E2-woARQS2FILlxUzk",
         "types" : [ "route" ]
      }
   ],
   "routes" : [
      {
         "bounds" : {
            "northeast" : {
               "lat" : 34.1330949,
               "lng" : -117.9143879
            },
            "southwest" : {
               "lat" : 33.8068768,
               "lng" : -118.3527671
            }
         },
         "copyrights" : "Map data ©2016 Google",
         "legs" : [
            {
               "distance" : {
                  "text" : "35.9 mi",
                  "value" : 57824
               },
               "duration" : {
                  "text" : "51 mins",
                  "value" : 3062
               },
               "end_address" : "Universal Studios Blvd, Los Angeles, CA 90068, USA",
               "end_location" : {
                  "lat" : 34.1330949,
                  "lng" : -118.3524442
               },
               "start_address" : "Disneyland (Harbor Blvd.), S Harbor Blvd, Anaheim, CA 92802, USA",
               "start_location" : {
                  "lat" : 33.8098177,
                  "lng" : -117.9154353
               },

  ... Additional results truncated in this example[] ...


         "overview_polyline" : {
            "points" : "knjmEnjunUbKCfEA?_@]@kMBeE@qIIoF@wH@eFFk@WOUI_@?u@j@k@`@EXLTZHh@Y`AgApAaCrCUd@cDpDuAtAoApA{YlZiBdBaIhGkFrDeCtBuFxFmIdJmOjPaChDeBlDiAdD}ApGcDxU}@hEmAxD}[tt@yNb\\yBdEqFnJqB~DeFxMgK~VsMr[uKzVoCxEsEtG}BzCkHhKWh@]t@{AxEcClLkCjLi@`CwBfHaEzJuBdEyEhIaBnCiF|K_Oz\\
            {MdZwAbDaKbUiB|CgCnDkDbEiE|FqBlDsLdXqQra@kX|m@aF|KcHtLm@pAaE~JcTxh@w\\`v@gQv`@}F`MqK`PeGzIyGfJiG~GeLhLgIpIcE~FsDrHcFfLqDzH{CxEwAbBgC|B}F|DiQzKsbBdeA{k@~\\oc@bWoKjGaEzCoEzEwDxFsUh^wJfOySx[uBnCgCbCoFlDmDvAiCr@eRzDuNxC_EvAiFpCaC|AqGpEwHzFoQnQoTrTqBlCyDnGmCfEmDpDyGzGsIzHuZzYwBpBsC`CqBlAsBbAqCxAoBrAqDdDcNfMgHbHiPtReBtCkD|GqAhBwBzBsG~FoAhAaCbDeBvD_BlEyM``@uBvKiA~DmAlCkA|B}@lBcChHoJnXcB`GoAnIS~CIjFDd]A|QMlD{@jH[vAk@`CoGxRgPzf@aBbHoB~HeMx^eDtJ}BnG{DhJU`@mBzCoCjDaAx@mAnAgCnBmAp@uAj@{Cr@wBPkB@kBSsEW{GV}BEeCWyAWwHs@qH?
            cIHkDXuDn@mCt@mE`BsH|CyAp@}AdAaAtAy@lBg@pCa@jE]fEcBhRq@pJKlCk@hLFrB@lD_@xCeA`DoBxDaHvM_FzImDzFeCpDeC|CkExDiJrHcBtAkDpDwObVuCpFeCdHoIl\\uBjIuClJsEvMyDbMqAhEoDlJ{C|J}FlZuBfLyDlXwB~QkArG_AnDiAxC{G|OgEdLaE`LkBbEwG~KgHnLoEjGgDxCaC`BuJdFkFtCgCnBuClD_HdMqEzHcBpB_C|BuEzCmPlIuE|B_EtDeBhCgAdCw@rCi@|DSfECrCAdCS~Di@jDYhA_AlC{AxCcL`U{GvM_DjFkBzBsB`BqDhBaEfAsTvEmEr@iCr@qDrAiFnCcEzCaE~D_@JmFdGQDwBvCeErEoD|BcFjC}DbEuD~D`@Zr@h@?d@Wr@}@vAgCbEaHfMqA`Cy@dAg@bAO`@gCi@w@W"
         },
         "summary" : "I-5 N and US-101 N",
         "warnings" : [],
         "waypoint_order" : []
      }
   ],
   "status" : "OK"
}

とりあえず、routes - legsdistanceduration が距離と時間になるようです。

この辺りをごにょごにょすれば使えるんやで、ということを覚えとけばいいでしょう。

検索してみた

例によってPythonでサンプル作ってみたわけですよ。

import urllib
import json
import os

# 位置座標クラス
class MapCoordinate:
    def __init__(self, latitude, longitude):
        self.latitude = latitude
        self.longitude = longitude

    def position(self):
        return "{0},{1}".format(self.latitude, self.longitude)

# ルートクラス
class MapRoute:
    mode_driving = "driving"
    mode_walking = "walking"
    mode_bicycling = "bicycling"
    mode_transit = "transit"

    def __init__(self, src, dest, mode):
        self.src = src
        self.dest = dest
        self.mode = mode
        self.lang = "ja"
        self.units = "metric"
        self.region = "ja"

# Goolge Map Direction 取得
def getGoogleMapDirection(route):

    # Goolge Map Direction API トークン
    api_key = os.environ["GOOGLE_MAP_API_KEY"]

    # Google Maps Direction API URL
    url = "https://maps.googleapis.com/maps/api/directions/json?origin={0}&destination={1}&mode={2}&language={3}&units={4}&region={5}&key={6}"

    try:
        # GET通信
        api_url = url.format(
            route.src.position(),
            route.dest.position(),
            route.mode,
            route.lang,
            route.units,
            route.region,
            api_key)
        html = urllib.urlopen(api_url)

        html_json = json.loads(html.read().decode('utf-8'))
        return html_json

    except Exception as e:
        raise e

これで、

src = MapCoordinate(34.733165, 135.500214) # 新大阪駅
dest = MapCoordinate(34.686669, 135.519586) # 大阪府庁舎
route = MapRoute(src, dest, MapRoute.mode_transit)

direction_json = getGoogleMapDirection(route)

みたいにして、取得したところ、、、

{
   "available_travel_modes" : [ "DRIVING", "WALKING" ],
   "geocoded_waypoints" : [ {}, {} ],
   "routes" : [],
   "status" : "ZERO_RESULTS"
}

??なんやこの結果?? と思って調べてみたら。

https://stackoverflow.com/questions/36640874/how-to-set-travel-mode-to-transit-in-google-map-direction-api

The Google Maps Directions Service supports all of the transit providers listed in the Transit Coverage List, except for those in Japan.

!?

https://developers.google.com/maps/faq#transit_directions_countries

Google マップのルートサービスでは、交通機関の対象リストに記載されているすべての交通機関(日本を除く)をサポートしています。

なんてこった日本。
何かしらのパワーを感じるぜ、、、

ということで、日本で使用できるのは walkingdriving の2モードのみのようです。

上記の処理を MapRoute.mode_drivingにすると無事結果が返ってきました!

{
   "geocoded_waypoints" : [
      {
         "geocoder_status" : "OK",
         "place_id" : "ChIJJab3ZDnkAGARuP4x7mqZCAM",
         "types" : [ "route" ]
      },
      {
         "geocoder_status" : "OK",
         "place_id" : "ChIJdbNzgi7nAGARndYTVDBnPIo",
         "types" : [ "route" ]
      }
   ],
   "routes" : [
      {
         "bounds" : {
            "northeast" : {
               "lat" : 34.7331109,
               "lng" : 135.5208023
            },
            "southwest" : {
               "lat" : 34.6856258,
               "lng" : 135.4987354
            }
         },
         "copyrights" : "地図データ ©2018 Google, ZENRIN",
         "legs" : [
            {
               "distance" : {
                  "text" : "7.2 km",
                  "value" : 7190
               },
               "duration" : {
                  "text" : "18分",
                  "value" : 1069
               },
               "end_address" : "日本、大阪府大阪市中央区 上町筋",
               "end_location" : {
                  "lat" : 34.6868503,
                  "lng" : 135.520398
               },
               "start_address" : "Unnamed Road, 5丁目-16 西中島 淀川区 大阪市 大阪府 532-0011 日本",
               "start_location" : {
                  "lat" : 34.7330081,
                  "lng" : 135.5002897
               },
               "steps" : [
                  {
                     "distance" : {
                        "text" : "0.3 km",
                        "value" : 261
                     },
                     "duration" : {
                        "text" : "1分",
                        "value" : 67
                     },
                     "end_location" : {
                        "lat" : 34.7314536,
                        "lng" : 135.5001444
                     },
                     "html_instructions" : "\u003cb\u003e東\u003c/b\u003eに進む",
                     "polyline" : {
                        "points" : "ix~rEy{_zXQy@AI@MDYJQJE\\KL?PARD\\H^RXP`@h@n@d@n@h@"
                     },
                     "start_location" : {
                        "lat" : 34.7330081,
                        "lng" : 135.5002897
                     },
                     "travel_mode" : "DRIVING"
                  },
                  {
                     "distance" : {
                        "text" : "0.3 km",
                        "value" : 335
                     },
                     "duration" : {
                        "text" : "1分",
                        "value" : 34
                     },
                     "end_location" : {
                        "lat" : 34.7287408,
                        "lng" : 135.4987354
                     },
                     "html_instructions" : "\u003cb\u003e右側\u003c/b\u003eのランプから \u003cb\u003e難波・淀屋橋\u003c/b\u003e 方面に進む",
                     "polyline" : {
                        "points" : "qn~rE{z_zXtE~CbBbALJVHXD^BbA?L@PF^H"
                     },
                     "start_location" : {
                        "lat" : 34.7314536,
                        "lng" : 135.5001444
                     },
                     "travel_mode" : "DRIVING"
                  },
                  {
                     "distance" : {
                        "text" : "2.9 km",
                        "value" : 2945
                     },
                     "duration" : {
                        "text" : "3分",
                        "value" : 205
                     },
                     "end_location" : {
                        "lat" : 34.7025868,
                        "lng" : 135.5018373
                     },
                     "html_instructions" : "\u003cb\u003e新御堂筋\u003c/b\u003e/\u003cb\u003e国道423号線\u003c/b\u003e に入る",
                     "maneuver" : "merge",
                     "polyline" : {
                        "points" : "s}}rEcr_zX`@AjTGb@?^A^EzFg@f\\_DfHm@d@GtAGL?zQ?bBCjA?vCUjHm@bCS|DOHFlBNx@CdEBz@C`@Eb@Kl@U`@[fA{@d@_@f@Uj@Qb@E`@CfBKlBMjBI~@E"
                     },
                     "start_location" : {
                        "lat" : 34.7287408,
                        "lng" : 135.4987354
                     },
                     "travel_mode" : "DRIVING"
                  },
                  {
                     "distance" : {
                        "text" : "0.9 km",
                        "value" : 854
                     },
                     "duration" : {
                        "text" : "4分",
                        "value" : 220
                     },
                     "end_location" : {
                        "lat" : 34.6979391,
                        "lng" : 135.5062121
                     },
                     "html_instructions" : "\u003cb\u003e国道423号線\u003c/b\u003e を直進する",
                     "maneuver" : "straight",
                     "polyline" : {
                        "points" : "ezxrEoe`zXjBGH?jFKNCfAA|IMRAPELILKJQJ[DQ@MBe@D{BZoKDcBC_A"
                     },
                     "start_location" : {
                        "lat" : 34.7025868,
                        "lng" : 135.5018373
                     },
                     "travel_mode" : "DRIVING"
                  },
                  {
                     "distance" : {
                        "text" : "1.1 km",
                        "value" : 1083
                     },
                     "duration" : {
                        "text" : "4分",
                        "value" : 251
                     },
                     "end_location" : {
                        "lat" : 34.6971247,
                        "lng" : 135.518018
                     },
                     "html_instructions" : "\u003cb\u003e京阪国道\u003c/b\u003e/\u003cb\u003e国道1号線\u003c/b\u003e に入る",
                     "maneuver" : "merge",
                     "polyline" : {
                        "points" : "c}wrEy`azXJmCHmCHoCHmDDcAFqCFqCHiCJuCRmGFeCHkCBu@JcDBaBFwAJcD"
                     },
                     "start_location" : {
                        "lat" : 34.6979391,
                        "lng" : 135.5062121
                     },
                     "travel_mode" : "DRIVING"
                  },
                  {
                     "distance" : {
                        "text" : "1.3 km",
                        "value" : 1260
                     },
                     "duration" : {
                        "text" : "3分",
                        "value" : 171
                     },
                     "end_location" : {
                        "lat" : 34.6858388,
                        "lng" : 135.5174162
                     },
                     "html_instructions" : "\u003cb\u003e東天満(交差点)\u003c/b\u003e を\u003cb\u003e右折\u003c/b\u003eして \u003cb\u003e天満橋筋\u003c/b\u003e/\u003cb\u003e府道30号線\u003c/b\u003e に入る\u003cdiv style=\"font-size:0.9em\"\u003eそのまま 府道30号線 を進む\u003c/div\u003e",
                     "maneuver" : "turn-right",
                     "polyline" : {
                        "points" : "_xwrEsjczXZOdCHdBFh@DdADV@zALxANt@FnBRdBHj@D~CBrFF~K\\dCAfBA|A?r@AT?fCE"
                     },
                     "start_location" : {
                        "lat" : 34.6971247,
                        "lng" : 135.518018
                     },
                     "travel_mode" : "DRIVING"
                  },
                  {
                     "distance" : {
                        "text" : "0.3 km",
                        "value" : 311
                     },
                     "duration" : {
                        "text" : "1分",
                        "value" : 85
                     },
                     "end_location" : {
                        "lat" : 34.6856258,
                        "lng" : 135.5208023
                     },
                     "html_instructions" : "\u003cb\u003e谷町2(交差点)\u003c/b\u003e を\u003cb\u003e左折\u003c/b\u003eして \u003cb\u003e上町筋\u003c/b\u003e に向かう",
                     "maneuver" : "turn-left",
                     "polyline" : {
                        "points" : "oqurE{fczXFcADmBZqN"
                     },
                     "start_location" : {
                        "lat" : 34.6858388,
                        "lng" : 135.5174162
                     },
                     "travel_mode" : "DRIVING"
                  },
                  {
                     "distance" : {
                        "text" : "0.1 km",
                        "value" : 141
                     },
                     "duration" : {
                        "text" : "1分",
                        "value" : 36
                     },
                     "end_location" : {
                        "lat" : 34.6868503,
                        "lng" : 135.520398
                     },
                     "html_instructions" : "\u003cb\u003e府庁南(交差点)\u003c/b\u003e を\u003cb\u003e左折\u003c/b\u003eして \u003cb\u003e上町筋\u003c/b\u003e に入る\u003cdiv style=\"font-size:0.9em\"\u003e目的地は前方左側です\u003c/div\u003e",
                     "maneuver" : "turn-left",
                     "polyline" : {
                        "points" : "epurE_|czXsFnA"
                     },
                     "start_location" : {
                        "lat" : 34.6856258,
                        "lng" : 135.5208023
                     },
                     "travel_mode" : "DRIVING"
                  }
               ],
               "traffic_speed_entry" : [],
               "via_waypoint" : []
            }
         ],
         "overview_polyline" : {
            "points" : "ix~rEy{_zXScAFg@JQJE\\KL?PARD\\H^RXP`@h@~AnAtE~CbBbALJVHx@HpA@p@PlUIbAAzGm@ne@mEzBOxWCbMcAbCS|DOHFlBN~F?z@C`@Eb@Kl@UhBwAd@_@f@Uj@Qb@EhCOxEWjDMtFKNCfAApJOPELIX]Pm@f@_QDcBC_AT{G`@sOrAkd@JyDJcDZOjFPnBJbGf@tE\\jEHrFF~K\\lFCnHGLqDZqNsFnA"
         },
         "summary" : "国道423号線",
         "warnings" : [],
         "waypoint_order" : []
      }
   ],
   "status" : "OK"
}

ということで、使う場合は注意しましょう!

余談

国内の路線データAPIが軒並み有料なのにすごい! と思ってウキウキだったのですが、世の中そんなに甘くないですね。
エンジニアの端くれとして、貴重なデータが安易に無料で使えないのは良いような悪いようなな気分ではあります。

ちなみにこの記事書く為に検索範囲を新大阪駅から大阪駅にして、 transit にして検索してみたところ、なんと結果が返ってきました

ただし、バスと徒歩を駆使した経路になります。なんやそれ。
あくまで路線の検索は不可能、ということのようです。

以上です。

seigo-pon
画像処理とかいろいろやりはじめてます
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした