よちよちpython

独習 python/Qpython/Pydroid3/termux/Linux

【PythonとAndroid地図アプリOsmAnd】経路座標デー タを取得・加工する

今回は、Androidの地図アプリ OsmAnd を使って

  • 経路座標の取得
  • Pythonによるそのデータ加工

を行います。オフラインで簡単に座標データが取得できます。





実行環境

  • Androidスマホ (全工程で使用)
  • 座標データ取得用
    • Android地図アプリ 「OsmAnd」
  • 座標データ加工用とブログ記事作成用
    • Termux F-Droid版
    • Python 3.10
    • JupyterNotebook



はじめに

Python地図を作成する時に使われるポピュラーなライブラリ folium は、Open Street Map というWikipediaの地図版のような誰でも自由に編集できる地図が使われています。

元々はJavaScriptの地図ライブラリ LeafletPythonで使えるようにしたものが folium です。地図はhtmlで出力・保存できます。JupyterNotebook上で作成すれば直ぐに地図が表示できますし、Webページにしたり貼り付けたりが可能です。



OsmAndによる座標データの取得

folium で地図作成したいとき、地図座標のデータが欲しいことがあります。 (foliumじゃなくても座標や地図が欲しい)
散歩や、自転車・バイク等でのツーリング経路の座標が数秒おきに取得できればなぁ、とか。地域の動植物の調査やマーケティング調査などに利用したい、とか。

座標データの取得はGoogleマップでも可能かも知れませんが、OsmAnd というAndroid地図アプリを使うと、オフラインのまま経路座標の取得ができます。
OsmAndGoogleプレイからダウンロード・インストールできます。

OsmAndアプリは folium と同じく Open Street Map が使われており、 無料 で使えます。煩わしい広告もでません。 そしてかなり多機能です。音声ナビゲーション機能なども付いている。
オプションで有料版もあります。さらなる機能の追加など。

  • リンク

OsmAnd — Maps & GPS Offline - Apps on Google Play



OsmAndの使い方(ザックリ)

ザックリと書きます。

オフラインで地図を表示させるので、表示したい地域の地図をダウンロードする必要があります。

  • マップダウンロード

OsmAndアプリの左下にあるボタンを押す

f:id:chayarokurokuro:20220316014517j:plain

  • オフラインマップをダウンロード保存する

Googleマップでも同じですが、オフラインマップは容量が大きいです。一地域で数百MBほどある。

日本のある地域のオフラインマップを保存したいときは、「アジア → 日本 → 地域選択」で進む。

f:id:chayarokurokuro:20220316015136j:plain

九州をダウンロードした。



  • 保存されると色が変わる

f:id:chayarokurokuro:20220316015222j:plain

九州が黄緑色に変化しています。

  • 未保存地域は表示できない

f:id:chayarokurokuro:20220316015337j:plain

関東地域はまだ保存していないので詳細地図を表示できません。促されています。



  • ダウンロード済み地域の地図を表示

f:id:chayarokurokuro:20220316015442j:plain

f:id:chayarokurokuro:20220316015515j:plain

マッパーと呼ばれるボランティアが地図情報を日々追加しています。Wikipediaのように、登録すれば誰でもマッパーになれ、OpenStreetMap地図の編集ができます。地図情報の追加具合によって、地図の充実度に地域差があります。



  • 旅程・経路記録

マップ左下のボタンから「プラグイン」→「旅程・経路記録」を押す

f:id:chayarokurokuro:20220316015819j:plain

f:id:chayarokurokuro:20220316015920j:plain

f:id:chayarokurokuro:20220316020005j:plain

「ON」にすると、その左側に「設定」ボタンが表示されます。これで経路記録が可能になりました。



経路記録は、スマホGPSをオンにして使います。5秒間隔GPS座標を取得・保存され、時刻と共に gpxファイル に記録されます。

gpxファイル は拡張子が「.gpx」のファイルですが、中身は XML形式 のテキストファイルです。



経路データ(gpxファイル)の取得

上で経路・行程の表示やデータの保存・取得が可能になりましたが、具体的な経路記録方法は省略します。



記録した経路データの gpxファイル は、

  1. 「アプリ左下ボタン」→
  2. プラグイン」→
  3. 「旅程・経路記録」で「ON」にする→
  4. 表示される「設定ボタン」→
  5. 画面一番下の「📁使用した経路」→

ここまで進むと次の画面になります。

f:id:chayarokurokuro:20220316021134j:plain



また同じ名前の「📁使用した経路」ボタン → 「経路データの縦3点リーダーボタン」を押すと、次の画面に。



f:id:chayarokurokuro:20220316021239j:plain

「共有」で gpxファイル を何らかの手段で入手します。ドライブに保存するとか、自分宛にメール送信するとか。
というのは、OsmAndのフォルダが開けない為にそのような手段でやっているのですが、他の方法があれば教えてください。



  • 経路地図

OsmAndアプリで取得した経路地図を表示させると

f:id:chayarokurokuro:20220316023751j:plain

赤い線で経路が表示されています。



以上で、OsmAndアプリで取得した経路座標データの保存とそのファイル(gpxファイル)取得までザックリ書いた。
あとはgpxファイルをfolium用に加工していきます。



Pythonによる経路座標データ(gpxファイル)の編集

ここからはJupyterNotebookを使って経路座標データファイル(gpxファイル)を、folium用に加工する作業に移ります。

  • 経路座標データファイル
# OsmAndで取得した経路座標データファイル
fname = "2022-02-06_15-27_Sun.gpx"
  • Pythonでファイルを開く
