百度地圖API詳解之公交導航

原文地址:http://blog.csdn.net/sup_heaven/article/details/8461593php

只是做爲備忘!!!html

 

一次調試百度地圖多marker事件監聽的問題,不知如何解決,後來看了原做者jz1108才知道要用閉包。以爲原做者jz1108關於百度地圖的文章寫的不錯,因此轉載到了CSDN,爲了尊重原做者jz1108,特此說明。瀏覽器

 

前面咱們介紹過駕車導航了,今天來講說公交導航。閉包

 

什麼是公交導航異步

公交導航功能是告訴使用者從A到B的公交出行方案,而不是某條具體的公交線路信息,這一點須要廣大開發者注意。函數

公交導航功能經過類TransitRoute來實現,這裏須要說說爲啥不是BusRoute,而是TransitRoute。百度提供的是公共交通導航,公共交通不單單涉及bus,可能還會有地鐵、渡輪甚至之後的飛機火車,因此這裏使用的是public transit中的transit進行描述。spa

 

一個簡單的例子.net

咱們仍是從一個簡單的例子開始:調試

複製代碼
var transit = new BMap.TransitRoute('北京', {
    renderOptions: {
        map: map,
        panel: 'panel'
    }
});
transit.search('西單', '頤和園');
複製代碼

代碼經過renderOptions設置渲染的地圖實例和側欄面板容器的id,其中map是已經實例化好的地圖,panel爲已經準備好的div元素的id。咱們會看到以下結果:code

 

地圖上顯示了一個方案,在面板中列出了全部方案的描述,點擊不一樣的方案地圖會予以展現。

除了使用字符串類型之外,還能夠提供座標進行查詢,這樣能夠獲得更精確的結果。好比從「麥當勞」到「肯德基」這樣的路線查詢就不會獲得結果,由於API不知道是從哪一個麥當勞到哪一個肯德基。下面的示例使用了座標進行搜索。

transit.search(new BMap.Point(116.315157,39.987946), 
               new BMap.Point(116.371499,39.880394));

下面是使用座標做爲參數進行查詢獲得的結果:

 

注意,因爲提供的是座標,因此起點和終點沒有具體的地點描述。

和駕車導航相似,起點和終點也能夠是LocalResultPoi類型,咱們仍是用上面的座標進行查詢,不過是封裝在一個LocalResultPoi類型當中的:

transit.search({title: '我這裏', point: new BMap.Point(116.315157,39.987946)}, 
               {title: '你這裏', point: new BMap.Point(116.371499,39.880394)});

這樣API在展現結果時就能夠顯示起點和終點的描述了。

 

自定義覆蓋物展現

若是你不滿意API提供的默認線路的顏色和標註的樣式,你也能夠選擇經過經過數據接口自行建立。注意,本身建立覆蓋物時,點擊列表中的方案將不會更新地圖區域,由於此時地圖區域的元素都是由開發者自行建立的。在使用數據接口以前,先經過一個結構圖來了解一個完整的公交方案的各個組成部分,以方便理解:

一個不須要換乘的公交方案是由:起點、起點到上車站的步行線路、上車站到下車站的公交線路以及下車站到終點的步行線路構成。固然有可能起點和上車站是重合的,或者終點和下車站是重合的,此時步行線路長度就爲0(起點或終點自己就爲公交站的時候)。若是有換乘,那麼每次換乘中的下車站到上車站也有步行線路(如上圖的第二個方案所示)。

因此不論公交方案具體是什麼樣,在數據上的表示都是一致的:

  • 直達方案:2條步行線路 + 1條公交線路
  • 換乘一次方案:3條步行線路 + 2條公交線路
  • 換乘兩次方案:4條步行線路 + 3條公交線路

以此類推。

API中經過TransitRouteResult來描述公交導航結果,經過TransitRoutePlan來描述一條公交方案。那麼怎麼獲取公交導航結果和具體的方案的信息呢?請看下面的示例:

複製代碼
var transit = new BMap.TransitRoute('北京', {
    onSearchComplete: function(result) {
        if (transit.getStatus() == BMAP_STATUS_SUCCESS) {
            // 從結果對象中獲取起點和終點信息
            var start = result.getStart();
            var end = result.getEnd();
            addStart(start.point, start.title);
            addEnd(end.point, end.title);
            // 直接獲取第一個方案
            var plan = result.getPlan(0);
            // 遍歷全部步行線路
            for (var i = 0; i < plan.getNumRoutes(); i++) {
                if (plan.getRoute(i).getDistance(false) > 0) {
                    // 判斷只有大於0的步行線路纔會繪製
                    addWalkRoute(plan.getRoute(i).getPath());
                }
            }
            // 遍歷全部公交線路
            var allLinePath = [];
            for (i = 0; i < plan.getNumLines(); i++) {
                allLinePath = allLinePath.concat(plan.getLine(i).getPath());
                addLine(plan.getLine(i).getPath());
            }
            // 最後根據公交線路的點設置地圖視野
            map.setViewport(allLinePath);
        }
    }
});

transit.search('北京大學', '北京交通大學');

// 添加起點覆蓋物
function addStart(point, title){
    map.addOverlay(new BMap.Marker(point, {
        title: title,
        icon: new BMap.Icon('http://images.cnblogs.com/cnblogs_com/jz1108/329471/o_blue.png', new BMap.Size(38, 41), {
            anchor: new BMap.Size(4, 36)
        })}));
}

