LoginSignup
8
9

More than 3 years have passed since last update.

iPhoneで撮った写真から緯度経度を取得しQGISで取り込む

Last updated at Posted at 2016-08-30

iPhoneで撮影した写真にはGPS情報が含まれます。このGPS情報を解析して、QGIS上にポイントとして落としてみます。使用するのはPILモジュールとOSモジュールを使用します。
CSVで出力したい場合はCSVモジュールも必要です。

写真メタデータ解析用の関数を作成

get_exif.py
from PIL import Image
from PIL.ExifTags import TAGS

def get_exif(fn):
    ret = {}
    i = Image.open(fn)
    info = i._getexif()
    for tag, value in info.items():
        decoded = TAGS.get(tag, tag)
        ret[decoded] = value
    return ret

関数にファイルを投げ込むとディクショナリにメタデータが格納されます。使い方は↓

my_image = 'hogehoge.jpg'
metadata = get_exif(my_image)

メタデータの中身は色々です。撮影した時間や機種名、その他種々。下の画像はPythonのエディタ(Spyder)のValiable exploreで中身を確認した様子です。

image

ディクショナリ項目GPSInfoの中にGPSの緯度経度情報が入っています。要素1は南北区分、要素2は緯度(度分秒)、要素3は東西区分、要素4は経度(度分秒)です。

In [1] print(metadata['GPSInfo'])
Out[1] {1: 'N', 2: ((31, 1), (35, 1), (1485, 100)), 3: 'E', 4: ((130, 1), (33, 1), (2132, 100)), 5: 0, 6: (11717, 787), 7: ((9, 1), (13, 1), (5680, 100)), 12: 'K', 13: (0, 1), 16: 'T', 17: (23003, 112), 23: 'T', 24: (23003, 112), 29: '2016:08:25', 31: (5, 1)}

度分秒単位はGISに投げ込むときに面倒くさいので、これを度単位に書き換えます。計算方法は以下の通り。

lon = int(metadata['GPSInfo'][4][0][0]) +
      float(metadata['GPSInfo'][4][1][0]) /60 + 
      (float(metadata['GPSInfo'][4][2][0])/float(metadata['GPSInfo'][4][2][1])) /3600
lat = int(metadata['GPSInfo'][2][0][0]) +
      float(metadata['GPSInfo'][2][1][0]) /60 +
      (float(metadata['GPSInfo'][2][2][0])/float(metadata['GPSInfo'][2][2][1])) /3600

対象ファイルが一つの場合は上述のやり方で問題無いですが、複数ファイルを扱いたいのが世の常です。なので以下の様なスクリプトを書きました。

import csv
import os

FileList = os.listdir()
WriteFile = open('photo_gps_point.csv','w')
writer = csv.writer(WriteFile, lineterminator='\n')

for pf in FileList:
    metadata = get_exif(pf)

    csvline = []
    csvline.append(pf)
    csvline.append(metadata['Model'])

    if 'GPSInfo' in metadata.keys():
        csvline.append(
         int(metadata['GPSInfo'][4][0][0]) +
         float(metadata['GPSInfo'][4][1][0]) /60 + 
         (float(metadata['GPSInfo'][4][2][0])/float(metadata['GPSInfo'][4][2][1])) /3600)
        csvline.append(
         int(metadata['GPSInfo'][2][0][0]) +
         float(metadata['GPSInfo'][2][1][0]) /60 +
         (float(metadata['GPSInfo'][2][2][0])/float(metadata['GPSInfo'][2][2][1])) /3600)
        writer.writerow(csvline)
    else:
        pass
WriteFile.close()

これで度単位緯度経度のCSVファイル(photo_gps_point.csv)が作成されました。
上述のコードでは作業の都合で撮影した機種名(Model)を入れていますが、これは無くても問題ありません。他に必要な項目があれば置き換えてもOKです。

参考(リンク切れ)

http://www.geopacific.org/opensourcegis/python/8q9u2w

8
9
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
9