iosswiftgoogle-mapsgmsmapviewbearing

GMSMapView update camera position so that it will always show direction towards top during navigation


I have used bearing property to rotate camera on mapview and not able to position the camera so that it will always show the navigation towards top.

Below is the screenshot of google map app, which automatically rotate it self during the navigation so that it always show the route towards top side.

enter image description here

Below is the screenshot of my app which always shows route in any direction like.

enter image description here

I have used below code to rotate the camera, but really don't know how to get required bearing angle s that it will always show in top direction.

            let cameraPosition = GMSCameraPosition.camera(withTarget: currentLocation, zoom: self.camera.zoom, bearing: MyRide.shared.bearing, viewingAngle: 45)
        let cameraUpdate = GMSCameraUpdate.setCamera(cameraPosition)

        CATransaction.begin()
        CATransaction.setValue(1.0, forKey: kCATransactionAnimationDuration)
        self.animate(with: cameraUpdate)
        CATransaction.commit()

Solution

  • let camera = GMSCameraPosition.camera(withTarget: CLLocationCoordinate2DMake(startLat, startLong), zoom: 17, bearing: getBearingBetweenTwoPoints(point1: CLLocationCoordinate2DMake(startLat, startLong), point2:CLLocationCoordinate2DMake(endLat, endLong)), viewingAngle: 45)
    

    Using below method of Bearing calculation, You will get bearing of starting point to ending point which you required.

    func degreesToRadians(degrees: Double) -> Double { return degrees * .pi / 180.0 }
    func radiansToDegrees(radians: Double) -> Double { return radians * 180.0 / .pi }
    
    func getBearingBetweenTwoPoints(point1 : CLLocationCoordinate2D, point2 : CLLocationCoordinate2D) -> Double {
    
        let lat1 = degreesToRadians(degrees: point1.latitude)
        let lon1 = degreesToRadians(degrees: point1.longitude)
    
        let lat2 = degreesToRadians(degrees: point2.latitude)
        let lon2 = degreesToRadians(degrees: point2.longitude)
    
        let dLon = lon2 - lon1
    
        let y = sin(dLon) * cos(lat2)
        let x = cos(lat1) * sin(lat2) - sin(lat1) * cos(lat2) * cos(dLon)
        let radiansBearing = atan2(y, x)
    
        return radiansToDegrees(radians: radiansBearing)
    }
    

    If you want dynamically get the bearing from your path then you have to get ending point of current route according to your need.