CLLocation 距离跟踪启动不正确
CLLocation distance tracking starts off incorrectly
我是 Swift 的新手(以及这个网站,如果我做错了什么,我深表歉意),我正在尝试制作一个 运行 应用程序来跟踪用户的位置。虽然我用来跟踪距离的功能有效,但它不是从 0 开始。当我点击开始按钮时,距离从一个随机数开始,然后从那里开始跟踪。
我的问题是:有没有我没有正确解决的问题?如果是这样,有没有办法修复它以便跟踪更准确?这是我目前所拥有的:
override func viewDidLoad() {
super.viewDidLoad()
stopwatchLabel.text = "00:00.00"
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.delegate = self
locationManager.requestAlwaysAuthorization()
locationManager.activityType = .fitness
locationManager.distanceFilter = 10.0
mapView.showsUserLocation = true
startLocation = nil
// Do any additional setup after loading the view.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
// MARK: - Location Delegate Methods
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation])
{
let location = locations.last
let center = CLLocationCoordinate2D(latitude: location!.coordinate.latitude, longitude: location!.coordinate.longitude)
let region = MKCoordinateRegion(center: center, span: MKCoordinateSpan(latitudeDelta: 0.002, longitudeDelta: 0.002))
self.mapView.setRegion(region, animated: true)
if startLocation == nil {
startLocation = locations.first
}
var distance = startLocation.distance(from: location!)
let lastDistance = location?.distance(from: location!)
distance += lastDistance!
distanceString = "\(distance)"
distanceLabel.text = distanceString
}
应用的外观如下:
the run screen
我发现其他人也问过类似的问题,但问题要么没有答案,要么是用不同的语言(例如Objective-C)。如果这个问题之前已经回答过而我只是忽略了它,有人可以 link 给我答案吗?谢谢!
位置管理器启动时,返回的第一个位置是缓存的、最后知道的位置。您需要通过时间戳检查这一点,并检查返回的准确度级别。在你的 didUpdateLocations
代表中是这样的:
let newLocation = locations.last
let timeDiff = newLocation?.timestamp.timeIntervalSinceNow
let accuracyNeeded:CLLocationAccuracy=100.0
if timeDiff < 5.0 && (newLocation?.horizontalAccuracy)!<=accuracyNeeded{
//your code here
}
您必须让传感器有时间预热。
这是一个典型的 didUpdateLocations
实现。我们跟踪自开始更新位置以来经过的时间以及随着传感器预热而提高的水平精度。如果水平精度在合理的时间内没有提高,我们就放弃。
您将需要一个 nil
属性,一个 Date?
,称为 startTime
,以及常量 REQ_TIME
和 REQ_ACC
。 self.stopTrying()
关闭更新并将 startTime
重置为 nil
。
let loc = locations.last!
let acc = loc.horizontalAccuracy
let time = loc.timestamp
let coord = loc.coordinate
if self.startTime == nil { // Date? property, keep track of time
self.startTime = Date()
return // ignore first attempt
}
let elapsed = time.timeIntervalSince(self.startTime)
if elapsed > REQ_TIME { // required time before giving up
self.stopTrying()
return
}
if acc < 0 || acc > REQ_ACC { // desired accuracy
return // wait for the next one
}
// got it
print("You are at \(coord.latitude) \(coord.longitude)")
我是 Swift 的新手(以及这个网站,如果我做错了什么,我深表歉意),我正在尝试制作一个 运行 应用程序来跟踪用户的位置。虽然我用来跟踪距离的功能有效,但它不是从 0 开始。当我点击开始按钮时,距离从一个随机数开始,然后从那里开始跟踪。
我的问题是:有没有我没有正确解决的问题?如果是这样,有没有办法修复它以便跟踪更准确?这是我目前所拥有的:
override func viewDidLoad() {
super.viewDidLoad()
stopwatchLabel.text = "00:00.00"
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.delegate = self
locationManager.requestAlwaysAuthorization()
locationManager.activityType = .fitness
locationManager.distanceFilter = 10.0
mapView.showsUserLocation = true
startLocation = nil
// Do any additional setup after loading the view.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
// MARK: - Location Delegate Methods
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation])
{
let location = locations.last
let center = CLLocationCoordinate2D(latitude: location!.coordinate.latitude, longitude: location!.coordinate.longitude)
let region = MKCoordinateRegion(center: center, span: MKCoordinateSpan(latitudeDelta: 0.002, longitudeDelta: 0.002))
self.mapView.setRegion(region, animated: true)
if startLocation == nil {
startLocation = locations.first
}
var distance = startLocation.distance(from: location!)
let lastDistance = location?.distance(from: location!)
distance += lastDistance!
distanceString = "\(distance)"
distanceLabel.text = distanceString
}
应用的外观如下:
the run screen
我发现其他人也问过类似的问题,但问题要么没有答案,要么是用不同的语言(例如Objective-C)。如果这个问题之前已经回答过而我只是忽略了它,有人可以 link 给我答案吗?谢谢!
位置管理器启动时,返回的第一个位置是缓存的、最后知道的位置。您需要通过时间戳检查这一点,并检查返回的准确度级别。在你的 didUpdateLocations
代表中是这样的:
let newLocation = locations.last
let timeDiff = newLocation?.timestamp.timeIntervalSinceNow
let accuracyNeeded:CLLocationAccuracy=100.0
if timeDiff < 5.0 && (newLocation?.horizontalAccuracy)!<=accuracyNeeded{
//your code here
}
您必须让传感器有时间预热。
这是一个典型的 didUpdateLocations
实现。我们跟踪自开始更新位置以来经过的时间以及随着传感器预热而提高的水平精度。如果水平精度在合理的时间内没有提高,我们就放弃。
您将需要一个 nil
属性,一个 Date?
,称为 startTime
,以及常量 REQ_TIME
和 REQ_ACC
。 self.stopTrying()
关闭更新并将 startTime
重置为 nil
。
let loc = locations.last!
let acc = loc.horizontalAccuracy
let time = loc.timestamp
let coord = loc.coordinate
if self.startTime == nil { // Date? property, keep track of time
self.startTime = Date()
return // ignore first attempt
}
let elapsed = time.timeIntervalSince(self.startTime)
if elapsed > REQ_TIME { // required time before giving up
self.stopTrying()
return
}
if acc < 0 || acc > REQ_ACC { // desired accuracy
return // wait for the next one
}
// got it
print("You are at \(coord.latitude) \(coord.longitude)")