Azure Maps Route Range APIの到達圏ポリゴン上限とisSimplifiedPolygonの仕様・制限まとめ

Azure Maps Route Range API を使って到達圏(isochrone)ポリゴンを描こうとすると、ドキュメントに書かれた距離・時間の上限と実際の挙動が違っていてハマりがちです。本記事では、プレビュー版 API で導入された isSimplifiedPolygon パラメーターに注目し、どこまでが仕様でどこからが制約なのか、最新ドキュメントと実測結果を踏まえて整理します。

日程Fit。無料・登録不要。「いつ空いてる?」を、ひとつのリンクで。リンクを送って、○△×でかんたん日程調整。無料で日程を作る。
目次

Azure Maps Route Range API と到達圏ポリゴンの基本

Azure Maps の Route Range API は、ある地点から「何分以内」「何 km 以内」で到達できる範囲をポリゴン(到達圏/isochrone)として返してくれる API です。POST /route/range に GeoJSON の Feature オブジェクトを送り、中心点(Point)と距離または時間の「予算(budget)」を指定すると、中心点と境界ポリゴンがセットで返ります。

リクエストの概念図は以下のようなイメージです。

  • geometry: {"type":"Point","coordinates":[経度, 緯度]}
  • properties.timeBudgetInSec: 例)3,600 秒(60 分)
  • または properties.distanceBudgetInMeters: 例)50,000 m(50 km)
  • オプション: optimizeRoute, travelMode, vehicleSpec など

返り値は FeatureCollection で、中心点(type=center)と境界ポリゴン(type=boundary)の 2 つの Feature が含まれます。

POST https://atlas.microsoft.com/route/range?api-version=2024-07-01-preview
Content-Type: application/geo+json

{
  "type": "Feature",
  "geometry": {
    "type": "Point",
    "coordinates": [ 3.1593, 43.4126 ]  // [経度, 緯度]
  },
  "properties": {
    "timeBudgetInSec": 3600,
    "travelMode": "driving"
  }
}

この基本形に、プレビュー版で追加されたのが isSimplifiedPolygon です。これが今回の「距離・時間の上限が違う」問題のカギになります。

「360 km まで」と書いてあるのに 100 km で BadRequest になる理由

現象のおさらい(2024-07-01-preview + isSimplifiedPolygon=false)

Azure Maps の Microsoft Q&A には、まさに今回と同じ現象が報告されています。

  • API バージョン: 2024-07-01-preview
  • 距離指定: distanceBudgetInMeters=100000
  • isSimplifiedPolygon=false
  • レスポンス: BadRequest(「One or more parameters in the request are invalid.」)
  • 時間指定でも 14,400 秒あたりで失敗
  • 一方で isSimplifiedPolygon=true にすると成功し、さらに距離・時間の上限を伸ばせる

元の質問では、ドキュメントには「360,000 m まで」と書いてあるのに、実際には 100,000 m でエラーになる、との指摘がされています。

POST https://atlas.microsoft.com/route/range?api-version=2024-07-01-preview
{
  "type": "Feature",
  "geometry": {
    "type": "Point",
    "coordinates": [ 3.1593, 43.4126 ]
  },
  "properties": {
    "distanceBudgetInMeters": 100000,
    "optimizeRoute": "shortest",
    "isSimplifiedPolygon": false,
    "travelMode": "driving"
  }
}

これに対して回答では、

  • プレビュー版特有の制約や未更新のドキュメントの可能性
  • isSimplifiedPolygon=true にしてまず試すべき
  • 距離よりも時間予算(timeBudgetInSec)の制限に当たっているケースもある
  • 解消しなければサポート チケットを切るべき

といったコメントが付いています。

ドキュメントの方が後から変更されていた

さらに興味深いのが、Azure API のチェンジログです。2024-07-01-preview の Route Range API について、以下のような変更履歴が公開されています。

