酢ろぐ!

カレーが嫌いなスマートフォンアプリプログラマのブログ。

iOSのLocationManager#requestLocation()で測位にどれくらいの時間がかかっているのか調べた

iOSで現在の位置情報を1回だけ取得したい場合には LocationManager#requestLocation()を利用します。OS側で測位が完了すると、LocationManager#locationManager(manager:didUpdateLocations:) で位置情報を受け取ることができます。

どれくらいの精度だとどれくらいの速度で測位が完了するのか、咄嗟に答えることができなかったので調べてみました。

f:id:ch3cooh393:20180815183829p:plain
GPSを使った測位処理のイメージ

シミュレータでの測位時間は15ミリ秒くらい

シミュレータで計測すると、1秒かからずに測位が完了しました。

16:22:24.014065 +0900 requestLocation
16:22:24.028382 +0900 didUpdateLocations

何度計測してもとても速いです。MacBook Pro (Retina, 15-inch, Mid 2015)でだいたい14ミリ秒くらい。

実機での測位時間は6000ミリ秒くらい

実機(iPhone X/iOS 11.4.1)にて計測したところ、早い時で1秒未満で完了しますが、遅い時だと6秒くらい測位にかかってしまうようです。

46:15.259415+0900 requestLocation
46:21.688697+0900 didUpdateLocations 誤差10.0m

47:26.945005+0900 requestLocation
47:26.945444+0900 didUpdateLocations 誤差10.0m

47:48.544144+0900 requestLocation
47:55.683432+0900 didUpdateLocations 誤差5.0m

元々のコードでは locationManager.activityType = .fitness を指定しており、かなり高精度で位置測位ができるようになっていました。現時点で最速の部類に入るiPhone Xでこれだけ時間がかかっているので、数世代前のiPhoneだともっと時間がかかってしまうことでしょう。

測位精度を落とすことでかかる時間は減るが誤差が増してしまう

精度を落とすと誤差は増すけれど測位時間が減るというのはよく知られています。

ただ実際にどれくらい早くなるのか計測した結果をまとめたことはなかったので、今回ついでに測位にかかる時間を計測してみることにしました。

desiredAccuracyプロパティで精度を指定することができます。desiredAccuracyプロパティについては「 desiredAccuracy - CLLocationManager | Apple Developer Documentation」をご覧ください。

kCLLocationAccuracyBestForNavigation ナビアプリなどで利用できる最高精度
kCLLocationAccuracyBest 最高精度(iOS,macOSでのデフォルト値)
kCLLocationAccuracyNearestTenMeters 誤差10m以内の正確さ
kCLLocationAccuracyHundredMeters 誤差100m以内の正確さ(watchOSでのデフォルト値)
kCLLocationAccuracyKilometer 誤差1,000m以内の正確さ
kCLLocationAccuracyThreeKilometers 誤差3,000m以内の正確さ

精度がkCLLocationAccuracyKilometerの場合の測位時間は1ミリ秒くらい

今回のケースではkCLLocationAccuracyBestForNavigationkCLLocationAccuracyBestの精度は必要なさそうだったのでkCLLocationAccuracyKilometerを指定して計測してみました。

locationManager.desiredAccuracy = kCLLocationAccuracyKilometer
locationManager.activityType = .other

測位にかかった時間は1ミリ秒くらいで、誤差は100m以内に収まっていました。

44:41.619705+0900 requestLocation
44:41.620617+0900 didUpdateLocations 誤差78.783367840145885m

45:00.837486+0900 requestLocation
45:00.838061+0900 didUpdateLocations 誤差65.0m

49:39.715457+0900 requestLocation
49:39.716497+0900 didUpdateLocations 誤差65.0m

前述の通り、iOSの位置測位は優秀なのでkCLLocationAccuracyKilometerを指定しても誤差が100m以内で収まっていました。計測環境等の条件があると思いますが、厳密な値が必要ないのであればkCLLocationAccuracyKilometerでも十分なのかもしれませんね。