MKMapView的用户位置在启动或恢复时出错

时间:2011-02-09 06:35:39

标签: iphone mkmapview game-center userlocation

当我开始使用我的应用程序时,或者很长一段时间后恢复,MKMapView的userLocation概念是错误的,并且显示我在海中。

我使用以下代码:

self.mapView.centerCoordinate = self.mapView.userLocation.location.coordinate;
[mapView setCenterCoordinate:self.mapView.userLocation.location.coordinate zoomLevel:ZOOM_LEVEL animated:YES];

经过漫长的应用程序简历或全新的开始......

7 个答案:

答案 0 :(得分:21)

这是预期的行为:iPhone使用GPS并不总是跟踪用户位置(它将耗费大量电池)。因此,只要显示地图,MKMapView实例就会显示它知道的最后一个“最佳”用户位置,然后通过激活跟踪来提高准确性(这是一个无缝过程,您无需关心关于它)。

您可以通过实施MKMapView协议来监控MKMapViewDelegate何时更新地图上的用户位置。只需实施:

- (void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation      {
    CLLocationAccuracy accuracy = userLocation.location.horizontalAccuracy;
    if (accuracy ......) {
    } 
}

(来自苹果文档here的更多信息)

我的示例中的上述代码检查mapView当前显示的位置的准确性,并做出相应的反应。

[编辑]
如果首先在海中显示用户位置真的打扰你,你可以隐藏用户位置,直到你得到一个准确/足够新的位置。
为此,请首先将showsUserLocation的{​​{1}}属性设置为MKMapView,直到获得足够准确的位置(由于之前的委托回调),然后将其设置为{{1 }}。
通过这样做,您将避免显示一个不准确或太旧而无法显示的位置(NO中有一个YES属性来检查它是否是旧位置

注意:您必须在您身边创建timestamp实例,MKMapView在内部创建一个实例并发布通过此委托选择器接收的位置。

答案 1 :(得分:4)

直接使用CLLocationManager时,通常会在第一个回调中获得缓存位置。它通常是一个很好的位置,虽然很旧。之后,您可以快速获得额外的回调,使用wifi,手机信号塔(如果有)提供更好的位置。如果您要求<你将获得1000米精度(经过更多秒)获得GPS三角测量。

这些都不应该是不准确的,不能在海洋中。我怀疑这行代码:

self.mapView.centerCoordinate = self.mapView.userLocation.location.coordinate;

userLocationlocationnil时访问坐标。如果userLocationlocation为nil,则返回0坐标。 lat = 0,lon = 0的位置位于非洲海岸附近的大西洋。您可以添加location的检查,以确保它在获取坐标之前不是nil,即:

if (self.mapView.userLocation.location) {
    self.mapView.centerCoordinate = self.mapView.userLocation.location.coordinate;
    [mapView setCenterCoordinate:self.mapView.userLocation.location.coordinate zoomLevel:ZOOM_LEVEL animated:YES];           
}

您还需要等待MKMapViewDelegate mapView:didUpdateUserLocation:的回调,以了解何时有可用的有效位置。您didUpdateUserLocation:的实施应丢弃任何horizontalAccuracy< -(void)mapView:(MKMapView*)mapView didUpdateUserLocation:(MKUserLocation*)userLocation { if (userLocation.location.horizontalAccuracy > 0) { [mapView setCenterCoordinate:self.mapView.userLocation.location.coordinate zoomLevel:ZOOM_LEVEL animated:YES]; } } 的位置0表示无效的位置。

{{1}}

答案 2 :(得分:1)

遗憾的是,这是GPS芯片的一项功能。它并不总是打开,因此在前几个时刻数据通常是错误的。您最好的选择可能是将应用程序记录的最后位置存储在NSUserDefaults中,然后在切换到实时数据之前等待精度达到您想要的位置,否则隐藏MkMapView直到精度达到您想要的位置是,然后在那一点显示它(你可以在过渡期间显示加载屏幕)

答案 3 :(得分:1)

就像杰里米·马塞尔(Jeremy Massel)写的那样,你必须解决应用程序启动/继续的第一个不良位置。几个月前发现了一篇很棒的博客文章:

http://troybrant.net/blog/2010/02/detecting-bad-corelocation-data/

答案 4 :(得分:1)

我在这里做的是 -

  1. 开始位置更新
  2. 关于位置更新,检查位置的年龄,如果它太旧,我等待
  3. 收到新的更新后我在地图上更新
  4. 如果您需要非常准确的位置,那么请检查准确性以及超时,超出该超时,您将无法忍受等待并使用不太准确的修复。

答案 5 :(得分:0)

离实际位置有多远?当应用程序刚刚开始或从很长一段时间恢复时,用户位置一般都是错误的。随着应用程序的运行,它将变得越来越准确。有一些方法可以在CLLocationManager中获取用户位置的准确性,看看你在那里得到了什么样的值。

答案 6 :(得分:0)

在我的应用中,我使用了以下方法:

首先 - 有一个默认位置是好的(例如 - 应用程序是关于一个城市 - 然后放大以显示整个城市)(在第一个应用程序打开时,没有数据下载时)

第二 - 如果用户已使用地图 - 可以存储他的坐标,并显示那些(+跨度(缩放)级别),以防没有其他数据可用。

第三 - 如果是数据:

1。)如果数据库已经有一些坐标 - 在第一个地图打开时(应用程序关闭时) - 缩小/缩小以显示地图上的所有引脚。

2。)当仍然在地图中并刚刚到达更新(新位置或更改内容)时,有两种可能性:

2.1。)如果用户未放大到任何位置 - 地图放大/缩小以显示所有位置。

2.2。)如果用户已放大 - 位置已更新,但地图未缩小

Ofcourse - 然后还有一些过滤按钮(例如:搜索,用户位置等等 - 过滤位置,缩小/缩小以显示过滤结果)