畢設(北斗導航項目)進行了一段時間,近日在實驗室給老師彙報進展時,因爲網絡不順暢,加載百度在線地圖及其各類操做時,時間過長,因而想將百度地圖離線化。查閱網上不少資料,有的是廣告(賣GIS應用的),有的版本過久......最後參考網上兩位前輩的博客內容,加以實踐,實現了地圖徹底離線且能進行基本操做。趁週末整理了實踐過程並記錄下來,但願能幫到有須要的朋友。javascript
注:感謝兩位前輩,其原文爲:開源中國:Web版百度地圖加載離線瓦片 ;csdn:使用百度地圖JS API構建離線地圖應用(完整教程)css
原文附帶Demo,你們能夠參考下,注意版本:百度離線地圖Demohtml
具體實現步驟:java
前期工做:構建在線地圖應用(版本API v1.3,其餘版本未測試,如須要可自行研究)。編程
準備好放源碼的文件夾(可爲中文),在其中創建三個文件夾:js、css、images,用於存放下面的文件。(基礎API下載地址:apiv1.3.min.js ;css文件下載地址:bmap.css )api
先創建一個簡單的在線地圖應用,以下:瀏覽器
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> 5 <title>DEMO</title> 6 <!--script type="text/javascript" src="js/apiv1.3.min.js"></script--> 7 <script type="text/javascript" src="http://api.map.baidu.com/api?v=1.3"></script> 8 <link rel="stylesheet" type="text/css" href="bmap.css"/> 9 </head> 10 <body> 11 <div style="width:520px;height:340px;border:1px solid gray" id="container"></div> 12 </body> 13 </html> 14 <script type="text/javascript"> 15 var map = new BMap.Map("container",{mapType: BMAP_NORMAL_MAP}); 16 var point = new BMap.Point(116.404, 39.915); // 建立點座標 17 map.centerAndZoom(point,5); // 初始化地圖,設置中心點座標和地圖級別。 18 19 //map.addControl(new BMap.MapTypeControl()); 20 map.addControl(new BMap.NavigationControl()); 21 map.enableScrollWheelZoom(); // 啓用滾輪放大縮小。 22 map.enableKeyboard(); // 啓用鍵盤操做。 23 </script>
以上代碼運行效果如圖:網絡
觀察其向網絡請求的文件:(我使用的是Firefox瀏覽器的Firbug插件)工具
這些需離線的資源文件主要有三類:圖標素材、依賴模塊API文件、瓦片地圖文件,後面會寫到詳細步驟。測試
接下來,進入正式工做。
第一步:訪問前期工做中的第一個入口:http://api.map.baidu.com/api?v=1.3,其內容以下:
1 function(){window.wise=1;window.netSpeed=254;window.netType=1; window.BMap_loadScriptTime = (new Date).getTime(); 2 document.write('<script type="text/javascript" src="http://api.map.baidu.com/getscript?v=1.3&ak=&services=&t=20150527115231"></script>'); 3 document.write('<link rel="stylesheet" type="text/css" href="http://api.map.baidu.com/res/13/bmap.css"/>');})();
這一步將得到一個js文件的位置和一個css文件的位置,而後分別下載下來,放在準備好的文件夾裏面,我分別存儲在/js和/css裏面。js的路徑後面有若干參數,無論,下載下來的文件從新命名就好,好比js文件命名爲apiv1.3.min.js
第二步:修改這個js中的代碼。因爲代碼是壓縮在一行上的,可經過網上的代碼在線格式化。
(我是使用了這個網站的工具JS/HTML/CSS格式化:http://tool.chinaz.com/tools/jsformat.aspx)
注意:修改文件的時候,建議與提供的Demo中的文件對比,並不是全按如下的修改方式
一、搜索變量:「imgPath」,直到找到一段代碼
1 var x=m?"https://sapi.map.baidu.com/":"http://api.map.baidu.com/"; 2 var cd={imgPath:x+"images/",cityNames:{"\u5317\u4eac":"bj",
把imgPath:x+"images/"中的x去掉便可,這樣就變成了跟網絡地址無關的相對位置了。這裏指出的images文件夾,是與未來的html文件夾平行的目錄裏面的。
二、搜索變量:「_baseUrl」,直到找到這樣的一段代碼
preLoaded:{},Config:{_baseUrl:x+"getmodules?v=1.3",_timeout:5000},
一樣,要去掉x,這個x也是前面這段代碼中的x。同時,不只要去掉x,更要把地址指向js目錄。
三、繼續搜索下一個「_baseUrl」,獲得下面的代碼:
1 window.setTimeout(function(){var cP=cN.Config._baseUrl+"&mod="+cN.Module._arrMdls.join(",");cy.request(cP);cN.Module._arrMdls.length=0;cN.delayFlag=false},1)
直接修改cP變量,注意:這裏把加載地址直接寫死
1 var cP=cN.Config._baseUrl+"modules";cy.request(cP);
這樣,咱們把動態加載編程手動加載了。咱們訪問這個地 址「http://api.map.baidu.com/getmodules?v=1.3&mod=map,oppc,tile,control,marker,poly」就能夠拿到一個js文件了。把它重命名爲上面指定的「modules」,丟在js文件夾裏面便可。後面會詳細說明加載模塊這個問題。
注意:若是須要更多的功能,我是經過從新加載以上的地址,其它的教程寫說不須要自動加載,經過另外配置參數獲取相關的功能就好,我沒親自配置過,有配置過的小夥伴能夠講講配置過程。
四、關鍵的一步:搜索「getTilesUrl」直到找到這樣的一段(參照物也能夠另選,好比「BMAP_NORMAL_MAP」):
1 aU.getTilesUrl = function(cN, cQ) { 2 var cR = cN.x; 3 var cO = cN.y; 4 var T = "20150518"; 5 var cP = "pl"; 6 if (this.map.highResolutionEnabled()) { 7 cP = "ph" 8 } 9 var cM = j[Math.abs(cR + cO) % j.length] + "?qt=tile&x=" 10 + (cR + "").replace(/-/gi, "M") + "&y=" 11 + (cO + "").replace(/-/gi, "M") + "&z=" + cQ + "&styles=" + cP 12 + (a9.browser.ie == 6 ? "&color_dep=32&colors=50" : "") 13 + "&udt=" + T; 14 return cM.replace(/-(\d+)/gi, "M$1") 15 }; 16 window.BMAP_NORMAL_MAP = new cv("\u5730\u56fe", aU, { 17 tips : "\u663e\u793a\u666e\u901a\u5730\u56fe" 18 });
「getTilesUrl」這個方法,這裏就是返回瓦片未知的關鍵方法。兩個參數中,第一個參數是{x,y},第二個參數就是z,這樣xyz就都有了。
直接把它計算出來的cM的結果從新計算一下,改爲:
1 //這個地方廢棄了上面的計算結果,直接採用本地圖片 2 cM = "tiles/" + cQ + "/" + cR + "/" + cO + ".jpg";
開始創建第四個文件夾,tiles。這個文件夾裏面的內容和後面的資源文件請在附件中下載。至於如何下載瓦片,問百度。至此,該文件的處理結束。
第三步:下載資源文件。(終於到資源文件的詳細介紹了,前期工做中提到)
一、圖片文件:能夠經過前期工做的第二張圖的方式獲取素材的下載地址,也可從Demo文件/images路徑下獲取,還有一種方式,引用前輩教程中的話:
查找bmap.css裏面全部的圖片文件,下載下來放在指定的文件夾裏面就行了。裏面總共不超過兩三個文件,下載下來放在 images文件夾裏面就好了。另外,剛纔的這個js裏面也有一些資源文件,也下載下來放在images文件夾裏面。這個經過搜索imgPath就能找 到,有png,有gif,有點文件可能須要經過https的地址才能下載的到。
獲得基本的圖標素材後,將以前所下載的bmap.css文件裏面圖片的url修改成本地路徑。
二、依賴模塊API文件(very very important!)
若是缺乏某個依賴模塊,則沒法使用相應的API。如下爲引用前輩教程的原話:
這個請求文件的原理是根據你在本身頁面中使用的API來向官網請求相應的依賴模塊API,參數的字符串格式是根據所使用依賴模塊的順序生成「模塊名」以「,」分隔。
在運行前期工做中的在線地圖時,就可發現,依賴的庫參數是什麼。例如:如下的代碼運行,所請求的依賴庫參數是http://api.map.baidu.com/getmodules?v=1.3&mod=map,oppc,tile,control
1 <script type="text/javascript"> 2 var map = new BMap.Map("container",{mapType:BMAP_NORMAL_MAP}); 3 var point = new BMap.Point(116.404, 39.915); // 建立點座標 4 map.centerAndZoom(point,5); // 初始化地圖,設置中心點座標和地圖級別。 5 6 //map.addControl(new BMap.MapTypeControl()); 7 map.addControl(new BMap.NavigationControl()); 8 map.enableScrollWheelZoom(); // 啓用滾輪放大縮小。 9 map.enableKeyboard(); // 啓用鍵盤操做。 10 //map.setCurrentCity("北京"); // 設置地圖顯示的城市 此項是必須設置的 11 </script>
我在本身操做過程當中的依賴庫命名爲modules(可修改,但與前面修改的JS文件要匹配),在Demo文件/js路徑下,裏面已有map,oppc,tile,control,menu,marker,infowindow這些模塊,如第二步的第3小步所述,後期可根據須要從新下載,或從新配置,我是直接從新下載。
再強調一次,地址爲:http://api.map.baidu.com/getmodules?v=1.3&mod=模塊名,根據本身須要,將內容添加到modules文件中,或從新下載,也能夠所有下載下來放入modules文件中。
如下爲前輩文章中提到的依賴模塊名稱、下載瓦片地圖文件方法。(我沒試過他的,有興趣的可嘗試)
一、全部依賴模塊名稱以下:(引前輩教程中的圖和內容,有誰知道這個圖是哪來的麼?)
二、Demo文件中的modules文件中在map模塊部分已經去掉了百度版權信息
若有須要,能夠直接使用此文件的map部分去除百度版權。
而後將此資源文件的請求路徑改成本地,須要在以前下載的apiv1.3.min.js中修改,因爲細節較多這裏就不詳細描述了,建議直接使用Demo文件中已修改好的apiv1.3.min.js文件。(若有興趣的話能夠經過「代碼比較軟件」與以前下載apiv1.3.min.js進行比較找到修改之處)
三、下載瓦片地圖文件(tile)
這裏提供一個下載瓦片地圖的軟件——全能電子地圖下載器1.9.5.zip ,裏面包含有註冊機,安裝過程就不描述了。
這裏是使用說明——使用說明(雖然軟件聲明能下載的地圖類型比較多,但好像只有百度地圖能正常使用)
根據本身須要下載瓦片地圖後直接拷貝到Demo文件/maptile路徑下(將原有的文件刪除)
最後:經歷了幾天,從查閱資料到完成初步的離線地圖的功能,和本身的軟件融合後,有些標註的功能還不太完善,以下圖,瓦片地圖由於沒註冊機,因此圖上不少廣告,且沒下載完整的瓦片地圖。暫時先總結了這部分離線操做,分享下本身的成果。
第一次寫博客,寫很久呀。。。^_^