GIS奮闘記

元GISエンジニアの技術紹介ブログ。主にPythonを使用。

スポンサーリンク

Python と Googleマップのタイムライン機能を使って自分の移動履歴を可視化してみよう!

さて、本日は Googleマップのタイムライン機能を使って自分の移動履歴を可視化してみようと思います。自分の移動履歴が見れるなんて面白そうですね!

タイムライン機能とは?

Googleマップの機能で自分がいる「場所」と「時間」を記録してくれるものです。

どのように記録したデータを利用するのか?

ここから JSON としてタイムライン機能が記録したデータをダウンロードすることができます。ただし、タイムライン機能をオンにしておく必要があるので、使用してみたいという方は先に設定を確認した方がいいかと思います。

appllio.com

どのように可視化するか

以下のエントリーと同じく PyShp と ArcGIS Pro を使用します。

www.gis-py.com

手順

  1. タイムライン機能が記録したデータをダウンロード(KML と JSON をダウンロードできますが、今回は JSON をダウンロードします)
  2. PyShp を使ってJSON を Shape ファイルに変換
  3. ArcGIS Proで可視化

1. JSON をダウンロード

1.https://takeout.google.com/settings/takeout/custom/location_history に行き、「次のステップ」を押します。

f:id:sanvarie:20201010074328p:plain

2.「エクスポートを作成」を押します。

f:id:sanvarie:20201010074407p:plain

3.「ダウンロード」を押します。

f:id:sanvarie:20201010074542p:plain

4.ロケーション履歴.json がダウンロードされます(以下のイメージでは緯度経度をマスキングしています) f:id:sanvarie:20201011212111p:plain

2. PyShp を使って json を Shape ファイルに変換

json をダウンロードしたら次はそれを Shape ファイルに変換します。

実行環境

Windows10 64bit
Python3.6.6
ArcGIS Pro2.6

サンプルコード

少し冗長になってしまいましたが、ロケーション履歴.json を Shape ファイルに変換するサンプルコードです。ポイントとラインの Shape ファイルに変換しています。

# -*- coding: utf-8 -*-
import json
from datetime import datetime
import shapefile

input_file = r"D:\python\data\GoogleMaps\Takeout\ロケーション履歴\ロケーション履歴.json"
output_file_point = r'D:\python\data\googlemaps\timeline_point.shp'
output_file_line = r'D:\python\data\googlemaps\timeline_line.shp'
output_projection_file_point = r'D:\python\data\googlemaps\timeline_point'
output_projection_file_line = r'D:\python\data\googlemaps\timeline_line'

def convert_time(timestamp):
    """ unix 時間を変換"""

    t = datetime.fromtimestamp(float(timestamp)/1000)
    return (t.year, t.month, t.day, t.hour, t.minute, t.second)

def create_projection_file(file):
    """ プロジェクションファイル作成"""

    with open("%s.prj" % file, "w") as prj:
        epsg = 'GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS 84",6378137,298.257223563]],PRIMEM["Greenwich",0],UNIT["degree",0.0174532925199433]]'
        prj.write(epsg)

def create_line():
    """ライン作成"""

    with shapefile.Writer(output_file_line) as w:

        # とりあえず属性は以下の一つとする
        w.field("年月日", "C")

        # json 読込
        json_open = open(input_file, 'r')
        json_load = json.load(json_open)

        verticles = []
        date = ""
        previous_date = ""

        for j in json_load["locations"]:

            timestamp = convert_time(j["timestampMs"])
            lat = float(j["latitudeE7"])/10000000
            lon = float(j["longitudeE7"])/10000000

            # 年月日ごとにラインを作成
            date = str(timestamp[0]) + "/" + str(timestamp[1]) + "/" + str(timestamp[2])

            if (len(verticles) == 0):
                verticles.append([lon, lat])
            elif (previous_date != "" and date != previous_date):

                if(len(verticles) > 1):
                    w.line([verticles])
                    w.record(previous_date)
                    # いったんクリア
                    verticles = []
                    verticles.append([lon, lat])
                elif(len(verticles) == 1):
                    verticles.append([lon, lat])
            else:
                verticles.append([lon, lat])

            previous_date = date

        # 最後ラインを作成
        if(len(verticles) > 0):
            w.line([verticles])
            w.record(previous_date)

        # プロジェクションファイル作成
        create_projection_file(output_projection_file_line)

def create_point():
    """ポイント作成"""

    with shapefile.Writer(output_file_point) as w:

        # とりあえず属性は以下の四つとする
        w.field("年月日", "C")
        w.field("時間", "C")
        w.field("緯度", "F", 12, 6)
        w.field("経度", "F", 12, 6)

        # json 読込
        json_open = open(input_file, 'r')
        json_load = json.load(json_open)
        for j in json_load["locations"]:

            timestamp = convert_time(j["timestampMs"])
            lat = float(j["latitudeE7"])/10000000
            lon = float(j["longitudeE7"])/10000000

            w.point(lon, lat)
            w.record(str(timestamp[0]) + "/" + str(timestamp[1]) + "/" + str(timestamp[2]),
                     str(timestamp[3]) + ":" + str(timestamp[4]) + ":" + str(timestamp[5]),
                     lat,
                     lon)

        # プロジェクションファイル作成
        create_projection_file(output_projection_file_point)

if __name__ == '__main__':
    create_point()
    create_line()

このように Shape ファイル(ポイントとライン)に変換することができました。

f:id:sanvarie:20201011224728p:plain

3. ArcGIS Pro で可視化

まずはポイントを可視化してみました。年月日と時間ごとにレコードを作成しました。田端駅周辺にいたことがわかります。ただ、これだと、どういう移動経路なのかがわかりません。

f:id:sanvarie:20201012060246p:plain

そこで、ラインを可視化してみます。以下の画像では2020/10/8は強調されたラインが移動経路になっています。

f:id:sanvarie:20201012060336p:plain

2020/10/10は北区→豊島区→大田区に移動しているのがわかります。

f:id:sanvarie:20201012060432p:plain

さいごに

Googleマップのタイムライン機能を使えばこんなに面白いことが簡単にできてしまうことが分かったかと思います。微妙に場所がずれているのが残念なのと(まぁ仕方ないとは思いますが)、どのタイミングで自分がいた地点が JSON に記録されるのか知れたらもっと楽しそうですね。また、今回も PyShp を使ってみたのですが、サクッと Shape ファイルを作るにはもってこいのライブラリなので、ぜひ使ってみてください。今回は以上です。