足立区の安全な経路検索サービスを公開しました。
世のため人のため、東京都内でも最も危険な足立区の安全性を高めるべく作成しました。
というのは冗談で、実用性のないお遊びです。
経路検索を行うときに、リスクがある箇所に重みづけして評価するということをやっています。学びを記載します。
作ったWEBサービスの説明
出発地点、到着地点、リスクの重みを指定すると、なるべく交通事故が発生していない、リスクが低そうな車両通行可能な道路を経路検索します
使用技術
- バックエンド: Flask
- フロントエンド: HTML, CSS, JavaScript
- 地図ライブラリ: Leaflet.js, OSMnx
- データ可視化: Folium
- デプロイ: Render.com
学び
交通事故発生箇所とリスク重みづけする地図情報の対応付けがムズイ
地図の道路情報はノードという点と、ノード間を結ぶエッジという線分で構成されています。
ノード、エッジの座標と交通事故発生箇所の座標が完全に一致するわけではありません。
ここで、対応付けの問題が発生します。
事故発生箇所を中心に半径100メートル内のノードに重み付けする案
ノードの配置間隔は一定ではないようで、一般の車両が通れる道路だと、最大200メートル間隔くらいらしい。だから半径100メートルなら最悪でも1ノードは存在するという考えです。
範囲が広すぎて交通事故と関係ない経路にもリスクがついてしまうのでやめました。
事故発生箇所を中心に半径100メートル内のノードに重み付けし、さらに中心からの距離に応じた補正係数をかける案
係数により少ない重みづけにはなるが、交通事故と関係ない経路にリスク加点してしまうのは変わらない。
おやじ狩りリスクポイントを避ける経路検索ならこれでよかったかもしれない
事故発生箇所から最寄りのノードのみをリスク評価対象とする案
よさそうだったが、同じ交差点内に複数ノード存在する場合があった。
交通事故発生箇所からの最寄りノードさえ通らなければ、同じ交差点を通ってもリスク評価しないのは正しく無いように思えたので止めました。
事故発生箇所から最寄りのノードに加えて、事故発生箇所からの距離が僅差かつ隣接しているノードがある場合、リスク評価する案
これにしました
データ量が多くてムズイ
当初は、日本全国経路検索する気でいましたが、とても愚かな考えでした。
リスクの重みづけをするという独自のアルゴリズムを実行する為、自前のバックエンド処理で経路計算を行う必要があります。
個人(しかも無料のデプロイサービスプラン)で全国の経路計算は無理だったので、最も安全な経路検索に意味がありそうな足立区に絞りました。
地図データ切り出し最適化
経路計算につかう地図データはOpenStreetMapから直接ファイルを取得し加工し、読み込む方法もあるようですが、
https://qiita.com/kkdd/items/b30db8fe72ad3861ad74
OSMnx(OpenStreetMapのデータをPythonで扱うライブラリ)を使用して、
下のようにOpenStreetMapから直接取得し、GraphML形式で保存する方法をとりました。
self.G = ox.graph_from_place('足立区, 東京都, 日本', network_type='drive')
ox.save_graphml(self.G, base_graphml_file)
リスク評価を含めてGraphML形式で保存しておくことが可能ですので、
なるべく計算済みのデータを読み込むだけの状態にして遅くならないようにしました。
STRtreeがとにかく早い
仕組み理解していませんが
地理データの世界では定番の高速化手法らしいです。
事故地点から近いノード検索するときに使用しました。
# 空間インデックスを作成
edge_tree = STRtree(edge_geometries)
# 各事故地点について処理
for accident in accident_data_proj.iterrows():
# 近いエッジを検索(100mバッファ)
buffer_dist = 100 # メートル
nearby_indices = edge_tree.query(accident_point.buffer(buffer_dist))
リスクの評価方法がムズイ
あまり安全な経路になってなさそうです。
大きい道路は母数が大きい分、事故が多くなるバイアスがある。
大きい道路を一直線に進むより細めの道路をくねくね進んだほうが安全という評価になってしまう。