iPhoneをGPSロガーとして使用する

GISやってる人間はたいてい動態管理に手を出します(俺調べ)。

GPSロガーを使った位置管理が昔からある手法、現在ではGoogleのロケーション履歴を使う方法もあります。普通の方はロケーション履歴で十分ですが、自力で緯度経度取得したいという奇特な人は iPhone + Python + pyicloud 使うと良いでしょう。

GIS屋はたいてい奇特な側です。

pyicloudとは

iPhoneでは端末を無くす/盗まれるといった時のためにiPhoneを探すという機能があり、端末の大まかな緯度経度をクラウドサービス上に保存しています。pyicloud は iCloud の情報を取得するライブラリで、これを使ってクラウド上の緯度経度を取得します。

pyicloudはiCloudを使ったサービスを呼び出すことができるので、例えばiPhoneから音を鳴らすとか、カレンダーの情報にアクセスするとかも可能です。何が出来るかはgithubの公式ページ書いてるので詳しいことは以下をご確認ください。

github.com

公式ではPython2系のお作法で書いてるのでコピペで動かすとPython3系の環境ではエラーが出ます。コピペ実行の際にはprintに括弧のつけ忘れに注意してください。

事前準備

Anacondaの環境が整っている場合はpip経由でpyicloudをインストールするだけでたぶん大丈夫。後はiCloudのサービスに登録しているかを確認してください。****@icloud.comのアカウントと紐づくパスワードが必要です。

pip install pyicloud

素のPython環境から動かす場合はモジュールの依存関係で色々エラーが出るので個々につぶしていってください。*1

REPLで使ってみる。

どういう情報が取れるかを対話環境(REPL)で見ていきます。個人的な好みで以降iPythonを使って作業を進めていきます*2。パスワード秘匿のためにgetpassを使っていますが、個々人の環境でやる場合は無くて問題ありません。

まずは必要なモジュールをインポートします。ついでにgetpassでiCloudの情報を入力。

from pyicloud import PyiCloudService
from getpass import getpass

# hoge@icloud.comを入力
iCloudAccount = getpass('Enter your icloud Account: ')
# パスワードを入力
iCloudPassword = getpass('Enter your icloud Password: ')

f:id:kazutaka83:20180825225637p:plain

入力したアカウント情報をPyiCloudServiceに渡します。

api = PyiCloudService(iCloudAccount, iCloudPassword)

これだけでOK。このapiを使ってiCloud経由で情報を取得したり、iPhoneを制御したりできます。

初めて使用する場合はiCloudの二段階認証を通す必要があるので以下のスクリプトを実行してください。

if api.requires_2fa:
    import click
    print("Two-step authentication required. Your trusted devices are:")
    
    devices = api.trusted_devices
    for i, device in enumerate(devices):
        print("  %s: %s" % (i, device.get('deviceName',
                 "SMS to %s" % device.get('phoneNumber'))))

    device = click.prompt('Which device would you like to use?', default=0)
    device = devices[device]
    if not api.send_verification_code(device):
        print("Failed to send verification code")
        sys.exit(1)

    code = click.prompt('Please enter validation code')
    if not api.validate_verification_code(device, code):
        print("Failed to verify verification code")
        sys.exit(1)

実行するとデバイス番号の入力を求められます。iCloudに複数台の端末を登録していない人は0、複数台iPhoneを持ってる人は使いたい端末番号を入力します*3

数字の入力後、SMSで認証コード(6桁)が送られてくるので入力します。

f:id:kazutaka83:20180825231636p:plain

緯度経度が欲しい場合、iphone.locationを呼び出します。返り値はdictなのでlongitude, latitudeを指定すると緯度経度を個々に取得できます。

#緯度経度に関するiCloud上の全情報を取得
api.iphone.location()

api.iphone.locationを見ると測位方法なんかを取得しているのがわかります。

# 緯度・経度を取得
api.iphone.location()['latitude']
api.iphone.location()['longtitude']

f:id:kazutaka83:20180825230951p:plain

これを定期的に回せば動態管理ができるようになりますね。iCloudに保存されている測位情報はそこまで精度が良くないので、ガチでサブメートル測位したい場合には向いてませんが、ある程度の場所を把握するのには使えます。

注意事項とおまけ

セキュリティのためだと思いますが認証はすぐに切れます。体感的には5分以内に切れているので、api.iphone.locationが値を返さない場合はもう一度 api = PyiCloudService() を実行して再認証してください。

あと、api.iphone.play_sound() を呼び出すとマナーモードの有無に関わらずiPhoneがなります。部屋でiPhoneなくしたときに便利です。

*1:「future, clickモジュールが無い」的なエラーが出た気が

*2:スクリーンショットがいい感じに映えるので

*3:複数台持ってないのでここは良くわからない


スポンサード リンク