項目旧ドキュメント現行ドキュメント
distanceBudgetInMeters
(isSimplifiedPolygon=false)
最大 360,000 m最大 90,000 m
timeBudgetInSec
(isSimplifiedPolygon=false)
最大 14,400 秒最大 3,600 秒
distanceBudgetInMeters
(isSimplifiedPolygon=true)
最大 500,000 m(変更なし)
timeBudgetInSec
(isSimplifiedPolygon=true)
最大 21,600 秒(変更なし)

つまり、

  • 当初のプレビュー ドキュメントには 360,000 m / 14,400 秒 と書かれていた
  • しかし実サービス側の制約はもっと厳しく(おおよそ 100 km / 3,600 秒)、BadRequest が出ていた
  • その後、ドキュメントの方が 90,000 m / 3,600 秒 に修正された

という流れになっていると読み取れます。

現在の公式ドキュメント上の制限値

2025-01-01 の GA 版 Route Range API ドキュメントを見ると、次のように記載されています。

パラメーターisSimplifiedPolygon=falseisSimplifiedPolygon=true
distanceBudgetInMeters最大 90,000 m最大 500,000 m
timeBudgetInSec最大 3,600 秒(1 時間)最大 21,600 秒(6 時間)

プレビュー版 2024-07-01-preview のドキュメントも、現在は同様の説明になっており、Route Range API が「高精細(HD)到達圏ポリゴンをサポートするプレビュー」として紹介されています。

ここから分かるのは、

  • 大きな到達圏を isSimplifiedPolygon=false(非簡略ポリゴン)で求めるのは仕様としてそもそも上限が低い
  • isSimplifiedPolygon=true に切り替えることが、大きな距離・時間を扱うための前提条件

ということです。「360,000 m と書いてあるのに 100,000 m で落ちる」のは、プレビュー初期のドキュメントの数値が実装より緩く書かれていて、のちに 90,000 m / 3,600 秒に修正された、と考えるのが自然です。

isSimplifiedPolygon の役割と内部的な制約のイメージ

isSimplifiedPolygon とは何をしているのか

isSimplifiedPolygon は、その名の通り「ポリゴンを簡略化するかどうか」を指定するフラグです。ドキュメントでは、簡略化により頂点数を減らしつつ形状を保つ、と説明されています。

  • false … より高精細なポリゴン(HD)。頂点数が多く、形状が詳細
  • true … 簡略化されたポリゴン。頂点数が少なく、軽量

高精細ポリゴンは GIS 的には魅力的ですが、その分だけ計算負荷とデータサイズが大きくなります。特に「距離 100 km の到達圏を、道路網を考慮して細かくトレースしたポリゴン」となると、頂点数は膨大になり、

  • ルート探索自体のコスト
  • ポリゴン生成・簡略化アルゴリズムのコスト
  • レスポンス転送のサイズ

などが一気に跳ね上がります。このため、サービス側には「非簡略ポリゴンでは距離・時間の上限を厳しめにする」という実装上の制約が設けられていると考えられます。

非簡略ポリゴンの距離・時間上限が厳しい理由

非簡略ポリゴン(isSimplifiedPolygon=false)の場合に距離 90 km / 時間 60 分までしかサポートされない背景としては、以下のような要因が推測できます。

  • 計算時間の上限: サーバー側のタイムアウトを防ぐため、一定以上の計算量になるリクエストを受け付けない
  • メモリ・CPU の保護: 極端に複雑なポリゴン生成が多数投げられた場合でも、他のユーザーに影響を与えないようにリソースを制御
  • ネットワーク帯域: 非簡略ポリゴンは GeoJSON のサイズも大きくなりがちで、レスポンスが大きくなり過ぎる

実際、Microsoft Q&A の回答でも、isSimplifiedPolygon=true にすることで計算負荷を抑え、より大きな距離・時間を扱えるようにすることが推奨されています。

実測ベースの挙動まとめ(2024-07-01-preview)

前述の Q&A スレッドでは、質問者自身が行った検証結果も共有されています。

指定項目必要な isSimplifiedPolygon備考
distanceBudgetInMeters0 ~ 100,000 mfalse非簡略ポリゴンで取得可
100,001 ~ 500,000 mtrue簡略ポリゴン必須
timeBudgetInSec0 ~ 3,600 秒false非簡略ポリゴンで取得可
3,601 ~ 21,600 秒true簡略ポリゴン必須

