Определенный алгоритм определения наиболее точных возвращаемых с iPhone CoreLocation? - PullRequest
8 голосов
/ 07 октября 2010

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

Учитывая, что didUpdateToLocation () может возвращать кэшированную или неточную информацию, как вы узнаете, когда у вас естьточное исправление?

Когда вы устанавливаете желаемую точность в kCLLocationAccuracyNearestTenMeters, HundredMeters, Kilometer, ThreeKilometer, кажется очевидным, что вы можете сравнить горизонтальную точность возвращаемых точек с желаемой точностью, чтобы решить, когда принимать точку.

Но значения kCLLocationAccuracyBestForNavigation и kCLLocationAccuracyBest равны -2 и -1 соответственно, так как я узнаю, когда у меня есть желаемая точность ??

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

Но эти проверки использовались, когда я искал точность в 10-100-х метрах ...не знаю, что, если что-нибудь проверить, когда я бегу ... AccuracyBestForNavigation или ... AccuracyBest ??Я полагаю, чтобы выровнять LocationManager, работающий постоянно, и никогда не ожидать его отключения и не фильтровать результаты ??

Кто-нибудь, кто умнее меня с ответом ??

Спасибо

Ответы [ 2 ]

3 голосов
/ 12 октября 2010

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

Я сделал обертку для LocationManager, как

@protocol LocationManagerWrapperDelegate <NSObject>

@required

- (void) locationUpdated: (CLLocation *) locationUpdate;
- (void) errorOccured: (NSError *) error;

@end

@interface LocationManagerWrapper : NSObject <CLLocationManagerDelegate>
{
    CLLocationManager *locationManager;
    id delegate;
    CLLocation *mostAccurateLocation;
    int updatesCounter;
    BOOL m_acceptableTimePeriodElapsed;
}

@property (nonatomic, retain) CLLocationManager *locationManager;
@property (nonatomic, retain) CLLocation *mostAccurateLocation;
@property (nonatomic, assign) id <LocationManagerWrapperDelegate> delegate;

- (void) startUpdatingLocation;

- (void) locationManager: (CLLocationManager *) manager
    didUpdateToLocation: (CLLocation *) newLocation
           fromLocation: (CLLocation *) oldLocation;

- (void) locationManager: (CLLocationManager *) manager
   didFailWithError: (NSError *) error;

+ (LocationManagerWrapper *) sharedInstance;

@end

Реализация

#define NUMBER_OF_TRIES 4   
#define ACCEPTABLE_TIME_PERIOD 15.0

- (void) startUpdatingLocation
{
NSAssert(self.delegate != nil, @"No delegate set to receive location update.");

updatesCounter = 0;
self.mostAccurateLocation = nil;
m_acceptableTimePeriodElapsed = NO;
[NSTimer scheduledTimerWithTimeInterval:ACCEPTABLE_TIME_PERIOD
                                 target:self
                               selector:@selector(acceptableTimePeriodElapsed:) 
                               userInfo:nil
                                repeats:NO];
[self.locationManager startUpdatingLocation];
}

- (void) acceptableTimePeriodElapsed: (NSTimer *) timer
{
@synchronized(self)
{
    m_acceptableTimePeriodElapsed = YES;
    // TODO: if period is set by user - check we have mostAccurateLocation at this point
    [self.delegate locationUpdated:self.mostAccurateLocation];
    [self.locationManager stopUpdatingLocation];
}
}

- (void) locationManager: (CLLocationManager *) manager
    didUpdateToLocation: (CLLocation *) newLocation
           fromLocation: (CLLocation *) oldLocation
{
@synchronized(self)
{
    if (m_acceptableTimePeriodElapsed) return;
    NSLog([NSString stringWithFormat:@"lat: %@, long: %@, acc: %@", 
           [ [NSNumber numberWithDouble:newLocation.coordinate.latitude] stringValue],
           [ [NSNumber numberWithDouble:newLocation.coordinate.longitude] stringValue],
           [ [NSNumber numberWithDouble:newLocation.horizontalAccuracy] stringValue]  ] );

    updatesCounter++;
    // ignore first returned value
    if (updatesCounter <= 1) return;
    if (self.mostAccurateLocation == nil ||
        self.mostAccurateLocation.horizontalAccuracy > newLocation.horizontalAccuracy)
    {
        self.mostAccurateLocation = newLocation;
    }
    if  (updatesCounter >= NUMBER_OF_TRIES)
    {
        [self.delegate locationUpdated:self.mostAccurateLocation];
        [self.locationManager stopUpdatingLocation];
    }
}
}

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

2 голосов
/ 22 декабря 2010

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

Но у меня действительно есть вопрос / предложение, если хотите. Когда я пытаюсь получить данные о местоположении на iphone, я сразу же получаю как минимум 3 набора координат с одинаковой горизонтальной точностью. Таким образом, большое количество попыток должно быть больше 4. Но тогда возникает вопрос: сколько попыток хорошо?

Так что я предлагаю вместо изменения количества попыток, мы можем немного изменить код, чтобы счетчик количества попыток увеличивался, только если точность по горизонтали значительно меньше предыдущей или меньше, чем самый точный, что-то в этом роде. Я просто думаю здесь вслух. Потому что я посмотрел все данные о местоположении, которые я получил от своего iphone 4 (и я не уверен, как это работает на других устройствах), и, судя по тому, что я увидел, местоположение обновляется довольно постоянно, и точность по горизонтали остается примерно одинаковым для первых нескольких обновлений, затем через некоторое время он внезапно падает с, скажем, 400 до 100, а затем через секунду или две снова падает до примерно 30. Все это происходит в течение около 30-50 обновлений, поэтому в этой ситуации максимальное количество попыток 4 может не сработать, если только вы не учитываете только прыжки. Что вы, ребята, думаете?

...