核心位置的准确性

时间:2014-07-21 14:41:25

标签: ios objective-c gps location core-location

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

Inaccurate location readings

我甚至可以在打开应用程序的情况下将iPhone放在桌面上,几分钟后我的应用就会因为这个漏洞而跟踪数百米的距离。

这是我的初始化代码:

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

    [self.locationManager startUpdatingLocation];
}

提前致谢! : - )

4 个答案:

答案 0 :(得分:18)

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

给定previousLocation,然后对于newLocation,计算与previousLocation的距离。如果distance >= (horizontalAccuracy * 0.5)那么我们就使用了该位置,该位置就成了新的previousLocation。如果距离较小,则我们会放弃该位置更新,请勿更改previousLocation并等待下一次位置更新。

这对我们的目的很有用,你可能会尝试类似的东西。如果你仍然发现太多的噪音更新,请增加0.5因子,或者尝试0.66。

您可能还希望在刚刚开始获得修复时防范案例,在这些情况下,您会获得一系列似乎正在移动的位置更新,但实际上正在发生的是准确性正在显着提高。

我会避免以水平精度开始任何位置跟踪或距离测量> 70米。这些都是全球导航卫星系统的劣质位置,尽管这可能是你在城市峡谷,重型树冠或其他信号条件差的情况下得到的。

答案 1 :(得分:5)

我已经使用这种方法来检索所需的位置精度(在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

下一步是检查位置的准确性是否足够好。为此,我们检查位置的水平距离是否检索到它,以免获得所需的准确度。如果是这种情况,我们可以阻止我们的经理:

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

使用最后一个if,我们将检查从最后一个位置检索的距离和新位置是否小于一个(这意味着两个位置非常接近)。如果是这种情况,那么我们将从检索到的最后一个位置获取时间间隔并检索新位置,并检查间隔是否超过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()
                }
            }

答案 2 :(得分:1)

这始终是卫星位置的问题。这是一个估计,估计可能会有所不同。每份新报告都是一个新的估计。你需要的是一个位置钳,在没有运动时忽略数值。

您可能会尝试使用传感器来了解设备是否实际移动。查看加速度计数据,如果它没有变化,那么即使GPS显示它也不会移动设备。当然,加速度计数据上存在噪音,因此您必须对其进行过滤。

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

答案 3 :(得分:0)

您可以采取更多措施来改善操作系统和您当前的接收效果。首先看,你的代码看起来没有任何问题 - 当涉及iOS位置更新时,你真的受操作系统和服务的支配。

您可以做的是控制您要注意的位置。当你从具有新位置的OS获得回调时,如果我在你的didUpdateLocations函数中 - 你可以忽略任何水平精度大于某个预定义阈值的位置,可能是25m?您最终会使用较少的位置更新,但噪音较少。