前面跟你們分享過百度地圖2.0離線版的修改製做,許多人問怎樣得到瓦片,這個過程其實並不複雜。稍微追蹤一下代碼就能夠得到瓦片。javascript
因爲想下載瓦片須要聯網,但須要修改代碼,所以不能直接用百度地圖的js。js須要下載下來修改使用,所以仍是參考前做《百度地圖2.0離線版的製做》吧,不過只須要下載下來加載到本身的html頁面中就能夠了。前文中的修改都是沒必要要的了,須要新修改代碼達到獲取瓦片地址,而後經過工具能夠下載。下載工具我就不提供了。css
第一步,修改「a_」方法html
若是不出意外的話,搜索方法定義「a_」應該能且只能找到一處,其調用者也只有一處,兩個都要改,咱們先來改「a_」定義。java
a_:function(a,b,c,d){var e=this;e.h1=b;var f=this.map.ta(),g=e.SD(a,c),i=f.k.Ob,b=[a[0]*i+b[0],(-1-a[1])*i+b[1]],k=this.wg[g];k&&k.Gb?(vb(k.Gb,b),d&&(d=new Q(a[0],a[1]),f=this.map.K.te?this.map.K.te.style:"normal",d=c.getTilesUrl(d,a[2],f),k.loaded=q,Fc(k,d)),k.loaded?this.vf():Gc(k,function(){e.vf()})):(k=this.fj[g])&&k.Gb?(c.Pb.insertBefore(k.Gb,c.Pb.lastChild),this.wg[g]=k,vb(k.Gb,b),d&&(d=new Q(a[0],a[1]),f=this.map.K.te?this.map.K.te.style:"normal",d=c.getTilesUrl(d,a[2],f),k.loaded= q,Fc(k,d)),k.loaded?this.vf():Gc(k,function(){e.vf()})):(k=i*Math.pow(2,f.qm()-a[2]),new H(a[0]*k,a[1]*k),d=new Q(a[0],a[1]),f=this.map.K.te?this.map.K.te.style:"normal",d=c.getTilesUrl(d,a[2],f),k=new Hc(this,d,b,a,c),Gc(k,function(){e.vf()}),k.$n(),this.wg[g]=k)},
這個太長了,也很差看哈,不過修改很是簡單,在最後增長一句「return d;」就行了。這樣咱們能夠找到瓦片的地址等信息。api
我給這段代碼稍加翻譯了一下,能夠看得更清楚一些。爲了方便,我將大多數的逗號表達式改爲多語句,將問號冒號三元表達改爲了if/else結構。數組
a_:function(a,b,c,d){ var e=this; e.h1=b; var f=this.map.va(); var g=e.SD(a,c);//名字,TILE-2-3-4-5,基本上是version-x-y-z var i=f.k.Ob; var b=[a[0]*i+b[0],(-1-a[1])*i+b[1]];//left和top的計算 var k=this.wg[g];//這個是個緩存結構看起來,是一個map //d彷佛永遠都是undefined,所以下面跟d相關的代碼都未執行。 if(k&&k.Gb){//找到緩存,k.Gb是具體的tile對應的image節點 vb(k.Gb,b);//設置image的位置,具體的位置在b中存儲了,兩個維度分別是left和top if(!!d){ console.log("====any here?? k.Gb="+k.Gb.src) d=new Q(a[0],a[1]); f=this.map.M.se?this.map.M.se.style:"normal"; d=c.getTilesUrl(d,a[2],f); k.loaded=q; Fc(k,d); } k.loaded?this.vf():Gc(k,function(){e.vf()}) }else{ k=this.fj[g];//這個不知道是什麼,看起來這裏永遠取不到數據 if(!!k&&!!k.Gb){//這一塊代碼也就廢掉了 c.Pb.insertBefore(k.Gb,c.Pb.lastChild); this.wg[g]=k; vb(k.Gb,b); if(d){ console.log("====any here?????????? k.Gb="+k.Gb.src) d=new Q(a[0],a[1]); f=this.map.M.se?this.map.M.se.style:"normal"; d=c.getTilesUrl(d,a[2],f); k.loaded= q; Fc(k,d); } k.loaded?this.vf():Gc(k,function(){e.vf()}) }else{ //未緩存的數據都走的這個地方,但只有未緩存的數據走的這裏 console.log("----all is here?"); k=i*Math.pow(2,f.qm()-a[2]); new H(a[0]*k,a[1]*k); d=new Q(a[0],a[1]);//Q是一個對象,x,y兩個屬性 f=this.map.M.se?this.map.M.se.style:"normal"; d=c.getTilesUrl(d,a[2],f);//第二個參數是z,所以a數組裏面本來就是[x,y,z] k=new Hc(this,d,b,a,c); Gc(k,function(){e.vf()}); k.$n(); this.wg[g]=k; } } return d; },
最後一句是增長的,其餘的註釋也好,輸出也好,都是探查和驗證的。具體不解釋了。這裏只是爲了說明,a_方法的目的就是隨時獲取瓦片的地址,並設置其展現位置。瓦片可能已經下載了,是不須要請求的。若是你的鼠標在拖動地圖,這個方法會瘋狂的執行。但因爲緩存的存在,所以瀏覽器仍是受得了的。瀏覽器
而後順着「a_」的調用方,咱們須要修改的是「cI」方法。這個方法我不知道名字會不會變更,就像a_同樣,不知道會不會在不一樣的版本文件裏會變化,我看這幾回的代碼這兩個方法的名字是沒變的。緩存
第二步,修改a_的調用方法
網絡
cI方法太長了,貼不過來,也看不過來,我貼相關的一部分吧app
for(k=0;k<i;k++)this.a_([v[k][0],v[k][1],n],u,e,a)
哈哈,就這樣,這部分也太簡單了:-)
不過咱們要修改爲別的樣子,把瓦片地址輸出出來。這個其實不用我來說了吧,你們都內心有數了。這也是爲何我上面修改了a_方法,讓他返回瓦片地址。
有兩點你們要注意,第一,不是每次調用a_方法都會得到瓦片地址,緩存了的瓦片地址是不返回瓦片地址的(undefined),只有新加載的瓦片會返回地址好比拖動或縮放了地圖。第二,a_方法不是隻計算瓦片地址,還包括加載瓦片、移動瓦片,使得顯示符合用戶要求。
for(k=0;k<i;k++){ var url = this.a_([v[k][0],v[k][1],n],u,e,a); if(!!url&&window["$collector$"]&&window["$collector$"].appendTile){ var path="tiles/"+n+"/"+v[k][0]+"/"+v[k][1]+".png"; window["$collector$"].appendTile(path, url); } }
我把它修改爲這樣了,這要求咱們定義一個全局變量對象$collector$,而後要求提供一個appendTile方法,而後把地址、路徑等信息輸出出來。我是這樣寫的,同時也是爲了對應《百度地圖2.0離線版的製做》文章,給出了瓦片在離線版中的位置。
第三步,編寫瓦片輸出代碼
這個更簡單了,你們能夠隨意發揮了。接口上面定義了,定義也是簡單粗暴的。
<html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>百度離線版2.0DEMO</title> <script type="text/javascript" src="js/apiv2.0.min.js"></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> <div id="list"></div> </body> </html> <script type="text/javascript"> var $collector$ = { appendTile: function(path, url){ addUrls(path, url); } }; function addUrls(path, url){ var div = document.getElementById("list"); var anchor = document.createElement("a"); anchor.href = url; anchor.innerHTML = path; div.appendChild(anchor); var br = document.createElement("br"); div.appendChild(br); } var map = new BMap.Map("container",{mapType: BMAP_NORMAL_MAP}); //設置衛星圖爲底圖 var point = new BMap.Point(111.404, 40.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); var polyline = new BMap.Polyline([ new BMap.Point(111.404, 40.915), new BMap.Point(112.404, 42.915), new BMap.Point(113.404, 39.915), new BMap.Point(114.404, 42.915), new BMap.Point(115.404, 39.915), new BMap.Point(116.404, 42.915) ], {strokeColor:"blue", strokeWeight:2, strokeOpacity:0.5}); map.addOverlay(polyline); </script>
效果圖:
超連接的文本是離線版瓦片應該放的位置,連接地址是瓦片實際的網絡地址。下載吧!
本方法修改簡單,缺點是不能像前一版那樣,窗口內的瓦片批量以此獲取,此次是窗口移動到哪裏,瓦片加載到哪裏。
之因此沒有像之前那樣,主要是2.0的版本修改比較大,不少原先能獲取到的數據如今都獲取不到了。但地圖的理論不變,計算方法不變。因爲數據獲取不到,所以光有理論也沒用了。
1.3版的瓦片在2.0裏面是直接可用的。