百度地圖JSAPI提供兩種繪製多折線的方式,一種是已知多折線經緯度座標串通過AddOverlay接口進行添加;另一種是通過在地圖上鼠標單擊進行繪製(鼠標繪製工具條庫)。目前這兩種方式只能繪製多折線,並不能同時繪製線的箭頭,以下介紹如何在線的拐點同時繪製箭頭,以供參考。最終效果如下:
1. 繪製箭頭方法:
上圖中,線段AB是通過JSAPI畫線方式添加的,只要繪製出CBD就可以實現箭頭效果。爲了靈活繪製箭頭,需要用戶自定義箭頭的長度(r)和角度(angle)。
實現步驟如下:
變量定義:pixelStart: 線的一端屏幕座標,pixelEnd:線的箭頭端屏幕座標;r:選取多長距離繪製箭頭(單位像素,並不是CB對應的箭頭的長度,而是紅色線段對應的距離);angle:箭頭線(CB或者DB)與AB的夾角。
1) 首先要將AB兩點的經緯度座標轉換成屏幕座標。
2) 然後根據AB兩點屏幕座標以及r長度,計算綠色小綠點的屏幕座標pixelTem。
3) 然後根據B點、小綠點的屏幕座標及angle角度,計算出C,D兩點的屏幕座標。
4) 利用map的座標轉換方法,將C,D兩點的屏幕座標轉成經緯度表示的座標。
5) 利用畫線方法,繪製CBD多折線。
備註:思路很簡單,主要是計算小綠點、C,D的屏幕座標麻煩。樓主計算這些點的公式均來自與初中數學公式,就不再贅述直接上代碼了。
完整代碼如下:
<!DOCTYPE html>
<html>
<head>
<metahttp-equiv="Content-Type"content="text/html; charset=utf-8"/>
<styletype="text/css">
body, html,#allmap {width: 100%;height: 100%;overflow: hidden;margin:0;}
#l-map{height:100%;width:78%;float:left;border-right:2px solid #bcbcbc;}
#r-result{height:100%;width:20%;float:left;}
</style>
<scripttype="text/javascript"src="http://api.map.baidu.com/api?v=1.4"></script>
<title>折線</title>
</head>
<body>
<divid="allmap"></div>
</body>
</html>
<scripttype="text/javascript">
var map = new BMap.Map("allmap");
var point = new BMap.Point(116.404, 39.915);
map.centerAndZoom(point, 15);
map.addControl(new BMap.NavigationControl());
map.enableScrollWheelZoom();
var polyline = new BMap.Polyline([
//new BMap.Point(116.399, 39.910),
new BMap.Point(116.405, 39.920),
new BMap.Point(116.425,39.91936),
new BMap.Point(116.415,39.93936),
// new BMap.Point(116.415,39.92936),
], {strokeColor:"blue", strokeWeight:3, strokeOpacity:0.5});
map.addOverlay(polyline);
addArrow(polyline,10,Math.PI/7);
function addArrow(polyline,length,angleValue){ //繪製箭頭的函數
var linePoint=polyline.getPath();//線的座標串
var arrowCount=linePoint.length;
for(var i =1;i<arrowCount;i++){ //在拐點處繪製箭頭
var pixelStart=map.pointToPixel(linePoint[i-1]);
var pixelEnd=map.pointToPixel(linePoint[i]);
var angle=angleValue;//箭頭和主線的夾角
var r=length; // r/Math.sin(angle)代表箭頭長度
var delta=0; //主線斜率,垂直時無斜率
var param=0; //代碼簡潔考慮
var pixelTemX,pixelTemY;//臨時點座標
var pixelX,pixelY,pixelX1,pixelY1;//箭頭兩個點
if(pixelEnd.x-pixelStart.x==0){ //斜率不存在是時
pixelTemX=pixelEnd.x;
if(pixelEnd.y>pixelStart.y)
{
pixelTemY=pixelEnd.y-r;
}
else
{
pixelTemY=pixelEnd.y+r;
}
//已知直角三角形兩個點座標及其中一個角,求另外一個點座標算法
pixelX=pixelTemX-r*Math.tan(angle);
pixelX1=pixelTemX+r*Math.tan(angle);
pixelY=pixelY1=pixelTemY;
}
else //斜率存在時
{
delta=(pixelEnd.y-pixelStart.y)/(pixelEnd.x-pixelStart.x);
param=Math.sqrt(delta*delta+1);
if((pixelEnd.x-pixelStart.x)<0) //第二、三象限
{
pixelTemX=pixelEnd.x+ r/param;
pixelTemY=pixelEnd.y+delta*r/param;
}
else//第一、四象限
{
pixelTemX=pixelEnd.x- r/param;
pixelTemY=pixelEnd.y-delta*r/param;
}
//已知直角三角形兩個點座標及其中一個角,求另外一個點座標算法
pixelX=pixelTemX+ Math.tan(angle)*r*delta/param;
pixelY=pixelTemY-Math.tan(angle)*r/param;
pixelX1=pixelTemX- Math.tan(angle)*r*delta/param;
pixelY1=pixelTemY+Math.tan(angle)*r/param;
}
var pointArrow=map.pixelToPoint(new BMap.Pixel(pixelX,pixelY));
var pointArrow1=map.pixelToPoint(new BMap.Pixel(pixelX1,pixelY1));
var Arrow = new BMap.Polyline([
pointArrow,
linePoint[i],
pointArrow1
], {strokeColor:"blue", strokeWeight:3, strokeOpacity:0.5});
map.addOverlay(Arrow);
}
}
</script>