【百度地图】显示从某站点出发的所有公交车路线

摘要:
需要在一个新的地方租房子或者买房子的时候,一个重要的考虑因素就是交通是否便利,我在租房子的时候就很想知道从我周边的公交车站,能够不换乘到达哪些地方,我当时有这个需求之后上网搜,并没有找到类似的功能,而且麻烦的是,百度地图最基本的API也没有同时显示多条线路的接口,所以只能借助百度地图的覆盖层来画折线,比较麻烦。于是就用百度地图的API简单实现了一个。

需要在一个新的地方租房子或者买房子的时候,一个重要的考虑因素就是交通是否便利,我在租房子的时候就很想知道从我周边的公交车站,能够不换乘到达哪些地方,我当时有这个需求之后上网搜,并没有找到类似的功能,而且麻烦的是,百度地图最基本的API也没有同时显示多条线路的接口,所以只能借助百度地图的覆盖层来画折线,比较麻烦。于是就用百度地图的API简单实现了一个。效果图如下:

【百度地图】显示从某站点出发的所有公交车路线第1张

在线的演示请点击本链接(在线演示链接已失效,这里下载源码)。简单说一下功能。在左侧指定公交车站名和城市名,点击查询后出现符合搜索条件的地点列表及经过的公交线路(包括地铁)简介,点击某一项之后,右侧地图定位到该公交车站,并以随机的颜色表示经过该公交站的公交线路,点击沿途各站,在弹出窗中显示该站的名字和经过该站的公交车列表。

下面介绍一下我的实现过程,首先是HTML简单的写一下上面的布局(这是最简单的布局,我的演示链接里面用bootstrap美化了一下):

<html>
<head>
    <meta http-equiv="Content-Type"content="text/html; charset=utf-8" />
    <style type="text/css">body, html{width:100%;height:100%;margin:0;font-family:"微软雅黑";}#l-map{height:500px;width:75%;float:left;}
    </style>
    <script type="text/javascript"src="http://api.map.baidu.com/api?v=2.0&ak=在百度开发者中心申请的key"></script>
    <title>公交/地铁线路查询</title>
</head>
<body>
    <div style="float:left;25%;display:inline;">
        <div id="r-query">请输入公交站名,如:“西单”:<br/>
            <input type="text"id="keyword"value="西单"/><br/>请输入城市名,如北京(仅作参考,如搜索泉城广场时,北京没有这个地址,一样会找到济南,但如果北京也有,就不会找济南了):<br/>
            <input type="text"id="location"value="北京"/><button id="query">查询</button>
        </div>
        <div id="l-result"></div>
    </div>
    <div id="l-map"></div>
</body>
</html>

这一步最主要就是要申请一个百度开发者中心的key,申请地址在:http://developer.baidu.com/map/index.php?title=jspopular,通过左侧的“获取密钥”来申请key。

下面是js代码,首先我定义了几个全局变量:

var map = new BMap.Map("l-map");
var busStationIcon = new BMap.Icon("busstation_marker.png", new BMap.Size(10,10));
var busStationHover = new BMap.Icon("busstation_marker_hover.png", new BMap.Size(10,10));
var infoWindow = new BMap.InfoWindow("");
varcurrentLocation;

map.centerAndZoom(new BMap.Point(116.404, 39.915), 15);
map.enableScrollWheelZoom();

var activePolyline;            //hover bus line
var stationList = Array();        //hover bus line stations
var currentPolyline;            //hovered origin line

map是地图对象,当鼠标滑过某条公交线路的时候,该线路变为蓝色,并显示沿途各站,activePolyline就是这条蓝色的折线,处于active状态的线路沿途各站信息存在stationList中,沿途各站平时用busStationIcon标识,鼠标滑过的时候用busStationHover,点击该图标弹出信息窗infoWindow来显示该站的名字和经过它的公交线路。

我没有用其它的js库,就是用原生的js来写的,先来看点击查询按钮后的响应事件:

document.getElementById('query').onclick=function(){
    map.clearOverlays();
    document.getElementById("l-result").innerHTML = "";
    new BMap.LocalSearch(document.getElementById('location').value, {
        onSearchComplete: searchComplete
    }).search(document.getElementById('keyword').value);
};

第一步清空地图上所有的覆盖物,这是考虑到再次点击查询的时候要把前一次地图上的查询结果清除掉,第二步是把显示符合条件站点的面板清空,也就是示例图中的左侧面板清空,第三步就是发起一个LocalSearch请求,第一个参数是搜索范围,也就是范例里的“北京”,第二个option参数里面,指定了结果返回后的回调函数searchComplete:

