示例的实现使用了两个文件,一个是百度地图的api,一个是百度的弧线类开源库CurveLine.js。
从百度的弧线类库-BMapLib.CurveLine类参考可以发现,文件只提供了一个实现弧线的实例化类BMapLib.CurveLine(Array, opts)
,但是CurveLine.js文件的代码中是有根据两个点,获取两个点所形成的弧线上的所有点的数组方法的function getCurveByTwoPoints(obj1, obj2)
,直接把它拷贝过来。
<!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" />
<title>百度地图弧线轨迹图</title>
<script type="text/javascript" src="http://api.map.baidu.com/api?v=2.0&ak=你的api密钥"></script>
<script type="text/javascript" src="CurveLine.js"></script>
<script type="text/javascript" src="CurveLinePatch.js"></script>
<style type="text/css">
html,body{
width:100%;
height:100%;
margin:0;
overflow:hidden;
font-family:"微软雅黑";
}
</style>
</head>
<body>
<div style="width:100%;height:100%;border:1px solid gray" id="container"></div>
</body>
</html>
<script type="text/javascript">
// 百度地图初始化,定义变量
var map = new BMap.Map("container");
map.centerAndZoom(new BMap.Point(118.454, 32.955), 6);
map.enableScrollWheelZoom();
var curve;//一条弧线
var trainIcon = new BMap.Icon("icon30-train-left.png", new BMap.Size(30,30));//火车图标
var trainMark; // 火车标注
var vectorBOArrow;//箭头图标
var moveInterval;//定时移动
var clearFlag = false;
var count = 0;//当前箭头运动的位置点
var totalPoint;//弧线上所有点的数量
var pointArray;//两个点确定的弧线上的所有点的数组
var startPointX = 116.432045;
var startPointY = 39.910683;
var endPointX = 120.129721;
var endPointY = 30.314429;
var pointA = new BMap.Point(startPointX,startPointY); // 创建点坐标A
var pointB = new BMap.Point(endPointX,endPointY); // 创建点坐标B
var trainPointArray =[];
trainPointArray.push(pointA);
trainPointArray.push(pointB);
function getRandomTwoPoints(){
var twoArray = [];
twoArray.push(pointA);
twoArray.push(pointB);
return twoArray;
}
/*为指定数组中的点更改图标为小火车*/
function batchAddTrainIcon(arr){
if(arr!=null && arr.length>0){
arr.forEach(function(value, index){
var trainMark = new BMap.Marker(value,{icon:trainIcon});
map.addOverlay(trainMark);// 将标注添加到地图中
//监听标注点击事件
trainMark.addEventListener("click", function(e){
console.log(e.target.getPosition().lng);
console.log(e.target.getPosition().lat);
if(clearFlag){
clearFlag = false;
drawCurveLine(getRandomTwoPoints());
initLineMap();
}else{
clearFlag = true;
clearInterval(moveInterval);
map.removeOverlay(curve);
map.removeOverlay(vectorBOArrow);
}
});
});
}
}
/*根据两个点画弧线*/
function drawCurveLine(twoPoints){
curve = new BMapLib.CurveLine(twoPoints, {strokeColor:"blue", strokeWeight:3, strokeOpacity:0.5}); //创建弧线对象
map.addOverlay(curve); //添加到地图中
}
/*初始化弧线轨迹图*/
function initLineMap(){
totalPoint = getCurveByTwoPoints(pointA,pointB).length;
pointArray = getCurveByTwoPoints(pointA,pointB);
count = 0;
vectorBOArrow = new BMap.Marker(pointArray[count], {
// 初始化方向向上的开放式箭头
icon: new BMap.Symbol(BMap_Symbol_SHAPE_FORWARD_CLOSED_ARROW, {
scale: 1,
strokeWeight: 1,
rotation: 180,
fillColor: 'gold',
fillOpacity: 0.8
})
}); // 创建箭头标注
map.addOverlay(vectorBOArrow);// 将箭头标注添加到地图中
moveInterval = setInterval(goWay,500);
}
/*让箭头移动*/
function goWay(){
map.removeOverlay(vectorBOArrow);
count = count+1;
if(count < totalPoint){
vectorBOArrow = new BMap.Marker(pointArray[count], {
// 初始化方向向上的开放式箭头
icon: new BMap.Symbol(BMap_Symbol_SHAPE_FORWARD_CLOSED_ARROW, {
scale: 1,
strokeWeight: 1,
rotation: 180,
fillColor: 'gold',
fillOpacity: 0.8
})
}); // 创建标注
map.addOverlay(vectorBOArrow);// 将标注添加到地图中
}
if(count >=totalPoint){
count =0;
}
}
batchAddTrainIcon(trainPointArray);
drawCurveLine(getRandomTwoPoints());
initLineMap();
</script>
CurveLinePatch.js文件
/*根据两个点,获取这两个点所形成的弧线上的所有点的数组*/
function getCurveByTwoPoints(obj1, obj2) {
if (!obj1 || !obj2 || !(obj1 instanceof BMap.Point) || !(obj2 instanceof BMap.Point)) {
return null;
}
var B1 = function(x) {
return 1 - 2 * x + x * x;
};
var B2 = function(x) {
return 2 * x - 2 * x * x;
};
var B3 = function(x) {
return x * x;
};
curveCoordinates = [];
var count=30; // 曲线是由一些小的线段组成的,这个表示这个曲线所有到的折线的个数
var isFuture=false;
var t, h, h2, lat3, lng3, j, t2;
var LnArray = [];
var i = 0;
var inc = 0;
if (typeof(obj2) == "undefined") {
if (typeof(curveCoordinates) != "undefined") {
curveCoordinates = [];
}
return;
}
var lat1 = parseFloat(obj1.lat);
var lat2 = parseFloat(obj2.lat);
var lng1 = parseFloat(obj1.lng);
var lng2 = parseFloat(obj2.lng);
// 计算曲线角度的方法
if (lng2 > lng1) {
if (parseFloat(lng2-lng1) > 180) {
if (lng1 < 0) {
lng1 = parseFloat(180 + 180 + lng1);
}
}
}
if (lng1 > lng2) {
if (parseFloat(lng1-lng2) > 180) {
if (lng2 < 0) {
lng2 = parseFloat(180 + 180 + lng2);
}
}
}
j = 0;
t2 = 0;
if (lat2 == lat1) {
t = 0;
h = lng1 - lng2;
} else if (lng2 == lng1) {
t = Math.PI / 2;
h = lat1 - lat2;
} else {
t = Math.atan((lat2 - lat1) / (lng2 - lng1));
h = (lat2 - lat1) / Math.sin(t);
}
if (t2 == 0) {
t2 = (t + (Math.PI / 5));
}
h2 = h / 2;
lng3 = h2 * Math.cos(t2) + lng1;
lat3 = h2 * Math.sin(t2) + lat1;
for (i = 0; i < count + 1; i++) {
curveCoordinates.push(new BMap.Point(
(lng1 * B1(inc) + lng3 * B2(inc)) + lng2 * B3(inc),
(lat1 * B1(inc) + lat3 * B2(inc) + lat2 * B3(inc))
));
inc = inc + (1 / count);
}
return curveCoordinates;
}
参考: