Reputation: 1351
I am integrating Mapbox iOS SDK into my app. Right now I am stuck at a point where I want to achieve car tracking feature like Uber app.
I used to have that feature with Google Maps SDK but I cant make it work with Mapbox SDK.
I am adding MGLPointAnnotation
object to add it on map and want to move it from point A to point B with animation.
I am doing it using
UIView.animate(withDuration: TimeInterval(duration), animations: {
// Update annotation coordinate to be the destination coordinate
point.coordinate = newCoordinate
}, completion: nil)
But for MGLPointAnnotation
I can't change its image because when there's a turn I want to rotate the image(Annotation).
If I use MGLAnnotationView
object I can change the image but I cant change its coordinate because its readonly.
What should I do here to achieve that functionality?
Upvotes: 0
Views: 961
Reputation: 2204
Several years ago I wrote smth similar, I used GoggleMaps, look through the code, maybe it will be helpful, I really don't remember what are all that numbers in angle counting
extension Double {
var degrees: Double {
return self * 180.0 / Double.pi
}
}
extension CLLocationCoordinate2D {
func angleToPosition(position : CLLocationCoordinate2D) -> CLLocationDegrees {
let bearingRadians = atan2(Double(position.latitude - latitude), Double(position.longitude - longitude))
var bearingDegrees = bearingRadians.degrees
// print("\(bearingDegrees)")
var roundDegrees = 360.0
if bearingDegrees < 0 {
if bearingDegrees > -90 {
roundDegrees = 350
}
if bearingDegrees < -90 && bearingDegrees > -180 {
roundDegrees = 370
}
bearingDegrees += roundDegrees
return 360 - bearingDegrees
}
roundDegrees = bearingDegrees < 90 ? 350 : 360
if bearingDegrees > 90 && bearingDegrees < 180 {
roundDegrees = 370
}
UserDefaults.standard.set(bearingDegrees, forKey: "bearingDegrees")
return roundDegrees - bearingDegrees
}
func duration(toDestination destination: CLLocationCoordinate2D, withSpeed speed : Double) -> Double {
let distance = GMSGeometryDistance(self, destination)
return distance / (speed * (1000 / 3600))
}
}
And this is the func which do the rotation, you can use it as soon as you receive new coordinates, or call it in for loop if you have certain polyline
func animateCarDrive(info: [String: Any]) {
let speed = info["speed"] as? Double ?? 40 // if your car's speed is changeable
let position = info["position"] as? CLLocationCoordinate2D // new point position
let duration = marker.position.duration(toDestination: position, withSpeed: speed)
marker.rotation = marker.position.angleToPosition(position: position)
CATransaction.begin()
CATransaction.setAnimationDuration(duration)
marker.position = position
CATransaction.commit()
}
Upvotes: 0