2013-02-18 14:02:10
在web開發(fā)中可能遇到這樣的需求:需要一個地圖系統(tǒng),選擇google map來完成地圖的展示,但是該web系統(tǒng)由于特殊性而不允許與外網(wǎng)鏈接,還有就是現(xiàn)在對google的訪問越來越不穩(wěn)定(國家網(wǎng)絡(luò)限制),因此希望將google map移植到內(nèi)網(wǎng)中使用。
可以將google map api分為3個部分來看待:
1、負責(zé)與服務(wù)器交互的js文件
2、google提供的技術(shù)支持,例如查找路徑、周邊搜索
3、google提供的地圖數(shù)據(jù)
如果需要開發(fā)的功能中包含第2部分的需求,那么可能比較復(fù)雜。因為路徑算法在google服務(wù)器上實現(xiàn),只是對外提供了接口,如果無法連接google網(wǎng)絡(luò)則無法實現(xiàn)。
但如果開發(fā)的web中對map的使用比較簡單,例如只是加載地圖,有簡單的地圖移動等功能,那么這樣的需求是可以將google map移植到內(nèi)網(wǎng)來處理的。這種方法也適用于自定義周邊搜索,例如需要完成的web功能就是通過查詢,獲取指定范圍內(nèi)的建筑物、獲取自定的標記(開發(fā)本地商戶搜索系統(tǒng)的時候,地圖上商戶數(shù)據(jù)的維護肯定是有web自己維護,而并非google提供的數(shù)據(jù),這種場景正好適合)。
下來來說如何將google map本地化,可以分為兩個步驟:
1、將google map使用的與服務(wù)器交互的js文件本地化
這個當(dāng)然是根據(jù)google map加載時候,所需要的js下載到本地,以后再應(yīng)用程序開發(fā)的時候,不引用google站點上的js,而是換成本地的js文件。具體有些什么js需要下載的,這里就不做詳細介紹了,可以通過firefox的firebug插件,或是google chrome等工具查看到http請求,分析并下載有效的js文件,可能還需要分析各個js之間在使用過程中加載外鏈js的地址,并予以修改、替換問對本地js的調(diào)用。google map api中需要使用到的js本地化,網(wǎng)絡(luò)上一個叫做rover.tang的朋友已經(jīng)做得很好,提供了google map api v3.8的本地化js,可以在網(wǎng)絡(luò)上找到。
2、將google map的地圖數(shù)據(jù)(tiles:瓦片)下載到本地,以及應(yīng)用的開發(fā)
說到地圖數(shù)據(jù),需要了解google map的一點基礎(chǔ)知識。google把在瀏覽器中顯示的地圖,分割成一塊一塊的圖片,稱之為tile,在瀏覽其中顯示地圖的部分,從google下載各個tile,然后拼接在一起,就能夠看到完整的一幅地圖。每一個tile的大小都是256*256的png圖片,因為存在縮放(縮放級別為0-19),每個縮放級別中,瀏覽器中顯示地圖的區(qū)域被劃分為多個tile,每個tile會根據(jù)去google站點下載對應(yīng)的地圖數(shù)據(jù),其實就是一張png圖片,在瀏覽器分別請求以獲取tile地圖圖片數(shù)據(jù)的時候,會傳遞給google 三個重要的參數(shù),1、tile的x坐標;2、tile的y坐標;3、當(dāng)前瀏覽器中顯示的地圖的縮放級別。
google map可以自定義地圖類型(MapType),詳細的可以參考https://developers.google.com/maps/documentation/javascript/maptypes
下面說說如何通過自定義方式加載地圖(地圖數(shù)據(jù)本地化)
//js代碼<script type="text/javascript">var map;var myCenter = new google.maps.LatLng(29.568381,106.552219);//重慶function CoordMapType() {}CoordMapType.prototype.tileSize = new google.maps.Size(256,256);CoordMapType.prototype.maxZoom = 19;CoordMapType.prototype.getTile = function(coord, zoom, ownerDocument) {var div = ownerDocument.createElement('div');div.innerHTML = '<img name="" src="./tiles/zoom_10/x_814-y_424-z_10.png"/>';//div.innerHTML = '<img name="" src="./tiles/zoom_' + zoom + '/x_' + coord.x + '-y_' + coord.y + '-z_' + zoom + '.png"/>';div.style.width = this.tileSize.width + 'px';div.style.height = this.tileSize.height + 'px';div.style.fontSize = '10';div.style.borderStyle = 'solid';div.style.borderWidth = '1px';div.style.borderColor = '#AAAAAA';return div;};var coordinateMapType = new CoordMapType();function initialize() {var mapOptions = {zoom: 10,center: myCenter,mapTypeId: "coordinate"};map = new google.maps.Map(document.getElementById("map_canvas"),mapOptions);map.mapTypes.set('coordinate',coordinateMapType);}google.setOnLoadCallback(initialize);</script>//html代碼<div id="map_canvas"></div>重點是代碼div.innerHTML = '<img name="" src="./tiles/zoom_10/x_814-y_424-z_10.png"/>',該代碼定義了自定義地圖到哪里加載地圖數(shù)據(jù)(tile),我們需要本地化google map,因此將google map對應(yīng)的tile下載到本地,按照自己的意愿命名存放在服務(wù)器上,因此我們需要根據(jù)自己存儲google map的地圖數(shù)據(jù),代碼示例中,統(tǒng)統(tǒng)只加載一個固定的圖片,僅作為測試,實際情況可以修改這里的規(guī)則。這樣,在加載地圖的時候,或是在移動地圖的時候,就會加載本地(本地服務(wù)器)的地圖的地圖數(shù)據(jù)。完成到這一步,就差google 地圖數(shù)據(jù)下載了,通過在線google地圖的移動,可以看出google map會去類似這樣的地址http://mt0.googleapis.com/vt?src=apiv3&x=814&y=423&z=10下載地圖數(shù)據(jù),x即tile的x坐標,y即tile的y坐標,z即縮放級別。因此采用任意的開發(fā)語言,或腳本,到google的服務(wù)器上下載對應(yīng)需要區(qū)域的地圖數(shù)據(jù),存放到本地即可。java實現(xiàn)網(wǎng)絡(luò)下載當(dāng)然有很多可以使用的東西了,這個就隨意發(fā)揮了。:)原文:http://www.iteye.com/topic/1122688