百度地圖2.0瓦片獲取

前面跟你們分享過百度地圖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裏面是直接可用的。

相關文章
相關標籤/搜索