0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

HERE Routing API v8 で複数ルートの距離・時間・有料道路料金を一括取得するWebアプリ

0
Posted at

はじめに

業務で「OD間の自動車最短経路(最短距離or最短時間)を一括で調べ、csvに出力したい」という場面に遭遇しました。
Googleマップで一件一件調べるのは非効率なので、座標CSVを投げると距離・所要時間・有料道路料金をまとめて返してくれるWebアプリを作りました。

地図表示・ターンバイターンのナビ案内まで確認できます。

ソースコード:https://github.com/masuda171/zidousya_keisan.git

作ったもの

2026-02-18 15.09の画像.jpeg

2026-02-18 15.10の画像.jpeg

  • CSVで複数の座標ペア(出発地・目的地)をアップロード
  • HERE Routing API v8 で自動車ルートを一括計算
  • 結果(距離・所要時間・有料道路料金)をテーブル表示+CSVエクスポート
  • OpenStreetMap上にルートを色分け表示
  • 料金所名・入口・出口を含む有料道路料金の内訳を表示
  • ターンバイターンの日本語ナビ案内をタイムライン形式で表示

技術スタック

分類 採用技術
フレームワーク Next.js 15 (App Router)
UIライブラリ React 19
地図 Leaflet + react-leaflet
ルートAPI HERE Routing API v8
ポリライン @here/flexpolyline

HERE Routing API とは

HERE が提供するルーティングAPIです。
無料枠(月250,000リクエスト)があり、日本の有料道路料金にも対応しています。

APIキーは HERE Developer Portal で取得できます。

アプリの処理フロー

ユーザーがHERE APIキーを入力
座標ペアを含むCSVをアップロード
HERE Routing API v8へのリクエストを200ms間隔で順次実行
結果を表示・CSV出力

実装のポイント

1. HERE Routing API v8 の呼び出し

const url = new URL("https://router.hereapi.com/v8/routes");
url.searchParams.set("transportMode", "car");
url.searchParams.set("routingMode", "fast");       // 最短時間
url.searchParams.set("departureTime", "any");       // 渋滞なし(標準速度)
url.searchParams.set("return", "summary,tolls,polyline,actions,instructions");
url.searchParams.set("lang", "ja");                // 日本語ナビ案内
url.searchParams.set("apikey", apiKey);
return パラメータで取得する情報を指定しますtolls で料金情報polyline で地図描画用のルート形状instructions でターンバイターンの日本語案内が取得できます

2. 有料道路料金の取り出し現金料金優先

function extractTollCost(data) {
  let total = 0;
  data.routes[0].sections.forEach((section) => {
    (section.tolls || []).forEach((toll) => {
      const fares = toll.fares || [];
      // 現金料金を優先、なければ最初のfareを使用
      const cashFare = fares.find((f) =>
        (f.paymentMethods || []).includes("cash")
      );
      const fare = cashFare ?? fares[0];
      if (fare) total += fare.price?.value ?? 0;
    });
  });
  return total;
}
paymentMethods  "cash" が含まれる fare を優先して取得しますETCと現金で料金が異なる場合があるためです

3. Leaflet  SSR 問題を回避
LeafletはブラウザのWindow APIに依存するためNext.jsのSSRと相性が悪いです


// dynamic importでSSRを無効化
const MapView = dynamic(() => import("./MapView"), { ssr: false });
4. HERE Flexible Polyline のデコード
HERE APIのルート形状は独自形式のFlexible Polylineで返ってきます
@here/flexpolyline パッケージでデコードします

import { decode } from "@here/flexpolyline";

// polyline文字列 → [[lat, lng], ...] の配列に変換
const positions = decode(polylineString).polyline;
5. CSV出力のExcel対応
日本語を含むCSVをExcelで開くと文字化けする問題への対処です


// UTF-8 BOMを先頭に付与
const blob = new Blob(["\uFEFF" + csvContent], {
  type: "text/csv;charset=utf-8;",
});
6. レート制限対策
HERE APIへのリクエストを200ms間隔で順次実行します


for (let i = 0; i < inputRows.length; i++) {
  // ... API呼び出し ...
  if (i < inputRows.length - 1) {
    await new Promise((r) => setTimeout(r, 200));
  }
}
入力CSVのフォーマット

id,origin_lat,origin_lng,dest_lat,dest_lng
1,35.6812,139.7671,34.6937,135.5023
2,35.6812,139.7671,35.0116,135.7681
出力CSVのフォーマット

id,出発地緯度,出発地経度,目的地緯度,目的地経度,距離_km,所要時間_分,有料道路料金_円,ステータス
1,35.6812,139.7671,34.6937,135.5023,519.32,287,6050,成功
ハマったところ
HERE APIのセクション構造
HERE Routing API v8ではルートは複数のセクション区間で構成されています
sections[0] だけを参照するとフェリー区間などを含む長距離ルートで距離時間が欠落することがありました


// NG: セクション0のみ
const dist = data.routes[0].sections[0].summary.length;

// OK: 全セクションを合算
const dist = sections.reduce((sum, s) => sum + (s.summary?.length ?? 0), 0);
ターンバイターンには return=instructions が必要
return=actions だけだと案内テキストが含まれません
instructions も明示的に指定する必要があります


// instructionsを含めないと instruction フィールドが空になる
url.searchParams.set("return", "summary,tolls,polyline,actions,instructions");
おわりに
HERE Routing APIは日本の有料道路料金まで取得できるのが便利です
業務で複数地点間の移動コスト計算が必要な方はぜひ試してみてください

ソースコード: [https://github.com/masuda171/zidousya_keisan.git]


0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?