functionsearchComplete(result) {
    var resultPanel = document.getElementById("l-result");
    for (var i = 0 ; i < result.getCurrentNumPois() ; i++) {
        var poi =result.getPoi(i);
        if (poi.type ==BMAP_POI_TYPE_NORMAL) {
            continue;
        }
        var link = document.createElement('a'); 
        link.setAttribute('href', 'javascript:void(0)');
        link.poi =poi;
        link.onclick=function(){
            map.clearOverlays();
            currentLocation = this.poi.province;
            var marker = new BMap.Marker(this.poi.point);
            map.addOverlay(marker);
            map.panTo(this.poi.point);
            var busNames = this.poi.address.split(';');
            for (i = 0 ; i < busNames.length ; i++) {
                busutil.getBusList(busNames[i]);
            }
        };
        link.innerText = poi.title + " (" + poi.province + "): " + poi.tags + " : " +poi.address;
        resultPanel.appendChild(link);
        resultPanel.appendChild(document.createElement('br'));
    }
}

遍历搜索结果,因为搜西单出来的可能不止一个站,可能还有西单东站西站南站北站,针对每一个符合公交条件的结果项,都创建一个a标签,所为符合条件,是指这个查询结果表示的是一个公交车站或地铁站,如果是普通地点BMAP_POI_TYPE_NORMAL,就不符合条件。给这个a标签一个poi属性,记录自己所表示的位置信息,当这个链接被点击的时候,清空地图的覆盖物,在该车站的位置创建marker,对于公交站或地铁站来说,address属性就是分号分隔的公交车列表,根据这个列表去查询每一条公交线路的信息,最后给这个a标签赋予显示的文字,我这里显示的是地点名称+省份+地点标签+公交信息。

这里比较重要的就是busutil查询公交线路的实现,百度地图的BusLineSearch对象有两个方法,一个叫做getBusList,它的参数是一个公交线名字,比如333路,返回匹配的公交,包括上行下行的等等,另一个方法叫做getBusLine,它的参数是一个BusListItem对象,也就是getBusList结果中的一项,下面看一下这个方法的实现:

var busutil = newBMap.BusLineSearch(map,{
    onGetBusListComplete: function(buslist) {
        busutil.getBusLine(buslist.getBusListItem(0));
    },
    onGetBusLineComplete: function(busline) {
        var color = "#" + Math.floor(Math.random() * 65535 * 256).toString(16);
        var polyline = new BMap.Polyline(busline.getPath(), {strokeColor:color, strokeWeight:5, strokeOpacity:0.7});
        map.addOverlay(polyline);
        if(isMobile()) {
            polyline.addEventListener("click", function(evt){
                showPolyline(evt, polyline, busline);
            });
        } else{
            polyline.addEventListener("mouseover", function(evt){
                showPolyline(evt, polyline, busline);
            });
        }
    }
});

第一个是得到公交列表的回调函数,比如我搜333路,可能得到两个公交,分别是333上行线路和333下行线路,这里直接取列表的第一项去获取线路详情(getBusLine),看到这里可能会有疑问,万一还有个“333路特别线”怎么办,这里说明一下,我这个代码并不严谨,假设所有的搜索都不会有歧义。第二个函数onGetBusLineComplete就是获取到某条线路详情之后的回调方法,首先为这条线随机生成一个颜色(DEMO上代码已经作了修改,RGB三色都在0-127之间抽取,避免浅颜色的线出现),根据线路详情中的公交站点列表创建折线。这里我做了一个判断,如果是非移动设备,当鼠标滑过某一条线路的时候就把那条线路激活,激活状态的线路变蓝,并显示沿途站点。在移动设备上没有鼠标滑过事件,所以用click事件来触发,但是很奇怪,真正在移动设备上看的时候,鼠标点击无效,这个问题我还不知道是为什么,大家如果发现了问题欢迎指正!

关于把鼠标滑过的线路激活该怎么实现,我并没有去修改原来那条折线,而是在那条折线之上覆盖了一个新的:

functionshowPolyline(evt, polyline, busline) {
    if (evt.target ==currentPolyline) {
        return;
    }
    currentPolyline =polyline;
    map.removeOverlay(activePolyline);
    removeCircles();
    activePolyline = new BMap.Polyline(busline.getPath(), {strokeColor:"#3333FF", strokeWeight:5, strokeOpacity:0.9});
    map.addOverlay(activePolyline);
        
    for (var i = 0 ; i < busline.getNumBusStations() ; i++) {
        var busStation =busline.getBusStation(i);
        addCircle(busline, busStation);
    }
}

