核心位置的准确性

我目前正在使用位置跟踪应用程序,而且我的CLLocationManager的位置更新不准确。 这导致我的应用程序跟踪距离,这实际上只是由不准确的GPS读数造成的。

不准确的位置读数

我甚至可以将我的iPhone放在桌子上,开启我的应用程序,几分钟后,我的应用程序就会因为这个缺陷跟踪数百米的距离。

这是我的初始化代码:

- (void)initializeTracking { self.locationManager = [[CLLocationManager alloc] init]; self.locationManager.delegate = self; self.locationManager.desiredAccuracy = kCLLocationAccuracyBest; self.locationManager.distanceFilter = 5; [self.locationManager startUpdatingLocation]; } 

提前致谢! 🙂

我在类似的应用程序中解决这个问题的方法之一是丢弃位置更新,其中距离变化略低于位置更新中报告的水平精度。

给定previousLocation ,然后为newLocation计算距离previousLocation距离。 如果distance >= (horizontalAccuracy * 0.5)那么我们使用该位置,并且该位置成为我们的新的previousLocation位置。 如果距离less,我们丢弃该位置更新,不要更改previousLocation并等待下一个位置更新。

这对我们的目的很有效,你可以尝试这样的事情。 如果你仍然发现噪声太多的更新,增加0.5的因素,也许尝试0.66。

当您刚刚开始修复问题时,您可能还需要防止出现这种情况,您可以在其中获得一系列位置更新,但实际上发生的情况是准确性显着提高。

我将避免以水平精度> 70米开始任何位置跟踪或距离测量。 对于全球导航卫星系统来说这些都是质量差的地方,尽pipe这可能是在城市峡谷,树冠沉重或其他信号不好的情况下得到的。

我已经使用这种方法来检索所需位置的准确性(在SWIFT中)

 let TIMEOUT_INTERVAL = 3.0 func locationManager(manager: CLLocationManager!, didUpdateLocations locations: [AnyObject]!) { let newLocation = locations.last as! CLLocation println("didupdateLastLocation \(newLocation)") //The last location must not be capured more then 3 seconds ago if newLocation.timestamp.timeIntervalSinceNow > -3 && newLocation.horizontalAccuracy > 0 { var distance = CLLocationDistance(DBL_MAX) if let location = self.lastLocation { distance = newLocation.distanceFromLocation(location) } if self.lastLocation == nil || self.lastLocation!.horizontalAccuracy > newLocation.horizontalAccuracy { self.lastLocation = newLocation if newLocation.horizontalAccuracy <= self.locationManager.desiredAccuracy { //Desired location Found println("LOCATION FOUND") self.stopLocationManager() } } else if distance < 1 { let timerInterval = newLocation.timestamp.timeIntervalSinceDate(self.lastLocation!.timestamp) if timerInterval >= TIMEOUT_INTERVAL { //Force Stop stopLocationManager() } } } 

哪里:

 if newLocation.timestamp.timeIntervalSinceNow > -3 && newLocation.horizontalAccuracy > 0 { 

检索的最后一个位置不能超过3秒前捕获,而最后一个位置必须具有有效的水平精度(如果小于1,则表示它不是有效的位置)。

然后,我们将使用默认值设置距离:

  var distance = CLLocationDistance(DBL_MAX) 

计算检索到的最后一个位置到新位置的距离:

 if let location = self.lastLocation { distance = newLocation.distanceFromLocation(location) } 

如果我们当地的最后一个位置尚未设置,或者新位置的水平精度比实际位置更好,那么我们将把我们的当地位置设置到新的位置:

 if self.lastLocation == nil || self.lastLocation!.horizontalAccuracy > newLocation.horizontalAccuracy { self.lastLocation = newLocation 

下一步是检查来自该位置的准确性是否足够好。 要做到这一点,我们检查是否检索到的位置的horizo​​ntalDistance,以防止所需的大量。 如果是这样,我们可以阻止我们的经理:

 if newLocation.horizontalAccuracy <= self.locationManager.desiredAccuracy { //Desired location Found self.stopLocationManager() } 

最后, if我们要检查从上一个检索位置到新位置的距离是多less(这意味着这两个位置非常接近)。 如果是这种情况,那么我们将从上一个检索的位置和检索到的新位置获取时间间隔,并检查是否超过3秒。 如果是这样的话,这意味着我们没有收到一个比我们当地的位置更准确的位置的时间超过3秒,所以我们可以停止位置服务:

 else if distance < 1 { let timerInterval = newLocation.timestamp.timeIntervalSinceDate(self.lastLocation!.timestamp) if timerInterval >= TIMEOUT_INTERVAL { //Force Stop println("Stop location timeout") stopLocationManager() } } 

卫星位置一直是个问题。 这是一个估计和估计可以改变。 每一个新的报告都是一个新的估计。 你需要的是一个位置夹,当没有移动时忽略数值。

您可能会尝试使用传感器来了解设备是否正在移动。 看看加速度计数据,如果它没有改变,那么即使GPS说它是设备不移动。 当然,加速度计数据上有噪声,所以你也要过滤掉。

这是一个棘手的问题要解决。

改善操作系统和当前接收给你的东西真的没有太多。 首先看起来,它看起来不像你的代码有什么问题 – 当涉及到iOS的位置更新,你真的是操作系统和你的服务的摆布。

你可以做的是控制你关注的位置。 如果我是在didUpdateLocations函数中,当你从新的位置获得操作系统的callback时,你可以忽略水平精度大于预定义阈值的任何位置,也许是25米? 你最终将使用更less的位置更新,但你会有更less的噪音。