10

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

我正在使用以下代码:

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

在应用程序的冗长恢复或全新的开始之后发生....

4

7 回答 7

21

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

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

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

(来自苹果文档的更多信息在这里

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

[编辑]
如果一开始在海中显示用户位置真的很困扰你,你可以隐藏用户位置,直到你得到一个足够准确/新鲜的位置。
为此,首先将 的showsUserLocation属性设置MKMapViewNO,直到获得足够准确的位置(感谢之前的委托回调),然后将其设置为YES.
通过这样做,您将避免显示不准确或太旧而无法显示的位置(有一个timestamp属性CLLocation可以检查它是否是旧位置)

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

于 2011-11-03T08:10:30.427 回答
4

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

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

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

正在访问坐标 whileuserLocationlocationis nil。如果userLocationorlocation为零,这将返回 0 坐标。lat=0, lon=0 的位置在大西洋,非洲海岸附近。在从中获取坐标之前,您可以添加一个检查location以确保它不为零,即:

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:应该丢弃任何具有表示无效位置的水平精度< 0 的位置。

-(void)mapView:(MKMapView*)mapView didUpdateUserLocation:(MKUserLocation*)userLocation
{
    if (userLocation.location.horizontalAccuracy > 0) {
        [mapView setCenterCoordinate:self.mapView.userLocation.location.coordinate zoomLevel:ZOOM_LEVEL animated:YES];           
    }
}
于 2011-11-07T19:32:49.523 回答
1

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

于 2011-02-09T06:52:13.277 回答
1

正如 Jeremy Massel 所写,您必须理清应用程序启动/继续时的第一个错误位置。几个月前发现了一篇很棒的博客文章:

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

于 2011-11-02T16:11:39.193 回答
1

我在这里做的是——

  1. 开始位置更新
  2. 在位置更新时,检查位置的年龄,如果太旧,我等
  3. 在收到新的更新时,我会在地图上更新它

如果您需要非常准确的位置,那么还要检查准确性和超时,超过该超时您不能容忍等待并使用不太准确的修复。

于 2011-11-04T18:45:46.243 回答
0

在我的应用程序中,我使用了这些方法:

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

其次 - 如果用户已经使用过地图 - 可以存储他的坐标,并在没有其他可用数据的情况下显示那些(+ span(zoom)级别)。

第三 - 在数据的情况下:

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

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

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

2.2.)如果用户放大 - 位置会更新,但地图不会缩小

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

于 2011-11-02T18:31:14.817 回答
0

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

于 2011-02-09T06:52:34.250 回答