【问题标题】:How to wait until location is completely found? (Core Location)如何等到完全找到位置? (核心位置)
【发布时间】:2011-05-31 05:14:52
【问题描述】:

我的应用程序有问题。我正在尝试以最精确的方式找到用户的位置,以确定他们的邮政编码。目前我有一个按钮,按下时会启动一个名为locateMe 的方法。

-(IBAction)locateMe; {
self.locationManager = [[CLLocationManager alloc] init];
locationManager.delegate = self;
locationManager.desiredAccuracy = kCLLocationAccuracyBest;
[locationManager startUpdatingLocation];

然后我实现了didUpdateToLocation:

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

       NSLog(@"Found location! %f,%f",newLocation.coordinate.latitude,newLocation.coordinate.longitude);
 }

我之前在didUpdateToLocation 中做过更复杂的事情,但是当我测试一些东西时,我意识到它找到的第一个位置至少并不精确。所以,我把NSLog 调用放在那里,它给了我一个类似于下面的输出......

Found location! 39.594093,-98.614834
Found location! 39.601372,-98.592171
Found location! 39.601372,-98.592171
Found location! 39.611444,-98.538196
Found location! 39.611444,-98.538196

如您所见,它首先给了我一个不正确的值,这导致我的应用出现问题,因为它没有给出正确的位置。

所以,这是我的问题。有什么方法可以等待位置管理器找到最精确的位置?

提前致谢!

编辑:我想要这样的东西:

if (newLocation.horizontalAccuracy <= locationManager.desiredAccuracy) {
}

但它永远不会被调用!

【问题讨论】:

    标签: iphone cocoa-touch core-location


    【解决方案1】:

    所以你可以真正看到发生了什么,尝试 NSLog'ging 你的 newLocation 对象的 Horizo​​ntalAccuracy 属性。您会看到每次点击都会缩小位置范围。

    这意味着您可以在您的位置经理为您提供更新时测试水平精度,并丢弃那些太不准确而无法使用的内容。

    【讨论】:

    • 啊,有道理。从来不知道那个属性。 :)
    【解决方案2】:

    NSLog() oldLocation 属性,我认为它应该(或不应该?)为零。如果出现故障,您可以隐藏 userLocation:

    - (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error {
        mapView.showsUserLocation = NO;
    }
    

    //编辑:desiredAccuracy 表示 didUpdateToLocation 只有在您远离旧位置时才会被调用。如果你将 desiredAccuracy 设置为 100m,它只会在用户从原来的位置移动 100m 时被调用。

    【讨论】:

    • 首次启动时,oldLocation 为 nil。在降低一级(精​​确度)后,它变为非零。
    • 是的,这就是我的意思。您可以检查它是否为 nil 并且不执行您通常会执行的代码。
    • 但即使它不是零,它仍然不是我需要的精确度。
    【解决方案3】:

    Core Location 经常调用 didUpdateToLocation 并在上一个会话期间检测到位置。因此,您可以跳过它发送给您的第一个位置。如果您根据这些数据计算用户速度,您应该注意这种行为。在这种情况下,行人通常以 100 英里/小时的速度行驶。 :)

    如果您要提交带有地理坐标的 cmets 或照片 - 在用户确实输入以撰写评论屏幕时开始接收地理坐标。虽然他会输入一条消息 - 检测到的位置变得非常准确。

    【讨论】:

    • 既然你提到了它,我想我应该在设置视图打开后立即开始接收位置(这就是我要获取我的位置的位置)。
    • 同意。如果您过早开始检测位置 - 它会耗尽设备电池。所以我建议只在真正需要的时候检测位置。
    • 感谢您的帮助。如何丢弃它给出的第一个位置?我会使用计数器吗?
    • 如果您没有根据位置事件执行计算 - 您只需使用最新位置。否则,您应该存储所有收到的位置,然后过滤它们。无论如何,这取决于您的要求。可能计数器就足够了。我们完成了带有路线记录的车速表,还有更复杂的过滤和处理。
    【解决方案4】:

    节省应用程序的启动(或唤醒)时间,并丢弃位置管理器中任何早于应用程序启动时间的结果。 CLLocation 上有一个日期戳。

    【讨论】:

    • 感谢您的回答。我不确定你是否完全理解我的意思。在加载设置视图之前,我不会启动位置管理器。我想等到位置更精确,然后抓取位置数据。那是我的问题。
    • 是的,但是您仍然可以存储应用程序启动时间并且不使用任何在此之前日期的位置 - 或者在您的情况下,您可以存储位置管理器的启动日期,这相当于同一件事。
    • 如果他们启动应用程序然后退出它(即进入后台),这可能会有点棘手。至少这是我使用地图应用程序的用例(启动、暂停、打开、暂停)。考虑到我在车里,结果位置可能很远。但作为一种万无一失的解决方案,它还不错。
    • 您可以使用 willResumeFromBackground 通知重置该启动日期戳。不接受比您的简历更早的日期,并且基本上在该日期重置完成后踢一次位置管理器 - 如果您停止并重新启动位置管理器,您将至少获得一个新的位置更新。
    【解决方案5】:

    我不明白你期望它如何工作。无法保证您将获得具有特定准确度的位置。您假设您最终将获得一个具有您想要的报告准确性的位置,并且这不一定会发生。 LocationManager 将向您发送一系列位置更新,这些更新通常但肯定不总是越来越准确。不幸的是,您不能要求设备接收到足够强的信号来为您提供任意准确的位置,并且设备无法预测未来说“这是我将要获得的最准确的位置” .

    您可以尝试存储在某个时间间隔内报告的所有位置,或者直到报告的准确性似乎稳定下来,并接受几秒钟后您可能不会获得明显更准确的位置。然后,您可以使用最后报告的位置,或者最准确的位置,或者所有这些位置的加权中心点,或者任何您认为有意义的位置。

    鉴于您说这将用于执行反向地理编码以获取邮政编码,我不得不想知道为什么这是一个问题。即使是最精细的位置也可能会命中用户当前的邮政编码,即使是最准确的位置也永远不会在每种情况下都完全正确,因此如果您的用户可以看到,您将希望允许用户更正它。

    【讨论】:

    • +1 我认为这是最好的答案。位置管理器不可能知道它何时收到最精确的位置。
    • 这个答案是正确的,但很迂腐。当然,不可能检测到某个位置何时达到预期效果(请参阅:停止问题)。然而,人们仍然希望以时间为代价获得良好的数据,并希望获得最佳实践。 OP想要什么非常清楚 - 这不是讲座。上面 Evgen 的回答是最有成效的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-12
    • 1970-01-01
    相关资源
    最近更新 更多