【问题标题】:How to set accuracy and distance filter when using MKMapView使用 MKMapView 时如何设置精度和距离过滤器
【发布时间】:2011-08-21 07:08:49
【问题描述】:

当我使用setShowsUserLocationMKMapView 来跟踪用户位置时,如何设置精度和距离过滤器?我不是在说CLLocationManager

谢谢,

【问题讨论】:

    标签: iphone ios ipad mkmapview cllocationmanager


    【解决方案1】:

    您无法控制内部MKMapView 位置管理器(用于跟踪带有蓝点的用户)的准确性,但您可以创建自己的位置管理器并使用它来重新定位地图。这是一个食谱...

    处理核心位置权限

    在核心位置委托中:

    - (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error
    {
        if ([CLLocationManager authorizationStatus] == kCLAuthorizationStatusDenied){
            NSLog(@"User has denied location services");
        } else {
            NSLog(@"Location manager did fail with error: %@", error.localizedFailureReason);
        }
    }
    

    就在设置位置管理器之前:

    if (![CLLocationManager locationServicesEnabled]){
        NSLog(@"location services are disabled"];
        return;
    }
    if ([CLLocationManager authorizationStatus] == kCLAuthorizationStatusDenied){
        NSLog(@"location services are blocked by the user");
        return;
    }
    if ([CLLocationManager authorizationStatus] == kCLAuthorizationStatusAuthorized){
        NSLog(@"location services are enabled");
    }  
    if ([CLLocationManager authorizationStatus] == kCLAuthorizationStatusNotDetermined){
        NSLog(@"about to show a dialog requesting permission");
    }
    

    设置核心位置

    self.locationManager = [CLLocationManager new];
    self.locationManager.purpose = @"Tracking your movements on the map.";
    self.locationManager.delegate = self;
    
    /* Pinpoint our location with the following accuracy:
     *
     *     kCLLocationAccuracyBestForNavigation  highest + sensor data
     *     kCLLocationAccuracyBest               highest     
     *     kCLLocationAccuracyNearestTenMeters   10 meters   
     *     kCLLocationAccuracyHundredMeters      100 meters
     *     kCLLocationAccuracyKilometer          1000 meters 
     *     kCLLocationAccuracyThreeKilometers    3000 meters
     */
    self.locationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters;
    
    /* Notify changes when device has moved x meters.
     * Default value is kCLDistanceFilterNone: all movements are reported.
     */
    self.locationManager.distanceFilter = 10.0f;
    
    /* Notify heading changes when heading is > 5.
     * Default value is kCLHeadingFilterNone: all movements are reported.
     */
    self.locationManager.headingFilter = 5;
    
    // update location
    if ([CLLocationManager locationServicesEnabled]){
        [self.locationManager startUpdatingLocation];
    }
    

    使用我们的位置管理器重新定位地图

    - (void)locationManager:(CLLocationManager *)manager 
        didUpdateToLocation:(CLLocation *)newLocation 
               fromLocation:(CLLocation *)oldLocation 
    {
        MKCoordinateRegion region = { { 0.0f, 0.0f }, { 0.0f, 0.0f } };
        region.center = newLocation.coordinate;
        region.span.longitudeDelta = 0.15f; 
        region.span.latitudeDelta = 0.15f;
        [self.mapView setRegion:region animated:YES];
    }
    

    把它放在委托人身上。 MKMapView 没有距离或精度过滤器,只有 CLLocationManager 有。 MKMapView 是围绕一个点的区域跨度,在上面的示例中为 0.15 度(0.15*111 公里)。

    我尝试过但没有成功的方法

    文档没有说明MKMapView 从哪里获取更新。我试过了

    - (void)locationManager:(CLLocationManager *)manager 
        didUpdateToLocation:(CLLocation *)newLocation 
               fromLocation:(CLLocation *)oldLocation {
        NSLog(@"newLocation %@", newLocation.timestamp);
        NSLog(@"last map location %@", [NSString stringWithFormat:@"%@",[[[self.mapView userLocation] location] timestamp]]);
    }
    

    我得到了不同的价值观。看起来MKMapView 使用了自己的CLLocationManager,这意味着您无法设置其准确性。您也不能为MKMapViewCLLocationManager 添加您的代表。

    我的印象是,设置准确性的唯一方法是将显示用户位置设置为 NO 并创建一个带有蓝点的自定义注释,这意味着手动重新定位已发布的地图。您可以使用 github 项目 artifact-extractor 从 SDK 中获取蓝点图形。

    我不知道我是否遗漏了什么,或者MKMapView 的这一部分很糟糕。

    【讨论】:

    • 您提供的代码是针对 CLLocationManager 而不是 MKMapView。
    • 嗨 Jano,在这种情况下,如果我也使用 [MKMapView setShowsUserLocation] 那么我不会有两个位置请求进程并行运行吗?一个来自 MKMapView,一个来自 CLLocation Manager?再次感谢您的澄清。
    • 我猜你会的。如果您想要自定义准确性,我会使用自定义注释并将其设置为 NO。看起来像一个解决方法,但我不知道更好。我会赞成这个问题并希望得到另一种意见。
    • @VanDuTran 避免使用手动发布的自定义注释。如果设备运行速度很快,它将消耗 CPU 速度。更好的方法是添加围绕“蓝点”包裹的 UIImageView,作为 MKMapViews 视图的子视图——这将使用 GPU 呈现注释只要无法滚动地图就可以工作。
    【解决方案2】:

    这里显示地图是一个示例代码。

    首先在您的 .h 文件中导入 MKMapKit 和 CoreLocation 框架。

    #import <MapKit/MapKit.h>
     #import <CoreLocation/CoreLocation.h>
    

    在 .h 文件中添加 MKMapKit 和 CoreLocation 委托

    @interface MapViewController : UIViewController <MKMapViewDelegate, CLLocationManagerDelegate>
    
    
    CGPoint gameMapCenter = CGPointMake([[UIScreen mainScreen] bounds].size.width / 2, [[UIScreen mainScreen] bounds].size.height / 2);
        gameMapView = [[MKMapView alloc] initWithFrame:CGRectMake(0, 0, 640, 620)];
        [gameMapView setCenter:gameMapCenter];
        [gameMapView setMapType:MKMapTypeStandard];
        [gameMapView setDelegate:self];
        [self.view addSubview:gameMapView];
        [gameMapView setShowsUserLocation:YES];
    

    使用CLLocationManager 获取用户位置。

    声明一个 CLLocationManager 的实例

    CLLocationManager *locationManager;
    

    ViewDidLoad

    locationManager = [[CLLocationManager alloc] init];
    
    [locationManager setDelegate:self];
    
    [locationManager setDesiredAccuracy:kCLLocationAccuracyBest];
    
    [locationManager setDistanceFilter:kCLDistanceFilterNone];
    
    [locationManger startUpdatingLocation];
    

    startUpdatingLocation方法实现:

    (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation 
    {
          //Your Stuff
    }
    

    【讨论】:

    • 是的,但我需要显示地图。地图是我的应用程序的主视图。
    • @VanDuTran 嘿,我在这里更新了我的答案,您可以找到如何添加地图视图以及如何获取用户位置。
    • 因为这个[gameMapView setShowsUserLocation:YES];和 [locationManger startUpdatingLocation];,你会有双重通知?
    • @VanDuTran 不,你不会,地图自己的 CLLocationManager 与你的 CLLocationManager 是分开的
    【解决方案3】:

    您无法设置准确度,但是,您可以通过 MKMapView 委托方法中的 userLocation 获取准确度。

    - (void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation
    {
        NSLog(@"%f", userLocation.location.horizontalAccuracy);
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-02-17
      • 2011-03-27
      • 2017-04-23
      • 1970-01-01
      相关资源
      最近更新 更多