1. 程式人生 > >百度地圖自定義圖層如何實現

百度地圖自定義圖層如何實現

如果要在百度地圖上實現一張自己自定義的地圖,就需要使用百度地圖自定義圖層介面。實現效果如下:


但是百度地圖中關於自定義圖層的介紹甚少,便以此博文以記錄,方便同行瞭解和使用。

百度地圖官方文件中,關於自定義圖層的介紹是這樣的:

=========華麗麗的分隔線===========

自定義圖層

地圖座標系

在使用自定義圖層前,您需要了解百度地圖的地圖座標系,百度地圖座標系涉及:

 經緯度球面座標系統

 墨卡託平面座標系統

 圖塊編號系統

經緯度是一種利用三維空間的球面來定義地球上的空間的球面座標系,它能夠標示地球上任何一個位置。通過倫敦格林尼治天文臺原址的經線為0度經線,從0度經線向東、向西各分180度。赤道為0度緯線,赤道以北的緯線稱為北緯、以南的稱為南緯。在百度地圖中,東經和北緯用正數表示,西經和南緯用負數表示。例如北京的位置大約是北緯39.9度,東經116.4度,那麼用數值標示就是經度116.6,緯度39.9。 在百度地圖中,習慣經度在前,緯度在後,例如:

var point = new BMap.Point(116.404, 39.915);  // 建立點座標,經度在前,緯度在後

由於百度地圖是顯示在平面上的,因此在地圖內部系統中需要將球面座標轉換為平面座標,這個轉換過程稱為投影。百度地圖使用的是墨卡託投影。墨卡託平面座標如下圖所示,平面座標與經緯度座標系的原點是重合的。

jsguide05.jpg


百度地圖在每一個級別將整個地圖劃分成若干個圖塊,通過編號系統將整個圖塊整合在一起以便顯示完整的地圖。當地圖被拖動或者級別發生變化時,地圖API將會根據平面座標計算出當前視野內所需顯示的圖塊的編號。百度地圖圖塊編號規則如下圖所示:

jsguide06.jpg


從平面座標原點開始的右上方向的圖塊編號為0,0,以此類推。在最低的縮放級別(級別 1)中,整個地球由 4 張圖塊組成。隨著級別的增長,地圖所使用的圖塊個數也隨之增多。

定義取圖規則

通過TileLayer類開發者可以實現自定義圖層。其中,TileLayer例項的getTilesUrl方法需要實現,用來告訴API取圖規則。getTilesUrl方法的引數包括tileCoord和zoom,其中tileCoord為圖塊的編號資訊,zoom為圖塊的級別,每當地圖需要顯示特定級別的特定位置的圖塊時就會自動呼叫此方法,並提供這兩個引數。使用者需要告知API特定編號和級別所對應的圖塊的地址,這樣API就能正常顯示自定義的圖層了。

新增和移除自定義圖層

以下程式碼在每個圖塊的所有縮放級別上顯示一個簡單的透明疊加層,使用浮動紅色小水滴表示圖塊的輪廓。

var map =
new BMap.Map("l-map"); // 建立地圖例項 var point = new BMap.Point(116.404, 39.915); // 建立點座標 map.centerAndZoom(point,15); // 初始化地圖,設定中心點座標和地圖級別 var tilelayer = new BMap.TileLayer(); // 建立地圖層例項 tilelayer.getTilesUrl=function(){ // 設定圖塊路徑 return "layer.gif"; }; map.addTileLayer(tilelayer); // 將圖層新增到地圖上
=========華麗麗的分隔線============

這裡講得讓人一知半解,最主要的是,文件中並沒有說明如何實現getTilesUrl方法,以及如何實現將一張自己的地圖分隔成符合百度地圖要求的圖塊。

現在記錄一下我解決這個問題的過程。

首先,我先下載百度地圖瓦格圖片切圖工具:https://github.com/jiazheng/BaiduMapTileCutter

其次,找到自己的地圖,匯入其中進行切片,參考Sup_Heaven轉的博文:http://blog.csdn.net/sup_heaven/article/details/8461586

最後將圖片放入專案資原始檔中,實現getTitlesUrl方法即可。

這裡需要補充一下的同,Sup_Heaven轉的博文中,並沒有詳細說明中心點和瓦格圖片之間的關係,只告訴我們其然卻不知其所以然。藉助度娘瞭解。百度地圖的所有瓦格圖片都是256px*256px的正方形圖片,其圖片的位置由經緯度和放大倍數zoom決定,所以在使用工具TileCutter時,設定對的級別範圍和中心點,否則會導致切出的圖片與實際需要不符。

如果大家在使用過程有疑問的,歡迎留言交流。