これは現行ドキュメントの「非簡略:90,000 m / 3,600 秒」「簡略:500,000 m / 21,600 秒」とほぼ整合しており、

  • ドキュメント(旧版)に書かれていた 360,000 m / 14,400 秒 は実装より緩めの値
  • 実装には初期から 90,000 m / 3,600 秒 相当の制約があり、その後ドキュメントが追いついた

と整理できます。

どう対処すべきか:推奨パターンと回避策

まずは isSimplifiedPolygon=true でリクエストしてみる

距離 100 km 超や時間 1 時間超の到達圏を扱う場合は、まず isSimplifiedPolygon=true を指定して成功するか確認するのが最も手軽です。

{
  "type": "Feature",
  "geometry": {
    "type": "Point",
    "coordinates": [ 3.1593, 43.4126 ]
  },
  "properties": {
    "distanceBudgetInMeters": 200000,   // 200 km
    "optimizeRoute": "shortest",
    "isSimplifiedPolygon": true,        // 簡略化を有効化
    "travelMode": "driving"
  }
}

この設定であれば、ドキュメント上の上限(500,000 m)以内に収まり、実績ベースでも成功しやすいことが報告されています。

時間指定の場合も同様で、6 時間(21,600 秒)程度までは isSimplifiedPolygon=true であれば扱えるとされています。

「簡略化だと粗すぎる」場合の分割アプローチ

ただし、用途によっては「isSimplifiedPolygon=true のポリゴンでは境界が粗く、分析精度が足りない」というケースもあります。その場合の現実解としては、

  • 中心点は同じにしたまま、距離・時間を小さく刻んで非簡略ポリゴンを複数回取得する
  • クライアント側(もしくはサーバー側の自前処理)でそれらのポリゴンを Union(和集合) する

という方法が有効です。

方式概要メリットデメリット
単発・簡略ポリゴンisSimplifiedPolygon=true で 1 回呼び出すAPI 呼び出し回数が少ない/実装が簡単境界が粗くなる場合がある
分割 + 非簡略ポリゴン非簡略(false)で 80~100 km を複数回取得し、自前で結合境界の精度を維持しやすい/用途に応じた細かさをコントロールしやすい呼び出し回数増/Union の実装が必要/レート制限と課金に注意

ポリゴンの結合には、以下のようなツール・ライブラリが利用できます。

  • JavaScript:Turf.js などの GIS ライブラリで union を利用
  • .NET:NetTopologySuite でポリゴンの Union 演算
  • データベース:PostGIS(ST_Union)など

このアプローチであれば、「描画用は簡略ポリゴン」「分析用は非簡略ポリゴンの複数結合」といった使い分けも可能です。

距離指定と時間指定の使い分け

Route Range API では、距離と時間の両方を同時に指定することはできず、どちらか片方を選ぶ必要があります。

  • 距離指定(distanceBudgetInMeters)
    高速道路か一般道かに関わらず「実走距離」で到達圏を見たい場合に向いています。ただし、非簡略ポリゴンでは 90,000 m までという制限がある点に注意が必要です。
  • 時間指定(timeBudgetInSec)
    「30 分圏」「60 分圏」といった時間ベースの到達圏を出したい場合に利用します。非簡略ポリゴンでは 3,600 秒まで、簡略ポリゴンなら 21,600 秒までが上限です。

「できるだけ高精度な非簡略ポリゴンを使いたい」場合は、時間指定で 60 分以内にしておくと、計算範囲を現実的なサイズに抑えやすくなります。

表示用ポリゴンと解析用ポリゴンを分ける

画面に表示するポリゴンと、ビジネスロジックで使うポリゴンを同一にする必要はありません。

  • 画面用:簡略ポリゴン(isSimplifiedPolygon=true)で、描画負荷を低減
  • 解析用:非簡略ポリゴン(isSimplifiedPolygon=false)を複数回取得し、裏側で結合して保持

