ルート距離・ETA計算 → GPKG保存 → 追加の堅牢化
1) ルート長とETA(徒歩/車)を出す
# ルートの延長[m]は G2 の edge 属性 'length' を合計(OSMnxが付けてくれてます)
meters = sum(ox.utils_graph.get_route_edge_attributes(G2, route, 'length'))
walk_kmh = 4.8 # 歩行速度(必要に応じて変更)
drive_kmh = 20.0 # 災害時の車想定の控えめ値(使うなら)
eta_walk_min = meters / (walk_kmh * 1000 / 60)
eta_drive_min = meters / (drive_kmh * 1000 / 60)
print(f"距離: {meters:.0f} m, 徒歩ETA: {eta_walk_min:.1f} 分, 車ETA(仮): {eta_drive_min:.1f} 分")
を実行すると
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
Cell In[7], line 2
1 # ルートの延長[m]は G2 の edge 属性 'length' を合計(OSMnxが付けてくれてます)
----> 2 meters = sum(ox.utils_graph.get_route_edge_attributes(G2, route, 'length'))
3 walk_kmh = 4.8 # 歩行速度(必要に応じて変更)
4 drive_kmh = 20.0 # 災害時の車想定の控えめ値(使うなら)
AttributeError: module 'osmnx' has no attribute 'utils_graph'
これは OSMnx のAPI変更が原因です。utils_graph.get_route_edge_attributes は環境によって存在しない
# ▼ 距離[m]の取り方をバージョン互換で
try:
# 新しめのOSMnx(推奨): ルートをGDF化して length を合計
route_edges = ox.routing.route_to_gdf(G2, route, fill_edge_geometry=True)
meters = float(route_edges["length"].sum())
except Exception:
# フォールバック: NetworkXからエッジ属性 length を合計
meters = 0.0
for u, v in zip(route[:-1], route[1:]):
ed = G2.get_edge_data(u, v) # MultiDiGraph: {key: attr_dict}
if isinstance(ed, dict) and len(ed):
meters += min(d.get("length", 0.0) for d in ed.values())
# ETA(必要なら速度を調整)
walk_kmh = 4.8
drive_kmh = 20.0
eta_walk_min = meters / (walk_kmh * 1000 / 60)
eta_drive_min = meters / (drive_kmh * 1000 / 60)
print(f"距離: {meters:.0f} m, 徒歩ETA: {eta_walk_min:.1f} 分, 車ETA(仮): {eta_drive_min:.1f} 分")
# Folium のツールチップにも表示
route_latlon = [(G2.nodes[n]["y"], G2.nodes[n]["x"]) for n in route]
folium.PolyLine(
route_latlon, weight=6, opacity=0.9,
tooltip=f"距離 {meters:.0f} m / 徒歩 {eta_walk_min:.1f} 分"
).add_to(m)
に変更
これで
距離: 3017 m, 徒歩ETA: 37.7 分, 車ETA(仮): 9.1 分 <folium.vector_layers.PolyLine at 0x33d5e6650>
となった
約3.0 km / 徒歩 ~38分 / 車 ~9分(仮) は現実的な値
とりあえずやることは
1) ルート長とETA(徒歩/車)を出す
2) ルートを GPKG に属性付きで保存
3) “ネットワーク的に最も近い”安全避難所を選ぶ(推奨)
いまは直線距離で1件選んでいます。候補を直線距離Top Nに絞ってから実際の経路長で最短を選ぶと堅牢
4) 追加の安全策(おすすめ)
* 自宅が浸水域内かを先に判定:内なら「即時・垂直避難」をUIに強調し、経路探索は参考扱いに。
5) 動作チェックのミニ・リスト
* evac.html を開いて、赤いルートが青の浸水域と交差していないか。
* shelters_safe に目的地が含まれているか(含まれなければCSV側の位置精度を見直し)。
* QGISで roads_safe と tsunami_inundation を重ね、視覚的にもOKか。
まずは
1) ルートをGPKGに属性付きで保存
from shapely.geometry import LineString
import geopandas as gpd
route_lonlat = [(G2.nodes[n]["x"], G2.nodes[n]["y"]) for n in route]
route_gdf = gpd.GeoDataFrame(
{"meters":[meters], "eta_min_walk":[eta_walk_min], "eta_min_drive":[eta_drive_min]},
geometry=[LineString(route_lonlat)], crs="EPSG:4326"
)
route_gdf.to_file("outputs/shizuoka_hazard.gpkg", layer="route_latest", driver="GPKG")
2) ルートが浸水域を跨いでないか最終チェック
import geopandas as gpd
ok = not route_gdf.intersects(tsunami.unary_union).iloc[0]
print("交差なし✅" if ok else "⚠️ 交差あり(パラメータ見直し)")
実行結果は
/var/folders/db/tkl5w9dd3kn3h53ctyl4s6180000gn/T/ipykernel_49497/3699053437.py:2: DeprecationWarning: The 'unary_union' attribute is deprecated, use the 'union_all()' method instead. ok = not route_gdf.intersects(tsunami.unary_union).iloc[0]
交差なし✅
となった
DeprecationWarning は unary_union が将来的に非推奨という通知だけなので、動作上は問題ありません。念のため 推奨APIに差し替える
import geopandas as gpd
# ok = not route_gdf.intersects(tsunami.unary_union).iloc[0]
# print("交差なし✅" if ok else "⚠️ 交差あり(パラメータ見直し)")
# 旧: tsunami.unary_union ← 警告が出る
# 新:
flood_union = tsunami.geometry.union_all()
ok = not route_gdf.intersects(flood_union).iloc[0]
print("交差なし✅" if ok else "⚠️ 交差あり(パラメータ見直し)")
これで警告は消える
これを修正したらGPTから
もう一段だけ堅牢に(任意)の項目が提案された
この部分は
3) 安全バッファ付きETA(渋滞・混雑を考慮)
4) Foliumツールチップに表示
の前に行う処理?
と聞いてみる
結論:はい、“堅牢チェック”は 3)安全バッファ付きETA・4)ツールチップ表示の前 にやるのがベストです。
理由:交差や境界ニアミスが見つかったらその経路は捨てて再探索するので、ETAや表示は検証済みルートに対してだけ出すのが安全
おすすめの処理順
1. ルート算出(orig→dest)
2. 堅牢チェック
* union_all() で津波ポリゴン結合
* 交差の有無 → あれば再探索(別避難所 or 半径拡大)
* 交差長[m](=0が理想)
* 近接判定(例:ルート1–5mバッファが浸水域に当たるか)
3. (ここで初めて)距離[m]→ETA計算(徒歩/車+安全係数)
4. Folium描画(ツールチップに距離/ETAを表示)
5. GPKGへ route_latest などを保存
チェック(交差・近接の堅牢判定)→ OKなら保存の順がベスト
不適切なルートをGPKGに残さないため。保存は“合格”ルートだけにしましょう。
とのこと