Как установить фильтр точности и расстояния при использовании MKMapView - PullRequest
29 голосов
/ 09 мая 2011

Когда я использую setShowsUserLocation с MKMapView для отслеживания местоположения пользователя, как мне установить фильтр точности и расстояния?Я не говорю о CLLocationManager.

Спасибо,

Ответы [ 3 ]

81 голосов
/ 09 мая 2011

Вы не можете контролировать точность внутреннего 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, что означает, что вы не можете установить его точность. Вы также не можете добавить своего делегата для CLLocationManager из MKMapView.

У меня сложилось впечатление, что единственный способ установить точность - это настроить показ пользовательского положения на NO и создать пользовательскую аннотацию с синей точкой, что означает повторное центрирование карты вручную после публикации. Вы можете получить изображение с синей точкой из SDK с помощью экстрактора иллюстраций проекта github.

Я не знаю, упускаю ли я что-то или эта часть MKMapView просто отстой.

3 голосов
/ 01 февраля 2013

Для отображения карты приведен пример кода.

Сначала импортируйте MKMapKit и CoreLocation Framework в ваш файл .h.

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

Добавить MKMapKit и CoreLocation Delegate в файл .h

@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
}
2 голосов
/ 09 апреля 2012

Вы не можете установить точность, однако вы можете получить точность через userLocation в методе делегата MKMapView.

- (void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation
{
    NSLog(@"%f", userLocation.location.horizontalAccuracy);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...