Enludus
お問い合わせ

歩くか、電車か、車か。経路を比べて決める地図アプリ Useful Map

移動手段ごとの所要時間を比べるための iOS アプリ Useful Map を作った話です。乗換案内は作り直さずに Apple の MapKit で所要時間を出し、運賃や乗換の詳細は Google マップに任せる、という分担にしました。

Useful Map は、目的地まで「歩く・電車・車のどれで行くか」を決めるための地図アプリです。iPhone と iPad で使えて、iOS 17 以上、無料です。2026 年 8 月に App Store で公開しました。

この記事では、何をするアプリなのか、どこを作ってどこを作らなかったのか、作っていてつまずいたところを書きます。

何をするアプリか

歩く・電車・車のどれが良いかは、経路アプリを何度も切り替えないと分かりません。徒歩で調べて、公共交通に切り替えて、車でも見て、頭の中で比べる。Useful Map は、この「比べる」ところだけを引き受けるアプリです。

役割はこう分けています。

  • Useful Map:どの移動手段で行くかを、所要時間で比べて決める
  • Google マップ:決めたあとで、運賃・乗換・駅の中などの詳細を見る

表示するのは所要時間が中心で、公共交通なら出発と到着の時刻も出します。運賃や乗換回数、路線名は出しません。

乗換案内は作らない

最初に決めたのは、乗換案内のエンジンを自分で作らない ことです。時刻表を集めて、乗換を探索して、運賃を計算する。これを個人で作って正しく保ち続けるのは無理があります。

経路の計算は、Apple の MapKit に任せています。iPhone の「マップ」と同じ仕組みで、徒歩・車・公共交通の所要時間を返してくれます。Google の API は使っていません。

ただ、MapKit の公共交通には大きな制約がありました。返ってくるのは 出発時刻・到着時刻・所要時間の 3 つだけ で、どの駅で乗ってどこで降りるのかは分かりません。運賃も乗換も分かりません。

最初の版は、この 3 つをそのまま使って、移動手段ごとの所要時間をカードで並べていました。

「29 分」とだけ出ても決められない

ところが、これを見てもらったときに「29 分とだけ出ても判断材料にならない」という指摘を受けました。たしかに、駅まで 15 分歩くのか、駅が目の前なのかで、同じ 29 分でも選び方は変わります。

そこで、経路を 区間の連なり として見せる形に作り替えました。

現在地
  │ 徒歩 6分
  ▼
御茶ノ水駅(推定)
  │ 公共交通 22分  10:32-10:54
  ▼
東京駅

MapKit は乗る駅を教えてくれないので、出発地と目的地のそれぞれ近くにある駅やバス停を探して、アプリ側で差し込んでいます。これはあくまで推定なので、画面にも「推定」と出し、押せば別の駅に選び直せるようにしました。

区間ごとに、移動手段のアイコンを押すと「公共交通 → 徒歩 → 車」と切り替わります。「駅までは歩かずに車で送ってもらう」といった組み合わせも、その場で試せます。下の「公共交通・徒歩・車」のボタンを押すと、全区間をまとめて切り替えて、合計の時間を比べられます。

現在地から御茶ノ水駅(推定)を経て東京駅までの経路を、徒歩 6 分と公共交通 22 分の区間に分けて表示した画面。下に合計 28 分と、公共交通・徒歩・車のボタンが並ぶ
経路を区間に分けた画面。乗る駅には「推定」と出る

ほかに、こんなこともできます。

  • 出発地と目的地を、ボタン 1 つで入れ替える
  • 区間の途中に経由地を足す
  • 出発時刻・到着時刻を指定する(目的地を探す前に決めておける)
  • 歩く速さを「ゆっくり / ふつう / はやい」で切り替える

歩く速さは人によって違うので、徒歩の区間にだけ係数をかけて補正しています。

最寄りの駅が遠いときは、駅まで歩く区間がとても長くなります。そこで、徒歩が 15 分を超える区間は、途中でバス停などを使えないかを試します。試した結果、合計で 3 分以上速くならなければ、歩きのまま残します。歩いた方が早いなら歩く、という判断です。

画面は地図 1 枚

タブは「地図」と「保存」の 2 つだけにしました。経路は地図の上下に重ねたシートで扱い、経路を見るために別の画面へ移りません。地図の上で線を見ながら、そのまま区間を直せるようにしたかったからです。

地点を直すときも、別の画面は出しません。その場で入力欄に変わり、検索候補が出ます。「現在地」や「地図で選ぶ」も同じ場所から選べ、地図を押すとその地点の名前を引いて差し込みます。

目的地の欄に「東京駅」と入力し、その場に検索候補と「地図で選ぶ」ボタンが出ている画面
目的地の欄がその場で入力欄に変わり、候補が出る

使い方

  1. 地図の上に、出発地・目的地・時刻の 3 行が並んでいます。出発地は最初は現在地です
  2. 目的地の欄を押して、行きたい場所を検索します
  3. 候補を選ぶと、その場で経路が区間に分かれて表示されます
  4. 区間のアイコンを押して移動手段を変えたり、下のボタンで全体を切り替えたりして、合計の時間を比べます
  5. 決めたら、区間の右端の矢印から Google マップを開きます

