- 过滤掉缓存的(旧的)位置数据,
- 过滤掉无效的定位结果(准确率 < 0),
- 将精度要求设置为
kCLLocationAccuracyBest
,
- 设置最小距离过滤器,最好至少 10 米以过滤掉位置噪声。
- 编辑
oldLocation
:当nil时不要计算距离。
您可以做的还有更多,但只要您获得足够好的水平精度(<30m),这应该可以工作。您可以过滤掉低准确度的结果,但是您必须自己跟踪 oldLocation ,这有点复杂。
添加一个 NSLog(见下文),以便您了解发生了什么。如果您仍然没有得到好的结果,请发布 NSLog 的输出,以便我们查看发生了什么并提供更多帮助。
-(void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
{
NSTimeInterval age = -[newLocation.timestamp timeIntervalSinceNow];
if (age > 120) return; // ignore old (cached) updates
if (newLocation.horizontalAccuracy < 0) return; // ignore invalid udpates
// EDIT: need a valid oldLocation to be able to compute distance
if (oldLocation == nil || oldLocation.horizontalAccuracy < 0) return;
CLLocationDistance distance = [newLocation distanceFromLocation: oldLocation];
NSLog(@"%6.6f/%6.6f to %6.6f/%6.6f for %2.0fm, accuracy +/-%2.0fm",
oldLocation.coordinate.latitude,
oldLocation.coordinate.longitude,
newLocation.coordinate.latitude,
newLocation.coordinate.longitude,
distance,
newLocation.horizontalAccuracy);
distanceMoved += distance;
theLabel.text = [NSString stringWithFormat: @"%f meters", distanceMoved];
}
- (void)viewDidLoad
{
locMan = [[CLLocationManager alloc] init];
locMan.delegate = self;
locMan.desiredAccuracy = kCLLocationAccuracyBest;
locMan.distanceFilter = 10;
[locMan startUpdatingLocation];
isInitial = true;
distanceMoved = 0.0;
[super viewDidLoad];
}
如果您想使用didUpdateLocations执行相同的操作,请针对 iOS6进行编辑:(因为现在不推荐使用上述方法)最简单的解决方案是简单地将每个位置保存在一个属性中,以便在下次更新时您拥有以前的位置。在类中声明一个属性来保存oldLocation
:
@property (nonatomic, retain) CLLocation* oldLocation;
然后在委托方法中保存每个newLocation
以oldLocation
供下次调用委托方法时使用:
-(void)locationManager:(CLLocationManager *)manager didUpdateToLocations:(NSArray *)locations
{
CLLocation* newLocation = [locations lastObject];
NSTimeInterval age = -[newLocation.timestamp timeIntervalSinceNow];
if (age > 120) return; // ignore old (cached) updates
if (newLocation.horizontalAccuracy < 0) return; // ignore invalid udpates
// EDIT: need a valid oldLocation to be able to compute distance
if (self.oldLocation == nil || self.oldLocation.horizontalAccuracy < 0) {
self.oldLocation = newLocation;
return;
}
CLLocationDistance distance = [newLocation distanceFromLocation: self.oldLocation];
NSLog(@"%6.6f/%6.6f to %6.6f/%6.6f for %2.0fm, accuracy +/-%2.0fm",
self.oldLocation.coordinate.latitude,
self.oldLocation.coordinate.longitude,
newLocation.coordinate.latitude,
newLocation.coordinate.longitude,
distance,
newLocation.horizontalAccuracy);
distanceMoved += distance;
theLabel.text = [NSString stringWithFormat: @"%f meters", distanceMoved];
self.oldLocation = newLocation; // save newLocation for next time
}