还有人把它钉死了吗? 我已经阅读了很多论坛帖子,我仍然无法判断这是否是一个固定的问题......
鉴于didUpdateToLocation()可以返回缓存或不准确的信息,您如何判断何时有准确的修复?
当您将所需精度设置为kCLLocationAccuracyNearestTenMeters,HundredMeters,Kilometer,ThreeKilometers时,您可以将返回点的水平精度与所需精度进行比较,以确定何时接受一个点。
但是kCLLocationAccuracyBestForNavigation和kCLLocationAccuracyBest的值分别是-2和-1,所以我怎么知道我什么时候有所需的精度?
我目前检查修复的时间并拒绝任何时间过于“过时”的修复。 然后检查水平精度是否为负,如果是,则拒绝。 如果我得到一个正的verticalAccuracy,那么我通常使用该修复,因为相应的水平精度也很好。
但是当我在10到100米的时间内寻找准确度时,就会使用这些检查...... 我不知道当我跑步时要检查什么... AccuracyBestForNavigation或... AccuracyBest ??我是否想要平衡持续运行的locationManager并且永远不要期望关闭它并且不过滤任何结果??
任何比我更聪明的答案?
由于
答案 0 :(得分: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
实施
#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次尝试以获得最准确的位置。这可能需要很长时间,如果用户正在等待(如我的情况),请定义时间限制。再一次,它适用于我的应用程序,但随意调整它或采取另一种方法。
答案 1 :(得分:2)
我知道这是我带回来的一个老线程,但我遇到了这个问题,因为我也在寻找一个最准确的解决方案,在阅读了你的解决方案之后,我非常喜欢它。像morgman一样,我也在想类似的东西,但你只是把我们的想法放在代码中,哈哈。我也喜欢你的前向多线程思想;)
但如果你愿意,我实际上有一个问题/建议。 当我尝试在iphone上获取位置数据时,我至少得到3组具有相同水平精度的坐标。因此,大量的尝试必须超过4.但问题是,有多少尝试是好的?
所以我建议不要改变尝试次数,我们可以稍微调整一下代码,这样尝试计数器的数量就会增加只有当水平精度远低于前一个,或者小于最精确的,类似的东西。我只是在这里大声思考。因为我查看了从iphone 4获得的所有位置数据(我不确定它在其他设备上是如何工作的),从我看到的情况来看,位置不断更新,水平精度对于前几次更新保持相对相同,然后一段时间之后它会突然从400减少到100,然后在一两秒之后,它又会再次下降到30左右。这一切都是在大约30-50个更新,所以在这种情况下,最多4次尝试可能不起作用,除非你只计算跳跃。你们觉得怎么样?