位置情報の許可を求められたら「App の使用中は許可」を選んでください。許可しない場合も、出発地を検索すれば同じように使えます。

詳細は Google マップへ渡す

運賃や乗換を知りたいときは、区間の右端の矢印を押します。すると、その区間の 2 地点と時刻の条件を引き継いだまま、Google マップが開きます。

Google の API を使わないので、やっていることは URL を組み立てて開くだけです。ただ、Google マップの公式の URL の形式では、出発時刻や到着時刻を指定できません。そこで、Google マップの画面が内部で使っている URL の形を調べて、時刻が入った URL を作っています。

これは公開されていない形式なので、いつ変わってもおかしくありません。そのため 2 つの備えをしています。

  • 時刻付きの URL が開けなかったら、公式の形式に切り替えて開く。時刻は引き継げなくても、地点と移動手段は渡せる
  • 毎朝 1 回、自動で本物の Google マップを開き、地点・移動手段・時刻が保たれているかを確かめる

区間ごとに開くのにも理由があります。Google マップは、公共交通で経由地を含む経路を扱えません。経路全体を渡すと計算できなくなるので、2 地点ずつに分けて渡しています。

つまずいたところ

頼んでいない駅が挟まり、遅くなっていた

実機で私鉄の区間を調べたとき、指定していない途中駅が 2 つ勝手に挟まり、直通なら 26 分の経路が 29 分と表示されていました。

原因は 2 つありました。1 つは、区間ごとの検索がすべて「今から出発」になっていたことです。駅まで 7 分歩くのに、その 7 分を無視して「今出る電車」を探していました。前の区間に着いた時刻から次の区間を探すように直しました。

もう 1 つは、区間を分ける判断が甘かったことです。「合計が 15% 以内の悪化なら分けてよい」としていたので、26 分が 29 分になる分け方が通っていました。待ち時間まで含めて測り、1 秒でも遅くなるなら分けない ようにしました。直通の電車に乗ったままの区間は、途中で区切ると次の便を待つ扱いになって必ず遅くなるので、自然と直通のまま残ります。

Google マップで「見つかりませんでした」

作った URL を実機の Safari で開いたら、「札幌駅が見つかりませんでした」と出ました。地点の部分に、場所の ID の代わりのつもりで入れていた空の値を、Google が本物の ID として探しに行って失敗していたのです。座標だけを渡す形に直したら開けるようになりました。

時刻が 9 時間ずれる

URL に入れる時刻は、普通の時刻の数値(UNIX 時間)とは少し違う意味でした。実際に試すと、「表示したい日付と時刻を、そのまま世界標準時の時刻として数値にしたもの」になっていました。素直に入れると、日本では 9 時間ずれます。この変換は 1 か所に閉じ込め、固定の値でテストしています。

審査で一度差し戻された

最初の審査では、App Store の Guideline 2.1(情報不足)で差し戻されました。審査用のメモは書いていたのに、審査担当者向けの連絡先が空だったのです。提出の仕組みはこれを弾いてくれなかったので、連絡先が入っていなければ提出の処理自体を止めるようにして、出し直しました。

端末の中で完結させる

Useful Map には、アカウントもサーバーもありません。保存した場所と最近の検索・経路は、端末の中にだけ保存します。位置情報は「現在地を出発地にする」ことと「地図に現在地を出す」ことにだけ使い、どこにも送りません。App Store のプライバシーの項目は「データの収集なし」です。

「保存済みと履歴」の画面。保存済みの場所、最近の経路「現在地 → 東京駅」、最近の検索「東京駅」が並ぶ
「保存」タブ。保存した場所と最近の経路・検索は端末の中にだけ残る

位置情報を許可しなくても、出発地を検索して指定すれば、すべての機能が使えます。

保存した場所には「自宅」「学校」のラベルを付けられます。保存した場所は地図の上部にボタンとして並ぶので、よく行く場所はすぐに選べます。

5 つの言語に対応

日本語・英語・簡体字中国語・韓国語・タイ語に対応しています。日本国内を移動する人の中には、日本語を読めない人もいます。端末の言語設定に合わせて自動で切り替わり、時刻の 12 時間制と 24 時間制の違いなども OS の仕組みに任せています。

これから

MapKit の公共交通は、Apple が提供している地域でしか使えません。対応していない地域では「この地域では公共交通の経路を取得できません」と出して、徒歩と車の比較だけを続けます。ここはアプリ側ではどうにもならないところです。

もう 1 つ、コードの中だけにある機能があります。電車の区間で「10:02 発ではなく 10:08 発に乗る」のように出発時刻を決めると、その前後の徒歩などの区間を、その時刻に合わせて取り直す仕組みです。中身はできていますが、画面から時刻を選ぶ操作はまだないので、今のアプリでは使えません。

使ってみて気になったことがあれば、ぜひ教えてください。


MapKit の ETA から区間を組み立てる処理、分割の判定と定数、所要時間を「指紋」にして便を選び直すしくみ、Google マップの URL の作り方と毎日の監視、CI からの App Store 提出まで、コードを引用して追った技術編は「Useful Map の経路計算を全部書く」に書きました。