我有一个实时跟踪应用程序,我正在跟踪车辆。我每隔10秒就会获得一个车辆位置,并在地图上移动车辆图标,例如优步,奥拉。
我的动画运行良好,但问题出现在汽车MKAnnotation标题上。 每当我的汽车位置发生变化时,如何改变汽车的航向?
我正在使用带有swift的apple mapkit而且对ObjectiveC没有很好的了解。
MyViewConroller代码在这里
import UIKit
import Alamofire
import SwiftyJSON
import MapKit
import SwiftLoader
class LiveTrackingVC: UIViewController , MKMapViewDelegate{
//Outlets
@IBOutlet weak var deviceNameLAble: UILabel!
@IBOutlet weak var myNavigation: UINavigationItem!
@IBOutlet weak var mapView: MKMapView!
@IBOutlet weak var lbAddress: UILabel!
@IBOutlet weak var lbDistance: UILabel!
@IBOutlet weak var lbAssestSpeed: UILabel!
// Classes Objects
let session = XSession()
var assestID = String().self
var lastPosition : CLLocationCoordinate2D?
var livePosition : CLLocationCoordinate2D?
var pointAnnotation : CarCustomeAnnotation!
var pinAnnotationView : MKAnnotationView!
let reuseIdentifier = "pin"
var timer = Timer()
@IBAction func finish(_ sender: UIBarButtonItem) {
self.dismiss(animated: true, completion: nil)
self.timer.invalidate()
}
override func viewDidLoad() {
super.viewDidLoad()
mapView.delegate = self
pointAnnotation = CarCustomeAnnotation()
liveAPI()
timer.invalidate()
timer = Timer.scheduledTimer(timeInterval: 5, target: self, selector: #selector(liveAPI), userInfo: nil, repeats: true)
self.mapView.isRotateEnabled = false
}
/*
Get live data from server
with assest ID.
*/
@objc func liveAPI() {
// print(self.session.getData(XConstant.webURL)+"/livestatus_new")
MyCall().call(WithRequest: XSApi.liveTracking(assestID), AndSuccessHandler: {
response in
SwiftLoader.hide()
let code = response?[API.SUCCESS].intValue
if(code == API.OK)
{
// Here is getting vehcile latest location data
self.handleLiveApi(listData: response![API.DATA].dictionaryValue)
}
})
{(response, error) in
print("Error")
}
}
/*
Live Tracking respone Handle
*/
func handleLiveApi(listData : Dictionary<String, JSON>)
{
self.lbDistance.text = listData["mileAge"]?.stringValue
let time = "".convertDateFormatter(date: (listData["DeviceTime"]?.stringValue)! )
self.myNavigation.title = time
self.deviceNameLAble.text = listData["DisplayName"]?.stringValue
let speed = (listData["Speed"]?.stringValue)!
self.lbAssestSpeed.text = speed + " km/h"
livePosition = CLLocationCoordinate2DMake(Double((listData["Latitude"]?.stringValue)!)!, Double((listData["Longitude"]?.stringValue)!)!)
pointAnnotation.pinCustomImageName = "ic_car_map"
if(lastPosition != nil )
{
pointAnnotation.courseDegrees = Double((lastPosition?.bearingToLocationDegrees(destinationLocation: livePosition!))!)
}
pinAnnotationView = MKAnnotationView(annotation: pointAnnotation, reuseIdentifier: reuseIdentifier)
mapView.addAnnotation(pinAnnotationView.annotation!)
if( lastPosition != nil)
{
pinAnnotationView.transform = CGAffineTransform(rotationAngle: CGFloat(pointAnnotation.courseDegrees))
self.moveCar(self.livePosition!)
}else{
pointAnnotation.coordinate = livePosition!
self.zoomMap(lat: (livePosition?.latitude)!,lng: (livePosition?.longitude)!)
}
lastPosition = livePosition
}
func zoomMap(lat:Double,lng:Double) {
let location = CLLocation(latitude: lat, longitude: lng)
let coordinateRegion = MKCoordinateRegionMakeWithDistance(location.coordinate,
1500 * 2.0, 1500 * 2.0)
self.mapView.setRegion(coordinateRegion, animated: true)
}
//--------------------------------------------------
//MARK:
//MARK: - Custom Methods
//--------------------------------------------------
func degreesToRadians(degrees: Double) -> Double { return degrees * .pi / 180.0 }
func radiansToDegrees(radians: Double) -> Double { return radians * 180.0 / .pi }
func getHeadingForDirectionFromCoordinate (_ fromLoc : CLLocationCoordinate2D , toLoc : CLLocationCoordinate2D) -> Double {
let fLat = degreesToRadians(degrees: fromLoc.latitude)
let fLng = degreesToRadians(degrees: fromLoc.longitude)
let tLat = degreesToRadians(degrees: toLoc.latitude)
let tLng = degreesToRadians(degrees: toLoc.latitude)
let degree = radiansToDegrees(radians: atan2(sin(tLng-fLng) * cos(tLat), cos(fLat)*sin(tLat)-sin(fLat)*cos(tLat)*cos(tLng-fLng)))
if (degree >= 0) {
return degree
} else {
return 360.0 + degree
}
}
func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) ->
MKAnnotationView? {
var annotationView = mapView.dequeueReusableAnnotationView(withIdentifier: reuseIdentifier)
if annotationView == nil {
annotationView = MKAnnotationView(annotation: annotationView?.annotation, reuseIdentifier: reuseIdentifier)
annotationView?.canShowCallout = false
} else {
annotationView?.annotation = annotation
annotationView?.canShowCallout = false
}
annotationView?.image = UIImage.init(named:pointAnnotation.pinCustomImageName)
return annotationView
}
//Inert Animation Duration and Destination Coordinate which you are getting from server.
func moveCar(_ destinationCoordinate : CLLocationCoordinate2D) {
UIView.animate(withDuration: 10, animations: {
self.pointAnnotation.coordinate = destinationCoordinate
}, completion: nil) }
}
public extension CLLocationCoordinate2D {
func bearingToLocationRadian(_ destinationLocation: CLLocationCoordinate2D) -> CGFloat {
let lat1 = self.latitude.degreesToRadians
let lon1 = self.longitude.degreesToRadians
let lat2 = destinationLocation.latitude.degreesToRadians
let lon2 = destinationLocation.longitude.degreesToRadians
let dLon = lon2 - lon1
let y = sin(dLon) * cos(lat2)
let x = cos(lat1) * sin(lat2) - sin(lat1) * cos(lat2) * cos(dLon)
var radiansBearing = atan2(y, x)
if(radiansBearing < 0.0)
{
radiansBearing += 2*Double.pi;
}
return CGFloat(radiansBearing)
}
func bearingToLocationDegrees(destinationLocation: CLLocationCoordinate2D) -> CGFloat {
return CGFloat(Double(bearingToLocationRadian(destinationLocation)).radiansToDegrees)
}
}
CarCustomeAnnotation
导入UIKit 导入MapKit
class CarCustomeAnnotation: MKPointAnnotation
{
var pinCustomImageName:String!
var courseDegrees : Double! // Change The Value for Rotating Car Image Position
}