最近做一個公司內部的班車項目,要求實時獲取班車的位置,一開始想法就是每隔5s獲取班車位置,然後更新班車marker的座標,做完之後發現,這個班車在地圖上是跳動的,需求部門說班車在瞬移~~~^_^~~~,要做連續的運動,就需要讓班車在這兩點直接做運動效果。縮短請求的間隔時間,很明顯不合理。那就去官方文檔找相應的marker運動api。找了一通。目前貌似沒有直接這樣的方法,面向百度編程的思路,又怎能難倒一個程序員呢
廢話不多數,就總結一下網上查到的解決方案。做一個簡單的demo
1.獲取地圖上的兩個點(開始位置,結束位置)
2.講兩個點轉化成平面座標系的點(地圖上的是球座標系點)
3.運用數學只是在兩點間的直線上畫若干個等距離小點,獲取他們的點座標
4.轉換成地圖座標,隔100毫秒設置新的marker位置
以下就是我的一個測試demo,一步步來講解一下
第一步,生成地圖創建兩點,一個代表起點,一個代表終點,爲了只管直接兩個點都在座標地圖上標記出來
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
<style type="text/css">
body, html,#allmap {width: 100%;height: 100%;overflow: hidden;margin:0;font-family:"微軟雅黑";}
</style>
<script type="text/javascript" src="http://api.map.baidu.com/api?v=2.0&ak=1PrtI9ftPfLUXbTNCFSL3hOQ6hHmV1R6"></script>
<title>設置點的新圖標</title>
</head>
<body>
<div id="allmap"></div>
</body>
</html>
<script type="text/javascript">
// 百度地圖API功能
var map = new BMap.Map("allmap");
var point = new BMap.Point(116.404, 39.915);
map.centerAndZoom(point, 13);
map.addControl(new BMap.NavigationControl());
var pointstart = new BMap.Point(116.417, 39.909);
var pointend = new BMap.Point(116.427, 39.919);
var markerstart = new BMap.Marker(pointstart); // 創建標註
var markerend = new BMap.Marker(pointend); // 創建標註
map.addOverlay(markerstart); // 將標註添加到地圖中
map.addOverlay(markerend); // 將標註添加到地圖中
</script>
直接複製實現以下效果
第二步:根據這兩個點的的球座標獲取平面座標
調用百度地圖 map.getMapType().getProjection().lngLatToPoint(point) 方法
_startPoint = map.getMapType().getProjection().lngLatToPoint(pointstart);
_endPoint = map.getMapType().getProjection().lngLatToPoint(pointend);
console.log(_startPoint);
console.log(_endPoint);
打印兩個點的平面座標如下
第三部:獲取平面上兩個點之間的若干個點的座標
以50個爲例,間隔相等,咱們分別算一下x和y的位置就可以 用x1+((x2-x1)/50)m m就是第幾個點
//xoy1 x1 或者y1, xoy2 x2或者y2 ,num 分割多少個點,m 第幾個點
function getpointitem(xoy1,xoy2,num,m) {
return (xoy2-xoy1)/num*m +xoy1
}
var num = 50;
var points = [];
for (var i=0;i<num;i++){
var x = getpointitem(_startPoint.x,_endPoint.x,num,i);
var y = getpointitem(_startPoint.y,_endPoint.y,num,i);
points.push({x:x,y:y});
}
console.log(points);
得到如下的點集合
第四部轉換成地圖座標 每100毫秒更新一個點位置;
轉換地理座標調用百度地圖的map.getMapType().getProjection().pointToLngLat(new BMap.Pixel(x, y));方法
更新marker位置調用marker.setPosition(point);方法
因爲裏面需要用的 間時函數,注意for循環聲明的 var i 會指向循環的最後一個,還是用一個全局的flag來進行計數
movepoint(_startPoint,_endPoint,markerstart,100,50);
// statpoint,開始點
// endpoint,結束點
// marker, 移動的marker
// timer, 間隔時間
// count 計數點
function movepoint(statpoint,endpoint,marker,timer,count) {
var currentCount = 0;
//兩點之間勻速移動
var intervalFlag = setInterval(function() {
//兩點之間當前幀數大於總幀數的時候,則說明已經完成移動
if (currentCount >= count) {
clearInterval(intervalFlag);
} else {
//動畫移動
currentCount++;//計數
var x = getpointitem(statpoint.x, endpoint.x, count, currentCount);
var y = getpointitem(statpoint.y, endpoint.y, count, currentCount);
//根據平面座標轉化爲球面座標
var pos = map.getMapType().getProjection().pointToLngLat(new BMap.Pixel(x, y));
console.log(pos)
//更新座標點
marker.setPosition(pos);
}
}, timer);
}
整體效果如下:
整體代碼如下複製即可使用
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
<style type="text/css">
body, html,#allmap {width: 100%;height: 100%;overflow: hidden;margin:0;font-family:"微軟雅黑";}
</style>
<script type="text/javascript" src="http://api.map.baidu.com/api?v=2.0&ak=1PrtI9ftPfLUXbTNCFSL3hOQ6hHmV1R6"></script>
<title>設置點的新圖標</title>
</head>
<body>
<div id="allmap"></div>
</body>
</html>
<script type="text/javascript">
// 百度地圖API功能
var map = new BMap.Map("allmap");
var point = new BMap.Point(116.404, 39.915);
map.centerAndZoom(point, 13);
map.addControl(new BMap.NavigationControl());
var pointstart = new BMap.Point(116.417, 39.909);
var pointend = new BMap.Point(116.427, 39.919);
var markerstart = new BMap.Marker(pointstart); // 創建標註
var markerend = new BMap.Marker(pointend); // 創建標註
map.addOverlay(markerstart); // 將標註添加到地圖中
map.addOverlay(markerend); // 將標註添加到地圖中
_startPoint = map.getMapType().getProjection().lngLatToPoint(pointstart);
_endPoint = map.getMapType().getProjection().lngLatToPoint(pointend);
console.log(_startPoint);
console.log(_endPoint);
//xoy1 x1 或者y1, xoy2 x2或者y2 ,num 分割多少個點,m 第幾個點
function getpointitem(xoy1,xoy2,num,m) {
return (xoy2-xoy1)/num*m +xoy1
}
movepoint(_startPoint,_endPoint,markerstart,100,50);
// statpoint,開始點
// endpoint,結束點
// marker, 移動的marker
// timer, 間隔時間
// count 計數點
function movepoint(statpoint,endpoint,marker,timer,count) {
var currentCount = 0;
//兩點之間勻速移動
var intervalFlag = setInterval(function() {
//兩點之間當前幀數大於總幀數的時候,則說明已經完成移動
if (currentCount >= count) {
clearInterval(intervalFlag);
} else {
//動畫移動
currentCount++;//計數
var x = getpointitem(statpoint.x, endpoint.x, count, currentCount);
var y = getpointitem(statpoint.y, endpoint.y, count, currentCount);
//根據平面座標轉化爲球面座標
var pos = map.getMapType().getProjection().pointToLngLat(new BMap.Pixel(x, y));
console.log(pos)
//更新座標點
marker.setPosition(pos);
}
}, timer);
}
</script>