こんな悩みにお答えします。
>>【位置情報】Googleマップ タイムライン機能の見方とロケーション履歴の設定方法(簡単5分!)
1. Aidemy
・・・AIエンジニアとしてのスキルを身に付けたい。その延長で就職、転職できたら嬉しい方におすすめ。
2.侍エンジニア塾
・・・基礎力と即戦力を身に付けられる、満足度No.1スクール
3. TechAcademy
・・・副業に向けてスキルアップしたい。フリーランスなどを目指している方向け。
4. AIジョブカレッジ
・・・コスパ良く、質の高い講座を受けたい方におすすめ。
本記事の信頼性
現在はデータサイエンティストとして大企業で活動しています。
1. 実行環境
以降、実際にコーディングしていく上で、実行環境を記載いたします。
- Python:3.6.4
- PyShp:2.1.3
PyShpはpipで簡単にインストールすることができます。
$pip install pyshp
2.
a. ユースケース
a-1. jsonデータの用意
まず、jsonファイルを用意する必要があります。以下の記事を参考にGoogleマップからロケーション履歴をダウンロードしましょう。
あなたのいた位置情報(緯度経度)を確認することができます。
>>【位置情報】Googleマップ タイムライン機能の見方とロケーション履歴の設定方法(簡単5分!)
a-2. GIS
GISではベクターデータをデータモデルとして地物を表現します。
- ポイント(点)
- ライン(線)
- ポリゴン(面)
の3つの要素で構成されます。
このベクターデータを格納できるのがshapeファイルということです!
b.
GISで位置情報を表示するためにはshapeファイルが必要になりますが、shapeファイルの構成は以下のとおりです(引用:esriジャパン)。
項番 | ファイルの拡張子 | 必須/推奨 | 概要 |
1 | |||
2 | |||
3 | |||
4 | |||
5 |
Pyshpを用いると簡単にこれらのファイルを作成することができます。今回は、#1~4までを作成してみます(オレンジ文字)。
c.
今回はあなたの移動履歴を地図上に表示することを目的としているため、ベクターデータの内、①ポイント(点)と②ライン(線)のファイルを作成します。①ポイント(点)は滞在ログが記録された地点、②ライン(線)は移動経路を表します。
コーディングについて関連記事がございましたので参考にさせていただきました。
>>Python と Googleマップのタイムライン機能を使って自分の移動履歴を可視化してみよう!
shapeファイルの構成は以下とします。
- ①ポイント(点)
- 年月日
- 時間
- 緯度
- 経度
- ②ライン(線)
- 年月日
#①ポイント
with shapefile.Writer(output_file_point) as w:
w.field("年月日", "C")
w.field("時間", "C")
w.field("緯度", "F", 12, 6)
w.field("経度", "F", 12, 6)
#②ライン
with shapefile.Writer(output_file_line) as w:
w.field("年月日", "C")
後は上記の属性に合うように、jsonファイルから値を抽出し、shapeファイルとして保存します。
# json 読込
json_open = open(input_file, 'r',encoding="utf-8_sig")
json_load = json.load(json_open)
for j in json_load["locations"]:
lat = float(j["latitudeE7"])/10000000
lon = float(j["longitudeE7"])/10000000
w.point(lon, lat)
w.record(str(j["timestamp"][0:4]) + "/" + str(j["timestamp"][5:7]) + "/" + str(j["timestamp"][8:10])
,str(j["timestamp"][11:13]) + ":" + str(j["timestamp"][14:16]) + ":" + str(j["timestamp"][17:23])
,lat,lon)
3. サンプルコード
import json
from datetime import datetime
import shapefile #PyShp
#フォルダ構成に合わせて適宜変更してください
###################################
input_file = "./Records.json"
output_file_point = './timeline_point.shp'
output_projection_file_point = './timeline_point.prj'
output_file_line = './timeline_line.shp'
output_projection_file_line = './timeline_line.prj'
###################################
#ポイントの作成
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',encoding="utf-8_sig")
json_load = json.load(json_open)
for j in json_load["locations"]:
lat = float(j["latitudeE7"])/10000000
lon = float(j["longitudeE7"])/10000000
#shape 書込
w.point(lon, lat)
w.record(str(j["timestamp"][0:4]) + "/" + str(j["timestamp"][5:7]) + "/" + str(j["timestamp"][8:10])
,str(j["timestamp"][11:13]) + ":" + str(j["timestamp"][14:16]) + ":" + str(j["timestamp"][17:23])
,lat,lon)
#プロジェクションファイル作成
with open(output_projection_file_point, "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',encoding="utf-8_sig")
json_load = json.load(json_open)
verticles = []
date = ""
previous_date = ""
for j in json_load["locations"]:
lat = float(j["latitudeE7"])/10000000
lon = float(j["longitudeE7"])/10000000
# 年月日ごとにラインを作成
date = str(j["timestamp"][0:4]) + "/" + str(j["timestamp"][5:7]) + "/" + str(j["timestamp"][8:10])
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):
#shape 書込
w.line([verticles])
w.record(previous_date)
#プロジェクションファイル作成
with open(output_projection_file_line, "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)
#unix時間を変換
def convert_time(timestamp):
t = datetime.fromtimestamp(float(timestamp)/1000)
return (t.year, t.month, t.day, t.hour, t.minute, t.second)
#メインの処理実行
if __name__ == '__main__':
create_point()
create_line()
実行した結果、フォルダに以下のようにファイルが格納されていれば無事完了です!
①ポイントに関するファイルが4つ。②ラインに関するファイルが4つです。
種別 | ファイル |
①ポイント | timeline_point.shp |
①ポイント | timeline_point.shx |
①ポイント | timeline_point.dbf |
①ポイント | timeline_point.prj |
②ライン | timeline_line.shp |
②ライン | timeline_line.shx |
②ライン | timeline_line.dbf |
②ライン | timeline_line.prj |
4. まとめ
PyShpを用いることで、簡単にshapeファイルへ変換することができます。
本記事では、GISへの描画を想定してポイントとラインの2つのshapeファイルを作成しましたが、用途に応じてご利用いただければと思います。
次回は、実際にGISを用いた位置情報の可視化を体験してみましょう。
本ブログでは、株式やプログラミングに関する記事を投稿しています。
プログラミング(Python)を学びたい方におすすめの書籍やプログラミングスクール、おすすめの学習方法などをご紹介しておりますのでぜひご覧ください。
は、プログラミングスクールという方法がおすすめです。
私の一押しは『TechAcademy』です。
質問することですぐに分からないところをクリアにできますし、進捗をサポートしてくれるため確実に成長することができます。
無料相談を実施しているため、まずは話を聞いてあなたのスタイルに合っているかどうか確認してみるのが良いと思います。
コメント