OSMxを使い最短経路の算出

OSMxを使い最短経路の算出

東京スカイツリーから
江戸東京博物館への最短経路を算出する

まずはスカイツリーと江戸東京博物館の座標をセットする

skytree = (35.7100,139.8180)
museum = (35.6963,139.7967)

次に一番近い node つまり交差点を取得

始点はスカイツリーなので

start = ox.get_nearest_node(G,skytree)

としたがエラー

--------------------------------------------------------------------------- AttributeError Traceback (most recent call last) Cell In[15], line 1 ----> 1 start = ox.get_nearest_node(G,skytree) AttributeError: module 'osmnx' has no attribute 'get_nearest_node'

これもバージョンの違いが原因

OSMnx 2.x では廃止され、ox.distance サブモジュールに移動
引数は (X=経度, Y=緯度) の順番で渡す必要があります
普通の Point(lon, lat) と同じ並び

start = ox.distance.nearest_nodes(G, X=skytree[1], Y=skytree[0])

とすればOK

同様に終点も

end = ox.distance.nearest_nodes(G,museum[1],museum[0])

次に最短経路

shortest_path = ox.shortest_path(G,start,end)

Foliumで表示できないので調べた

plot_route_folium
https://github.com/gboeing/osmnx/issues/1252
によれば

release (currently 1.9.4), then run your code. The latest v1 release will remain compatible with the v1 API, but any deprecated functionality you’re using will issue a FutureWarning with simple guidance to make it v2 compatible.
Yes, the folium module was deprecated with a warning for removal back in 2023, and finally removed in v2.0.0. The good news: interactive web mapping with folium remains easy to do with OSMnx in ~2 lines of code! See this example in the Examples Gallery for a demonstration.

となっていて
foliumモジュールは2023年に削除の警告とともに非推奨となり、最終的にv2.0.0で削除されました。

とのこと

https://github.com/gboeing/osmnx-examples/blob/main/notebooks/11-interactive-web-mapping.ipynb
のサンプルが参考になりそう

OSMnx 2.0.6 には Folium 専用関数は無い → 自分で PolyLine を追加すればOK

再度GPTでコード生成

route = nx.shortest_path(G, orig, dest, weight="length")

というように

weight="length")

があるので調べた

✅ weight の意味
networkx.shortest_path の weight 引数は、**「どのエッジ属性を最短経路計算に使うか」**を指定するものです。
OSMnx で作成した G(道路グラフ)には、各エッジ(道路の区間)に様々な属性があります:
* “length” : 区間の長さ(メートル単位) ← デフォルトでよく使う
* “travel_time” : 区間の推定走行時間(秒単位)※ ox.add_edge_speeds / ox.add_edge_travel_times を実行した場合のみ
* その他、highway(道路種別)や lanes(車線数)など

✅ 例
1. 最短距離ルート(距離を最小化)

route = nx.shortest_path(G, orig, dest, weight="length")

2. 最短時間ルート(所要時間を最小化)
まず速度と所要時間をエッジに付与してから:

import osmnx as ox

G = ox.add_edge_speeds(G)        # 各道路に推定速度 (km/h) を追加
G = ox.add_edge_travel_times(G)  # 各道路に travel_time (秒) を追加

route = nx.shortest_path(G, orig, dest, weight="travel_time")

✅ まとめ
* weight=”length” → 「最短距離ルート」
* weight=”travel_time” → 「最短時間ルート」
* 他のエッジ属性を指定すれば、それに基づいた経路探索ができる

OSMnxについて

OSMnxについて

OSMは
Open street map の略

pythonで道路ネットワーク分析

も参考にする

先にインストール

pip install osmnx

でインストールできる

import folium
import osmnx as ox
import matplotlib.pyplot as plt
from shapely.geometry import Point,LineString,Polygon

で必要なものをインポート

まずは道路データの取得
今回は取得するのは道路なので drive にする
歩道なら walkなどを指定

Queryでどこの道路データを取るか指定
今回は
日本の東京都の墨田区にするので

query ="Sumidaku,Tokyo,Japan"
G = ox.graph_from_place(query,network_type="drive")

とする

print(G)で表示すると

MultiDiGraph with 3000 nodes and 7834 edges

となる

Nodes は交差点
Edges は道路の数
みたいな感じ

これを foliumで表示する

しかし

ox.plot_graph_folium(G)

だと

---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
Cell In[9], line 1
----> 1 ox.plot_graph_folium(G)

AttributeError: module 'osmnx' has no attribute 'plot_graph_folium'

✅ 背景
* 以前の OSMnx (v1.x くらいまで) には ox.plot_graph_folium(G) がありました。
* しかし OSMnx 2.0 以降では Folium 連携機能は 専用モジュールに移動しています。

from osmnx import folium as ox_folium

を追加
しかしエラーになる

ラッキーピエロ全店を最短でめぐりたい

では

ox.plot.plot_graph_folium

を使っている

ちなみにドキュメントは
https://osmnx.readthedocs.io/en/stable/index.html

調べてもバージョンは2.06で最新

GPTは2.1が最新と言っているが実際は2.06が最新

https://speakerdeck.com/mopinfish/osmnxniyorujie-lu-gou-zao-nofen-xi-toke-shi-hua?slide=20
を参考に行う

pip install contextily
でインストール

📌 まとめ
* contextily = 背景地図を GeoPandas/Matplotlib に簡単に追加するモジュール
* OpenStreetMap などのタイルを呼び出せる
* EPSG:3857(Web地図座標系)に自動変換してくれる

https://qiita.com/yutowac/items/b8e3d7653d3dcad16faf
の場合使っているバージョンが古い可能性がある

import osmnx as ox
import matplotlib.pyplot as plt
import contextily as cx

# 道路ネットワークの取得
place = "Higashi-ku, Sapporo, Hokkaido, Japan"
G = ox.graph_from_place(place, network_type="drive")

# グラフを GeoDataFrame に変換
nodes, edges = ox.graph_to_gdfs(G)

# 地図の作成
fig, ax = plt.subplots(figsize=(15, 15))

# エッジの描画
edges.plot(ax=ax, linewidth=0.5, edgecolor="dimgray")

# 背景地図の追加(OpenStreetMap)
cx.add_basemap(ax, crs=edges.crs.to_string(),
               source=cx.providers.OpenStreetMap.Mapnik)

# 地図の表示
plt.show()

で表示できたので
これを元にGPTでコード生成

import osmnx as ox
import matplotlib.pyplot as plt
import contextily as cx

# 墨田区の道路ネットワークを取得
query = "Sumida-ku, Tokyo, Japan"
G = ox.graph_from_place(query, network_type="drive")

# グラフを GeoDataFrame に変換
nodes, edges = ox.graph_to_gdfs(G)

# 描画
fig, ax = plt.subplots(figsize=(12, 12))

# 道路(edges)を描く
edges.plot(ax=ax, linewidth=0.7, edgecolor="blue")

# 背景地図を追加(OpenStreetMap)
cx.add_basemap(ax,
               crs=edges.crs.to_string(),
               source=cx.providers.OpenStreetMap.Mapnik)

# 表示
plt.show()

これで地図と情報が表示できた

あとは別の方法として
交差点を赤
道路を青
背景を白
で表示する

ox.plot_graph(G,bgcolor="white",node_color="red",edge_color="blue",node_size=2)

で表示はされる
ただし地図にはならない