といった構成にしておくと、ユーザー体験と精度をうまく両立できます。特に Web マップ上で大量の頂点を持つポリゴンをズーム・パンする場合、ブラウザ側の描画性能もボトルネックになりやすいため、用途別のポリゴンを持つ設計はおすすめです。

実装チェックリスト(ハマりどころ再点検)

パラメーター周り

  • 座標順序: [経度, 緯度] が正解です。GeoJSON の仕様に従っているため、一般的な「緯度・経度」の順と逆になりがちなので注意します。
  • distanceBudget と timeBudget は同時指定しない: どちらか一方だけを指定する必要があります。
  • isSimplifiedPolygon の既定値: ドキュメント上は既定値が true になっているため、明示的に false を指定した場合だけ上限が厳しくなります。
  • optimizeRoute: 既定値は fastestWithoutTraffic で、shortest を指定すると形状や計算コストに影響する可能性があります。
  • travelMode: drivingtruck で到達圏が変わります。トラック用の制約を考慮する HD ルーティング機能も存在します。

エラー処理・レート制限

  • BadRequest の中身を見る: 単なる 400 ではなく、レスポンス ボディにエラーコードやメッセージが含まれるため、ログに残すと原因切り分けが楽になります。
  • 上限ギリギリを攻めない: 90,000 m / 3,600 秒 ちょうどではなく、80,000 m / 3,000 秒 程度に余裕を持たせると環境差・将来の仕様変更にも耐えやすくなります。
  • バッチ API 利用時はさらに慎重に: post-route-range-batch では 1 回に 100 件までまとめて処理できますが、1 件あたりの制約は同じです。非簡略ポリゴンで上限に近い値を多数投げると、バッチ単位で失敗しやすくなります。
  • リトライ戦略: BadRequest は通常「再試行しても成功しないエラー」のため、単純リトライではなく、パラメーターを変えて再送する必要があります。

プレビュー版と GA 版の使い分け

Azure Maps の Route API には、v1.0 → v2025-01-01 への移行ガイドが公開されており、Route Range API も新しいバージョン系統に含まれています。

  • プレビュー版(2024-07-01-preview)
    高精細 isochrone(HD polygons)や新しいパラメーターを試せますが、プレビュー利用規約の対象であり、原則として本番利用は推奨されません。
  • GA 版(2025-01-01 など)
    安定性重視で、本番環境向け。記事執筆時点では、HD ポリゴン関連の機能は「簡略ポリゴンのみサポート」といった制限が残っている部分もあります。

要件として「本番サービスで使いたいが、プレビュー利用は避けたい」という場合は、GA 版でどこまで要件を満たせるかを検証し、足りない部分については Azure サポートに相談するのが現実的です。

Azure サポートに問い合わせる際のポイント

ドキュメントと実挙動が食い違っていると感じたら、最終的には Azure サポートに問い合わせるのが最も確実です。その際は、以下の情報を添えると回答が早くなります。

  • 正確なリクエスト内容
    エンドポイント URL(api-version を含む)、リクエスト ボディ JSON、ヘッダー(特に認証関連)
  • レスポンス全文
    HTTP ステータスコード、レスポンス ボディ、ヘッダー領域(x-ms-error-code など)
  • 再現条件
    距離/時間のしきい値、isSimplifiedPolygon の有無、travelMode、optimizeRoute の値など
  • 期待値と実際の違い
    「ドキュメントでは XXX と書かれているが、YYY で失敗する」といった形で、参照したドキュメントの URL も添える

今回のように、チェンジログを見ると「旧ドキュメントの値が後から修正された」ケースもあるため、サポート経由で最新の制約や今後のロードマップを確認しておくと安心です。

