基于vue和高德实现线条绘制和线条编辑以及道路搜索

1,290 阅读1分钟

最近整理代码感觉这个功能挺有意思记录一下

image.png 就是能随便的在地图上绘制线条,选中后能随意删除 修改,也可以查询数据库后根据数据库的线条来编辑, 主要用到了高德提供的这些插件功能,后端是按照一条线一条线存的 一个起始坐标一个结束坐标 只存直线

['AMap.MouseTool', 'AMap.PolyEditor', 'AMap.Autocomplete', 'AMap.PlaceSearch']

具体代码如下

<template>
  <div class="map">
    <div class="GDMap" ref="GDMap" id="GDMap"></div>
    <div class="btns">
      <el-cascader
        class="city"
        v-model="city"
        :options="cityOptions"
        :props="{ expandTrigger: 'hover' }"
      ></el-cascader>
      <el-input id="name" name="name" v-model="roadName" placeholder="请输入路名"></el-input>
      <div class="btnsdiv">
        <el-button class="btnItem" type="primary" plain @click="queryLine">查询路段</el-button>
        <el-button class="btnItem" type="info" plain @click="draw">开始绘制</el-button>
        <el-button class="btnItem" type="danger" plain @click="delectLine">删除线路</el-button>
        <el-button class="btnItem" type="success" plain @click="comit">提交</el-button>
      </div>
    </div>
    <div class="seachRoad">
        <el-input id="keyword" ref="keyword" type="text" placeholder="请输入路名关键字:(选定后搜索)" v-model="seachText"></el-input>
    </div>
  </div>
</template>

<script>
import AMap from 'AMap' // 引入高德地图
import axios from 'axios'
import roadApi from '../api/road'
export default {
  data () {
    return {
      seachText: '',
      autocomplete: '',
      GDMap: null,
      city: ['上海', '上海'],
      cityOptions: [],
      roadName: '',
      mouseTool: null,
      polyline: null,
      currentLine: null,
      PolyEditor: null,
      path: [],
      lineList: []
    }
  },
  created () {
    this.initCity()
  },
  mounted () {
    this.GDMap = new AMap.Map('GDMap', {
      zoom: 10, // 级别
      center: [121.523362, 31.172272], // 中心点坐标
      mapStyle: 'amap://styles/be21eca74ae720ac8eac408ebb004414'
    })
    this.initMap()
  },
  methods: {
    async initCity () {
      var res = await axios.get('/js/city.json')
      res.data.provinces.forEach(item => {
        var cityItem = {
          value: item.provinceName,
          label: item.provinceName,
          children: []
        }
        item.citys.forEach(val => {
          cityItem.children.push({
            value: val.citysName,
            label: val.citysName
          })
        })
        this.cityOptions.push(cityItem)
      })
    },
    initMap () {
      var _this = this
      this.GDMap.plugin(['AMap.MouseTool', 'AMap.PolyEditor', 'AMap.Autocomplete', 'AMap.PlaceSearch'], function () {
        // 鼠标插件初始化
        _this.mouseTool = new AMap.MouseTool(_this.GDMap)
        AMap.event.addListener(_this.mouseTool, 'draw', function (e) {
          _this.polyline = e.obj
          _this.lineList.push(_this.polyline)
          // 为线注册点击事件和控制修改删除
          _this.polylineClick(_this.polyline)
        })
        // 搜索道路
        _this.mapSeachRoad()
      })
    },
    // 搜索道路
    mapSeachRoad () {
      var autoOptions = {
        city: this.city[1], // 城市,默认全国
        input: document.getElementById('keyword')
      }
      this.autocomplete = new AMap.Autocomplete(autoOptions)
      var placeSearch = new AMap.PlaceSearch({
        city: this.city[1],
        map: this.GDMap
      })
      AMap.event.addListener(this.autocomplete, 'select', function (e) {
        placeSearch.search(e.poi.name)
      })
    },
    async queryLine () {
      // 查询前先清空历史
      this.lineList = []
      this.path = []
      this.GDMap.clearMap()
      var res = await roadApi.getLineByRoadName({
        roadName: this.roadName,
        city: this.city[1]
      })
      console.log(res)
      for (let i = 0; i < res.data.length; i++) {
        var path = [
          new AMap.LngLat(parseFloat(res.data[i].startLng), parseFloat(res.data[i].startLat)),
          new AMap.LngLat(parseFloat(res.data[i].endLng), parseFloat(res.data[i].endLat))
        ]
        var seachPolyline = new AMap.Polyline({
          path: path,
          borderWeight: 2, // 线条宽度,默认为 1
          strokeWeight: 5,
          cursor: 'crosshair',
          fillColor: '#00b0ff',
          strokeColor: 'red',
          lineJoin: 'round' // 折线拐点连接处样式
        })
        var _this = this
        this.GDMap.plugin(['AMap.PolyEditor'], function () {
          _this.polylineClick(seachPolyline)
        })
        this.lineList.push(seachPolyline)
        this.GDMap.add(seachPolyline)
      }
    },
    polylineClick (polyline) {
      var _this = this
      polyline.on('click', function (w) {
        // 关闭正在绘制的draw,关闭之前可能出现的修改器
        _this.mouseTool.close(false)
        // 关闭之前打开的修改器
        if (_this.PolyEditor !== null) {
          _this.PolyEditor.close()
        }
        _this.currentLine = w.target
        _this.PolyEditor = new AMap.PolyEditor(_this.GDMap, w.target)
        _this.PolyEditor.open()
      })
    },
    draw () {
      // 关闭之前打开的修改器
      if (this.PolyEditor !== null) {
        this.PolyEditor.close()
      }
      this.polyline = this.mouseTool.polyline({
        cursor: 'auto',
        strokeColor: 'red',
        strokeWeight: '4',
        draggable: 'true'
      })
    },
    delectLine () {
      if (this.currentLine != null) {
        this.lineList = this.lineList.filter(val => val !== this.currentLine)
        this.GDMap.remove(this.currentLine)
        this.currentLine = null
        // 因为点击线条后会自动开启修改器 所以关闭一下,通过deleteType来控制回调是否执行
        this.PolyEditor.close()
      } else {
        this.$message.warning('请先选中线路')
      }
    },
    async comit () {
      // 关闭之前打开的修改器,防止用户开启修改器未关闭直接提交无法拿到修改后的数据
      if (this.PolyEditor !== null) {
        this.PolyEditor.close()
      }
      this.lineList.forEach((val, inx) => {
        const paths = {
          type: inx,
          path: []
        }
        val.getPath().forEach(item => {
          paths.path.push(item)
        })
        this.path.push(paths)
      })
      let comitPath = []
      for (let i = 0; i < this.path.length; i++) {
        // 获取到每条线的路径
        var linePath = this.path[i].path
        // 遍历路径
        for (let j = 0; j < linePath.length; j++) {
          // 如果还没有到最后一个坐标点
          if (j !== (linePath.length - 1)) {
            comitPath.push({
              id: '',
              startLng: linePath[j].lng,
              startLat: linePath[j].lat,
              endLng: linePath[j + 1].lng,
              endLat: linePath[j + 1].lat,
              index: j,
              roadName: this.roadName,
              city: this.city[1]
            })
          }
        }
      }
      comitPath = JSON.stringify(comitPath)
      console.log(comitPath)
      var res = await roadApi.add({
        road: comitPath,
        roadName: this.roadName
      })
      console.log(res)
      this.lineList = []
      this.GDMap.clearMap()
      this.path = []
      this.$message.success('提交成功')
    }
  }
}
</script>