Aggressor
Aggressor

Reputation: 13551

iPhone GPS User Location is moving back and forth while the phone is still

I am doing some mapkit and corelocation programming where I map out a users route. E.g. they go for a walk and it shows the path they took.

On the simulator things are working 100% fine.

On the iPhone I've run into a major snag and I don't know what to do. To determine if the user has 'stopped' I basically check if the speed is (almost) 0 for a certain period of time.

However just keeping the phone still spits out this log for newly updated location changes (from the location manager delegate). These are successive updates in the locationManager(_:didUpdateLocations:) callback.

speed 0.021408926025254 with distance 0.192791659974976
speed 0.0532131983839802 with distance 0.497739230237728
speed 11.9876451887096 with distance 15.4555990691609
speed 0.230133198005176 with distance 3.45235789063791
speed 0.0 with distance 0.0
speed 0.984378335092039 with distance 11.245049843458
speed 0.180509147029171 with distance 2.0615615724029
speed 0.429749086272364 with distance 4.91092459284206

Now I have the accuracy set to best:

_locationManager                    = CLLocationManager()
_locationManager.delegate           = self
_locationManager.distanceFilter     = kCLDistanceFilterNone
_locationManager.desiredAccuracy    = kCLLocationAccuracyBest

Do you know if there is a setting or I can change to prevent this back and forth behaviour. Even the user pin moves wildly left and right every few seconds when the phone is still.

Or is there something else I need to code to account for this wild swaggering?

Upvotes: 1

Views: 2040

Answers (1)

Aggressor
Aggressor

Reputation: 13551

I check if the user has moved a certain distance within a certain time to determine if they have stopped (thanks to rmaddy for the info):

/**
    Return true if user is stopped. Because GPS is in accurate user must pass a threshold distance to be considered stopped.
*/
private func userHasStopped() -> Bool
{
    // No stop checks yet so false and set new location
    if (_lastLocationForStopAnalysis == nil)
    {
        _lastLocationForStopAnalysis = _currentLocation
        return false
    }

    // If the distance is greater than the 'not stopped' threshold, set a new location
    if (_lastLocationForStopAnalysis.distanceFromLocation(_currentLocation) > 50)
    {
        _lastLocationForStopAnalysis = _currentLocation
        return false
    }

    // The user has been 'still' for long enough they are considered stopped
    if (_currentLocation.timestamp.timeIntervalSinceDate(_lastLocationForStopAnalysis.timestamp) > 180)
    {
        return true
    }

    // There hasn't been a timeout or a threshold pass to they haven't stopped yet
    return false
}

Upvotes: 1

Related Questions