はじめてのOSMnx　~最短経路探索を添えて~


OSMnxに関する日本語の記事があまりなく，英語弱者の自分には情報収集が大変すぎました...
そこで他の英語弱者の役に立てばいいなと書きました．
なので英語弱者による，英語弱者のための，OSMnx入門記事となります．

#１．OSMnxについて
OSMnxとはなんぞや？と思う人も多いと思うので，初めに少し説明をしておきます．
まずOpenStreetを知っていますか？
###OpenStreetMapとは
wikipediaの地図版だと思って下さい．
誰でも書けて，誰でも使える地図，それが[OpenStreetMap](https://www.openstreetmap.org)です．
この地図には，地名や道路などの情報が書き込まれています．

そしてその情報を使うため開発されたのがOSMnxです．
###OSMnxとは
OpenStreetMapの地図のデータを使うためのPythonのパッケージです．
地図データを取得したり，分析したり，視覚化したりすることができます．

#２．OSMnxをインストールする手順
開発者様が書いたインストール方法で簡単にできたので，それを載せときます．

###STEP1
まず初めにAnacondaを入れましょう．Anacondaの入れ方は[他サイト](https://www.python.jp/install/anaconda/windows/install.html)を参照して下さい．

pipコマンドでやる方法も色んなサイトで示されていますが，Geopandasとかインストールする際にエラーがでて詰まりやすいです(体験談)

###STEP2
Anacondaを入れたら，この２つのコマンドを打つだけです．
```conda config --prepend channels conda-forge```
```conda create -n ox --strict-channel-priority osmnx```

これでもうAnacondaの仮想環境ox上でOSMnxを使える状態となります．

OSMnxを使うときは，Anaconda Promptを開いた時
```activate ox```
とコマンドを打って仮想環境oxに切り替えて下さい．

#３．OSMnxによる最短経路探索
OSMnxのインストール方法だけだとあまりに味気なかったんで，最短経路探索を添えておきます．

今回は東京スカイツリーを中心として道路ネットワークを取得します．
OpenStreetMapで見ると東京スカイツリー周辺の道路はこのような感じです．
<img width="500" alt="tokyoSkyTreeMap.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/551611/43aeb4ee-79b2-74c0-80c8-da7470c93b14.png">

そしてOSMnxで，道路ネットワークを取得し表示した画像です．
<img width="500" alt="tokyoSkyTreeGraph.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/551611/057be591-5b9d-fd93-71c4-8d8c8fa14edc.png">

重ねると一致していることがよくわかると思います．
<img width="500" alt="overlay.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/551611/73e6d75e-a455-1d7d-74d5-f26438f243fe.jpeg">

この道路ネットワークの種類と取得方法を詳しく見ていきましょう．

##道路ネットワークの種類
道路といっても歩行者用もあれば車用もありますよね？
なので色んな種類の道路ネットワークが取得できます．

* 'drive' - 車が通れる公道
* 'drive_service' - 車が通れる公道＋サービス道路を含む？(ここの訳が不明です)
* 'walk' - 歩道
* 'bike' - 自転車が通れる道路
* 'all' - 私道でない全ての道路
* 'all_private' - 私道も含む全ての道路

今回は'drive'の道路ネットワークを取得しています．

##道路ネットワークの取得方法
道路ネットワークの取得する時に

* 緯度と経度
* 地名
* 住所

などのいづれかを指定します．

今回は緯度と経度を指定し，道路ネットワークを取得しています．

###緯度と経度による取得
緯度と経度から道路ネットワークを取得する関数はこれです．
```ox.graph_from_point(center_point, dist=300, network_type='drive')```

* center_point - 緯度，経度の入ったタプル
* dist -　指定した所から何メートル以内のデータを取るか
* network_type - どの種類の道路ネットワークを取るか 

他にも引数はありますが，省略

##最短経路探索
ここまでで道路ネットワークの取得方法見てきました．
道路ネットワークを取得しさえすれば，最短経路探索はこの関数で簡単に計算できます．
```ox.shortest_path(G, orig, dest, weight='length')```

* G - 入力のグラフ
* orig - スタートのノード
* dest - 目標のノード
* weight - 最短経路を求めるときは'length'を入れる

全体のコードは以下のようになります．

```python:shortestPath.py
import osmnx as ox

# 東京スカイツリーの緯度，経度
location_point = (35.7100069, 139.8108103)
# 東京スカイツリーを中心に300m以内の車道のグラフ
G = ox.graph_from_point(location_point, dist=300, network_type='drive')

# 取得した道路ネットワークを表示
ox.plot_graph(G, node_color='r')

# ノードのorigからdestまでの最短ルートを計算
orig = list(G)[0]
dest = list(G)[1]
route = ox.shortest_path(G, orig, dest, weight='length')
#最短ルートを表示
ox.plot_graph_route(G, route, route_color='y', route_linewidth=6, node_size=0)
```

これを実行すると，このようなノードからノードまでの最短経路のグラフが出力されます．
ノードは今回適当に0個目と1個目を選んでいます．

<img width="500" alt="tokyoSkyTreeRoot.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/551611/5fab5c2d-d267-ab6c-ae8d-60ffadf8b575.png">

最短経路っぽいルートがきちんと出力されるのが確認できました．

#参考資料
[開発者様が書いたインストール方法](https://osmnx.readthedocs.io/en/stable/#installation)
[OpenStreetMap](https://www.openstreetmap.org)
[開発者様のGithub](https://github.com/gboeing)
 ・サンプルプログラムが沢山上げられてます
[OSMnxのモジュールの説明](https://osmnx.readthedocs.io/en/stable/index.html)