1. 程式人生 > >使用百度API實現實時公交線路查詢及地圖顯示

使用百度API實現實時公交線路查詢及地圖顯示

需求:當外部輸入公交線路號,點選查詢按鈕的時候,會在div上顯示所有包含此公交線路號的列表,點選列表中的項,會在百度地圖上繪製出其線路。

實現:

第一步:生成線路列表

使用的百度API:服務類中BusLineSearch類是公交線路搜尋類。

構造其物件,呼叫其getBusList方法,在此方法的回撥函式OnGetBusListComplete中返回BusListResult型別的公交列表結果

查詢

$("#query").click(function () {
        map.clearOverlays();
        busNo = $('#keyword').val();
        busutil.getBusList(busNo);
        window.localStorage.setItem("busNo", busNo);
        //設定curItemNo=0,查詢後會顯示div中第一條線路
        curItemNo = 0;
        $("#keyword").val("");
})

回撥函式

busutil = new BMap.BusLineSearch("杭州", {
        renderOptions: {panel: "itemResult"},
        onGetBusListComplete: function (buslist) {           
            var lineNameList = buslist.KA;
            var html = [];
            for (var i in lineNameList) {
				//為每一項新增點選事件
                html.push('<li><a href="javascript:void(0)" onclick="subgo(' + i + ' )">' + lineNameList[i].name +
                    '</a></li>');
            }
            var l_result = document.getElementById("l-result");
            l_result.innerHTML = '<ul>' + html.join('') + '</ul>';
            },        
    });

第二步:列表項點選事件

使用的百度API:服務類中BusLineSearch類是公交線路搜尋類,設定curItemNo,再次呼叫其getBusList方法。

點選

function subgo(itemNo) {
    curItemNo = itemNo;
    window.localStorage.setItem("curItemNo", curItemNo);
    busutil.getBusList(busNo);
}

第三步:列表項點選顯示具體的線路資訊

使用的百度API:服務類中BusLineSearch類是公交線路搜尋類,呼叫其getBusLine方法,其引數為busListItem型別,,在方法的回撥函式onGetBusLineComplete中返回型別為BusLine的公交資訊。

這個地方比較關鍵,我們前面獲得了BusListResult型別的公交列表結果,其有一個getBusListItem的方法,返回BusListItem型別的結果,表示獲取某一個具體的公交列表中的物件。將這個物件傳給getBusLine方法,在其回撥函式onGetBusLineComplete中畫具體線路。

onGetBusLineComplete回撥函式

busutil = new BMap.BusLineSearch("杭州", {
        renderOptions: {panel: "itemResult"},
        onGetBusListComplete: function (buslist) {
            
            var lineNameList = buslist.KA;
            var html = [];
            for (var i in lineNameList) {
                html.push('<li><a href="javascript:void(0)" onclick="subgo(' + i + ' )">' + lineNameList[i].name +
                    '</a></li>');
            }
            var l_result = document.getElementById("l-result");
            l_result.innerHTML = '<ul>' + html.join('') + '</ul>';
			//呼叫getBusLine方法,獲取一個具體的公交列表中的物件
            busutil.getBusLine(buslist.getBusListItem(curItemNo));
        },
        onGetBusLineComplete: function (busline) {
			//畫具體線路            
        }
    });


第四步:畫具體線路

使用的百度API:覆蓋物類中的Polyline,使用瀏覽器的向量製圖工具(如果可用)在地圖上繪製折線的地圖疊加層。

通過呼叫getBusLine方法,返回busLine型別的物件,其有getPath()方法,返回Array<Point>的公交線地理座標點陣列(注意:其array.length要比站點數.length多很多)。
onGetBusLineComplete: function (busline) {
            var polyline = new BMap.Polyline(busline.getPath(), {
                strokeColor: "#3333FF",
                strokeWeight: 5,
                strokeOpacity: 0.7
            });
            map.clearOverlays();
            map.addOverlay(polyline);
			//新增站點Marker
			showPolyline(busline);
        },

第五步:在polyline上畫站點,迴圈獲取其站點資訊,並新增Marker到polyline上

使用的百度API:BusLine物件有兩個方法,getNumBusStations()獲取公交站點個數以及getBusStation(i),返回值為BusStation,表示獲取一個具體的公交站物件。

以及用覆蓋物類中的Marker類

showPolyline方法

function showPolyline(busline) {
    for (var i = 0; i < busline.getNumBusStations(); i++) {
        var busStation = busline.getBusStation(i);
        pointsArr[i] = busStation.position;
        busStationArr[i] = busStation.name;
        if (i == 0) {
            addCircle(i,busline, busStation, startMarkerIcon);
        } else if (i == busline.getNumBusStations() - 1) {
            addCircle(i,busline, busStation, endMarkerIcon);
        } else {
            if(busStation.name == stationName){
                addCircle(i, busline, busStation, busStationFocusIcon);
            }else{
                addCircle(i, busline, busStation, busStationIcon);
            }
        }
    }
	//設定地圖的視野
    map.setViewport(pointsArr);    
}

addCircle方法

function addCircle(index,busline, busStation, icon) {
    var marker = new BMap.Marker(busStation.position, {icon: icon});
    markerArr[index] = marker;
    marker.setTitle(busStation.name);    
    map.addOverlay(marker);
}

第六步:為Marker新增click事件,使其可以顯示站點公交的實時資訊

      百度地圖API:使用覆蓋物類中的InfoWindow類

function addCircle(index,busline, busStation, icon) {
    var marker = new BMap.Marker(busStation.position, {icon: icon});
    markerArr[index] = marker;
    marker.setTitle(busStation.name);
    marker.addEventListener("click", function () {
        infoWindow.setTitle(busStation.name + " (" + busline.name + ")");
        //前臺給後端SL_ID(StopLine 公交線路站點表的主鍵
        //後臺返回給前端兩個資訊 最近一輛公交正在開往--站,據此--分鐘--米
        //如果有第二輛公交的資訊,那麼也進行顯示
        $.ajax({
            url: 'http://xx.xxx.xxx.xxx/busStationInfo',
//                data: {"SL_id":sl_id},
            type: 'get',
            datatype: 'json',
            async: 'false',
            success: function (json) {
                stationName = busStation.name;
                window.localStorage.setItem('stationName', stationName);
                var busInfoList = json.station;
                var infoArr = [];
                for (var i in busInfoList) {
                    infoArr[i] = "最近第" + (parseInt(i) + 1) + "輛公交車正在開往" + busInfoList[i].nextstop + ",距本站" +
                        busInfoList[i].stopcount +
                        "站," + busInfoList[i].distance + ",需要" + busInfoList[i].time;

                }
        });
    });
    map.addOverlay(marker);
}

最後,要考慮以下幾點內容

1. div中busList選中項與未選項顏色的切換

2. 在百度地圖中新增一個反向的按鈕控制元件,參照百度官方API可以實現

3. 地圖中選中站點與未選站點的icon切換

上一張效果圖