一 功能介绍:

vue高德批量路线规划+多组路线带途径节点marker+各路线不同颜色显示+各marker带点击监听事件(显示途径点详细内容)

效果图:

二、实现

1.本项目使用的 高德api 故需要申请高德web开发相关申请配置 见这篇

2.oneSelectCharts.vue 地图渲染图组件

<template>
  <div class="clearFix">
    <div id="mapAmap2" class="clearFix card-shadow">
      <div class="clearFix">
        <canvas></canvas>
      </div>
    </div>
    <div id="panel0"></div>
  </div>
</template>

<script>
  // import AMap from 'AMap'
  // import AMapUI from 'AMapUI'
  import * as Utils from '@/utils/index'
  export default {
    name: '',
    props: [],
    components: { },
    data() {
      return {
      }
    },
    mounted() {
      // this.getList()
    },
    methods: {
      initFunc(arr) {
        const that = this
        const arr = [
          {
            'id': 356,
            'truckModel': '牧马人',
            'startAddr': '广东省 深圳市 福田区 上步中路1012号711便利店',
            'startLongitude': '114.095357',
            'startLatitude': '22.544519',
            'trainWaybillDtos': [
              {
                'id': 4804,
                'waybillNum': 'YD20200403171829273899179',
                'receivingAddr': '广东省 深圳市 罗湖区 火车站皮带廊夹层第二标段商铺',
                'externalNum': '704',
                'longitude': '114.128293',
                'latitude': '22.521280',
                'startAddr': '广东省 深圳市 福田区 上步中路1012号711便利店',
                'startLongitude': '114.015357',
                'startLatitude': '22.504519'
              },
              {
                'id': 4805,
                'waybillNum': 'YD20200403171829273899179',
                'receivingAddr': '广东省 东莞市 xxxx',
                'externalNum': '704',
                'longitude': '114.108293',
                'latitude': '22.501280',
                'startAddr': '广东省 深圳市 福田区 上步中路1012号711便利店',
                'startLongitude': '114.085357',
                'startLatitude': '22.524519'
              },
              {
                'id': 4806,
                'waybillNum': 'YD20200403171829273899179',
                'receivingAddr': '广东省 佛山市 xxxxxx',
                'externalNum': '704',
                'longitude': '114.158293',
                'latitude': '22.511280',
                'startAddr': '广东省 深圳市 福田区 上步中路1012号711便利店',
                'startLongitude': '114.075357',
                'startLatitude': '22.514519'
              }
            ]
          },
          {
            'id': 357,
            'truckModel': '牧xxxxxxx',
            'startAddr': '广东省 深圳市 福田区 上步中路xxxxx便利店',
            'startLongitude': '114.215357',
            'startLatitude': '22.484519',
            'trainWaybillDtos': [
              {
                'id': 4804,
                'waybillNum': 'YD20200403171829273899179',
                'receivingAddr': '广东省 深圳市 罗湖区 火车站皮带廊夹层第二标段商铺',
                'externalNum': '704',
                'longitude': '114.183293',
                'latitude': '22.561280',
                'startAddr': '广东省 深圳市 福田区 上步中路1012号711便利店',
                'startLongitude': '114.095357',
                'startLatitude': '22.544519'
              },
              {
                'id': 4824,
                'waybillNum': 'YD20200403171829273899179',
                'receivingAddr': '广东省 深圳市 宝安区',
                'externalNum': '704',
                'longitude': '114.174293',
                'latitude': '22.541280',
                'startAddr': '广东省 深圳市 福田区 上步中路1012号711便利店',
                'startLongitude': '114.095357',
                'startLatitude': '22.544519'
              },
              {
                'id': 4825,
                'waybillNum': 'YD20200403171829273899179',
                'receivingAddr': '广东省 深圳市 光明区',
                'externalNum': '704',
                'longitude': '114.104293',
                'latitude': '22.531280',
                'startAddr': '广东省 深圳市 福田区 上步中路1012号711便利店',
                'startLongitude': '114.095357',
                'startLatitude': '22.544519'
              }
            ]
          }
        ]
        // lineNameStr 线路名称 所用字段, spotNameStr 途径站点名称 所用字段,pathListNameStr 路径数组 所用字段
        const toParams = { lineNameStr: 'id', spotNameStr: 'receivingAddr', pathListNameStr: 'trainWaybillDtos' }
        // that.$refs.oneSelectChartsRef.initMap(arr, toParams)
        that.initMap(arr, toParams)
      },
      initMap(lineData, toParams) {
        console.log('initMap2', lineData, toParams)
        const _this = this
        const { lineNameStr, spotNameStr, pathListNameStr } = toParams
        const mapObj = new AMap.Map('mapAmap2', {
          mapStyle: 'amap://styles/grey', // 换地图样式风格
          center: [116.397559, 39.89621],
          zoom: 1
        })
        const colors = ['#DC143C', '#5F9EA0', '#00BFFF', '#C71585', '#6495ED',
          '#008B8B', '#FFFF00', '#FFD700', '#FFDEAD', '#FF4500',
          '#FF8C00', '#8B4513', '#FFF5EE', '#FF7F50', '#FF6347']
        let routeLine_obj = {}
        let Driving_obj = new AMap.Driving({
          map: mapObj, // map 指定将路线规划方案绘制到对应的AMap.Map对象上
        })
        Driving_obj.clear() // 清理
        // console.log('lineData[0][pathListNameStr]', lineData[0][pathListNameStr])
        for (let f = 0; f < lineData.length; f++) {
          const item_path = lineData[f][pathListNameStr]
          const now_length = item_path.length
          // 这里  本数据结构 特殊,[起点]是单列在父级数据结构内,不在 路径规划list内
          const nowStartItem = lineData[f]
          const item_start_path = nowStartItem
          item_start_path.longitude = nowStartItem.startLongitude
          item_start_path.latitude = nowStartItem.startLatitude
          item_start_path[spotNameStr] = nowStartItem.startAddr
          const item_end_path = item_path[now_length - 1]
          const now_arr = item_path.slice(0, now_length - 1) // 这里 本数据结构 特殊,[起点]是单列在父级数据结构内,不在 路径规划list内
          const item_way_path = now_arr.map(item => {
            return new AMap.LngLat(item.longitude, item.latitude)
          })
          Driving_obj.search(
            new AMap.LngLat(item_start_path.longitude, item_start_path.latitude),
            new AMap.LngLat(item_end_path.longitude, item_end_path.latitude),
            { waypoints: item_way_path },
            function(status, result) {
              //  searchResult即是对应的驾车导航信息,相关数据结构文档请参考  https://lbs.amap.com/api/javascript-api/reference/route-search#m_DrivingResult
              if (status === 'complete') {
                console.log('获取货车规划数据成功')
                if (result.routes && result.routes.length) {
                  drawRoute(result.routes[0], f)
                }
              } else {
                console.log('获取货车规划数据失败:' + result)
              }
            })
          createMarkerNormal(lineData[f][lineNameStr], now_arr)
          createMarkerOne(lineData[f][lineNameStr],item_start_path, '起点')
          createMarkerOne(lineData[f][lineNameStr],item_end_path, '终点')
        }
        // 途径节点 marker(集合)- 此处用了 new AMap.Text 需 版本1.4.2
        function createMarkerNormal(lineName, now_arr) {
          const middleMarkers = []
          // -------- 中途 站点-----------
          now_arr.forEach((item, index) => {
            // 创建一个 Icon
            const siteIcon = new AMap.Icon({
              // 图标尺寸
              size: new AMap.Size(25, 34),
              // 图标的取图地址
              // image: '//a.amap.com/jsapi_demos/static/demo-center/icons/poi-marker-default.png',
              // image: '//a.amap.com/jsapi_demos/static/demo-center/icons/dir-marker.png',
              image: '//a.amap.com/jsapi_demos/static/demo-center/icons/dir-via-marker.png',
              // 图标所用图片大小
              imageSize: new AMap.Size(25, 34),
              // 图标取图偏移量
              // imageOffset: new AMap.Pixel(0, 0)
            });
            const siteMarker = new AMap.Marker({
              // text: lineName + '路线-' + (index + 1) + '号站点',
              // icon: '//a.amap.com/jsapi_demos/static/demo-center/icons/poi-marker-' + (index + 1) + '.png',
              icon: siteIcon,
              position: new AMap.LngLat(item.longitude, item.latitude),
              offset: new AMap.Pixel(-12, -32),
              map: mapObj
            })
            // 给 Text 带上自定义私货
            siteMarker.lisaSiteInfo = item
            // 监听地图- Text 的 点击事件
            const clickHandler1 = function(e) {
              // log.success("carText模拟触发了地图click事件!");
              console.log('carText模拟触发了地图click事件-e')
              const siteInfo = e.target.lisaSiteInfo
              new AMap.InfoWindow({
                content: lineName + '路线' + '-' + (index + 1) + '号站点</br>地址:' + siteInfo[spotNameStr]
              }).open(mapObj, e.lnglat)
              // 向父级调用事件
              _this.$emit('site-click', item)
            }
            siteMarker.on('click', clickHandler1)
            siteMarker.setMap(mapObj)
            middleMarkers.push(siteMarker)
            //-------siteText-------
            // label默认蓝框白底左上角显示,样式className为:amap-marker-label
            const siteText = new AMap.Text({
              offset: new AMap.Pixel(0, -50),  //设置文本标注偏移量
              text: item[spotNameStr],
              position: new AMap.LngLat(item.longitude, item.latitude), // 这里特殊 本数据结构, startLatitude
              map: mapObj
            })
            siteText.lisaSiteInfo = item
            siteText.on('click', clickHandler1)
            siteText.setMap(mapObj)
            middleMarkers.push(siteText)
          })
          // console.log('middleMarkers', middleMarkers)
          return middleMarkers
        }
        // 起点 或 终点 marker(单个)
        function createMarkerOne(lineName, item, type) {
          let iconUrl = '', siteName = ''
          if (type === '起点') {
            iconUrl = 'https://webapi.amap.com/theme/v1.3/markers/n/start.png'
            siteName = '起点'
          } else if (type === '终点') {
            iconUrl = 'https://webapi.amap.com/theme/v1.3/markers/n/end.png'
            siteName = '终点'
          } else {
            // 途经
            iconUrl = '//a.amap.com/jsapi_demos/static/demo-center/icons/dir-via-marker.png'
            siteName = '途经点'
          }
          // -------- 站点-----------
          const oneMarker = new AMap.Marker({
            icon: iconUrl,
            position: new AMap.LngLat(item.longitude, item.latitude),
            offset: new AMap.Pixel(-9, -32),
            map: mapObj
          })
          // 给 Text 带上自定义私货
          oneMarker.lisaSiteInfo = item
          // 监听地图- Text 的 点击事件
          const clickHandler1 = function(e) {
            // log.success("carText模拟触发了地图click事件!");
            console.log('carText模拟触发了地图click事件-e')
            const siteInfo = e.target.lisaSiteInfo
            new AMap.InfoWindow({
              content: lineName + '路线' + '-' + siteName + '</br>地址:' + siteInfo[spotNameStr]
            }).open(mapObj, e.lnglat)
            // 向父级调用事件
            _this.$emit('site-click', item)
          }
          oneMarker.on('click', clickHandler1)
          oneMarker.setMap(mapObj)
          //-------siteText-------
          // label默认蓝框白底左上角显示,样式className为:amap-marker-label
          const siteText = new AMap.Text({
            offset: new AMap.Pixel(0, -50),  //设置文本标注偏移量
            text: item[spotNameStr],
            position: new AMap.LngLat(item.longitude, item.latitude), // 这里特殊 本数据结构, startLatitude
            map: mapObj
          })
          siteText.lisaSiteInfo = item
          siteText.on('click', clickHandler1)
          siteText.setMap(mapObj)
          return oneMarker
        }
        // 行驶路线规划
        function drawRoute(route, index) {
          const path = parseRouteToPath(route)
          // 生成 折线路线
          routeLine_obj = new AMap.Polyline({
            zIndex: 52,
            path: path,
            isOutline: true,
            outlineColor: '#ffeeee',
            borderWeight: 2,
            strokeWeight: 5,
            strokeColor: colors[index] || '#A52A2A',
            lineJoin: 'round'
          })
          routeLine_obj.setMap(mapObj)
        }
        // 解析DrivingRoute对象,构造成AMap.Polyline的path参数需要的格式
        // DrivingResult对象结构参考文档 https://lbs.amap.com/api/javascript-api/reference/route-search#m_DriveRoute
        function parseRouteToPath(route) {
          const path = []
          for (let i = 0, l = route.steps.length; i < l; i++) {
            const step = route.steps[i]
            for (let j = 0, n = step.path.length; j < n; j++) {
              path.push(step.path[j])
            }
          }
          return path
        }
      }
    }
  }
</script>

<style rel="stylesheet/scss" lang="scss" scoped>
  #mapAmap2{
    margin: 0 0 0 0;
    width:100%;
    height:800px;
  }
</style>

 

Logo

前往低代码交流专区

更多推荐