# APIで近くの交通停留所を検索するには？

> ROOTE APIで近くの停留所を検索する方法：座標、半径、JavaScriptの例、結果の読み取りとエラー処理を紹介します。

Source: https://www.roote.ai/ja/guides/api%E3%81%A7%E8%BF%91%E3%81%8F%E3%81%AE%E4%BA%A4%E9%80%9A%E5%81%9C%E7%95%99%E6%89%80%E3%82%92%E6%A4%9C%E7%B4%A2%E3%81%99%E3%82%8B%E6%96%B9%E6%B3%95/
Language: ja
Author: ROOTE

ある地点の周囲の停留所を検索するには、その地点の緯度・経度と半径を近接APIに渡します。返答の状態や返却されたエンティティ、カバレッジ情報を確認してから一覧や地図を表示しましょう。

ROOTE契約 roote-1.0.0 において、GET /v1/transit/nearby のルートは近隣の交通拠点を検出します。発車情報やリアルタイムのアラートは取得しません。拠点の検索とその次の発車の検索は別の操作です。

## パラメータの設定

リクエストではlatが緯度、lngが経度を表します。別名のlonも契約内で説明されています。パラメータradiusはメートル単位の半径を示し、limitは要求する結果の最大数です。フィルターmodesで交通手段を指定できます。

| パラメータ | 例 | 意味 |
| --- | --- | --- |
| lat | 44.8378 | 検索地点の緯度 |
| lng | -0.5792 | 検索地点の経度 |
| radius | 600 | 指定する半径（メートル単位） |
| limit | 10 | 要求する結果の最大数 |
| modes | bus,tram | 検索対象の交通手段 |

