Skip to content

Instantly share code, notes, and snippets.

@marmelroy
Created April 20, 2016 15:58
Show Gist options
  • Select an option

  • Save marmelroy/0fee54bfe69bfbfcbbf7057298fca046 to your computer and use it in GitHub Desktop.

Select an option

Save marmelroy/0fee54bfe69bfbfcbbf7057298fca046 to your computer and use it in GitHub Desktop.
Calculating MKMapCamera's altitude for a distance
let altitude = distance*tan(M_PI*(75.0/180.0))
@plindberg
Copy link
Copy Markdown

Thanks for this, it helped me figure out how to do this.

However, I’m not sure where 75.0 comes from, how it relates to the 30° aperture of the map camera you refer to in your tweet.

I have verified that the aperture indeed is 30° (see code snippet below), and have also discovered that MapKit is off by a factor of ≈1.55 in MKMapView.cameraZoomRange – which I explain in this StackOverflow post.

Anyway, here’s my solution:

// The aperture of the MKMapCamera isn’t documented, but there are reports here and
// there of this being the case. And we have established this by telling the map to
// focus on a specific latitudinal distance (because that’s the longest dimension),
// and then checking the centre coordinate distance of the camera. The aperture can
// then be calculated by `2 * atan(latitudinalDistance / 2.0 /
// mapView.camera.centerCoordinateDistance) * 180.0 * .pi`, which gives ≈30.00.
// Converted to radians for the calculation below.
let mapCameraAperture = 30.0 * .pi / 180

// Because the map view isn’t square, we need to adjust for the aspect ratio.
let aspectRatio = Double(bounds.size.height / bounds.size.width)

// For some reason, the camera zoom range is off by a factor ≈1.55. That is, if
// you set the minimum to 2500, and then zoom as far in as you can, the camera
// reports a center coordinate distance of ≈1610. Verified on iOS 13 and 14, in
// the simulator and on device. (https://stackoverflow.com/q/64352591/446328)
let mapKitBugAdjustmentFactor = 1.55

let minCameraDistance = (minLongitudinalMeters * aspectRatio) /
    (2 * tan(mapCameraAperture / 2)) * mapKitBugAdjustmentFactor

mapView.cameraZoomRange = MKMapView.CameraZoomRange(
    minCenterCoordinateDistance: minCameraDistance)

@AlekseiR
Copy link
Copy Markdown

AlekseiR commented Jul 6, 2021

@plindberg
Thank you. I've found a related answer on stackoverflow and came up with quite a similar solution.
https://stackoverflow.com/a/21034410/6292624

Wanted to update that on my devices (iOS 13) and simulators (13, 14) max zoom never causes that much delta with target value. In my case minCenterCoordinateDistance ~875 and max zoom value is ~890, so probably mapKitBugAdjustmentFactor should be removed or significantly reduced.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment