I have an MKMap view with a custom image (as an MKAnnotationView) that shows the current course bearing direction as shown below (The image is the blue circle with the directional arrow and extending dotted blue line):
MapKit provides the current bearing (in degrees) as well as the pitch of the map camera (also in degrees). When the map is rotated, the pitch changes or if the course bearing direction changes, this image most be rotated in 3 dimensions to continue to orient the image around the current bearing. The code being used for this currently is:
let rotationRadians = getHeadingIndicatorRotation(cameraHeading: mapView.camera.heading, courseHeading: navigation.lastLocation.course)
let pitchRadians = Conversions.toRadians(degrees: mapView.camera.pitch)
let t1 = CATransform3DMakeRotation(rotationRadians, 0, 0, 1)
let t2 = CATransform3DMakeRotation(pitchRadians, 1, 0, 0)
view.layer.transform = CATransform3DConcat(t1, t2)
This will properly rotate the image to show the dotted blue line in the direction of course bearing; unless the mapView camera pitch != zero. When non-zero, the dotted blue line shows slightly off (directionally) depending on where in the map the user's location is. When centered, the dotted blue line shows correctly, but when the current location is to the left of center, the dotted blue line skews too far left, and when the current location is right of center, the dotted blue line skews too far right.
This is shown by drawing an MKPolyLine for the current location along the course bearing (in red below).
I do want to draw the course bearing as an MKPolyLine as it has to be removed and redrawn every time the current location changes which makes the map flicker significantly. Is there a transform of the image that will work when the MKMapCamera's pitch is non zero? Or does the curvature of the earth along with how the iOS map camera draws things cause this to not be solvable?