Strange GPS Behavior in Outdoor Activity Tracking App

Hi everyone,

I’m encountering a strange issue with GPS tracking in my app, and I’m hoping for some insights.

I’m developing an app that records users' GPS activities (walking, biking, etc.) with app in the foreground and/or background. Most activities are outdoors, sometimes in areas with poor GPS reception, such as mountains.

To track user location, we’re using:

locationManager = CLLocationManager()
locationManager.distanceFilter = 3
locationManager.activityType = .fitness
locationManager.pausesLocationUpdatesAutomatically = false
locationManager.allowsBackgroundLocationUpdates = true

The Issue

In certain scenarios, the GPS behaves unexpectedly.

For example (see attached image below): A user followed a normal route (brown line), then reached an intersection and turned right (blue arrow). However, the GPS continued straight for about 200 meters (brown line) before correcting itself and resuming accurate tracking.

Here’s a snippet of the recorded coordinates during this misbehavior:

time,latitude,longitude,elevation,verticalAccuracy,horizontalAccuracy
10:17:17,47.92408,7.10438,950.82375,4.74865,4.80005
10:17:33,47.92410,7.10435,950.14966,4.74865,4.10799
10:17:44,47.92412,7.10431,943.63913,4.74865,4.46287
10:17:53,47.92413,7.10427,939.51380,4.74865,4.60644
10:17:59,47.92415,7.10424,934.82986,4.74865,4.52599
10:18:02,47.92417,7.10420,932.53145,4.74865,4.823035
10:18:05,47.92418,7.10416,927.84917,4.748655,4.59619
10:18:09,47.92420,7.10413,924.89886,4.748655,4.50172
10:18:13,47.92422,7.10409,923.35354,4.74865,4.77356
10:18:18,47.92424,7.104055,920.16327,4.74865,4.78286
10:18:22,47.92426,7.10400,915.23174,4.74865,4.66226
10:18:28,47.92427,7.10397,906.08626,4.74865,4.97331
10:18:31,47.92429,7.10394,903.25157,4.74865,4.81649
10:18:35,47.92431,7.10390,895.27948,4.74865,5.15392
10:18:38,47.92433,7.10386,889.71076,4.74865,5.25283
10:18:42,47.92435,7.10382,881.74041,4.74865,5.49089
10:18:46,47.92437,7.103785,874.34945,4.74865,5.55564
10:18:49,47.92439,7.10374,869.63184,4.74865,5.37537
10:18:53,47.92441,7.10370,861.26690,4.74865,5.39344
10:18:57,47.92443,7.10366,854.67646,4.74865,5.30404
10:19:01,47.92445,7.10362,848.48881,4.74865,5.59742
10:19:06,47.92447,7.10359,836.48915,4.74865,5.65666
10:19:08,47.92449,7.103555,835.72566,4.74865,5.54957
10:19:10,47.92450,7.10352,834.41579,4.74865,5.63540
10:19:13,47.92452,7.10348,830.17080,4.74865,5.65795
10:19:16,47.92454,7.10344,828.17052,4.74865,5.72169
10:19:19,47.92456,7.10340,824.93658,4.74865,5.62606
10:19:24,47.92458,7.10337,818.40503,4.74865,5.23265
10:19:34,47.92460,7.103335,804.42539,4.74865,4.683855
10:19:38,47.92462,7.10329,799.51747,4.74865,4.47590
10:19:48,47.92464,7.10324,784.97044,4.74865,4.59459
10:19:50,47.92466,7.10320,782.04750,4.748655,4.71036
10:19:57,47.92468,7.10317,777.49314,4.74865,4.60504
10:20:05,47.92469,7.10313,771.30168,4.74865,4.35574
10:20:09,47.92472,7.10308,766.64446,4.74865,4.94510
10:20:13,47.92474,7.10304,757.33384,4.74865,5.39175
10:20:15,47.92476,7.10300,753.52157,4.74865,5.442045
10:20:20,47.92477,7.10297,742.66179,4.74865,5.52391
10:20:23,47.92479,7.10293,735.38369,4.74865,5.44657
10:20:25,47.92480,7.10290,732.19367,4.74865,5.519945
10:20:28,47.92482,7.10286,725.15380,4.748655,5.58173
10:20:31,47.92484,7.10282,717.08813,4.74865,5.37805
10:20:34,47.92486,7.102785,710.35208,4.74865,5.27918
10:20:37,47.92488,7.10274,706.16774,4.748655,5.53270
10:20:40,47.92490,7.10270,702.84802,4.74865,5.71088
10:20:41,47.92648,7.10356,940.27115,6.600805,10.78768
10:20:43,47.92651,7.10355,940.24665,6.61807,10.45243

