Проблемы с точностью CoreLocation

У меня есть программа с менеджером местоположения, настроенная следующим образом:

self.locationManager = [[CLLocationManager alloc] init];
[locationManager startUpdatingLocation];
locationManager.delegate = self;
locationManager.distanceFilter = kCLDistanceFilterNone; 
locationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters;

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

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

Заранее спасибо!


person Ben Harris    schedule 20.07.2009    source источник


Ответы (3)


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

Вы не можете просто перейти к десятиметровому результату - не зря его называют «желаемой», а не обязательной точностью. Вы должны дать ему время, чтобы рассчитать более точные позиции.

person Kendall Helmstetter Gelner    schedule 20.07.2009
comment
По какой-то причине, когда я проверяю это свойство ([newLocation horizontalAccuracy]), LocationManager обновляется только дважды, а newLocation оба раза одинаково. Вы знаете причину этого? - person Ben Harris; 20.07.2009
comment
Это лучший результат, который он мог найти на тот момент. Вы не всегда будете получать результаты в пределах десяти метров - даже если у вас есть GPS в iPhone, иногда в помещении приходится прибегать к триангуляции вышек сотовой связи. - person Kendall Helmstetter Gelner; 21.07.2009

Недавно я решил эту проблему и обнаружил, наконец, внимательно прочитав документацию, что CoreLocation работает в отдельном потоке, поэтому вы можете запустить его, а затем получать события по мере его обновления. Он находится в документации под рубрикой «Получение Местоположение пользователя ". Итак, вот где вы начинаете обновление:

- (void)startStandardUpdates
{
    if (nil == locationManager)
        locationManager = [[CLLocationManager alloc] init];
    locationManager.delegate = self;
    locationManager.desiredAccuracy = kCLLocationAccuracyBest;
    locationManager.distanceFilter = none;
    [locationManager startUpdatingLocation];
}

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

- (void)locationManager:(CLLocationManager *)manager
    didUpdateToLocation:(CLLocation *)newLocation
    fromLocation:(CLLocation *)oldLocation
{
    if (newLocation.horizontalAccuracy < 30.0)
    {
        NSLog(@"latitude %+.6f, longitude %+.6f\n",
                newLocation.coordinate.latitude,
                newLocation.coordinate.longitude);
        [manager stopUpdatingLocation];
    }
}

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

person mutatron    schedule 12.04.2011

Одна из стратегий - запустить таймер на период, достаточный для получения исправления (что также будет приемлемо для пользователя).

+ (NSTimer *)scheduledTimerWithTimeInterval:(NSTimeInterval)seconds target:(id)target selector:(SEL)aSelector userInfo:(id)userInfo repeats:(BOOL)repeats

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

Вероятно, это лучшее, что вы собираетесь получить. Вы можете дать пользователю возможность попробовать еще раз для местоположения, если оно все еще недостаточно точное.

person Kevin    schedule 11.08.2009