サンプル実装(C# / JavaScript)

C#(HttpClient)で Route Range API を呼び出す例

using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Text.Json;

var client = new HttpClient();

var requestBody = new
{
    type = "Feature",
    geometry = new
    {
        type = "Point",
        coordinates = new[] { 3.1593, 43.4126 } // [lon, lat]
    },
    properties = new
    {
        timeBudgetInSec = 7200,          // 2 時間
        isSimplifiedPolygon = true,      // 大きな到達圏なので true
        travelMode = "driving",
        optimizeRoute = "fastestWithoutTraffic"
    }
};

var json = JsonSerializer.Serialize(requestBody);

var request = new HttpRequestMessage(
    HttpMethod.Post,
    "https://atlas.microsoft.com/route/range?api-version=2024-07-01-preview");

request.Content = new StringContent(json, Encoding.UTF8, "application/geo+json");
request.Headers.Add("Subscription-Key", "<YOUR_SUBSCRIPTION_KEY>");

var response = await client.SendAsync(request);
var responseContent = await response.Content.ReadAsStringAsync();

if (!response.IsSuccessStatusCode)
{
    // ログに詳細を出しておくと、後から解析しやすい
    Console.Error.WriteLine($"Status: {response.StatusCode}");
    Console.Error.WriteLine(responseContent);
}

JavaScript(ブラウザ / Node.js)での呼び出し例

const url =
  "https://atlas.microsoft.com/route/range?api-version=2024-07-01-preview";

const body = {
  type: "Feature",
  geometry: {
    type: "Point",
    coordinates: [3.1593, 43.4126]
  },
  properties: {
    distanceBudgetInMeters: 80000,   // 非簡略で扱いやすい距離に抑える
    isSimplifiedPolygon: false,
    travelMode: "driving"
  }
};

fetch(url, {
  method: "POST",
  headers: {
    "Content-Type": "application/geo+json",
    "Subscription-Key": "<YOUR_SUBSCRIPTION_KEY>"
  },
  body: JSON.stringify(body)
})
  .then(async (res) => {
    const json = await res.json();
    if (!res.ok) {
      console.error("Route Range error:", json);
      return;
    }
    // json.features[1] が boundary ポリゴンになっている想定
    console.log("Isochrone polygon:", json);
  })
  .catch((err) => console.error(err));

これらのサンプルをベースに、

  • 距離・時間を変化させて BadRequest が出る境界値を確認する
  • isSimplifiedPolygon の true/false を切り替えて挙動を比較する
  • ポリゴンの頂点数・GeoJSON サイズをログに出しておく

といった検証を行うと、実際のワークロードに対してどの設定が最適か見えてきます。

まとめ:いま押さえておきたいポイント

  • Route Range API の 距離・時間の上限は isSimplifiedPolygon の値で切り替わる(非簡略:90 km / 1 時間、簡略:500 km / 6 時間が目安)。
  • 旧ドキュメントでは 360,000 m / 14,400 秒 と書かれていた時期があり、実装と乖離していたが、現在は 90,000 m / 3,600 秒 に修正されている
  • 大きな到達圏を取りたいときは isSimplifiedPolygon=true が必須。非簡略ポリゴンで無理に距離・時間を伸ばすと BadRequest になりやすい。
  • 簡略ポリゴンでは精度が足りない場合、非簡略ポリゴンを複数回取得して Union する分割アプローチが現実解。
  • 座標順序([経度, 緯度])、距離/時間予算のどちらか片方の指定、プレビュー機能と GA 機能の違いなど、実装時のチェックポイントを押さえておくと、トラブルシューティングが格段に楽になる。
  • ドキュメントと実挙動に差異を感じたら、リクエスト/レスポンスの詳細と共に Azure サポートへ問い合わせることで、最新の制約や既知の問題を確認できる。

Route Range API は、店舗商圏分析や物流ルート設計、公共交通のアクセシビリティ評価など、多くのシナリオで強力な武器になります。一方で、プレビュー版ならではの上限値やドキュメントの揺れも存在します。本記事の内容をベースに、「非簡略でどこまで攻めるか」「簡略ポリゴンで割り切るか」を意識した設計を行えば、Azure Maps の到達圏ポリゴンをより安全かつ効率的に活用できるはずです。

この記事を書いた人

実務の現場で詰まりがちなポイントを地図にするITブログ「IT trip」を運営。Windows/Office(Teams・Excel)からSQL、サーバ運用、ガジェットまで、再現性のある手順と“なぜそうなるか”を丁寧に解説します。読んだらすぐ試せること、そして迷った人の次の一歩が見えることを大切にしています。

コメント

コメントする

目次