At 10:17:44, the location data was correct.

Shortly after, CLLocationManager started returning inaccurate coordinates. Despite the system reporting good horizontal and vertical accuracy, the altitude readings drop progressively from 940m to 702m, even though the user remained at 940m in reality. (We also recorded barometric elevation, which confirms that he stayed around 900m)

Then, at 10:20:41, the GPS corrected itself.

Questions

  1. Is it possible that GPS could "lock onto" the wrong path, generating valid-looking but incorrect coordinates?
  2. Can we force CLLocationManager to use GPS exclusively (disabling other sensors like Wi-Fi)? I assumed that setting activityType = .fitness would prioritize outdoor tracking, but I’m still being located indoors.
  3. Could adjusting the activityType improve this behavior?
  4. Could having multiple CLLocationManager() instances in our app cause issues? (We use one to save the GPS coordinates, but MapBox also creates a CLLocationManager with lower accuracy for its Telemetry framework, for example)

Thanks in advance for any help or suggestions!

Answered by Engineer in 808429022

CoreLocation will correct received/perceived coordinates to known roads and paths based on the activityType. .fitness is one of the activity types that will use corrected coordinates. If you want no such corrections, you may want to give `.other' a try.

2- CoreLocation will use fused data from whatever sources it can get to return reliable locations. It is not possible to turn off parts, or to force the locations to one source or the other.

3- adjusting .activityType will change this behavior. Whether it is an improvement or not depends on your use case. Setting it to .other will stop following known paths, but you will also lose any corrections made to the location data that reduces jitter.

4- I don't know if having multiple location managers effect anything in your case, but it is always possible that they will interfere. Most common types of interference will be that the properties for one will override the properties of the other (biased towards the better settings), and if not careful about threading and classes, you could end up with re-entrant code in the delegate methods.


Argun Tekant /  DTS Engineer / Core Technologies

CoreLocation will correct received/perceived coordinates to known roads and paths based on the activityType. .fitness is one of the activity types that will use corrected coordinates. If you want no such corrections, you may want to give `.other' a try.

2- CoreLocation will use fused data from whatever sources it can get to return reliable locations. It is not possible to turn off parts, or to force the locations to one source or the other.

3- adjusting .activityType will change this behavior. Whether it is an improvement or not depends on your use case. Setting it to .other will stop following known paths, but you will also lose any corrections made to the location data that reduces jitter.

4- I don't know if having multiple location managers effect anything in your case, but it is always possible that they will interfere. Most common types of interference will be that the properties for one will override the properties of the other (biased towards the better settings), and if not careful about threading and classes, you could end up with re-entrant code in the delegate methods.


Argun Tekant /  DTS Engineer / Core Technologies

CoreLocation will correct received/perceived coordinates to known roads and paths

When you say “correct”, you mean the opposite. - as @Toldy’s example perfectly demonstrates.

based on the activityType. .fitness is one of the activity types that will use corrected coordinates.

Really?? It always used to be that “fitness” was the one mode that did not snap the locations to where Apple thinks the paths are. Has this changed at some point???

Concerning the:

Setting it to .other will stop following known paths

I did some outdoor testing with .other this weekend and the snap-to-road behavior still occurred.

Same behavior than with .fitness: on this picture the user turned right, but instead the GPS generated “corrected data” that turned left for 50 meters and then snapped to the right road

I came across other links that recommend .otherNavigation instead. Nothing in the documentation is very specific about this, but I'll give it a try and get back to you.

Links :

Strange GPS Behavior in Outdoor Activity Tracking App
 
 
Q