luoxuancong

luoxuancong

高德地圖大於16個途經點生成路線方案(VUE技術棧)

開發需求#

最近做了一個裝配運輸的項目,其中有一個【路線規劃】的功能,用戶輸入起點、終端後默認生成一條導航路線,需要設置途經點來合理規劃地圖路線,並且需要對每個途經點進行車速限制。

實現過程#

1. 透過高德自帶的拖拽生成途經點來完成#

高德地圖 可拖拽的路線規劃

<script type="text/javascript">
    var map, route, marker;
    //基本地圖加載
    map = new AMap.Map("container", {
        resizeEnable: true
    });
    //繪製初始路徑
    var path = [];
    path.push([116.303843, 39.983412]);
    path.push([116.321354, 39.896436]);
    path.push([116.407012, 39.992093]);
    map.plugin("AMap.DragRoute", function() {
        route = new AMap.DragRoute(map, path, AMap.DrivingPolicy.LEAST_FEE); //構造拖拽導航類
        route.search(); //查詢導航路徑並開啟拖拽導航
    });
</script>

官方的 demo 相當給力,幾行代碼就實現了可自由拖拽的功能,第一反應就用這個了,基本功能也能滿足。

官方實現效果如下:

拖拽生成網點圖片

在實現點擊途經點設置限速的時候,居然發現官方沒有給這些生成的途經點提供回調方法,有點兒坑。

設置途經點點擊方法

// 透過官方的mousemove方法來實時獲取當前鼠標在地圖上的位置
triggerClick() {
  const that = this
  that.map.on('mousemove', function(ev) {
  	var lnglat = ev.lnglat
  	that.currentLngLat = lnglat // 將經緯度信息保存下來
	})
},
addMarkerClick() { // 定義點擊方法
      const that = this
      var infoWindow = new that.AMap.InfoWindow({
        offset: new that.AMap.Pixel(0, -20)
      })
      // 拿到地圖上的marker 點

      setTimeout(() => {
        var dom = document.getElementById('container').getElementsByClassName('amap-marker') // 獲取地圖上所有途經點的dom
        dom = Array.from(dom).filter((item) => {
          if (item.style.display !== 'none') {
            return item
          }
        })
        dom.forEach((item, index) => { // 遍歷dom
          const img = item.getElementsByTagName('img')[0]
          if (img) {
            img.onclick = (e) => { // marker 點擊事件
              const list = [ // 經緯度數組格式數據
                that.currentLngLat.lng,
                that.currentLngLat.lat
              ]
              const distanceList = this.mapData.waypoints.map(item => { // 獲取每個途經點到當前點距離list
                const p = [item.lng, item.lat]
                return that.AMap.GeometryUtil.distance(list, p)
              })
              const min = Math.min.apply(null, distanceList) // 拿到距離當前位置最近的點
              const index = distanceList.indexOf(min) // 獲取索引
              const currentPoint = this.mapData.waypoints[index] // 獲取觸發點擊途經點的經緯度數據
              const LngLat = new that.AMap.LngLat(currentPoint.lng, currentPoint.lat)
              infoWindow.setMap(that.map)
              // 設置marker信息展示內容
              const speedLimit = currentPoint.speedLimit ? currentPoint.speedLimit + 'KM' : '未設置'
              infoWindow.setContent(
                '<b>報警信息 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</b>  <br/><br/>' +
            '<b> 限速: </b> <span class="speed-input">' + speedLimit + '</span><br/><br/>' +
            `<button id="closeBtn" type="button" class="el-button el-button--small" "><span>關閉</span></button> <button id="editBtn" type="button" class="el-button el-button--primary el-button--small"><span>設 置</span></button>`
              )
              infoWindow.open(that.map, LngLat) // 打開彈窗消息
              setTimeout(() => {
                document.getElementById('closeBtn').onclick = () => {
                  infoWindow.close()
                }
                document.getElementById('editBtn').onclick = () => {
                  that.limitSet(index)
                }
              }, 500)
            }
          }
        })
      }, 500)
   }

到這裡之後 基本能完成想要的效果了。

拖拽生成點效果

但是由於官方 api 的限制,當我大於十六個網點後出現了這種情況。

大於十六個點

超過十六個點後,前面的點就沒有在線路規劃的範圍內了,這樣肯定是不行的。

2. 放棄官方的拖拽方法,來實現途經點規劃路線#

由於時間關係,先把最終完成的效果展示一下,具體實現方法下次完善。

最終效果圖

3. 源碼#

今天花了點時間將地圖 demo 整理了出來,基本功能發出來了,具體的業務邏輯大家根據自己的需求做調整。
github 源碼地址
基本交互

路線詳情展示

4. 預覽地址#

demo 預覽地址

載入中......
此文章數據所有權由區塊鏈加密技術和智能合約保障僅歸創作者所有。