在一些第三方的地圖 SDK 中,每每會有 zoomLevel
這樣一個屬性,經常使用於設置地圖的縮放等級。git
可是在 iOS 自帶的地圖控件 MKMapView
是沒有這樣一個屬性的。取而代之的是利用 MKCoordinateRegion
和 MKCoordinateSpan
來配置地圖顯示的中心和區域縮放的大小。web
咱們先來看看 MKCoordinateRegion
和 MKCoordinateSpan
的這兩個初始化方法:算法
MKCoordinateRegion(center: CLLocationCoordinate2D, span: MKCoordinateSpan)
MKCoordinateSpan(latitudeDelta: CLLocationDegrees, longitudeDelta: CLLocationDegrees)
複製代碼
結合 文檔 ,咱們能夠將 MKCoordinateRegion
理解爲地圖上一塊方形區域, center
是這塊方形區域的中心地理座標,而 MKCoordinateSpan
是這塊區域的 經緯度範圍,那麼它的兩個參數的取值範圍是:bash
瞭解了 MKCoordinateRegion
和 MKCoordinateSpan
後,咱們該如何利用它們來計算出 zoomLevel
呢?這裏咱們須要先了解一下 Tiled web map 這個概念。Tiled web map
的設計初衷是爲了能在網絡上更好的傳輸和展現地圖,其中最先應用起來的是 Google Maps
, 而後慢慢地成爲了地圖工具中一個不成文的標準。它把地圖以圖片的形式切割成不少個小塊: Tile
,當用戶在地圖上滑動或者縮放時,就會加載更多的 Tile
,對比之前直接加載一大塊圖片的方式效率更高,用戶體驗更好。網絡
大部分的 Tiled web map
會依據 Google Maps 的一些實現標準:app
Tile
是 256x256 像素。Tile
上。Tile
的像素會加倍。也就是說一個 Tile
會被四個 Tile
替換掉。上面原圖片來自 troybrant.net,由原圖拼接而成。ide
根據上面的標準,咱們能夠得出這樣一個公式:工具
W 表示地圖一邊長的像素。ui
咱們知道地球經度一週360度,那麼一個經度範圍佔 Tiled web map
的多少像素呢?簡單的除法能夠得知:spa
上面說到 MKCoordinateSpan
它表示地圖顯示區域的 經緯度範圍,假設咱們把 MKMapView
的寬度設置爲 width
, 而 MKCoordinateSpan.longitudeDelta
是當前 MKMapView
顯示區域的經度範圍。那麼咱們能夠獲得這樣一個等式:
一個簡單的轉換,便可得出 zoomLevel
的計算公式:
用代碼形式展現:
let mapWidth = mapView.frame.size.width
let zoomLevel = log2(360 * Double(mapWidth) / 256.0 / mapView.region.span.longitudeDelta)
複製代碼
咱們還能夠給 MKMapView
擴展一下:
extension MKMapView {
var zoomLevel: Double {
return log2(360 * Double(frame.size.width) / 256.0 / region.span.longitudeDelta)
}
}
複製代碼