Web版百度地圖加載離線瓦片


注:本文參考網絡教程,瓦片也是通過網絡下載。向原作者致敬!原作地址:http://download.csdn.net/download/dkm8873/9233731

原作版本已久,由於代碼混淆壓縮,無法添加標記等特性。本文通過修改最新的 代碼達到離線版的目的,而且功能可以任意擴充。本文每一個步驟都經過試驗,萬無一失。

 

點此直接下載完整版Demo代碼

先准備好一個放置源碼的文件夾,然后將獲取的文件放進去。建立三個文件夾:js、css、images。

第一步,自然是訪問一個入口:http://api.map.baidu.com/api?v=1.3

里面的內容是這樣的(原本沒有換行,為了閱讀方便一點,加了兩個回車):

(function(){ window.BMap_loadScriptTime = (new Date).getTime();  document.write('<script type="text/javascript" src="  document.write('<link rel="stylesheet" type="text/css" href="http://api.map.baidu.com/res/13/bmap.css"/>');})();

這一步將獲得一個js文件的位置和一個css文件的未知,然后分別下載下來,放在准備好的文件夾里面,我分別存儲在/js和/css里面。js的路徑后面有若干參數,不管,下載下來的文件重新命名就好,比如叫做apiv1.3.min.js

接下來要修改這個js中的一點代碼了。由於代碼是壓縮在一行上的,因此修改起來有點麻煩。

  1. 搜索變量:“imgPath”,直到找到一段代碼(同樣加了一個回車):

var x=m?"https://sapi.map.baidu.com/":"http://api.map.baidu.com/"; 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目錄。

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

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

下面會看到,我更直接的把加載地址都寫死了。看第三步

繼續搜索下一個“_baseUrl”,得到下面的代碼:

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變量吧,寫死好了,我就是這樣做的:

var cP=cN.Config._baseUrl+"getmodules.js";cy.request(cP);

這樣,我們把動態加載編程手動加載了。我們訪問這個地址“http://api.map.baidu.com/getmodules?v=1.3&mod=map,oppc,tile,control,marker”就可以拿到一個js文件了。把它重命名為上面指定的“getmodules.js”,丟在js文件夾里面即可。

如果需要更多的功能,也不需要自動加載,反正都是本地的,另外配置參數獲取相關的功能就好了。

3. 關鍵的一步,也是最復雜的一步:搜索“getTilesUrl”直到找到這樣的一段(參照物也可以另選,比如“BMAP_NORMAL_MAP”):

if(this.map.highResolutionEnabled()){cP="ph"}var cM=j[Math.abs(cR+cO)%j.length]+"?qt=tile&x="+(cR+"").replace(/-/gi,"M")+"&y="+(cO+"").replace(/-/gi,"M")+"&z="+cQ+"&styles="+cP+(a9.browser.ie==6?"&color_dep=32&colors=50":"")+"&udt="+T;return cM.replace(/-(\d+)/gi,"M$1")};window.BMAP_NORMAL_MAP=

這段代碼這么長,我格式化一下來看好了(代碼截取比上面更長一些)

    aU.getTilesUrl = function(cN, cQ) {         var cR = cN.x;         var cO = cN.y;         var T = "20150518";         var cP = "pl";         if (this.map.highResolutionEnabled()) {             cP = "ph"         }         var cM = j[Math.abs(cR + cO) % j.length] + "?qt=tile&x="                 + (cR + "").replace(/-/gi, "M") + "&y="                 + (cO + "").replace(/-/gi, "M") + "&z=" + cQ + "&styles=" + cP                 + (a9.browser.ie == 6 ? "&color_dep=32&colors=50" : "")                 + "&udt=" + T;         return cM.replace(/-(\d+)/gi, "M$1")     };     window.BMAP_NORMAL_MAP = new cv("\u5730\u56fe", aU, {         tips : "\u663e\u793a\u666e\u901a\u5730\u56fe"     });

說一下“getTilesUrl”這個方法,這里就是返回瓦片未知的關鍵方法。兩個參數中,第一個參數是{x,y},第二個參數就是z,這樣xyz就都有了。

來個短路吧,直接把它計算出來的cM的結果重新計算一下,改成:

        //這個地方廢棄了上面的計算結果,直接采用本地圖片         cM = "tiles/" + cQ + "/" + cR + "/" + cO + ".jpg";

這里意味着我們要建立第四個文件夾,tiles了。這個文件夾里面的內容和后面的資源文件請在附件中下載。至於如何下載瓦片,請自行百度吧。

OK了,這個文件的處理就結束了。

第二步:下載圖片等資源文件。

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

 

第三步,寫demo.html吧。這個直接貼代碼。

<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>百度離線版DEMO</title> <script type="text/javascript" src="js/apiv1.3.min.js"></script> <!--script type="text/javascript" src="http://api.map.baidu.com/api?v=1.3"></script--> <link rel="stylesheet" type="text/css" href="css/bmap.css"/> </head> <body> <div style="width:520px;height:340px;border:1px solid gray" id="container"></div> </body> </html> <script type="text/javascript"> var map = new BMap.Map("container",{mapType: BMAP_NORMAL_MAP});      //設置衛星圖為底圖 var point = new BMap.Point(111.40440.915);    // 創建點坐標 map.centerAndZoom(point,5);                     // 初始化地圖,設置中心點坐標和地圖級別。 //map.addControl(new BMap.MapTypeControl()); map.addControl(new BMap.NavigationControl()); map.enableScrollWheelZoom();                  // 啟用滾輪放大縮小。 map.enableKeyboard();                         // 啟用鍵盤操作。   //map.setCurrentCity("北京");          // 設置地圖顯示的城市 此項是必須設置的 var marker = new BMap.Marker(point); map.addOverlay(marker);  </script>

效果圖:

 

補記:

由於這個離線版的百度地圖對IE支持不佳,現在已經查明原因,在於圖片的格式和聲明上。百度提供的tiles圖片聲稱都是jpg格式的,但圖片實際是png格式的,因此在IE下面就死板的認為要用jpg解碼,結果無法解析。但IE對於網絡的圖片則按照實際的內容進行區分和解析,這個是沒問題的,因為圖片在網上完全可能是動態的,比如authcode.do之類的,就沒有擴展名只說。看起來這是IE的問題了。

這樣看來解決這個問題就好辦了,更改文件擴展名!

這個可以通過cmd命令來完成。比如我的命令就是:

for /F %i in ('dir /A:D /S /B') do copy "%i\*.jpg" "%i\*.png"

之所以用了拷貝,而不是直接重命名,還是想保留原文件。

這樣前面第三步把擴展名改為“.png”,就ok了。


免責聲明!

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



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