所以我正在处理iPhone GPS的一些准确性问题。我有一个使用位置的应用程序。
在委托方法locationManager: didUpdateToLocation: fromLocation:
中,我正在返回一个位置。从一些研究来看,即使将desiredAccuracy
属性设置为kCLLocationAccuracyBest
,GPS在返回的第一个结果上也不总是准确的。
为了解决这个问题,我不会在stopUpdatingLocation
返回newLocation:
之前至少调用3次(这很快)。关于是否stopUpdatingLocation
并返回newLocation
,我还讨论了另外两个“要求”。我试过的一种方法是检查纬度和长度为newLocation
并与oldLocation
进行比较,如果这些不相同,则保持位置更新运行。我也尝试检查oldLocation
和newLocation
之间的距离,如果它不到20米,那就没事了。这两个都是通过返回至少3次运行来测试的。后一种方式不那么“严格”,因为如果用户在移动的车辆中,newLocation
和oldLocation
很难与100%完全相同。
现在,我的问题是,即使执行上述操作(基本上不接受某个位置,直到CLLocationManager
上发生了一些更新并检查CLLocations
之间的距离(或者它们是否是相同的)我在测试时有时会看到有些奇怪的位置结果。
如果我离开应用程序,进入Maps.app,使用GPS,然后打开多任务处理,强制退出我的应用程序,然后重新打开它以获得干净的启动,有时会修复。
人们习惯于解决同类问题的经验和可能的解决方案?评论和解决方案赞赏:)
答案 0 :(得分:45)
我不记得我从哪个项目获得了以下代码,但这对我来说非常有效(我记得它来自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's no longer necessary
[NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(stopUpdatingLocation:) object:nil];
}
}
}
希望这有帮助!
通过Apple的“Locate Me”示例项目中的GetLocationViewController.m
,可从以下位置获取:
https://developer.apple.com/library/content/samplecode/LocateMe/Introduction/Intro.html
答案 1 :(得分:0)
从donkim的回答考虑更换这一行
[NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(stopUpdatingLocation:) object:nil];
带行
[NSObject cancelPreviousPerformRequestsWithTarget: self];