これらの座標はボルドーの検索例です；必ずしも停留所を示しているわけではありません。最新の制約、フィールド、条件は [ROOTE OpenAPI契約書](https://api.roote.ai/openapi.json) をご確認ください。

## 最初のサーバーサイドリクエストを送信する

以下はfetchが利用できるNode.js環境向けのJavaScript例です。アクセストークンが必要な場合はサーバーサイドの環境変数に保持します。この例ではブラウザに秘密情報を置く必要はありません。

```
async function rechercherArrets(token = process.env.ROOTE_API_TOKEN) {
  const url = new URL('https://api.roote.ai/v1/transit/nearby');
  url.search = new URLSearchParams({
    lat: '44.8378',
    lng: '-0.5792',
    radius: '600',
    limit: '10',
    modes: 'bus,tram'
  }).toString();

  const headers = { Accept: 'application/json' };
  if (token) headers.Authorization = `Bearer ${token}`;

  const response = await fetch(url, {
    headers,
    signal: AbortSignal.timeout(10000)
  });
  if (!response.ok) {
    throw new Error(`Erreur HTTP ${response.status}`);
  }

  const data = await response.json();
  if (data.contract_version !== 'roote-1.0.0') {
    throw new Error('Version du contrat non reconnue');
  }
  if (!['success', 'empty', 'partial'].includes(data.status)) {
    throw new Error('Recherche indisponible');
  }
  if (!Array.isArray(data.stations)) {
    throw new Error('Réponse sans collection stations valide');
  }

  return {
    status: data.status,
    stations: data.stations,
    lines: data.lines,
    operators: data.operators,
    coverage: data.coverage,
    warnings: data.warnings,
    attributions: data.attributions,
    meta: data.meta
  };
}
```

参照している契約は匿名またはトークンによるアクセスを規定しており、適用されるポリシーに従います。アクセス権や制限を確認してください。HTTPレスポンスが正常でも内容確認は必要です。運用環境ではスキーマによるオブジェクト検証も行いましょう。

## エンティティとその関係を読む

stationsコレクションには返却された拠点が含まれます。それぞれのid、name、entity_kind、location、distance_metersなどを参照してください。line_ids、operator_idsは、linesおよびoperatorsコレクションのデータを紐付けるための参照です。

地理的な距離は距離として表示してください。経路計算なしに徒歩時間に換算しないでください。ガイド [近くの停留所の探し方](https://www.roote.ai/ja/guides/ichiban-chikai-basutei-toramu-teiryuujo-no-mitsukekata/) ではアクセスによって実際の移動が変わる理由を説明しています。

不明な情報も明示的に扱うことが重要です。契約ではaccessibility.wheelchair がunknownの場合がありますが、これはyesやnoとは異なります。発車可能な能力は発車一覧ではありません。

## 一覧または地図で表示する

IDはUI要素の安定化に、名前はラベルに、位置は座標表示に使います。路線は名前で近接させるより、参照で結びつけてください。

表示する路線の色やラベルは外部入力として検証してください。名前は注入HTMLではなくテキストで扱いましょう。

データ提供元の帰属は保持し、契約で必須とされるものは表示してください。

## 空の結果、部分的な返答、エラーの処理

empty は結果がゼロであることを示しますが、交通機関の物理的な不在を証明するものではありません。partial は制限を伴いつつ有用な拠点を含む場合があります。結果と警告を適切に提示しましょう。

coverage、warnings、metaの制限情報を確認してください。切り捨てられた一覧が完全なカバレッジでないこともあります。ネットワークエラーやHTTPエラー時は「停留所なし」と置き換えず、サービス停止を示しましょう。

429エラーの場合はリトライの指針やサービスのHTTPヘッダーを参照し、ループしないように注意してください。

## stations、zones、platformsの区別

entity_kindフィールドは拠点の階層を区別します。近接した結果は異なるプラットフォームの可能性があり、似た名前は異なる情報源のものかもしれません。

単純な近接だけで拠点を自動統合しないでください。サービスが示す関係やIDを使ってください。当社のガイド [GTFS, GTFS-RT, GBFS](https://www.roote.ai/ja/guides/gtfs-gtfs-rt-gbfs-%E3%81%AE%E3%81%A1%E3%81%8C%E3%81%84/) がデータの背景を説明しています。

## 運用環境への統合準備

位置やフィルターが意味のある変化時に検索を行い、同じ呼び出しはまとめ、タイムアウトを設定し、データ種別やサービス状況に応じてキャッシュを制御しましょう。

場所一覧とリアルタイム情報は更新頻度の要件が異なります。完全、空、部分、エラーのレスポンスを検証してからユーザー画面を提供してください。

## 都市サービスへの検索範囲を拡大する

停留所と都市サービスは別々のルートを使用します。同じ地点の周辺でトイレを検索するには、GET /v1/services/nearby ルートに lat と lon を渡し、types=toilets を指定します。modes=toilets をこのルートに送らないでください：この用語は地図のURL用語であり、サービスフィルター用ではありません。

次のJavaScriptの例は半径600メートルのサービスURLを構築します。リクエストは発行しません。前述のHTTPおよび契約制御を再利用してください。期待されるコレクションは stations ではなく services になります。service_type、location、distance_meters、および実際に存在する属性を保持してください。

REST契約には特に toilets、drinking_water、fountain、wifi、parking、charging、aed、locker が記載されています。MCPによって公開されるタイプは異なる場合があります。受け入れ可能なパラメータ、その範囲やアクセス制限については、使用するインターフェースのスキーマを参照してください。

サービスの属性は検索時に開いている保証を意味しません。不明なアクセシビリティはサービスが利用不可であることと同義ではありません。エラーで空のリストが返されたからといってトイレの不存在を証明しません。名前と地点に単純化するのではなく、各ファミリー固有のデータを保持してください。

結合マップには結果をファミリーと識別子で連結してください。Transitから返された停留所を消去せずにサービスのエラーを表示します。検索は同じ地点に集中したままですが、状態やカバレッジは異なる可能性があります。

```
const url = new URL('https://api.roote.ai/v1/services/nearby');
url.search = new URLSearchParams({
  lat: '44.8416106', lon: '-0.5810938',
  radius: '600', limit: '10', types: 'toilets'
}).toString();
console.log(url.toString());
```

[空検索やエラー検索の診断](https://www.roote.ai/ja/guides/api%E7%B5%90%E6%9E%9C%E3%81%AA%E3%81%97%E3%81%A8%E3%82%A8%E3%83%A9%E3%83%BC%E3%81%AE%E9%81%95%E3%81%84/)

[フィルター付きマップをウェブサイトに直接埋め込む](https://www.roote.ai/ja/guides/%E3%82%B5%E3%82%A4%E3%83%88%E3%81%AB%E3%83%A2%E3%83%93%E3%83%AA%E3%83%86%E3%82%A3%E3%83%9E%E3%83%83%E3%83%97%E3%82%92%E7%B5%84%E3%81%BF%E8%BE%BC%E3%82%80%E6%96%B9%E6%B3%95/)

[これらの検索を用いたアシスタントを構築する](https://www.roote.ai/ja/guides/%E3%82%A2%E3%83%89%E3%83%AC%E3%82%B9%E5%91%A8%E8%BE%BA%E3%81%AE%E3%83%A2%E3%83%93%E3%83%AA%E3%83%86%E3%82%A3%E3%82%A2%E3%82%B7%E3%82%B9%E3%82%BF%E3%83%B3%E3%83%88%E3%81%AE%E4%BD%9C%E3%82%8A%E6%96%B9/)

## よくある質問

### Nearbyは次の発車時刻を提供しますか？

ここで示す契約では提供しません。このルートは交通拠点の検索のみで、発車情報は別の能力が必要です。

### エラー後に空一覧を表示してもいいですか？

サービス停止を示すメッセージにしてください。エラーは停留所不在の証明ではありません。

### APIトークンをブラウザに置けますか？

秘密情報はサーバー側に保管すべきです。利用するアプリケーションとアカウントに適したアクセスモデルを使ってください。
