用于确定从iPhone CoreLocation返回的最准确的确定算法?

mor*_*man 8 iphone core-location

还有人把它钉死了吗?我已经阅读了很多论坛帖子,我仍然无法分辨这是否是一个固定的问题......

鉴于didUpdateToLocation()可以返回缓存或不准确的信息,您如何判断何时有准确的修复?

当您将所需精度设置为kCLLocationAccuracyNearestTenMeters,HundredMeters,Kilometer,ThreeKilometers时,您可以将返回点的水平精度与所需精度进行比较,以确定何时接受一个点.

但是kCLLocationAccuracyBestForNavigation和kCLLocationAccuracyBest的值分别是-2和-1,那么我怎么知道什么时候我有所需的精度?

我目前检查修复的年龄并拒绝任何时间过于"过时"的修复.然后检查水平精度是否为负,如果是,则拒绝.如果我得到一个正的verticalAccuracy然后我通常使用该修复,因为相应的水平精度也很好.

但是,当我在10到100米的时间内寻找准确性时,就会使用这些检查......我不知道在运行时有什么需要检查... AccuracyBestForNavigation或... AccuracyBest ?? 我是否想要平衡持续运行的locationManager并且永远不要期望关闭它并且不过滤任何结果?

有人比我更聪明有答案吗?

谢谢

fsp*_*rit 3

这并不是一个真正确定的、完美的算法(我怀疑是否有一个算法可以完成这项任务,因为外部条件,我的意思是,你可以尝试在平原上或坟墓内获取你的位置),它是一个临时算法,而且它对我有用。

我为 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
Run Code Online (Sandbox Code Playgroud)

执行

#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];
    }
}
}
Run Code Online (Sandbox Code Playgroud)

代码不是很好(格式也不是),但我认为这个想法很简单明了,获取第一个位置,扔掉它,它是一个缓存的位置,最多尝试 3 次以获得最准确的位置。它可能需要很长时间,如果用户正在等待(如我的情况),请定义一个时间限制。再一次,它适用于我的应用程序,但请随意调整它或采取另一种方法。