问题
I am using the CoreLocation
framework to get my speed and distance to calculate average speed.
On the first update that CoreLocation
sends out, it shows negative values for both speed and distance traveled. How can I fix this?
Speed is locationController.locationManager.location.speed
where locationController
holds my CoreLocation
delegate. Distance is calculated by taking the old location and the new location and calculating distance.
//Distance
- (void)locationManager:(CLLocationManager *)manager
didUpdateToLocation:(CLLocation *)newLocation
fromLocation:(CLLocation *)oldLocation
{
// make sure the old and new coordinates are different
if ((oldLocation.coordinate.latitude != newLocation.coordinate.latitude) &&
(oldLocation.coordinate.longitude != newLocation.coordinate.longitude))
{
mDistance = [newLocation distanceFromLocation:oldLocation];
}
}
回答1:
The data returned by Core Location may be invalid for a number of reasons. Before you use the data, run this method to see if it is valid.
// From http://troybrant.net/blog/2010/02/detecting-bad-corelocation-data/
- (BOOL)isValidLocation:(CLLocation *)newLocation
withOldLocation:(CLLocation *)oldLocation
{
// filter out nil locations
if (!newLocation){
return NO;
}
// filter out points by invalid accuracy
if (newLocation.horizontalAccuracy < 0){
return NO;
}
// filter out points that are out of order
NSTimeInterval secondsSinceLastPoint = [newLocation.timestamp
timeIntervalSinceDate:oldLocation.timestamp];
if (secondsSinceLastPoint < 0){
return NO;
}
// filter out points created before the manager was initialized
NSTimeInterval secondsSinceManagerStarted = [newLocation.timestamp
timeIntervalSinceDate:locationManagerStartDate];
if (secondsSinceManagerStarted < 0){
return NO;
}
// newLocation is good to use
return YES;
}
回答2:
There's a note in the CLLocationManager Class Reference:
Because it can take several seconds to return an initial location, the location manager typically delivers the previously cached location data immediately and then delivers more up-to-date location data as it becomes available. Therefore it is always a good idea to check the timestamp of any location object before taking any actions.
You should check whether you're getting a cached value and ignore it, waiting for the first "real" update.
NSTimeInterval timeSinceLastUpdate = [[newLocation timestamp] timeIntervalSinceNow];
// If the information is older than a minute, or two minutes, or whatever
// you want based on expected average speed and desired accuracy,
// don't use it.
if( timeSinceLastUpdate < -60 ){
return;
}
回答3:
If you are collecting the first point, it has no reference to calculate speed or distance. I believe it is defined to return -1 if it can't get you what you need.
To resolve this, simply check for the negative values.
if(location.speed > 0) {
return;
}
来源:https://stackoverflow.com/questions/7970664/corelocation-negative-values