Python + folium で Strava の "全"記録を地図で可視化 🚲

昨年から自転車で遠出をする機会が増えて、走ったルートを Garmin Edge で記録していた。Garmin Edge の記録は Garmin ConnectStrava 等の Web サービスで可視化できる

f:id:hiboma:20170315113719p:plain

記録が増えてくると 過去の記録を全部重ね合わせた1枚の地図 を作ったらおもしろいんじゃね?という疑問がでてきた。 自分の知る限りでは複数回の走行記録を表示できるサービスはないようなので自作した

(追記)

Strava で有料プランを使うとよいっぽい。後からみつかるんだよな。こういうの〜〜

blog.strava.com

Python + folium がよいかんじ

いろいろ試行錯誤してみたところ Pythonfolium というライブラリを使うことで 期待に沿った地図がつくれた

過去に記録した緯度・経度をプロットするだけで こんな地図になる。花弁のように青く広がっている線が、私が過去に走行した全軌跡

f:id:hiboma:20170912172822p:plain

地図は HTML + JS で生成されていて、移動やズームできる

f:id:hiboma:20170912180023p:plain

f:id:hiboma:20170315111927p:plain

繰り返し通ったルートは多重の線で判別できる

f:id:hiboma:20170315111953p:plain

画像タイルサーバーと、プロットする線の色・透明度を変更すると情報の見え方が変わる。 濃淡 によってよく通る道が表現される

f:id:hiboma:20170912173340p:plain

f:id:hiboma:20170913093924p:plain

f:id:hiboma:20170913114728p:plain

昨年度に夏季休暇に秋田から仙台まで、今年は東京から仙台まで縦断旅行したが、そのような時系列も軌跡として辿ることができる (注: 私にとっては思い入れのある 夏の軌跡 も、第三者には 鍋底に張り付いたスパゲティの茹でクズ のように見えることだろう 🍝 )

f:id:hiboma:20170912173457p:plain

赤色で箱根の峠道をプロットすると毛細血管のよう見えてグロテスク 💀 色の選択は大事だね

f:id:hiboma:20170316011147p:plain

世界 is 広い

f:id:hiboma:20170912175606p:plain

… とこんな地図が folium のパワーで作れる

マップのつくりかた

GitHub にコードをあげておいた。

github.com

GPX のデータがあれば以下のような手順で作れるはず

$ git clone https://github.com/hiboma/gpx-overlay
$ cd gpx-overlay
$ pip install -r requirements.txt

# activities.zip は strava から取得する
$ unzip -d activities activities.zip
$ bin/overlay.py 
$ open overlay.html

間違い・more better な方法があれば教えていただきたい

1. GPX を用意する

自転車に限らず 緯度・経度のデータがあればなんでもよい。データが必要だ。

Garmin ユーザーであれば Garmin Connect から過去の記録を GPX でエクスポートして、緯度経度を抜き出すことができる。Garmmin Connect では 1個ずつ手動でポチポチしないと エクスポートできないみたいで、量が多い場合はひじょーに面倒

便利: Strava で一括エクスポートする

Strava と連携していれば一括エクスポートが可能で楽ちん

f:id:hiboma:20170316005735p:plain

2. 地図の作成

folium で地図に線を描くインタフェースは下記のような感じで提供されている

import folium

# 緯度・経度
locations= [[35.335545, 139.547333], [35.335533, 139.547348],  ... ] 
line = folium.PolyLine(locations=locations)
osm = folium.Map()
osm.add_child(line)

osm.save('/path/to/map.html')

緯度経度を list で渡すだけ。これだけでインタラクティブな HTMLが生成される (注: よりよい感じにするために 描画の色や透明度、デフォルト表示の緯度経度の指定など詰めていく必要があろう)

性能の評価

GPX のサイズが 285 MB、1031173 件の 緯度\t経度 のリストを扱ったが、初回のHTML生成に要する時間は MacBook Pro (Retina 13-inch、Early 2015) だと 下記の水準

./bin/overlay.py  32.61s user 0.93s system 83% cpu 40.024 total

XML をパースする部分が足を引っ張っていたようなので 2回目以降は pickle 化したキャッシュを使うようにすると そこそこ速くなった。繰り返し作業しててもギリギリストレスにならないレベル

./bin/overlay.py  12.25s user 0.57s system 91% cpu 14.062 total

/usr/bin/time -l で 最大 RSS を取ると下記のような結果 300MB ちょい?

       14.25 real        12.40 user         0.55 sys
 320937984  maximum resident set size 🍣
         0  average shared memory size
         0  average unshared data size
         0  average unshared stack size
    106449  page reclaims
         0  page faults
         0  swaps
         0  block input operations
         5  block output operations
         0  messages sent
         0  messages received
         0  signals received
      1215  voluntary context switches
     35781  involuntary context switches

Web サービスにするならリソースの扱いに一工夫いりそうだが、個人のローカル環境で楽しむ用途なら問題ないだろう

成果物の評価

タイルサーバーにはデフォルトで OpenStreetMap を利用しているらしい。OSM については過去に調べていた

hiboma.hatenadiary.jp

js のライブラリは Leaflet を使っているらしい。フロントエンドには疎いので、どういう素性のものかググって調べた程度しか分からない

感想

  • 自転車に限らず散歩、ランニング、自動車の走行記録からも同様の地図は作れるだろう
  • 他の人のデータと重ね合わせるのも楽しそう
  • 作ってみて分かったが、個人の行動がよく分かるセンシティブなデータでもある
  • Google Photo 等の写真の EXIF から緯度経度を抜き出し、写真へのリンクを貼れると よりたのしい地図になるだろう
  • GPX には緯度経度以外のデータ( 高さ、時刻 ) も付いているが、このスクリプトでは利用できていないので、これらを使った別の表現方法は考えうるだろう
    • ただし、速度の表現は Garmin Connect や Strava 等で高機能なインタフェースで実装されているので、車輪の再開発感はある (ムズカシソウ
  • 生成したデータを地図化して Garmin にインポートすることで 「自分が過去に通ったルート・よく通るルート」 という地図や簡易のナビを作れるだろうか? これは楽しそう
  • 時系列で線の色を分けると、違った特徴が観察できる地図になるだろう (例: 2016年は山によく行っていた、2017年は海にいっていた etc)

プライバシー

自宅周辺の緯度経度が密にプロットされていることもあり、生成した HTML は一般公開はしないので ご了承を 😲

参考にしたリンク

qiita.com

sinhrks.hatenablog.com

sinhrks.hatenablog.com

github.com

pynash.org

pypi.python.org