Подтвердить что ты не робот

CLLocationManager и вопросы точности - любой опыт?

Итак, я имею дело с некоторыми проблемами точности с iPhone GPS. У меня есть приложение, которое использует местоположение.

В методе делегата locationManager: didUpdateToLocation: fromLocation: мне возвращается местоположение. Из немного исследований, похоже, что GPS не всегда точна в первом результате, который он возвращает, даже если для параметра desiredAccuracy установлено значение kCLLocationAccuracyBest.

Чтобы обойти это, я не называю stopUpdatingLocation, прежде чем он вернет newLocation: не менее 3 раз (это очень быстро). Я также играл с двумя другими "требованиями" относительно того, следует ли stopUpdatingLocation и вернуть newLocation. Один из способов, которым я пытался, - проверить lat и long на newLocation и сравнить с oldLocation, и если они не совпадают, сохраните обновление местоположения. Я также попытался проверить расстояние между oldLocation и newLocation, и если оно меньше 20 метров, это нормально. Оба они тестируются с возвратом не менее 3 пробегов. Последний способ менее "строгий", так как newLocation и oldLocation довольно сложно избежать 100-процентного идентичности, если пользователь находится в движущемся транспортном средстве.

Теперь, моя проблема заключается в том, что даже при выполнении вышеизложенного (в основном, не принимающего местоположение, до тех пор, пока не произойдет несколько обновлений на CLLocationManager И, проверяя расстояние между CLLocations (или они идентичны), я все еще видя несколько странные результаты для местоположений, иногда, при тестировании.

Иногда, если я покину приложение, зайдите в Maps.app, используйте GPS, затем откройте многозадачность, принудительно закройте мое приложение, а затем снова откройте его, чтобы получить чистый запуск.

Любые переживания и возможные решения, которые люди использовали для решения одной и той же проблемы? Комментарии и решения оценены:)

4b9b3361

Ответ 1

Я не помню, какой проект был именно таким, из которого я получил следующий код, но это сработало для меня очень хорошо (я помню, это было из видео WWDC 2010). В моем коде я оставил комментарии от оригинального проекта тактично, поэтому, надеюсь, это поможет.

- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation {
    // test the age of the location measurement to determine if the measurement is cached
    // in most cases you will not want to rely on cached measurements
    NSTimeInterval locationAge = -[newLocation.timestamp timeIntervalSinceNow];

    if (locationAge > 5.0) return;

    // test that the horizontal accuracy does not indicate an invalid measurement
    if (newLocation.horizontalAccuracy < 0) return;

    // test the measurement to see if it is more accurate than the previous measurement
    if (bestEffortAtLocation == nil || bestEffortAtLocation.horizontalAccuracy > newLocation.horizontalAccuracy) {
        // store the location as the "best effort"
        self.bestEffortAtLocation = newLocation;

        // test the measurement to see if it meets the desired accuracy
        //
        // IMPORTANT!!! kCLLocationAccuracyBest should not be used for comparison with location coordinate or altitidue 
        // accuracy because it is a negative value. Instead, compare against some predetermined "real" measure of 
        // acceptable accuracy, or depend on the timeout to stop updating. This sample depends on the timeout.
        //
        if (newLocation.horizontalAccuracy <= locationManager.desiredAccuracy) {
            // we have a measurement that meets our requirements, so we can stop updating the location
            // 
            // IMPORTANT!!! Minimize power usage by stopping the location manager as soon as possible.
            //
            [self stopUpdatingLocation:NSLocalizedString(@"Acquired Location", @"Acquired Location")];

            // we can also cancel our previous performSelector:withObject:afterDelay: - it no longer necessary
            [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(stopUpdatingLocation:) object:nil];
        }
    }
}

Надеюсь, это поможет!

Через GetLocationViewController.m в примере проекта Apple Locate Me, доступного по адресу:

https://developer.apple.com/library/content/samplecode/LocateMe/Introduction/Intro.html

Ответ 2

Из ответа donkim рассмотрим замену этой строки

[NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(stopUpdatingLocation:) object:nil];

с линией

[NSObject cancelPreviousPerformRequestsWithTarget: self];