2010-06-22 87 views
4

我正在开发一个计算用户行进距离的应用程序。我正在使用CLLocationManager类来完成这项工作,但我最初获取了缓存数据,并且距离变量突然增加。请帮助我...我已经使用了以下代码....Corelocation不正确的距离

注意:distance是一个静态var。这里

- (void)viewDidLoad { 
    [super viewDidLoad]; 
//bestEffortAtLocation = nil; 
oldLocat = [[CLLocation alloc]init]; 
newLocat = [[CLLocation alloc]init]; 
locationManager =[[CLLocationManager alloc]init]; 
locationManager.delegate = self; 
locationManager.distanceFilter = kCLDistanceFilterNone; 
locationManager.desiredAccuracy = kCLLocationAccuracyBest; 
[locationManager startUpdatingLocation]; 

    } 

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




// test that the horizontal accuracy does not indicate an invalid measurement 
if (newLocation.horizontalAccuracy < 0) return; 


NSLog(@"accuracy %d",newLocation.horizontalAccuracy); 

// test the age of the location measurement to determine if the measurement is cached 
// in most cases you will not want to rely on cached measurements 
NSTimeInterval locationAge = -[newLocation.timestamp timeIntervalSinceNow]; 
//NSLog(@"time %d",locationAge); 

if (locationAge > 5.0) return; 



self.oldLocat = oldLocation; 
self.newLocat = newLocation; 


double latDegrees = newLocation.coordinate.latitude; 
NSString *lat = [NSString stringWithFormat:@"%1.5f°",latDegrees]; 
latLabel.text = lat; 
double longDegrees = newLocation.coordinate.longitude; 
NSString *longt = [NSString stringWithFormat:@"%1.5f°",longDegrees]; 
longLabel.text = longt; 
[self computeDistanceFrom:oldLocat tO:newLocat]; 

    } 

    -(void)computeDistanceFrom:(CLLocation *)oldL tO:(CLLocation *)newL 
{ 
NSLog(@"oldd %@",oldL); 
NSLog(@"new %@",newL); 


distance = distance + [oldL getDistanceFrom:newL]; 
NSLog(@"distance %f",distance); 

} 

该控制台显示下列数据.......

精度0 oldd(空)新< 28.62114850,77.37001021> +/-80.00米 (速度-1.00 MPS /当然-1.00)@ 2010-06-22 19时21分59秒0530距离 0.000000

精度0 oldd < 28.62114850,77.37001021> +/-80.00米(速度-1.00 MPS /课程-1.00)@ 2010-06-22 19:21:59 +0530新< 28.61670485, 77.37068155> +/-80.00米(速度-1.00 MPS /当然-1.00)@ 2010-06-22 19时22分○○秒0530 距离498.211345

精度0 oldd < 28.61670485, +77.37068155> +/- 80.00m(speed -1.00 mps/course -1.00)@ 2010-06-22 19:22:00 +0530 new < +28.62112748, +77.36998540> +/- 80.00m(speed -1.00 mps/course -1.00)@ 2010-06-22 19:23:02 +0530距离994.432508

回答

7

从最初获取缓存位置之前是正常的。您可以通过查看CLLocationtimestamp来忽略较旧的缓存数据。

您正在错误地打印精度,使用%f不是%d,类型是double不是int。

当GPS第一次启动时,位置可能会快速变化,因为您从细胞三角测量中获得的精确位置较低,然后当您获取GPS时,您将获得更高精度的位置。这些可以相距很远(1000米),看起来你几秒钟就可以移动很远,但只有精度发生了变化。

请勿使用两个位置精度差异很大的计算距离。

编辑添加代码示例,如何忽略旧的位置数据。您决定要忽略的年龄,我在这里用了60秒:

- (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 
    ... 
} 
+0

谢谢progrmr,但你可以告诉我如何删除缓存的数据使用时间戳........,如果上述方法来计算距离是错误的,那么我应该如何着手......是任何其他方式来计算距离.....因为我已经看到许多应用程序在App Store中做同样的工作,如计算距离,速度等.pls给我你的宝贵意见。 – Siddharth 2010-06-23 06:42:52

+1

我添加了一个代码示例以显示如何删除旧的缓存数据,但是您已经在代码中执行了该操作。 – progrmr 2010-06-23 14:36:15

2

您已经确保您的位置更新时间少于五秒钟。这就是这行代码所做的:

if (locationAge > 5.0) return; 

如前所述由progrmr,问题的关键是在这里几乎可以肯定,你依靠的是低精度的,因此该位置在出现在位置的初步估计随着它更好地解决您的位置问题而迅速移动。你需要做的是首先确保只有当你有一个准确的初始位置修正时,oldLocation才会被设置,然后只有比较newLocations和oldLocation,如果它们也是可接受的分辨率的话。

例如,你可以有这样的事情:

- (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; 
} 

注意从上面的代码,你不需要方法computeDistanceFrom:收件人:和还没有实际需要的财产self.newLocat,在至少在这部分代码中。