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

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

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

下面介绍一下我的实现过程,首先是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;width: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("");
var currentLocation;

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:

function searchComplete(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 = new BMap.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就是获取到某条线路详情之后的回调方法,首先为这条线随机生成一个颜色(这里也不完善,可能会出现颜色很浅的线),根据线路详情中的公交站点列表创建折线。这里我做了一个判断,如果是非移动设备,当鼠标滑过某一条线路的时候就把那条线路激活,激活状态的线路变蓝,并显示沿途站点。在移动设备上没有鼠标滑过事件,所以用click事件来触发,但是很奇怪,真正在移动设备上看的时候,鼠标点击无效,这个问题我还不知道是为什么,大家如果发现了问题欢迎指正!

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

function showPolyline(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);

    new BMap.LocalSearch(currentLocation, {
        onSearchComplete: function(result) {
            var poi;
            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的地方,欢迎大家指正!

时间: 2024-10-14 20:17:46

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

百度地图输入一个位置到另一个位置的路线

1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> 5 <title>驾车途经点</title> 6 <script src="http://libs.baidu.com/jquery/2.0.0/jquery.min

百度地图API显示多个标注点,解决提示信息问题以及给标注增加地图旁的文字连接提示的另一种解决办法

原文:百度地图API显示多个标注点,解决提示信息问题以及给标注增加地图旁的文字连接提示的另一种解决办法 公司的网站改版要求在一个页面显示百度地图.上面要同时显示很多标注点,标注点当然要有提示信息嘛,提示信息也当然要不一样嘛,因为给标注绑定的鼠标事件当你移动鼠标上去的其实循环值已经是最后值了,所以无论你怎么做,所有的标注点都是同一个提示,就是最后的那个提示.我就打开百度找方案嘛.一找之下,搜了几十页就一个解决方案,大家都是你拷贝我的我拷贝你的.做个闭包.把循环的值锁定在里面.代码照着做,也的确可以

Android 百度地图开发(一)--- 申请API Key和在项目中显示百度地图

标签: Android百度地图API Key  分类: Android 百度地图开发(2)  最近自己想研究下地图,本来想研究google Map,但是申请API key比较坑爹,于是从百度地图入手,其实他们的用法都差不多,本篇文章就带领大家在自己的Android项目中加入百度地图的功能,接下来我会写一系列关于百度地图的文章,欢迎大家到时候关注!   一 申请API key 在使用百度地图之前,我们必须去申请一个百度地图的API key,申请地址http://lbsyun.baidu.com/a

js 调用百度地图,并且定位用户地址,显示省市区街,经纬度

网上的一些百度地图例子,基本上没有连套的 定位 例子.下面我分享一套我自己弄的,废话不多说,看代码,里面有注释! 1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta name="viewport" content="initial-scale=1.0, user-scalable=no" /> 5 <meta http-equiv="Content-Type"

百度地图的使用之获取数据库表中信息的坐标点显示在地图上

//通用封装好的js: var map = new BMap.Map("container"); //建树Map实例 var point = new BMap.Point(103.976032, 33.845509); // 建树点坐标 map.centerAndZoom(point, 6); // 初始化地图,设置中心点坐标和地图级别. //地图事件设置函数: map.enableDragging(); //启用地图拖拽事件,默认启用(可不写) map.enableScrollWhe

通过百度地图API显示当前位置在地图上(图标显示)--第三方开源--百度地图(二)

1.下载百度地图的demo,下载地址:http://lbsyun.baidu.com/sdk/download?selected=mapsdk_basicmap,mapsdk_searchfunction,mapsdk_lbscloudsearch,mapsdk_calculationtool,mapsdk_radar 2.把demo里面的BaiduMapsApiDemo解压,把BaiduMapsApiDemo文件夹里面的libs里面的所有文件都复制到自己的项目的libs里面 3.配置Andro

Android 百度地图只显示 网格?

最近写百度地图,显示的 时候 只显示 我那个不显示具体的数据? 这是为什么呢? 原来是因为:  自己的Key错了. Key 是唯一的: 之前的 Key : 是  MD5 :包名 这是错误的格式! Key : 应该是  SHA1 ; 包名: 解决方案: 创新建一个 APP .重新设置 Key!

百度地图开发,标记只能显示在北京地图上T_T

============问题描述============ public class MainActivity extends Activity {       MapView mMapView = null;       BaiduMap mBaiduMap; // UI相关 Button resetBtn; Button clearBtn;     @Override       protected void onCreate(Bundle savedInstanceState) {     

C#显示百度地图API

http://dev.baidu.com/wiki/static/map/API/examples/?v=1.3&2_0#2&0 太原市的经纬度:112.596, 37.884 北京市的经纬度:116.404, 39.915 // JScript 文件代码示例http://dev.baidu.com/wiki/static/map/API/examples/?v=1.3&7_8#7&8 /************************地图初始化时,添加了十个自定义标注图标