原文地址: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(起点或终点自己就为公交站的时候)。若是有换乘,那么每次换乘中的下车站到上车站也有步行线路(如上图的第二个方案所示)。
因此不论公交方案具体是什么样,在数据上的表示都是一致的:
以此类推。
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中还提供了以下几个回调函数,它们的含义和触发时机以下: