百度地圖離線化(API v=1.3)


  畢設(北斗導航項目)進行了一段時間,近日在實驗室給老師匯報進展時,由於網絡不暢,加載百度在線地圖及其各種操作時,時間過長,於是想將百度地圖離線化。查閱網上很多資料,有的是廣告(賣GIS應用的),有的版本太久......最后參考網上兩位前輩的博客內容,加以實踐,實現了地圖完全離線且能進行基本操作。趁周末整理了實踐過程並記錄下來,希望能幫到有需要的朋友。

  :感謝兩位前輩,其原文為:開源中國:Web版百度地圖加載離線瓦片 ;csdn:使用百度地圖JS API構建離線地圖應用(完整教程)

  原文附帶Demo,大家可以參考下,注意版本:百度離線地圖Demo

具體實現步驟:

  前期工作:構建在線地圖應用(版本API v1.3,其他版本未測試,如需要可自行研究)。

准備好放源碼的文件夾(可為中文),在其中建立三個文件夾:js、css、images,用於存放下面的文件。(基礎API下載地址:apiv1.3.min.js ;css文件下載地址:bmap.css )

  先建立一個簡單的在線地圖應用,如下:

 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中的文件對比,並非全按以下的修改方式

1、搜索變量:“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文件夾平行的目錄里面的。

2、搜索變量:“_baseUrl”,直到找到這樣的一段代碼

preLoaded:{},Config:{_baseUrl:x+"getmodules?v=1.3",_timeout:5000},

  同樣,要去掉x,這個x也是前面這段代碼中的x。同時,不僅要去掉x,更要把地址指向js目錄。

1 preLoaded:{},Config:{_baseUrl:"js/",_timeout:5000},

  這個地址用來動態加載組件。系統中用到哪些組件,就下載加載哪些組件。最終系統會訪問類似於“http://api.map.baidu.com/getmodules?v=1.3&mod=map,oppc,tile,control,marker”的url加載組件。

 3、繼續搜索下一個“_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文件夾里面即可。后面會詳細說明加載模塊這個問題。

  注意:如果需要更多的功能,我是通過重新加載以上的地址,其它的教程寫說不需要自動加載,通過另外配置參數獲取相關的功能就好,我沒親自配置過,有配置過的小伙伴可以講講配置過程。

4、關鍵的一步:搜索“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。這個文件夾里面的內容和后面的資源文件請在附件中下載。至於如何下載瓦片,問百度。至此,該文件的處理結束。

  第三步:下載資源文件。(終於到資源文件的詳細介紹了,前期工作中提到)

  1、圖片文件:可以通過前期工作的第二張圖的方式獲取素材的下載地址,也可從Demo文件/images路徑下獲取,還有一種方式,引用前輩教程中的話:

查找bmap.css里面所有的圖片文件,下載下來放在指定的文件夾里面就好了。里面總共不超過兩三個文件,下載下來放在 images文件夾里面就行了。另外,剛才的這個js里面也有一些資源文件,也下載下來放在images文件夾里面。這個通過搜索imgPath就能找 到,有png,有gif,有點文件可能需要通過https的地址才能下載的到。

  得到基本的圖標素材后,將之前所下載的bmap.css文件里面圖片的url修改為本地路徑。

  2、依賴模塊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文件中。

  以下為前輩文章中提到的依賴模塊名稱、下載瓦片地圖文件方法。(我沒試過他的,有興趣的可嘗試)

1、所有依賴模塊名稱如下:(引前輩教程中的圖和內容,有誰知道這個圖是哪來的么?)


2、Demo文件中的modules文件中在map模塊部分已經去掉了百度版權信息


如有需要,可以直接使用此文件的map部分去除百度版權。

然后將此資源文件的請求路徑改為本地,需要在之前下載的apiv1.3.min.js中修改,由於細節較多這里就不詳細描述了,建議直接使用Demo文件中已修改好的apiv1.3.min.js文件。(如有興趣的話可以通過“代碼比較軟件”與之前下載apiv1.3.min.js進行比較找到修改之處)

3、下載瓦片地圖文件(tile)

這里提供一個下載瓦片地圖的軟件——全能電子地圖下載器1.9.5.zip ,里面包含有注冊機,安裝過程就不描述了。

這里是使用說明——使用說明(雖然軟件聲明能下載的地圖類型比較多,但好像只有百度地圖能正常使用)

根據自己需要下載瓦片地圖后直接拷貝到Demo文件/maptile路徑下(將原有的文件刪除)

最后:經歷了幾天,從查閱資料到完成初步的離線地圖的功能,和自己的軟件融合后,有些標注的功能還不太完善,如下圖,瓦片地圖因為沒注冊機,所以圖上很多廣告,且沒下載完整的瓦片地圖。暫時先總結了這部分離線操作,分享下自己的成果。

第一次寫博客,寫好久呀。。。^_^


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM