Нужно ли давать дистанционный фильтр для получения лучшего местоположения? - PullRequest
1 голос
/ 14 декабря 2009

Я использую диспетчер местоположения в своем приложении, и я получаю неточное местоположение. Я использую приведенный ниже код для получения местоположения

locationManager.delegate = self;
locationManager.desiredAccuracy = kCLLocationAccuracyBest;

и в методе didupdatetolocation я использую этот код.

LatitudeData = [[NSString alloc] initWithFormat:@"%f",newLocation.coordinate.latitude];
    LongitudeData = [[NSString alloc] initWithFormat:@"%f",newLocation.coordinate.longitude];
    [UIApplication sharedApplication].networkActivityIndicatorVisible=NO;
    [self insertNewLocationInDataBase];

мне нужно установить дистанционный фильтр? Как я могу получить точное местоположение? Я хочу получить точное местоположение, затем вставлю местоположение в базу данных.

1 Ответ

8 голосов
/ 14 декабря 2009

Получение хорошего результата от Core Location за разумное время требует некоторой осторожности.

Проблема в том, что как только вы начнете обновление, didUpdateToLocation будет срабатывать несколько раз. Каждый раз, когда он стреляет, местоположение должно быть более точным. Однако вы не знаете, сколько раз он сработает, и не знаете, как быстро произойдет блокировка с запрошенной вами точностью (если она когда-либо произойдет). Согласно документации дополнительные события генерируются, если минимальное пороговое расстояние (как указано в свойстве distanceFilter) превышено или , определяется более точное значение местоположения. Изменение distanceFilter не даст вам лучшего местоположения (если, конечно, вы не заинтересованы в точных движениях ).

Существуют некоторые общие настройки, которые помогут упростить эту задачу, но вы, вероятно, захотите поиграть с этим в зависимости от желаемой эвристики.

  • Установите таймер после отправки startUpdating для вызова селектора (может быть просто performSelector:afterDelay:). Установите максимальную задержку, в течение которой вы готовы ждать разумного приближения. В методе этого селектора я проверю, чтобы убедиться, что местоположение является достаточно точным для размещения в базе данных, и вставлю его. Если это не так, я бы предупредил пользователя.
  • В didUpdateToLocation немедленно откажитесь от всех слишком старых мест. LocationManager часто сначала возвращает кэшированное значение своего местоположения - и оно может быть очень старым.
  • В didUpdateToLocation просто сохраните последний результат в переменной экземпляра, если он не соответствует вашей желаемой точности.
  • В didUpdateToLocation, если новое местоположение достаточно точное, отмените выполнение селектора после задержки и вместо этого немедленно вызовите его.

Это всего лишь грубый набросок, но это довольно универсальная настройка, которую вы можете легко расширить, чтобы получить желаемую функциональность.

Вот основные принципы того, как это может работать. Это парный фрагмент из одного из моих контроллеров представления, чтобы показать основы соответствующих частей:

- (void)viewWillAppear:(BOOL)animated {
    [self.locationManager startUpdatingLocation];
    [self performSelector:@selector(finishUpdating) withObject:nil afterDelay:10.0];
    [super viewWillAppear:animated];
}

- (void) locationManager:(CLLocationManager *)manager
     didUpdateToLocation:(CLLocation *)newLocation
            fromLocation:(CLLocation *)oldLocation {
    /* Refuse updates more than a minute old */
    if (abs([newLocation.timestamp timeIntervalSinceNow]) > 60.0) {
        return;
    }
    /* Save the new location to an instance variable */
    self.lastUpdatedLocation = newLocation;

    /* If it's accurate enough, cancel the timer */
    if (newLocation.horizontalAccuracy < 20.0) {
        [NSObject cancelPreviousPerformRequestsWithTarget:self 
                                                 selector:@selector(finishUpdating) 
                                                   object:nil]
        /* And fire it manually instead */
        [self finishUpdating];
    }
}

- (void) finishUpdating {
    /* Check the accuracy of self.lastUpdatedLocation, and either
     * save it or alert the user that it's not accurate enough */
    [self.locationManager stopUpdatingLocation];
}
...