2017-06-20 37 views
2

我對swift比較陌生,我試圖在我的應用中添加一個功能,該功能跟蹤在受限時間內行進的距離。使用核心位置時的不精確的距離旅行值

但是,當我運行該應用程序時,即使手機接收到的經緯度是準確的,我仍然遇到多個問題: 1.該應用程序只記錄位置變化幾秒鐘 2.應用程序記錄即使設備靜止不動也會發生劇烈運動。

任何和所有的幫助表示讚賞。這裏是我的代碼:

import UIKit 
import CoreLocation 
import FirebaseAuth 
import FirebaseDatabase 

class MWTCountdownViewController: UIViewController, CLLocationManagerDelegate { 

@IBOutlet weak var timerLabel: UILabel! 
@IBOutlet weak var metersLabel: UILabel! 
@IBOutlet weak var ConfirmTrialButton: UIButton! 
var zeroTime = TimeInterval() 
var timer : Timer = Timer() 
var ref: DatabaseReference? 

let locationManager = CLLocationManager() 
var startLocation: CLLocation! 
var lastLocation: CLLocation! 
var distanceTraveled: Double = 0.0 

override func viewDidLoad() { 
    super.viewDidLoad() 
    ConfirmTrialButton.isHidden = true 
    ConfirmTrialButton.isEnabled = false 
    locationManager.requestWhenInUseAuthorization() 

    if CLLocationManager.locationServicesEnabled(){ 
     locationManager.delegate = self 
     locationManager.desiredAccuracy = kCLLocationAccuracyBest 
     distanceTraveled = 0.0 
     startLocation = nil 
     lastLocation = nil 
     locationManager.startUpdatingLocation() 
     locationManager.startMonitoringSignificantLocationChanges() 
     locationManager.distanceFilter = 10 

    } else { 
     print("Need to Enable Location") 
    } 

    timer = Timer.scheduledTimer(timeInterval: 0.01, target: self, selector: #selector(MWTCountdownViewController.updateTime), userInfo: nil, repeats: true) 
    zeroTime = Date.timeIntervalSinceReferenceDate 


    ref = Database.database().reference() 

} 
func updateTime() { 
    let currentTime = Date.timeIntervalSinceReferenceDate 
    var timePassed: TimeInterval = currentTime - zeroTime 
    let minutes = UInt8(timePassed/60.0) 
    timePassed -= (TimeInterval(minutes) * 60) 
    let seconds = UInt8(timePassed) 
    timePassed -= TimeInterval(seconds) 
    let millisecsX10 = UInt8(timePassed * 100) 

    let strMinutes = String(format: "%02d", minutes) 
    let strSeconds = String(format: "%02d", seconds) 
    let strMSX10 = String(format: "%02d", millisecsX10) 

    timerLabel.text = "\(strMinutes):\(strSeconds):\(strMSX10)" 

    if timerLabel.text == "06:00:00" { 
     timer.invalidate() 
     locationManager.stopUpdatingLocation() 
     ConfirmTrialButton.isHidden = false 
     ConfirmTrialButton.isEnabled = true 
    } 
} 

func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) { 
    if startLocation == nil { 
     startLocation = locations.first as CLLocation! 
    } else if let location = locations.last { 
     let lastDistance = lastLocation.distance(from: location) 
     distanceTraveled += lastDistance 
     let trimmedDistance = String(format: "%.2f", distanceTraveled) 
     metersLabel.text = "\(trimmedDistance) m" 
    } 

    lastLocation = locations.last as CLLocation! 
} 
+0

我將不勝感激任何示例代碼添加爲了解決這個問題。謝謝。 – solthums

回答

1

您目前的計算行程距離的策略會高估距離,可能會造成很大的影響。

目前,您認爲您始終可以將報告的最後位置與locationManager(didUpdateLocations:)之間的距離與您的總行程距離相加。不幸的是,這不是一個安全的假設。

在文檔爲startUpdatingLocation我們看到:

接收器主要是產生更新事件超過在distanceFilter屬性的值時。更新可能會在其他情況下提供。例如,如果硬件收集更準確的位置讀數,則接收器可以發送另一個通知。

該設備的初始位置固定可能是非常不準確。您收到的第一批位置更新可能不會指示設備的任何移動,而只是越來越精確的測量。至少您應該考慮新位置的,以嘗試確定您是否可以使用您收到的數據。例如。如果您獲得多個相距10米的測量值,但所有測量值都具有100米的精確度,您真的不知道設備是否移動了。

這裏值得注意的是,desiredAccuracy可以防止傳送不準確的位置,它只是指定設備應該如何努力才能獲得越來越精確的位置。

當請求高精度位置數據時,位置服務提供的初始事件可能沒有您請求的準確性。定位服務儘可能快地提供初始事件。然後,它會繼續根據您請求的準確性確定位置,並在有數據可用時根據需要提供其他事件。

即使在其最高精度CLLocation數據將包含相當數量的抖動。即使設備保持靜止,計算每個報告位置之間的距離也會顯示出大量移動。相反,您可能希望收集所有報告的位置,並使用某種平滑或曲線擬合來估計實際的行進路徑。

準確地說,您要在這裏使用什麼樣的策略,取決於您對設備移動的假設。導航應用通常會將估計位置固定在已知道路上。正在運行的應用程序需要處理相當緊密的循環,以便他們可以跟蹤圍繞60米寬的軌道運行。一個下坡滑雪應用程序可能需要處理大量的橫向移動,但能夠在跑步過程中不會出現顯着的上坡。

+0

謝謝喬納。雖然我理解你的邏輯和代碼中的缺陷,但我想不出實現這種過濾的方法。這個應用程序將跟蹤步行距離,並需要相當準確。您能否提供更多提示或示例代碼添加?謝謝。 – solthums

+0

某些選項:您可以嘗試在開始跟蹤之前等待準確的位置修復,如果無法獲得所需的準確性(儘管這可能會導致應用程序無法在室內或其他不良接收環境中使用),則會失敗。你可以嘗試從你的位置建造一條更加緩慢的小路(並根據精度和移動方向調整控制點)來猜測實際的行駛路徑。您可以將曲線擬合(如https://blog.demofox.org/2016/12/22/incremental-least-squares-curve-fitting/)應用到位置的滑動窗口(計數或時間)。 – Jonah

+0

如果你知道你只需要支持步行速度,也許你可以每隔幾秒將報告的位置平均到一個單一的估計位置,或者你可能會找到一種方法來忽略或修改需要不合理的旅行速度的位置。 – Jonah