1. 程式人生 > >百度地圖API詳解之公交導航

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

一次除錯百度地圖多marker事件監聽的問題,不知如何解決,後來看了原作者jz1108才知道要用閉包。覺得原作者jz1108關於百度地圖的文章寫的不錯,所以轉載到了CSDN,為了尊重原作者jz1108,特此說明。

前面我們介紹過駕車導航了,今天來說說公交導航。

什麼是公交導航

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

公交導航功能通過類TransitRoute來實現,這裡需要說說為啥不是BusRoute,而是TransitRoute。百度提供的是公共交通導航,公共交通不僅僅涉及bus,可能還會有地鐵、渡輪甚至以後的飛機火車,所以這裡使用的是public transit中的transit進行描述。

一個簡單的例子

我們還是從一個簡單的例子開始:

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

程式碼通過renderOptions設定渲染的地圖例項和側欄面板容器的id,其中map是已經例項化好的地圖,panel為已經準備好的div元素的id。我們會看到如下結果:

地圖上顯示了一個方案,在面板中列出了所有方案的描述,點選不同的方案地圖會予以展示。

除了使用字串型別以外,還可以提供座標進行查詢,這樣可以得到更精確的結果。比如從“麥當勞”到“肯德基”這樣的路線查詢就不會得到結果,因為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後會觸發此函式。

相關推薦

地圖API公交導航

一次除錯百度地圖多marker事件監聽的問題,不知如何解決,後來看了原作者jz1108才知道要用閉包。覺得原作者jz1108關於百度地圖的文章寫的不錯,所以轉載到了CSDN,為了尊重原作者jz1108,特此說明。 前面我們介紹過駕車導航了,今天來說說公交導航。 什麼是公

地圖API駕車導航

本文將向大家介紹如何使用百度地圖API提供的駕車導航服務進行開發。 一個簡單的示例 駕車導航服務根據傳入的起點和終點資訊給出從起點到終點的駕車路線,我們先從一個最簡單的示例看起: var map = new BMap.Map('container'); map.cent

地圖API地圖標註(一)

本文將向大家介紹百度地圖API的標註(Marker)的使用方法和一些實現細節。 標註概述 標註(Marker)是用來表示一個點位置的可見元素,每個標註自身都包含地理資訊。比如你在西單商場位置添加了一個標註,不論地圖移動、縮放,標註都會跟隨一起移動,保證其始終指向正確的地理位置。 從上面的圖可以看

地圖api實現的定位,導航,附近搜尋

實現功能:  1、定位,根據裝置自動定位,設定到區,可自行調整;         2、附近地標搜尋,顯示定位附近圖書館,可更改;         3、路線規劃,點選終點或手動輸入終點位置; 程式碼實現: <%@ page language="java" imp

地圖api座標轉換,兩點導航

<script type="text/javascript" src="http://api.map.baidu.com/api?v=2.0&ak=18cfc0dbeaf7a8cead27ddaf88bac861"></script> <

地圖API定位當前和公交查詢

前言 本文主要介紹百度地圖中自動定位到當前的功能,然後可以指定起始位置查詢公交。 原始碼 <!DOCTYPE html> <html> <head>

地圖api----根據用戶ip定位城市

服務 利用 bsp result 城市 blog 經緯度 name 定位 LocalCity 這個類是利用用戶IP地址去百度數據庫裏查詢得到IP所在的城市,用法如下: var objCity = new BMap.LocalCity(); objCity.get(func

計算道第一場A無人車

官方給出的題目解析是二分搜尋 直接二分最後的最大值,然後檢車錢是否足夠即可   為什麼不能將l設定為最小值的原因:while迴圈的退出條件是r-l <= 0題目中有一句話就是任何時候每一輛車的重量必須大於等於1kg 按照你原來的設計思想,也就是將l設定為最小值那麼當

地圖API地圖退拽標記點獲取經緯度的實現程式碼

<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

地圖API本地搜尋與範圍搜尋

地圖服務是指可以提供資料資訊的介面,比如說本地搜尋/路線規劃等,下面小編給大家整理下百度地圖API之本地搜尋和範圍搜尋,具體請看下文。 地圖服務概述   地圖服務是指那些提供資料資訊的介面,比如本地搜尋、路線規劃等等。百度地圖API提供的服務有: LocalSearc

地圖api獲取當前使用者地理位置-瀏覽器定位

<script> var x=document.getElementById("demo"); function getLocation() { if (navigator.geolocation) { navigator.geolocation.getCurrentPos

地圖API應用——利用定位SDK和地圖SDK來進行定位和顯示當前位置

在專案開發中,尤其是O2O或者體育運動類專案的APP開發過程中,經常會出現利用GPS定位獲取當前位置並在地圖上顯示的情況,下面就來結合實際的例子來簡要介紹一下如何實現這個功能,使用的是百度地圖最新的地圖SDK(baidumapapi_v2_4_1)和定位SDK(locSDK

地圖api固定標記點跳動,點選顯示詳情

一.首先引入所申請的ak金鑰<script type="text/javascript" src="http://api.map.baidu.com/api?ak=PlhFWpA02aoURjAOpnWcRGqw7AI8EEyO&v=2.0&services=false"><

地圖API折線

剛接觸百度地圖api不久,再根據座標資料畫折線上,傷了不少腦筋,使用它想小夥伴們多,文件也算豐富, 現總結下在地圖上折線的表示。 1、引用地圖api   如: <script type="text/javascript" src="http://api.map.b

地圖api點選地圖獲取座標點

一.首先引入所申請的ak金鑰<script type="text/javascript" src="http://api.map.baidu.com/api?ak=PlhFWpA02aoURjAOpnWcRGqw7AI8EEyO&v=2.0&services=false"><

(Android)呼叫地圖api新增覆蓋物

一、自定義類Info public class Info implements Serializable { private double latitude; private double longitude; private int imgI

[013] 地圖API城市POI搜尋-獲取所有結果(Android)

      本文主要講解如何通過百度地圖API搜尋得到一個城市裡的所有POI。這裡有必要對“所有”這個詞進行強調一下,以便引起重視,之所以這樣說,是因為在搜尋POI時,預設僅返回一頁的搜尋結果10條,那麼如何才能得到所有的搜尋結果呢?其實baidu map api是提供了相關

HTML5頁面直接調用地圖API,獲取當前位置,直接導航目的地(轉)

wid dir tle mark utf-8 mil 獲取 open init HTML5頁面直接調用百度地圖API,獲取當前位置,直接導航目的地 我是應用在微信中,自定義菜單,菜單直接鏈接到這個HTML5頁面,獲取當前位置後,頁面中定好目的地,這樣打開頁面後直接進入導航頁

地圖api入門介紹(js篇)

顯示 .com cnblogs androi web 入門介紹 步驟 api 地圖api 最近因為用到了百度地圖的api,感覺還有點用記錄一下,一方面充實一下自己,第二也希望有用到的同學可以參考一下;因為之前用過android baidu api 所以再用web

在混合app開發過程中使用地圖api的出現坐標偏差的解決

百度 api call cordova overlay forum gpo ext ddr 在項目中使用ngCordova的$cordovaGeolocation模塊獲取當前位置經緯度,當展示在百度地圖中時發現有誤差(我的測試誤差為1.7公裏左右),查資料發現百度地圖經緯度