我遇到的情況:
1、使用騰訊地圖畫出路徑,並在地圖上表示方向(也就是箭頭指向)
我查了很多的資料,並沒有詳細的結論,我按照api給的方法,我自定義做出的效果
vue+element+騰訊地圖API,(僅供參考)
效果圖如下:
思路
1、首先看是否跟我使用的方法聲明Map一致的方法,騰訊地圖的JavaScript API GL的api(如有不同,可以看邏輯,邏輯是一樣的,但是需要自己去專研下代碼)
https://lbs.qq.com/webApi/jav...
2、如果看到這裏,那我先講下邏輯,我之前考慮過方案:
(1)地圖自帶的線段帶的箭頭指向(跟實際需求不符) ,而且,箭頭不能大於具體寬度,這樣我們沒辦法擴展,果然放棄了(希望騰訊地圖api,這裏可以改善下)
這時示例地址:
https://lbs.qq.com/webDemoCen...
這是api地址:
https://lbs.qq.com/webApi/jav...
(2)自定義DOM覆蓋物(DOMOverlay)這是百度搜索最多的方案,但是我看過,可以做到,聲明img結構(img就是箭頭的圖片),按照img旋轉不同的角度所得到的,但是會出現一種bug,就是不會隨着地圖縮放而進行變化,這就很惱火了,所以我就沒考慮(測試肯定給我提bug)
(3)這種目前我使用的一種,根據兩點的座標,判斷角度、拿到箭頭的三角座標給畫兩條線,結合成箭頭形狀,(説白點:就是跟畫線一樣,畫出來的箭頭)
(4)根據畫多邊形,進行繪製,但是原理都是一樣的,先找到箭頭的三角座標,之後進行處理,需要看具體的需求,(如果是箭頭是覆蓋有顏色的,那就先拿到座標,進行多邊形繪製,效果也能實現)。重點:拿到箭頭的三個角的座標!!!
(5)其他的方案,大同小異,都是根據需求,結合座標,進行繪製。
下面我就具體講下第三種
1、聲明map以及polylineLayer(前面是地圖,後面是畫線),點位的聲明,我就不做粘貼的,會一點都應該會撒點
<div class="echarts_heating" id="map"></div> //html
var map = new TMap.Map(document.getElementById("map"), {
zoom: 11, //設置地圖縮放級別
center: center, //設置地圖中心點座標
mapStyleId: "style1", //個性化樣式默認style
disableDefaultUI: true,
showControl: false,
baseMap: {
type: "vector",
features: ["base", "building3d", "point"], // 隱藏矢量文字可根據需求去配置
},
// mapStyleId: "style1", //設置樣式ID,本例中的key綁定的style1為經典地圖樣式
//(若使用未綁定的樣式或無效ID,則會提示錯誤,並用地圖默認樣式顯示)
});
畫線polylineLayer的聲明以及線段的風格
var polylineLayer = new TMap.MultiPolyline({
map, // 繪製到目標地圖
// 折線樣式定義
styles: {
style_blue: new TMap.PolylineStyle({
color: "#F15E59", // 線填充色
width: 3, // 折線寬度
lineCap: "round", // 線端頭方式
}),
style_dash: new TMap.PolylineStyle({
color: "#F15E59", // 線填充色
width: 3, // 折線寬度
lineCap: "butt", // 線端頭方式
dashArray: [6, 5], // 虛線展示方式
}),
},
geometries: [],
});
在vue的methods中
//arr是點位座標,[起點,終點] index,indexli,是為了不同的id所循環出來的,方便不同的命名,可取消
computeHeading(arr, index, indexli) {
// 根據computeDistance去查詢兩點之前的距離
let computeDistance = TMap.geometry.computeDistance(arr);
// 查詢兩點之前的距離,如果距離過短,不進行任何處理
if (computeDistance > 1500) {
let computeHeading = TMap.geometry.computeHeading(arr[0], arr[1]);
// 根據computeHeading,獲取當前點位的的角度
let du; //這個變量只是為了不讓箭頭的頂端和icon重疊而聲明的反向的角度
if (computeHeading > 0) {
du = computeHeading - 180;
// 因為地圖的座標系中只有【180,-180】所以進行逆時針轉換
} else {
du = computeHeading + 180;
}
// path0 就是根據computeDestination,反向拿到的新的箭頭頂點的座標
// 其中200,是icon與頂點的距離,可調整
let path0 = TMap.geometry.computeDestination(arr[1], du, 200);
// top1,top2,是畫箭頭的角度獲取,
// 因為地圖的座標系中只有【180,-180】所以進行逆時針轉換
// 我這邊取得是偏移40度, 140,220,可調整
let top1 = this.computeRotaion(computeHeading + 140);
let top2 = this.computeRotaion(computeHeading + 220);
// path1,path2是根據箭頭的座標,預計畫的線段長度、以及角度,去獲取箭頭兩邊的點位座標
let path1 = TMap.geometry.computeDestination(path0, top1, 1200);
let path2 = TMap.geometry.computeDestination(path0, top2, 1200);
// console.log("path1", path1);
// 根據獲得到箭頭的三點左邊,進行繪製,這邊也可以繪製覆蓋性多邊形 index,indexli,可修改,可取消,只要是不同的id即可
this.polylineLayer.add({
styleId: "style_blue",
id: "pl1_" + index + "_" + indexli,
paths: [path0, path1],
});
this.polylineLayer.add({
styleId: "style_blue",
id: "pl2_" + index + "_" + indexli,
paths: [path0, path2],
});
// 根據不同長度,做不同的方案,根據長度在10000米以上的,我這邊做中間的箭頭,原理同上//
if (computeDistance > 10000) {
// 先拿到中間的點位座標
let pathzhong = TMap.geometry.computeDestination(
arr[1],
du,
computeDistance / 2
);
// path3,path4,是中間箭頭兩邊點位座標,
let path3 = TMap.geometry.computeDestination(pathzhong, top1, 1200);
let path4 = TMap.geometry.computeDestination(pathzhong, top2, 1200);
// 在根據三點座標,進行畫線,作出箭頭 index,indexli,可修改,可取消,只要是不同的id即可
this.polylineLayer.add({
styleId: "style_blue",
id: "pl3_" + index + "_" + indexli,
paths: [pathzhong, path3],
});
this.polylineLayer.add({
styleId: "style_blue",
id: "pl4_" + index + "_" + indexli,
paths: [pathzhong, path4],
});
}
}
},
// 由於地圖座標的範圍【180,-180】所以進行轉化
computeRotaion(heading) {
let rotation;
if (heading > 180) {
rotation = heading - 360;
} else {
rotation = heading;
}
return rotation;
}
註釋中有完整的解釋,需要耐心去看,也可以根據自身的情況去修改。我這裏沒有進行封裝,但是可以正常的使用,如果你需要多組件調用,,需要自己去封裝搞下,我就不在這把我需求封裝的拿出來了,畢竟需求不同
總結:
希望多提意見,有更好的建議,可以留言,虛心學習!
卑微的小劉!