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 预览地址

加载中...
此文章数据所有权由区块链加密技术和智能合约保障仅归创作者所有。