4

我正在开发一个计算用户行进距离的应用程序。我正在使用 CLLocationManager 类来执行此操作,但我最初获取的是缓存数据,并且距离变量也在突然增加。请帮帮我......我使用了以下代码......

注意:距离是一个静态变量。这里

  - (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 (null) new <+28.62114850, +77.37001021> +/- 80.00m(速度 -1.00 mps / course -1.00)@ 2010-06-22 19:21:59 +0530 距离 0.000000

精度 0 oldd <+28.62114850, +77.37001021> +/- 80.00m(速度 -1.00 mps / course -1.00)@ 2010-06-22 19:21:59 +0530 new <+28.61670485, +77.37068155> +/- 80.00 m(速度 -1.00 mps / 路线 -1.00)@ 2010-06-22 19:22:00 +0530 距离 498.211345

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

4

2 回答 2

8

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

您打印的精度不正确,使用 %f 而不是 %d,类型是 double 而不是 int。

当 GPS 首次启动时,位置可能会迅速变化,因为您从小区三角测量中获得的位置精度较低,然后当您获得 GPS 采集时,您会获得更高精度的位置。这些可能相距很远(1000m),看起来您在几秒钟内移动了很远,但只有精度发生了变化。

不要使用精度差异很大的两个位置来计算行进距离。

编辑添加了代码示例,如何忽略旧的位置数据。你决定忽略多少岁,我在这里用了 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
    ...
}
于 2010-06-23T03:38:45.820 回答
2

您已经确保您的位置更新不到五秒。这就是这行代码的作用:

if (locationAge > 5.0) return;

正如 progrmr 所说,这里的关键问题几乎可以肯定是您依赖于低准确度的初始位置估计,因此该位置似乎在快速移动,因为它可以更好地定位您的位置。您需要做的是首先确保 oldLocation 仅在您具有准确的初始位置修复时才被设置,然后仅将 newLocation 与该 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:tO:,而且 self.newLocat 属性实际上也不是必需的,至少在这部分代码中是这样。

于 2011-09-27T11:12:55.667 回答