// 添加終點覆蓋物
function addEnd(point, title){
    map.addOverlay(new BMap.Marker(point, {
        title: title,
        icon: new BMap.Icon('http://images.cnblogs.com/cnblogs_com/jz1108/329471/o_red.png', new BMap.Size(38, 41), {
            anchor: new BMap.Size(4, 36)
        })}));
}

// 添加路線
function addWalkRoute(path){
    map.addOverlay(new BMap.Polyline(path, {
        strokeColor: 'black',
        strokeOpacity: 0.7,
        strokeWeight: 4,
        strokeStyle: 'dashed',
        enableClicking: false
    }));
}

function addLine(path){
    map.addOverlay(new BMap.Polyline(path, {
        strokeColor: 'blue',
        strokeOpacity: 0.6,
        strokeWeight: 5,
        enableClicking: false
    }));
}
複製代碼

在上面的代碼中,經過TransitRouteOptions的onSearchComplete屬性設置了回調函數,一旦檢索完成這個回調函數就會被調用。在回調函數開始咱們先判斷檢索是否成功,若是成功表示至少有一條公交方案返回,這裏咱們先經過結果對象獲取起點和終點,接着直接獲取第一條方案,遍歷方案中全部步行線路和公交線路並繪製在地圖上,最後咱們根據公交線路的點來設置一個合適的地圖視野。

你會在瀏覽器中獲得以下效果:

 

在獲取結果對象時,除了經過回調函數參數獲取之外,還能夠經過TransitRoute的getResults方法得到,須要注意的是,因爲搜索過程是異步的,如下代碼的寫法將不會獲得結果:

transit.search('西單', '頤和園');
var res = transit.getResults();  // undefined

由於search方法調用結束後搜索結果並無當即返回。開發者能夠在回調函數中調用此方法當即得到結果,也能夠等回調函數執行完若干時間後再想獲取結果數據時調用。

 

自定義方案描述

經過TransitRoutePlan的getDescription能夠得到完整的方案描述,可是若是開發者想自行定義描述的形式則可經過數據接口進行。例如:

複製代碼
var transit = new BMap.TransitRoute('北京', {
    onSearchComplete: function(result) {
        if (transit.getStatus() == BMAP_STATUS_SUCCESS) {
            // 從結果對象中獲取起點和終點信息
            var start = result.getStart().title;
            var end = result.getEnd().title;
            
            // 直接獲取第一個方案
            var plan = result.getPlan(0);
            // 獲取步行線路與公交線路個數總和,用於遍歷
            var total = plan.getNumRoutes() + plan.getNumLines();
            
            var description = ['從' + start];
            var addEndTitle = true;
            for (var i = 0; i < total; i++) {
                if (i % 2 == 0) {
                    // i爲偶數
                    // 處理第一個步行描述邏輯
                    if (i / 2 == 0) {
                        if (plan.getRoute(i / 2).getDistance(false) == 0) {
                            description = ['從'];
                        }
                    }
                    // 處理最後一個步行描述邏輯
                    if (i / 2 == plan.getNumRoutes() - 1) {
                        if (plan.getRoute(i / 2).getDistance(false) == 0) {
                            addEndTitle = false;
                        }
                    }
                    if (plan.getRoute(i / 2).getDistance(false) > 0) {
                        description.push('步行約' + plan.getRoute(i / 2).getDistance(true) + '至');
                    }
                } else {
                    // i爲奇數
                    var line = plan.getLine((i - 1) / 2);
                    if (i == 0) {
                        description.push(line.getGetOnStop().title + ', ');
                    }
                    if (i > 0) {
                        if (plan.getRoute((i - 1) / 2).getDistance(false) > 0) {
                            description.push(line.getGetOnStop().title + ', ');
                        }
                    }
                    description.push('乘坐' + line.title + ', ');
                    description.push('通過' + line.getNumViaStops() + '站');
                    description.push('在' + line.getGetOffStop().title + '站下車,');
                }
            }
            if (addEndTitle) {
                description.push(end + '。');
            }
            // 替換可能出現的末尾位置的逗號
            var descriptionStr = description.join('').replace(/\uff0c$/, '。');
        }
    }
});

transit.search('北京大學', '北京交通大學');
複製代碼

變量descriptionStr的內容爲:「從北京大學步行約60米至北京大學西門, 乘坐運通106(中央黨校北門-田村北路), 通過6站在中國農業科學院站下車,乘坐26(二里莊-西便門), 通過4站在北京交通大學站下車。」。

 

回調函數詳解

前面的幾個例子咱們使用了onSearchComplete回調函數,在API中還提供了以下幾個回調函數,它們的含義和觸發時機以下:

    • onMarkersSet:若是設置了渲染的地圖,則API自動添加標註後會觸發此函數。
    • onPolylinesSet:若是設置了渲染的地圖,則API自動添加線路覆蓋物後會觸發此函數。
    • onInfoHtmlSet:若是設置了渲染地圖,當用戶點擊標註彈出信息窗口時會觸發此函數。
    • onResultsHtmlSet:若是設置了渲染側欄,則API填充完HTML後會觸發此函數。
相關文章
相關標籤/搜索