【Python】【位置情報】PyShpを用いてjsonファイルをshapeファイルへ変換する方法(簡単5分!)

プログラミング
スポンサーリンク

地図データを利用する際によく目にするjsonファイルとshapeファイル。分析や可視化にあたりファイルの変換を行いたいけど良い方法はないかな。

こんな悩みにお答えします。

実は、Pythonを用いることで簡単にjsonファイルからshapeファイルに変換することができます。

なぜなら、Pythonには豊富なライブラリが用意されているからです。

今回は、jsonファイルをshapeファイルに変換する方法をご紹介します。

この記事を読み終えると、位置情報を扱うためのファイル変換を容易に行うことができるようになります。

本記事の内容

・PyShpの利用方法
・jsonファイルをshapeファイルに変換する方法

>>【位置情報】Googleマップ タイムライン機能の見方とロケーション履歴の設定方法(簡単5分!)

 

Pythonを学べるおすすめのプログラミングスクール
1. Aidemy
・・・AIエンジニアとしてのスキルを身に付けたい。その延長で就職、転職できたら嬉しい方におすすめ。
2.侍エンジニア塾
・・・基礎力と即戦力を身に付けられる、満足度No.1スクール
3.
TechAcademy
・・・副業に向けてスキルアップしたい。フリーランスなどを目指している方向け。
4
. AIジョブカレッジ
・・・コスパ良く、質の高い講座を受けたい方におすすめ。

本記事の信頼性

ひよこ
ひよこ

私は、大学時代にプログラミングを学び、PHPなどのWeb系言語からAIに用いられるPythonまで幅広く経験してきました。

現在はデータサイエンティストとして大企業で活動しています。

また今ではほぼ不労所得として月10万円以上の収益を継続的に達成しています。

 

1. 実行環境

以降、実際にコーディングしていく上で、実行環境を記載いたします。

  • Windows10
  • Python:3.6.4
  • PyShp:2.1.3

PyShpはpipで簡単にインストールすることができます。

$pip install pyshp

 

2. PyShpを用いたファイル変換(json⇒shape)

jsonファイルからshapeファイルへの変換について、どのような用途があるでしょうか。ここでは具体的なユースケースを基に方法をご説明いたします。

 

a. ユースケース

Googleマップから入手した位置情報履歴(json)をGISで表示する(shape)ためのファイル変換を想定する

 

a-1. jsonデータの用意

まず、jsonファイルを用意する必要があります。以下の記事を参考にGoogleマップからロケーション履歴をダウンロードしましょう。

あなたのいた位置情報(緯度経度)を確認することができます。

>>【位置情報】Googleマップ タイムライン機能の見方とロケーション履歴の設定方法(簡単5分!)

 

a-2. GIS

GIS(Geographic Information System)
地理情報システム。地球上に存在する地物や事象はすべて地理情報と言えますが、これらをコンピューターの地図上に可視化して、情報の関係性、パターン、傾向をわかりやすいかたちで導き出すのが GIS の大きな役割。(引用:esriジャパン

GISではベクターデータをデータモデルとして地物を表現します。

  • ポイント(点)
  • ライン(線)
  • ポリゴン(面)

の3つの要素で構成されます。

ひよこ
ひよこ

このベクターデータを格納できるのがshapeファイルということです!

b. shapeファイルの構成

GISで位置情報を表示するためにはshapeファイルが必要になりますが、shapeファイルの構成は以下のとおりです(引用:esriジャパン)。

項番ファイルの拡張子必須/推奨概要
1.shp必須図形の情報を格納する主なファイル
2.shx必須図形のインデックス情報を格納するファイル
3.dbf必須図形の属性情報を格納するテーブル
4.prj推奨図形の持つ座標系の定義情報を格納するファイル。ArcGIS で使用されます
5.sbn および.sbx推奨空間インデックスを格納するファイル。空間インデックスを持つと、ArcGIS で空間検索のパフォーマンスを向上させることができます

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. まとめ

今回は、jsonファイルをshapeファイルに変換する方法をご紹介しました。

PyShpを用いることで、簡単にshapeファイルへ変換することができます。

本記事では、GISへの描画を想定してポイントとラインの2つのshapeファイルを作成しましたが、用途に応じてご利用いただければと思います。

次回は、実際にGISを用いた位置情報の可視化を体験してみましょう。

 

 

 

本ブログでは、株式やプログラミングに関する記事を投稿しています。
プログラミング(Python)を学びたい方におすすめの書籍やプログラミングスクール、おすすめの学習方法などをご紹介しておりますのでぜひご覧ください。

独学で挫折してしまう方は、プログラミングスクールという方法がおすすめです。

私の一押しは『TechAcademy』です。

質問することですぐに分からないところをクリアにできますし、進捗をサポートしてくれるため確実に成長することができます。

無料相談を実施しているため、まずは話を聞いてあなたのスタイルに合っているかどうか確認してみるのが良いと思います。

スキルアップを目指したい方におすすめのオンライン学習サービス

コメント

タイトルとURLをコピーしました