是否有必要提供距离过滤器以获得最佳位置?

时间:2009-12-14 16:44:12

标签: objective-c iphone-sdk-3.0 core-location

我在我的应用程序中使用位置管理器,我的位置不准确。我使用下面的代码来获取位置

locationManager.delegate = self;
locationManager.desiredAccuracy = kCLLocationAccuracyBest;

并且在didupdatetolocation方法中我正在使用此代码。

LatitudeData = [[NSString alloc] initWithFormat:@"%f",newLocation.coordinate.latitude];
    LongitudeData = [[NSString alloc] initWithFormat:@"%f",newLocation.coordinate.longitude];
    [UIApplication sharedApplication].networkActivityIndicatorVisible=NO;
    [self insertNewLocationInDataBase];

我需要设置distancefilter吗?我如何获得准确的位置?我想获得准确的位置然后将位置插入数据库。

1 个答案:

答案 0 :(得分:8)

在合理的时间内从Core Location获得良好的结果需要仔细研究。

问题是,一旦开始更新,didUpdateToLocation将会多次触发。每次发射时,位置应该更准确。但是,您不知道它会触发多少次,也不知道锁定到您所要求的准确度的速度有多快(如果有的话)。根据{{​​3}},如果超出最小阈值距离(由distanceFilter属性指定),则会生成其他事件,从而确定更准确的位置值。更改distanceFilter不会为您提供更好的位置(当然,除非您对精确的动作感兴趣)。

有一些常见的设置可以帮助简化这一过程,但您可能希望根据您希望的特定启发式方法来解决这个问题。

  • 发送startUpdating以调用选择器后设置计时器(可以像performSelector:afterDelay:一样简单)。将延迟设置为您愿意等待合理近似值的最长时间。在该选择器的方法中,我将检查以确保该位置足够准确以放置在数据库中,并插入它。如果不是,我会提醒用户。
  • didUpdateToLocation中,立即丢弃任何太旧的位置。 LocationManager通常会首先返回其位置的缓存值 - 而且可能非常旧。
  • didUpdateToLocation中,只需将最新结果保存到实例变量中,如果它不符合您的预期准确度。
  • didUpdateToLocation中,如果新位置足够准确,请在延迟后取消执行选择,然后立即调用。

这只是一个粗略的草图,但它是一个非常多功能的设置,您可以轻松扩展以获得您想要的功能。

以下是这可行的基本概要。这是我的一个视图控制器的配对片段,只显示相关部分的基础知识:

- (void)viewWillAppear:(BOOL)animated {
    [self.locationManager startUpdatingLocation];
    [self performSelector:@selector(finishUpdating) withObject:nil afterDelay:10.0];
    [super viewWillAppear:animated];
}

- (void) locationManager:(CLLocationManager *)manager
     didUpdateToLocation:(CLLocation *)newLocation
            fromLocation:(CLLocation *)oldLocation {
    /* Refuse updates more than a minute old */
    if (abs([newLocation.timestamp timeIntervalSinceNow]) > 60.0) {
        return;
    }
    /* Save the new location to an instance variable */
    self.lastUpdatedLocation = newLocation;

    /* If it's accurate enough, cancel the timer */
    if (newLocation.horizontalAccuracy < 20.0) {
        [NSObject cancelPreviousPerformRequestsWithTarget:self 
                                                 selector:@selector(finishUpdating) 
                                                   object:nil]
        /* And fire it manually instead */
        [self finishUpdating];
    }
}

- (void) finishUpdating {
    /* Check the accuracy of self.lastUpdatedLocation, and either
     * save it or alert the user that it's not accurate enough */
    [self.locationManager stopUpdatingLocation];
}