with open(fname, mode='r') as f:
    r = f.read()
    print(r)
<?xml version='1.0' encoding='UTF-8' standalone='yes' ?>
<gpx version="1.1" creator="OsmAnd 4.1.11" xmlns="http://www.topografix.com/GPX/1/1" xmlns:osmand="https://osmand.net" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd">
  <metadata>
    <name>2022-02-06_15-27_Sun</name>
  </metadata>
  <trk>
    <trkseg>
      <trkpt lat="33.3027671" lon="130.5579563">
        <ele>84.2</ele>
        <time>2022-02-06T06:27:19Z</time>
        <hdop>7.2</hdop>
        <extensions>
          <osmand:speed>0.6</osmand:speed>
        </extensions>
      </trkpt>
      <trkpt lat="33.3027594" lon="130.5579148">
        <ele>92.9</ele>
        <time>2022-02-06T06:27:25Z</time>
        <hdop>3.9</hdop>
        <extensions>
          <osmand:speed>0.4</osmand:speed>
        </extensions>
      </trkpt>

    (中略 同じようなデータが続く)

  </extensions>
</gpx>

経路座標のファイルは 拡張子が「.gpx」 になっていますが、中身は上で見て分かるように XMLファイル です。

  • 座標の書かれた行だけ取得

「<trkpt lat=」から始まる行に座標が記録されている。この行だけを抜き出します。標準ライブラリの re (正規表現ライブラリ)を使っています。

import re

# 5個だけ取り出してみる
re.findall(r'<trkpt.*>', r)[0:5]
['<trkpt lat="33.3027671" lon="130.5579563">',
 '<trkpt lat="33.3027594" lon="130.5579148">',
 '<trkpt lat="33.3027713" lon="130.557914">',
 '<trkpt lat="33.302769" lon="130.5579141">',
 '<trkpt lat="33.3027669" lon="130.5579148">']

座標の緯度、経度を2次元のリスト形式で取得できれば、foliumで経路地図が作成できる。

上のデータから、さらに不要な部分を削除し、リスト形式に整形していきます。

import re

# 座標データ行のみ取得
origin = re.findall(r'<trkpt.*>', r)

# 上のリストから、座標のみ取得
for i in origin:
    print(re.findall(r'lat=".*" ', i))
    print(re.findall(r'lon=".*"', i))
    print('-'*20)
    
['lat="33.3027671" ']
['lon="130.5579563"']
--------------------
['lat="33.3027594" ']
['lon="130.5579148"']
--------------------
['lat="33.3027713" ']
['lon="130.557914"']
--------------------
['lat="33.302769" ']
['lon="130.5579141"']
--------------------
['lat="33.3027669" ']
['lon="130.5579148"']
--------------------
['lat="33.3027651" ']
['lon="130.5579129"']
(以下省略)



  • 座標だけ取得
import re

# 座標データ行のみ取得
origin = re.findall(r'<trkpt.*>', r)

# 上のリストから、座標のみ取得
strlist = [re.findall('\d{1,8}\.\d{1,8}',i) for i in origin]

strlist[0:3]
[['33.3027671', '130.5579563'],
 ['33.3027594', '130.5579148'],
 ['33.3027713', '130.557914']]
  • 数字が文字列型になっているので、float型に変換する
data = [[float(j) for j in i] for i in strlist]

# 5個だけ表示
data[0:5]
[[33.3027671, 130.5579563],
 [33.3027594, 130.5579148],
 [33.3027713, 130.557914],
 [33.302769, 130.5579141],
 [33.3027669, 130.5579148]]

座標データをファイルに保存

上で加工した座標データは2次元のリスト型です。これを CSVファイル で保存しておきましょうかね。Pandasを使えば保存も読み込みも楽です。

import pandas as pd

# 座標データをCSVファイルで保存
savename = "locations.csv"

df = pd.DataFrame(data)
df
0 1
0 33.302767 130.557956
1 33.302759 130.557915
2 33.302771 130.557914
3 33.302769 130.557914
4 33.302767 130.557915
... ... ...
115 33.301906 130.564784
116 33.301955 130.564830
117 33.301985 130.564841
118 33.302007 130.564844
119 33.302034 130.564849

120 rows × 2 columns

df.to_csv(savename, index=None)
  • 保存されたか確認
!ls |grep locations.csv
locations.csv
  • 読み込めるか確認
# 座標データファイルを読み込み
df_read = pd.read_csv(savename)
df_read
0 1
0 33.302767 130.557956
1 33.302759 130.557915
2 33.302771 130.557914
3 33.302769 130.557914
4 33.302767 130.557915
... ... ...
115 33.301906 130.564784
116 33.301955 130.564830
117 33.301985 130.564841
118 33.302007 130.564844
119 33.302034 130.564849

120 rows × 2 columns

保存と読み込みの確認ができました。



おわりに

データの整形はLinuxコマンドやVimエディタを使うともう少し簡単にできるかも。grepsed コマンドなど。

OsmAndの旅程・経路記録はデフォルトで5秒間隔の記録になっています。1分で12行、10分で120行、1時間だと720行の座標データになります。
foliumで数十もの座標を表示させようとすると、かなりデカいhtmlになります。データ量に気をつけて。



次回は、今回作った経路座標データからfoliumのAntPath というプラグインで経路地図を作ってみます。

【追記】
作ってみました。【foliumプラグインAntPath】OsmAndアプリで取得した経路座標データから経路地図を作成 - よちよちpython
【追記おわり】



以上です。



【参考 関連】