🚢

GeoJSONで保存された航跡を可視化する

2023/02/23に公開約3,200字

JM-Safety というアプリを使うと、海上に出たときの航跡を GeoJSON 形式でエクスポートすることができます。海に出た航海の記録を地図上に可視化してみましょう。

航跡の出力

アプリケーションの [設定] タブから [自動航跡] を選択し、エクスポートしたい航跡の […] をタップして、GeoJSON 形式を選択してエクスポートします。

エクスポートした GeoJSON はこんな感じです。 位置情報を計測した座標と、それをつないだラインの情報が格納されているようです。

{
  "type": "FeatureCollection",
  "features": [
    {
      "type": "Feature",
      "geometry": {
        "type": "Point",
        "coordinates": [
          136.84544598030465,
          34.490214499486207
        ]
      },
      "properties": {
        "speed": 0,
        "time": "2023-02-06T06:15:48Z",
        "course": 187.55082230507176
      }
    },
... (snip) ...
    {
      "type": "Feature",
      "geometry": {
        "type": "Point",
        "coordinates": [
          136.89735123931979,
          34.521865794529262
        ]
      },
      "properties": {
        "speed": 7.8675466026004157,
        "time": "2023-02-06T06:38:48Z",
        "course": 101.30644890919768
      }
    },
    {
      "type": "Feature",
      "geometry": {
        "type": "LineString",
        "coordinates": [
          [
            136.84544598030465,
            34.490214499486207
          ],
... (snip) ...
          [
            136.89735123931979,
            34.521865794529262
          ]
        ]
      },
      "properties": {
        "name": "2023-02-06-1515_2023-02-06-1538",
        "color": "#ff00bfff"
      }
    }
  ]
}

地図上への航跡のプロット

folium という、JavaScript のマップライブラリである Leaflet を Python から扱えるようにしたライブラリを用いて、地図上に航跡をプロットしていきます。

まず、folium をインストールしましょう。

$ pip install folium

とりあえず、Jupyter notebook で GeoJSON のファイルを読み込みます。

import json
import folium

with open("2023-02-06-1515_2023-02-06-1538.geojson", 'rt') as f:
    data = json.load(f)

次にマップを作成します。 location で初期値の座標、zoom_start で倍率を設定します。マップは OpenStreetMapを選択しました。

m = folium.Map(
    location=[34.490, 136.895],
    tiles="OpenStreetMap",
    zoom_start=13
)

json をパースして、geometrytypePoint なら Marker を、LineString なら Polylines を追加します。(それにしても、GeoJSON の座標って、なんで緯度と経度が逆なんでしょうね?)

for feature in data['features']:
    if feature['geometry']['type'] == 'Point':
        point = [feature["geometry"]["coordinates"]
                 [1], feature["geometry"]["coordinates"][0]]
        folium.Marker(location=point).add_to(m)
    elif feature['geometry']['type'] == 'LineString':
        coordinates = []
        for c in feature['geometry']['coordinates']:
            coordinates.append((c[1], c[0]))
        folium.PolyLine(coordinates).add_to(m)

Jupyter notebook なら、単にオブジェクトを表示すれば地図が表示されます。

m

マップをファイルに保存したければ、save() を使います。

m.save("index.html")

が、しかしですね、こんなことしなくても、標準機能で GeoJSON をマップにオーバーレイできました。

m2 = folium.Map(
    location=[34.490, 136.895],
    tiles="OpenStreetMap",
    zoom_start=13
)
folium.GeoJson(
    "2023-02-06-1515_2023-02-06-1538.geojson", 
    name="geojson"
).add_to(m2)

m2

参考

Discussion

ログインするとコメントできます