先判断如果要激活的线路已经是激活状态,那么什么也不做,否则把原来的蓝色线路删除,并根据刚刚被滑过的线路创建新的折线,并把各个站点作为marker添加到激活线路上,怎么添加marker的代码我就不粘贴了,看一下当marker被点击的时候做了什么,我们光知道这里有个站还不够,肯定要知道这是哪一路公交,最好还能知道有没有我熟悉的公交也经过这里:

marker.addEventListener("click", function(){
    infoWindow.setTitle(busStation.name + " (" + busline.name + ")");
    infoWindow.setContent("");
    marker.openInfoWindow(infoWindow);

    newBMap.LocalSearch(currentLocation, {
        onSearchComplete: function(result) {
            varpoi;
            for (var i = 0 ; i < result.getCurrentNumPois() ; i++) {
                poi =result.getPoi(i);
                if (poi.type != BMAP_POI_TYPE_NORMAL && poi.title ==busStation.name) {
                    infoWindow.setContent(poi.address);
                    break;
                }
            }
        }
    }).search(busStation.name);
});

当某一个公交站被点击的时候,先弹出信息窗,把当前激活的是哪一个公交显示出来,同时发起查询请求,查一下还有哪些公交经过这里,这里也是假设结果列表的第一项一定是准确的,也就是假设我搜索“菊园”,第一个结果项肯定是“菊园”而不是“菊园东站”,然后把路过这里的所有公交显示出来。

这样这个功能就完成了,有bug的地方,欢迎大家指正!

免责声明:文章转载自《【百度地图】显示从某站点出发的所有公交车路线》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇转载.怎样在Quartus II中转化HDL文件为bsf文件?NumPy之:ndarray多维数组操作下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

Vue --》 如何在vue中调用百度地图

1.项目根目录下下载百度地图插件 npm install vue-baidu-map –save 2.在首页index.html中引入百度地图: <script type="text/javascript" src="http://api.map.baidu.com/api?v=2.0&ak=秘钥"></script> 我...

百度地图 api bug 解决.......

百度地图 遇到了一个默明奇妙的bug.....  调用后中心点 不再 point(标注的点上...)这是需要执行一次(仅一次) 当 地图 加载完后 执行(这个方法你每次改地图 都会执行...所以让他执行一次......因为这个问题只会在 首次出现...) //百度地图的 js .... var userLocation = {la: 0, lg...

如何用Apache POI操作Excel文件-----如何对一个单元格加注解?

有的时候,我们需要通过操作Apache POI,在生成Cell数据的同时,能对其生成的Cell,加上注解(comments),类似于下面的。 那么对于这种情况,我们的代码应该如何写呢? 借花献佛,我就用Apache POI官方提供的例子,然后加上一些注解,给大家看一下。本例子的测试代码是基于POI-3.12的。 执行完后,将会生成上图所示的Excel工作...

百度地图JavaScript API获取用户当前经纬度和详细地理位置,反之通过详细地理位置获取当前经纬度

本文并非原创,原创地址为:https://www.cnblogs.com/Can-daydayup/p/10941470.html 前言:   前段时间刚好使用了百度地图的js api定位获取用户当前经纬度并获取当前详细位置和通过当前用户详细地理位置换取用户当前经纬度坐标的功能,为了方便下次找起来方便一些自己在这里记录一下,希望也能够帮助到有需要的童鞋们!...

Mapbox Style 规范

Mapbox ( 中文官网 )致力于打造全球最漂亮的个性化地图。 这里记录下其 Web 端 API Mapbox GL JS 的地图样式规范 Style 的各个配置项: 必填项会加上 * ,方便根据目录进行查看 1. version * version:版本号(必填,且值必须为 8) "version": 8 2. name name:名称(可选,用于给...

高德地图在h5项目中的集成(点标记)

关于高德地图在项目中的集成,网上已经有很多相关的很优秀的文章了,故本篇内容仅用于参考和巩固。 1.使用高德地图之前需要在高德开放平台(https://lbs.amap.com/dev/index)创建一个key 有这个key之后就可以进行开发了。 2.在项目中引入外部文件,将链接中的key替换自己的key就可以了 3.在文件中添加div标签座位容器,添...