百度地图API-项目总结
1.开始
在开始调用百度地图api之前,请先注册百度账号并获取密钥,之后便可借该密钥使用相关服务功能,详情参考官方文档:http://lbsyun.baidu.com/index.php?title=jspopularGL/guide/getkey
2.项目介绍
在“智慧公交”项目中,通过调用百度地图api主要实现了以下需求:
2.1 附近公交页面
- 地图创建
- 根据后端接口传来的位置信息 实现自定义公交标注的实时移动
- 个性化地图
- 绘制公交行驶轨迹
2.2 实时公交页面
- 地图创建
- 根据城市名和公交编号查看公交实时位置、首末车时间以及沿线公交站点
- 点击公交标注,打开信息窗口查看公交状态信息(车内人数等)
2.3 代码
-
附近公交页面
<!DOCTYPE html> <html lang="en"> <head> <!--适应移动端页面展示--> <meta name="viewport" content="initial-scale=1.0, user-scalable=no" /> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>BaiduMap</title> <!--设置容器样式大小,使地图充满整个浏览器窗口--> <style type="text/css"> html{height:100%} body{height:100%;margin:0px;padding:0px} #container{height:100%} </style> <!--引用百度地图API文件--> <script type="text/javascript" src="//api.map.baidu.com/api?v=2.0&ak=请在这里填入您的密钥"></script> <script type="text/javascript" src="https://api.map.baidu.com/api?v=1.0&type=webgl&ak=请在这里填入您的密钥"></script> <!-- 引入axios --> <script crossorigin="anonymous" src="https://cdn.bootcdn.net/ajax/libs/axios/0.21.0/axios.js"></script> <!-- 需求: 1.要坐标转换后的标注点 2.要行驶轨迹 --> </head> <body> <!--创建地图容器元素--> <div id="container"></div> <script type="text/javascript"> // 创建地图实例,其参数可以是元素id也可以是元素对象。 var map = new BMapGL.Map("container"); // 设置中心点坐标,(百度BD09坐标),这里我们使用BMapGL命名空间下的Point类来创建一个坐标点。Point类描述了一个地理坐标点, var currentLongitude,currentlatitude; currentLongitude=113.51589; currentlatitude=34.817217; var point = new BMapGL.Point(currentLongitude,currentlatitude); // 初始化地图,设置中心点坐标和地图级别,地图必须经过初始化才可以执行其他操作 map.centerAndZoom(point, 15); // 创建小车图标 var myIcon = new BMapGL.Icon("img/bus.png", new BMapGL.Size(40, 40)); var last_point; var marker=new BMapGL.Marker(point, { icon: myIcon, rotation:90, title: '11111' }); map.addOverlay(marker); //自定义轨迹绘制函数 function draw_trail(lon,lat){ var t = new BMap.Point(lon,lat); //清除原有标注 var allOverlay=map.getOverlays(); for(var i=0;i<allOverlay.length;i++){ //console.log(allOverlay[i].toString()); if(allOverlay[i].toString()==="Marker"){ map.removeOverlay(allOverlay[i]); } } //创建新的标注 var marker = new BMapGL.Marker(t, { icon: myIcon }); // 将标注添加到地图中 map.addOverlay(marker); console.log('last_point='); console.log(last_point); console.log('t='); console.log(t); //创建折线 var polyline = new BMap.Polyline([ last_point, t ], {strokeColor:"blue", strokeWeight:2, strokeOpacity:0.5}); polyline.disableMassClear(); //将折线添加到地图中 map.addOverlay(polyline); last_point = t; } //每隔1秒执行一次getTrail函数, setInterval("getTrail()",1000); function getTrail(){ //进行ajax请求,从后端获取公交车最新的经纬度及公交信息,进行坐标转换后,调用自定义轨迹绘制函数并将转换后的坐标的经度和纬度作为参数传给该函数,清除原有标注,添加新的标注,将每次获取的坐标与上一次的坐标连线绘制成轨迹 axios.get('http://localhost:9999/index/getPosition') .then(function(res){ var busList=res.data; //定义信息窗口 var opts = { width : 250, // 信息窗口宽度 height: 100, // 信息窗口高度 title : "公交信息:" // 信息窗口标题 } // 创建Marker标注,使用小车图标 for(var i=0;i<busList.length;i++){ //定义传来的原始坐标点pt var pt = new BMapGL.Point(busList[i].longitude,busList[i].latitude); //定义传来的信息窗口信息 var content = busList[i].info; //坐标转换 //坐标转换完之后的回调函数,在该函数中进行调用轨迹绘制函数 translateCallback = function (data){ if(data.status === 0) { //调用轨迹绘制函数,并将最新坐标转换后的坐标作为参数传给该函数,进行与上次坐标的连线,绘制出轨迹 draw_trail(data.points[0].lng,data.points[0].lat); } } setTimeout(function(){ var pt = new BMapGL.Point(busList[0].longitude,busList[0].latitude); var convertor = new BMap.Convertor(); var pointArr = []; pointArr.push(pt); convertor.translate(pointArr, 1, 5, translateCallback) }, 1000); } //公交标注信息窗口点击事件 function addClickHandler(content,marker){ marker.addEventListener("click",function(e){ openInfo(content,e)} ); } function openInfo(content,e){ var p = e.target; var point = new BMapGL.Point(p.getPosition().lng, p.getPosition().lat); var infoWindow = new BMapGL.InfoWindow(content,opts); // 创建信息窗口对象 map.openInfoWindow(infoWindow,point); //开启信息窗口 } }) } map.enableScrollWheelZoom(true); //开启鼠标滚轮缩放 // map.setHeading(64.5); //设置地图旋转角度 // map.setTilt(73); //设置地图的倾斜角度 var scaleCtrl = new BMapGL.ScaleControl(); // 添加比例尺控件 map.addControl(scaleCtrl); var zoomCtrl = new BMapGL.ZoomControl(); // 添加缩放控件 map.addControl(zoomCtrl); //自定义的地图样式 map.setMapStyleV2({ styleId: '956d45924c795423b3377be09f67aca8' }); </script> </body> </html>
-
实时公交页面
<!DOCTYPE html> <html> <head> <!--适应移动端页面展示--> <meta name="viewport" content="initial-scale=1.0, user-scalable=no" /> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>附近公交</title> <!--设置容器样式大小,使地图充满整个浏览器窗口--> <style type="text/css"> html{height:100%} body{height:100%;margin:0px;padding:0px} #container{height:100%} #r-result { position: fixed; top: 10px; right: 10px; z-index: 99; width: 250px; height: 450px; overflow-y: auto; background: #fff; box-shadow: 0 2px 6px 0 rgba(27, 142, 236, 0.5); border-radius: 7px; } #result{ padding: 7px 10px; position: fixed; top: 10px; left: 20px; width: 300px; background: #fff; box-shadow: 0 2px 6px 0 rgba(27, 142, 236, 0.5); border-radius: 7px; z-index: 99; } #cityName{ width:170px; margin-right:10px; height:25px; border: 1px solid rgba(27, 142, 236, 0.5); border-radius: 5px; } #result button{ border: 1px solid rgba(27, 142, 236, 0.5); border-radius: 5px; background: rgba(27, 142, 236, 0.5); color: #fff } #busName{ width:170px; margin-right:10px; height:25px; border: 1px solid rgba(27, 142, 236, 0.5); border-radius: 5px; } </style> <!--引用百度地图API文件--> <script type="text/javascript" src="https://api.map.baidu.com/api?v=2.0&ak=请在这里填入您的密钥"></script> <script type="text/javascript" src="https://api.map.baidu.com/api?v=1.0&type=webgl&ak=请在这里填入您的密钥"></script> <script crossorigin="anonymous" src="https://cdn.bootcdn.net/ajax/libs/axios/0.21.0/axios.js"></script> <script src="//libs.baidu.com/jquery/1.9.0/jquery.js"></script> <!-- 需求: 1.定位到当前城市(当前位置)(结果:浏览器定位定位当前位置不精确(定到了市中心),暂用查询城市) 2.通过查询城市和公交编号显示公交路线 3.获取公交位置,并在该位置添加公交标注点(需坐标转换) 4.Ajax轮询获取最新经纬度,经坐标转换后,将标注添加到地图中,并实现公交实时位置移动,不需要轨迹 --> </head> <body> <!--创建地图容器元素--> <div id="container"></div> <div id='r-result'></div> <div id='result'> 城市名: <input id="cityName" type="text"/><br/> 公交名: <input id="busName" type="text"/> <button onclick="theLocation()"/>查询</button> </div> <script type="text/javascript"> // 创建地图实例,其参数可以是元素id也可以是元素对象。 var map = new BMapGL.Map("container"); // 设置中心点坐标,(百度BD09坐标),这里我们使用BMapGL命名空间下的Point类来创建一个坐标点。Point类描述了一个地理坐标点, var currentLongitude,currentlatitude; currentLongitude=116.331398; currentlatitude=39.897445; var point = new BMapGL.Point(currentLongitude,currentlatitude); // 初始化地图,设置中心点坐标和地图级别,地图必须经过初始化才可以执行其他操作 map.centerAndZoom(point, 11); //城市定位 function theLocation(){ var city = document.getElementById("cityName").value; var bus = document.getElementById("busName").value; if(city != ""){ map.centerAndZoom(city,11); // 用城市名设置地图中心点 var busName = bus; busline.getBusList(busName); } } //公交查询 var busline = new BMapGL.BusLineSearch(map,{ renderOptions:{map:map,panel:"r-result"}, onGetBusListComplete: function(result){ if(result) { var fstLine = result.getBusListItem(0);//获取第一个公交列表显示到map上 busline.getBusLine(fstLine); } } }); function busSearch(){ var bus = document.getElementById("busName").value; var busName = bus; busline.getBusList(busName); } setTimeout(function(){ busSearch(); },1500); //每隔1秒执行一次getLoc函数, setInterval("getLoc()",1000); function getLoc(){ //进行ajax请求,从后端获取公交车经纬度及公交信息,将经纬度进行转换为百度坐标,添加标注 axios.get('http://localhost:9999/index/getPosition') .then(function(res){ var busList=res.data; // 创建小车图标 var myIcon = new BMapGL.Icon("img/bus.png", new BMapGL.Size(40, 40)); //创建信息窗口 var opts = { width : 250, // 信息窗口宽度 height: 100, // 信息窗口高度 title : "公交信息:" // 信息窗口标题 } // 创建Marker标注,使用小车图标 for(var i=0;i<busList.length;i++){ //定义传来的原始坐标点pt var pt = new BMapGL.Point(busList[i].longitude,busList[i].latitude); //定义传来的信息窗口信息 var content = busList[i].info; //坐标转换 //坐标转换完之后的回调函数 translateCallback = function (data){ if(data.status === 0) { // map.setCenter(data.points[0]); //清除原有标注 var allOverlay=map.getOverlays(); for(var i=0;i<allOverlay.length;i++){ if(allOverlay[i].toString()==="Marker"){ map.removeOverlay(allOverlay[i]); } } //创建新的标注 var marker = new BMapGL.Marker(data.points[0], { icon: myIcon }); //给标注添加信息窗口 addClickHandler(content,marker); //将标注添加到地图中 map.addOverlay(marker); } } setTimeout(function(){ var pt = new BMapGL.Point(busList[0].longitude,busList[0].latitude);//? var convertor = new BMap.Convertor(); var pointArr = []; pointArr.push(pt); convertor.translate(pointArr, 1, 5, translateCallback) }, 1000); } function addClickHandler(content,marker){ marker.addEventListener("click",function(e){ openInfo(content,e)} ); } function openInfo(content,e){ var p = e.target; var point = new BMapGL.Point(p.getPosition().lng, p.getPosition().lat); var infoWindow = new BMapGL.InfoWindow(content,opts); // 创建信息窗口对象 map.openInfoWindow(infoWindow,point); //开启信息窗口 } }) } map.enableScrollWheelZoom(true); //开启鼠标滚轮缩放 // map.setHeading(64.5); //设置地图旋转角度 // map.setTilt(73); //设置地图的倾斜角度 var scaleCtrl = new BMapGL.ScaleControl(); // 添加比例尺控件 map.addControl(scaleCtrl); var zoomCtrl = new BMapGL.ZoomControl(); // 添加缩放控件 map.addControl(zoomCtrl); //自定义的地图样式 map.setMapStyleV2({ styleId: '956d45924c795423b3377be09f67aca8' }); </script> </body> </html>
3.问题记录
3.1 坐标转换
问题:直接使用从后台传来的经纬度信息,在百度地图上定位有偏差
原因:后台定位模块坐标(WGS84,一种大地坐标系)与百度地图坐标(BD09,百度坐标系)不一致
解决:需进行坐标转换(单个原始坐标转换成百度坐标)
示例代码:
//GPS坐标
var x = 116.32715863448607;
var y = 39.990912172420714;
var ggPoint = new BMap.Point(x,y);
//地图初始化
var bm = new BMap.Map("allmap");
bm.centerAndZoom(ggPoint, 15);
//这里是坐标转换完之后的回调函数
translateCallback = function (data){
if(data.status === 0) {
var marker = new BMap.Marker(data.points[0]);
bm.addOverlay(marker);
bm.setCenter(data.points[0]);//将转换后的点设置为新的中心点
}
}
setTimeout(function(){
var convertor = new BMap.Convertor();
var pointArr = [];
pointArr.push(ggPoint);
convertor.translate(pointArr, 1, 5, translateCallback)
}, 1000);
3.2 Ajax轮询请求
需求:为实现获取实时经纬度等信息,需要隔一定时间向后台做一次数据请求
方案:利用setInterval(“fun()”,时间间隔ms)计时器,实现定时执行函数fun(),并在该函数中进行ajax请求
示例代码:
//每隔1秒执行一次getLoc函数,
setInterval("getLoc()",1000);
function getLoc(){
//进行ajax请求
axios.get('接口地址')
.then(function(res){
//balabala
}
}
3.3 标注点实时移动(清除上一个标注)
思路:实时获取后台公交经纬度信息,经坐标转换之后,清除上一个标注,创建新的标注并添加到地图中
问题:在实现公交标注实时移动的过程中,上一个公交标注无法清除
背景:尝试了以下几种方法,均无效
var marker = new BMap.Marker(...);
//方法1
map.removeOverlay(marker);
//方法2
marker.remove();
//方法3
marker.enableMassClear(); 表示允许覆盖物在map.clearOverlays方法中被清除
map.clearOverlays(); 表示清除所有覆盖物
解决:遍历地图上所有覆盖物并保存,在其中查询名为“Marker”(名称根据控制台打印获得,可能不一样)的覆盖物,找到之后用removeOverlay()方法清除
//获取地图上所有的覆盖物
var allOverlay = map.getOverlays();
for(var i = 0;i<allOverlay.length;i++) {
if(allOverlay[i].toString()=="Marker"){
map.removeOverlay(allOverlay[i]);
}
}
3.4 轨迹绘制
说明:思路已有,网上有类似轨迹绘制成功前例,自定义经纬度信息时 可成功实现轨迹的绘制,但在该项目中未成功实现,尝试多种方法仍未找到错误原因
需求:在附近公交页面实现公交标注的实时移动,并绘制其行驶轨迹路线
思路:通过ajax请求,从后端获取公交车最新的经纬度及公交信息,进行坐标转换后,调用自定义轨迹绘制函数并将转换后的坐标的经度和纬度作为参数传给该函数,清除原有标注,添加新的标注,将每次获取的坐标与上一次的坐标连线绘制成轨迹
代码:
//自定义轨迹绘制函数
function draw_trail(lon,lat){
var t = new BMap.Point(lon,lat);
//清除原有标注
var allOverlay=map.getOverlays();
for(var i=0;i<allOverlay.length;i++){
//console.log(allOverlay[i].toString());
if(allOverlay[i].toString()==="Marker"){
map.removeOverlay(allOverlay[i]);
}
}
//创建新的标注
var marker = new BMapGL.Marker(t, {
icon: myIcon
});
// 将标注添加到地图中
map.addOverlay(marker);
console.log('last_point=');
console.log(last_point);
console.log('t=');
console.log(t);
//创建折线
var polyline = new BMap.Polyline([
last_point,
t
], {strokeColor:"blue", strokeWeight:2, strokeOpacity:0.5});
polyline.disableMassClear();
//将折线添加到地图中
map.addOverlay(polyline);
last_point = t;
}
//每隔1秒执行一次getTrail函数,
setInterval("getTrail()",1000);
function getTrail(){
//进行ajax请求
axios.get('http://localhost:9999/index/getPosition')
.then(function(res){
var busList=res.data;
//信息窗口
var opts = {
width : 250, // 信息窗口宽度
height: 100, // 信息窗口高度
title : "公交信息:" // 信息窗口标题
}
// 创建Marker标注,使用小车图标
for(var i=0;i<busList.length;i++){
//定义传来的原始坐标点pt
var pt = new BMapGL.Point(busList[i].longitude,busList[i].latitude);
//定义传来的信息窗口信息
var content = busList[i].info;
//坐标转换
//坐标转换完之后的回调函数,在该函数中进行调用轨迹绘制函数
translateCallback = function (data){
if(data.status === 0) {
draw_trail(data.points[0].lng,data.points[0].lat);
}
}
setTimeout(function(){
var pt = new BMapGL.Point(busList[0].longitude,busList[0].latitude);
var convertor = new BMap.Convertor();
var pointArr = [];
pointArr.push(pt);
convertor.translate(pointArr, 1, 5, translateCallback)
}, 1000);
}
function addClickHandler(content,marker){
marker.addEventListener("click",function(e){
openInfo(content,e)}
);
}
function openInfo(content,e){
var p = e.target;
var point = new BMapGL.Point(p.getPosition().lng, p.getPosition().lat);
var infoWindow = new BMapGL.InfoWindow(content,opts); // 创建信息窗口对象
map.openInfoWindow(infoWindow,point); //开启信息窗口
}
})
}
4.另外
4.1 版本问题
Bmap 和 BMapGL,,版本的不同,而所给示例中适用的版本也不同,需要时可都引入(经验之谈,不知道是不是这个原因,网上也未找到相关解释,但此法可解决问题)
Bmap:<script type="text/javascript" src="//api.map.baidu.com/api?v=2.0&ak=您的密钥"></script>
BMapGL:<script type="text/javascript" src="//api.map.baidu.com/api?type=webgl&v=1.0&ak=您的密钥"></script>
4.2 百度地图生成器
作用:可直接生成简单的百度地图api的调用代码,或查询某地经纬度等信息,或体验相关内容
地址:http://api.map.baidu.com/lbsapi/creatmap/index.html
另外:自动生成的代码插入网页后,可能存在标注图标不显示的问题。经过查阅资料,好多人说这是百度图库存在问题。解决:只需要改变代码中标注图标的图片路径 就可以了。
var icon = new BMap.Icon("http://map.baidu.com/image/us_mk_icon.png",)
4.3 官网
更多内容请自行参考百度地图api官方开发文档
http://lbsyun.baidu.com/index.php?title=jspopularGL