How to turn GMSMarker in the direction the user is moving in Swift?

I am using this code.

let marker = GMSMarker() marker.position = coordinates marker.tracksViewChanges = true marker.icon = UIImage(named:"car") marker.appearAnimation = kGMSMarkerAnimationNone marker.map = mapView 

location manager code

 func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) { let location = locations.last! as CLLocation if(checkingLocation == false) { let camera = GMSCameraPosition.camera(withLatitude: (location.coordinate.latitude), longitude: (location.coordinate.longitude), zoom: 16.0) oldLocationCenter = location marker.position = (locationManager.location?.coordinate)! self.mapView?.animate(to: camera) // checkingLocation = true locationManager.stopUpdatingLocation() } else { let updateCam = GMSCameraUpdate.setTarget(CLLocationCoordinate2D(latitude: location.coordinate.latitude, longitude: location.coordinate.longitude)) updateMarker(coordinates: location.coordinate, degrees:DegreeBearing(A: oldLocationCenter, B: location) , duration: 10.0) self.mapView?.animate(with: updateCam) locationManager.stopUpdatingLocation() } } func updateMarker(coordinates: CLLocationCoordinate2D, degrees: CLLocationDegrees, duration: Double){ // Keep Rotation Short CATransaction.begin() CATransaction.setAnimationDuration(10.0) marker.rotation = degrees CATransaction.commit() // Movement CATransaction.begin() CATransaction.setAnimationDuration(duration) marker.position = coordinates // Center Map View let camera = GMSCameraUpdate.setTarget(coordinates) mapView.animate(with: camera) CATransaction.commit() } func DegreeBearing(A:CLLocation,B:CLLocation)-> Double{ var dlon = self.ToRad(degrees: B.coordinate.longitude - A.coordinate.longitude) let dPhi = log(tan(self.ToRad(degrees: B.coordinate.latitude) / 2 + M_PI / 4) / tan(self.ToRad(degrees: A.coordinate.latitude) / 2 + M_PI / 4)) if abs(dlon) > M_PI{ dlon = (dlon > 0) ? (dlon - 2*M_PI) : (2*M_PI + dlon) } return self.ToBearing(radians: atan2(dlon, dPhi)) } func ToRad(degrees:Double) -> Double{ return degrees*(M_PI/180) } func ToBearing(radians:Double)-> Double{ return (ToDegrees(radians: radians) + 360) / 360 } func ToDegrees(radians:Double)->Double{ return radians * 180 / M_PI } 

Using the code above, my marker (car) moves from the old to the new location, I also used these places to get the angle of inclination. But he does not spin. Is there any other way to achieve this? Please guide me.

+5
source share
2 answers

For proper navigation, you first need to set up your location manager object like this

 fileprivate func initLocationManager() { locationManager = CLLocationManager(); locationManager!.delegate = self; locationManager!.desiredAccuracy = kCLLocationAccuracyBest; locationManager!.activityType = .automotiveNavigation; if LocationTracker.authorized() == false { requestAuthorization() } } 

After that, you need to find a legal location, because in the ios system try to give a better place, but you are not sure if some temporary location also comes from the cache or your location may be zick zack, so you need the following code in locationUpdate

  func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) { if locations.count > 0 { let _ = locations.first let location = locations[locations.count-1] let maxAge:TimeInterval = 60; let requiredAccuracy:CLLocationAccuracy = 100; let locationIsValid:Bool = Date().timeIntervalSince(location.timestamp) < maxAge && location.horizontalAccuracy <= requiredAccuracy; if locationIsValid { NSLog(",,, location : %@",location); NSLog("valid locations....."); } } } 

your navigation is going smoothly, but note that location accuracy is not very good on the iPad. This type of module only works for iphone.

+3
source

I found a solution by updating the header. In the didUpdateLocations method, we need to update the header

 locationManager.startUpdatingHeading() 

Thus, the marker rotates when the user moves.

 func locationManager(_ manager: CLLocationManager, didUpdateHeading newHeading: CLHeading) { let heading:Double = newHeading.trueHeading; marker.groundAnchor = CGPoint(x: 0.5, y: 0.5) marker.rotation = heading marker.map = mapView; print(marker.rotation) } 
+1
source

Source: https://habr.com/ru/post/1260707/


All Articles