Corelocation incorrect distances

强颜欢笑 提交于 2019-11-29 11:10:00

It is normal to initially get a cached location from before. You can ignore older cached data by looking at the timestamp of the CLLocation.

You are printing the accuracy incorrectly, use %f not %d, type is double not int.

Location can change quickly when GPS first starts because you have a low accuracy location from cell triangulation, then as you get GPS acquisition you get a higher accuracy location. Those can be far apart (1000m) and it appears that you moved far in a few seconds but only the accuracy has changed.

Don't use two locations that have very different accuracy for computing distance traveled.

EDIT Added code sample, how to ignore old location data. You decide how old to ignore, I used 60 seconds here:

- (void)locationManager:(CLLocationManager *)manager 
    didUpdateToLocation:(CLLocation *)newLocation 
           fromLocation:(CLLocation *)oldLocation {

    NSTimeInterval ageInSeconds = -[newLocation.timestamp timeIntervalSinceNow];
    if (ageInSeconds > 60.0) return;   // data is too long ago, don't use it

    // process newLocation
    ...
}

You are already ensuring that your location updates are less than five seconds old. That is what this line of code does:

if (locationAge > 5.0) return;

As stated by progrmr, the key issue here is almost certainly that you're relying on initial estimates of location that are of low accuracy and so the location is appearing to move rapidly as it gets a better fix on your location. What you need to do is first ensure that oldLocation only gets set when you have an accurate initial location fix, and then only compare newLocations to that oldLocation if they also are of acceptable resolution.

For instance, you could have something like this:

- (void)locationManager:(CLLocationManager *)manager
    didUpdateToLocation:(CLLocation *)newLocation
           fromLocation:(CLLocation *)oldLocation{

    // Ignore location updates that are less than 10m accuracy, or where the horizontalAccuracy < 0
    // which indicates an invalid measurement.
    NSLog(@"New location accuracy %.0fm", newLocation.horizontalAccuracy);
    if ((newLocation.horizontalAccuracy < 0) || (newLocation.horizontalAccuracy > 10)) return;

    // Ignore location updates that are more than five seconds old, to avoid responding to
    // cached measurements.
    NSTimeInterval locationAge = -[newLocation.timestamp timeIntervalSinceNow];
    if (locationAge > 5) return;

    if (self.oldLocat == NULL)
    {    
        // For the first acceptable measurement, simply set oldLocat and exit.
        self.oldLocat = newLocation;
        return;
    }

    // A second location has been identified. Calculate distance travelled.
    // Do not set self.oldLocat from the oldLocation provided in this update, as we wish to
    // use the last place we calculated distance from, not merely the last place that was
    // provided in a location update. 
    CLLocationDistance distance = [newLocation distanceFromLocation:self.oldLocat];
    NSLog(@"Distance: %.0fm", distance);

    // This new location is now our old location.
    self.oldLocat = newLocation;
}

Note with the code above you do not require the method computeDistanceFrom:tO:, and also the property self.newLocat is not actually required, at least in this section of code.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!