在Swift中录制CLLocationPoints时不准确
问题描述:
我正在使用应用程序来记录散步,但我无法使多段线与其他应用中看起来一样平滑,例如runkeeper。我尝试过不同的activityType,desiredAccuracy等等。我已经在iPhone 5c,6s和7上进行了测试。它总是看起来像示例照片,它在露天录制下没有任何附近的建筑物。有什么我失踪?在Swift中录制CLLocationPoints时不准确
这是我viewDidLoad
,viewWillAppear
,viewDidAppear
,locationManager
和rendererFor overlay
:
import UIKit
import MapKit
import CoreLocation
...
override func viewDidLoad() {
super.viewDidLoad()
myLocations = []
manager.delegate = self
manager.desiredAccuracy = kCLLocationAccuracyBest
manager.activityType = .fitness
manager.distanceFilter = 5
}
override func viewWillAppear(_ animated: Bool) {
//Map
logMap.delegate = self
logMap.mapType = MKMapType.standard
manager.requestAlwaysAuthorization()
manager.startUpdatingLocation()
manager.allowsBackgroundLocationUpdates = true
logMap.userTrackingMode = MKUserTrackingMode(rawValue: 1)!
}
override func viewDidAppear(_ animated: Bool) {
let status = CLLocationManager.authorizationStatus()
if status == .notDetermined || status == .denied || status ==
.authorizedWhenInUse {
manager.requestAlwaysAuthorization()
manager.requestWhenInUseAuthorization()
manager.requestLocation()
}else{
manager.startUpdatingLocation()
logMap.showsUserLocation = true
}
if status != .denied {
manager.startUpdatingLocation()
}
}
func locationManager(_ manager: CLLocationManager,
didChangeAuthorization status: CLAuthorizationStatus) {
if status == .authorizedWhenInUse {
manager.requestLocation()
}
if status == .authorizedAlways {
logMap.showsUserLocation = true
logMap.mapType = MKMapType(rawValue: 0)!
//logMap.userTrackingMode = MKUserTrackingMode(rawValue: 3)!
manager.startUpdatingLocation()
}
}
func locationManager(_ manager: CLLocationManager, didUpdateLocations
locations: [CLLocation]){
if(isLoging==true){
if(myLocations.count > 1){
self.distance = self.distance +
Int(locations[0].distance(from: myLocations.last!))
}
myLocations.append(locations[0])
setDistance()
}
// paint line
if (myLocations.count > 1){
let sourceIndex = myLocations.count - 1
let destinationIndex = myLocations.count - 2
let c1 = myLocations[sourceIndex].coordinate
let c2 = myLocations[destinationIndex].coordinate
var a = [c1, c2]
let polyline = MKPolyline(coordinates: &a, count: a.count)
logMap.add(polyline)
}
}
func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer {
if overlay is MKPolyline {
let polylineRenderer = MKPolylineRenderer(overlay: overlay)
polylineRenderer.strokeColor = UIColor.blue
polylineRenderer.lineWidth = 4
return polylineRenderer
}
return MKPolylineRenderer(overlay: overlay)
}
结果:
答
尝试设置distanceFilter
到kCLDistanceFilterNone
。这会通知你每一个动作,但会消耗最多的电池。
即使您在建筑物外,仍然无法获得完美的准确性。 如果我猜测其他健身应用程序假设你没有穿过建筑物和东西,所以他们调整你的路径来匹配街道。
我知道Strava展示了我通过建筑物和花园的路径,因为它们没有达到完美的精确度。
答
这样做是为了获得最佳的准确性,以便每次获取您的位置。
override func loadView() {
print("loadView called")
// Enable some map settings
map.isMyLocationEnabled = true
map.settings.myLocationButton = true
map.settings.compassButton = true
map.settings.scrollGestures = true
map.settings.zoomGestures = true
map.delegate = self
view = map
}
override func viewDidLoad() {
super.viewDidLoad()
print("ViewDidLoad called")
// Configuring location manager.
locationManager = CLLocationManager()
locationManager.delegate = self
locationManager.requestWhenInUseAuthorization()
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.startUpdatingLocation()
locationManager.startMonitoringSignificantLocationChanges()
}
添加委派的ViewController:CLLocationManagerDelegate,GMSMapViewDelegate
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
print("locationManager function called")
// Fetch current location coordinates
let locValue:CLLocationCoordinate2D = (locationManager.location?.coordinate)!
currentLatitude = locValue.latitude
currentLongitude = locValue.longitude
print("Current Location = \(currentLatitude!), \(currentLongitude!)")
// Zoom to current location
let target = CLLocationCoordinate2D(latitude: currentLatitude!, longitude: currentLongitude!)
map.camera = GMSCameraPosition.camera(withTarget: target, zoom: 17)
locationManager.stopUpdatingLocation()
//DispatchQueue.main.asyncAfter(deadline: .now() + 1.75, execute: {self.webResponse()})
}