Swift3でiOS用のGPSロガーアプリを作った話

#概要
iOS端末向けGPSロガーアプリを作り、アプリ利用者の動線を記録しようと試みた。
GPSの弱点である、屋根のある室内等の電波の障害となりうるものがある地点において、多数の『位置飛び』が観測された。
データ分析の際にこの位置飛びはノイズとなりうる為、除去が求められる。
* * *
この記事は[自身のブログ](http://chancp3.hatenablog.com/)に記載した情報を纏め、追記したものである。
* * * 
#背景
ここ数年で日本全国に急速に普及したスマートフォン。
最近では世帯あたりの普及率が従来型携帯電話、いわゆるガラケーの割合を追い抜いた[^1]とされている。
[^1]: [『日本経済新聞』2016年04月08日 WEB刊](http://www.nikkei.com/article/DGXLASDF08H0R_Y6A400C1EE8000/)
スマートフォンには様々な高精度センサが搭載されており、処理能力も高い。
今回はその中でもGPS情報を利用して、アプリを利用している人の位置情報を随時記録するアプリを作成した。
#GPSとは
##名称
GPSはGlobal Positioning System（全地球測位システム / グローバルポジショニングシステム）の略称。
##基本的な測定手法
3つの距離測定衛星と1つの誤差修正衛星の合計4機の人工衛星を必要最低数として利用し、位置を測定している。
衛星から発された電波が地表位置に届くまでにかかった時間を利用して距離を割り出し、時刻誤差修正用の4つ目の衛星を使い位置を修正している。
<img width="500px" alt="feature130826_img01_w800.png" src="https://qiita-image-store.s3.amazonaws.com/0/157315/00459aec-c39b-beb5-ef8b-1fed96e72fde.png">
（画像引用：[Humming HEADS](http://www.hummingheads.co.jp/reports/feature/1308/130826_02.html)）

YouTubeに投稿されている下記の動画も非常に分かりやすく解説されている。
・[サイエンスチャンネル](https://www.youtube.com/watch?v=Ml2MYumw5Qg)
・[TED-Ed](https://www.youtube.com/watch?v=70cDSUI4XKE)
#開発環境・動作環境
##開発環境
・macOS 10.12 Sierra
・Xcode8
・Swift3.0
##動作環境
・iOS9.0以上
・iPhone6, iPhone6S, iPhone6 Plus, iPhone6S Plus, iPhone SE
#アプリ詳細
今回紹介には至らなかったが、実は前代のGPSロガーアプリも作成している。
そのアプリからの反省点を踏まえ、改善を行なったものを今回紹介する。

![Simulator Screen Shot 2016.12.13 10.24.17.png](https://qiita-image-store.s3.amazonaws.com/0/157315/25801be4-f6ce-27da-f720-fe84263d53f9.png "Simulator Screen Shot 2016.12.13 10.24.17.png")

![Simulator Screen Shot 2016.12.13 10.28.35.png](https://qiita-image-store.s3.amazonaws.com/0/157315/ea6db5bc-187b-84df-9775-86ca993fc355.png)

ユーザがスタートボタンを押すことにより、計測開始。
自動的に位置情報がサーバに送信され、バックアップ用に内部データベースにも保存される仕組み。
##計測・記録可能な情報
・ユーザ名/年齢/性別
・緯度経度
・観測時間
・更新距離（1つ前の記録点からどれだけ離れた距離か）[^2]
[^2]: [【Qiita】iOS/swiftで緯度・経度から2点間の距離を算出する](http://qiita.com/ymiz/items/b00c4da44070a66c8445)
・歩行速度（更新距離と時間から計算）
・位置情報測位精度値（Horizontal Accuracyのみ使用）[^3]
[^3]: [【Stack Overflow】 Xcode: How to show GPS strength value?](http://stackoverflow.com/questions/10583449/xcode-how-to-show-gps-strength-value)
・ジオフェンシング[^4]
[^4]: [【Qiita】ある地点への接近を知らせる（CoreLocation::CLLocationManager.startMonitoringForRegion）](http://qiita.com/shngt/items/07ff2cd5b22ebde27b05)
##使用しているサービス
・[Microsoft Azure](https://azure.microsoft.com/ja-jp/) (SQL/BLOB)
・[RealmSwift](https://realm.io/jp/docs/swift/latest/)
~~・[Firebase](https://firebase.google.com/?hl=ja)~~【使用中止】
##課題点
GPS測位は、GPS信号の持つ直進性の性質により、屋根のある場所や建物群の間では精度が非常に悪くなるという弱点を持つ。
その為、室内においてはビーコンなどの近距離無線を用いる手法が一般的であり、屋外においてもPDR(Pedestrian Dead Reckoning)と呼ばれる加速度センサ等と組み合わせる手法が研究されている。
##改善策
今回はGPSのみでどこまで測定できるのかを検証した。
実験データはここでは記載できないが、フィルタをなにも設定せず測定した場合、位置飛びだと見られる点によって、まとまりのない経路図[^5]が出来上がった。
[^5]: [可視化サイト](http://www.gpsvisualizer.com/)を利用
そこで下記に記す４個のフィルタを設定し、組み合わせることで位置飛びを削減することを試みた。

・更新距離5m以内
・位置情報測位精度値48m以内
・歩行速度10km/h以内
・上記３個のフィルタをクリアした点が、5個以上連続した場合のみ記録

事前に測定を行なったデータを分析した結果、改善策として上記フィルタを考えた。
測定時に位置情報測位位置精度値は記録されていなかった為、今回の比較には用いず、他３個のフィルタで比較を行う。
##比較結果・考察
先ほどのフィルタのうち、測位精度値を除く３個のフィルタで測定を行なったところ、
何もフィルタを設定しない場合と比較して約18%のデータ削減に成功した。

しかしながら、この結果には本来記録されるべきデータが削除されていたり、
逆に位置飛びであると判定されるべき点が残っていたり、という問題点が未だ存在する。
PDRやビーコン等と組み合わせたり、クラスタリングにより処理する方法も用いた方がより効果的であると考えられる。

##参考サイト
・[RealmSwiftで簡単なGPSロガー作ってみたのでメモ](http://blog.koogawa.com/entry/2015/08/02/151452)
・[バックグラウンドで位置情報を取得する（CoreLocation::CLLocationManager）](http://qiita.com/shngt/items/6687edeb055113e5fd70)