Corin1998 commited on
Commit
2b8854f
·
verified ·
1 Parent(s): 5a131e7

Create providers/navitia.py

Browse files
Files changed (1) hide show
  1. services/providers/navitia.py +42 -0
services/providers/navitia.py ADDED
@@ -0,0 +1,42 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from __future__ import annotations
2
+ import os
3
+ import requests
4
+ from typing import Optional
5
+
6
+ # 使い方:
7
+ # 1) https://www.navitia.io/ でAPIトークンを取得し、環境変数 NAVITIA_TOKEN に設定
8
+ # 2) カバレッジを NAVITIA_COVERAGE(例: "jp-tokyo")に設定
9
+ # 取得できない場合は None を返す(フォールバックはOSRM + 概算運賃)
10
+
11
+ def get_journey(from_lat: float, from_lon: float, to_lat: float, to_lon: float, when_iso: Optional[str] = None) -> Optional[dict]:
12
+ token = os.getenv("NAVITIA_TOKEN")
13
+ coverage = os.getenv("NAVITIA_COVERAGE") # e.g., "jp-tokyo"
14
+ if not token or not coverage:
15
+ return None
16
+ url = f"https://api.navitia.io/v1/coverage/{coverage}/journeys"
17
+ params = {
18
+ "from": f"coord:{from_lon};{from_lat}",
19
+ "to": f"coord:{to_lon};{to_lat}",
20
+ }
21
+ if when_iso:
22
+ params["datetime"] = when_iso.replace(":", "").replace("-", "")
23
+ try:
24
+ r = requests.get(url, params=params, auth=(token, ""), timeout=25)
25
+ r.raise_for_status()
26
+ j = r.json()
27
+ journeys = j.get("journeys") or []
28
+ if not journeys:
29
+ return None
30
+ best = min(journeys, key=lambda x: x.get("duration", 1e12))
31
+ fare_total = None
32
+ if best.get("fare", {}).get("total"):
33
+ # navitiaの金額はcentime等の可能性があるため、そのまま返さず最小単位(value)を使う
34
+ total = best["fare"]["total"]
35
+ if isinstance(total, dict) and "value" in total:
36
+ fare_total = float(total["value"])
37
+ return {
38
+ "duration_s": float(best.get("duration") or 0),
39
+ "fare": fare_total,
40
+ }
41
+ except Exception:
42
+ return None