vuecli3.0中引入高德地图以及使用到的一些常用方法(正向地理编码,逆向地理编码, 画canvas,点击,鼠标事件,海量点)

借鉴:https://blog.csdn.net/rty426/article/details/90718375

1、高德地图的引入,高德API官网,我是用的webJs

2、高德地图实例中心:https://lbs.amap.com/demo-center/js-api

在vue中的具体操作,

1)在pubilc下的index.html中引入

<link rel="stylesheet" href="https://a.amap.com/jsapi_demos/static/demo-center/css/demo-center.css" />
<script type="text/javascript" src="https://webapi.amap.com/maps?v=1.4.8&key=060b3560b843b060ea897549060f6503&plugin=AMap.ControlBar,AMap.Geocoder,AMap.MouseTool,AMap.Autocomplete,AMap.Driving,AMap.DragRoute,AMap.LabelsLayer,Map3D,ElasticMarker,AMap.DistrictSearch,AMap.DistrictLayer"></script>
<script src="https://webapi.amap.com/ui/1.0/main.js?v=1.0.11"></script>

2、在vue.config.js中进行配置

module.exports = {
    lintOnSave: false,//关闭lint服务
    configureWebpack: {
        externals: {
            'AMap': 'AMap'
        }
    }
}

 3、封装的map组件

<template>
  <div style="position:relitive">
    <span
      style="font-size:12px;z-index:1000;width:30%;height:30px;line-heigt:30px;background:#fff;color:#333;position:absolute;top:40px;left:0px;"
    >{{ area }}</span>
    <el-input
      size="mini"
      style="width:30%;position:absolute;top:0px;left:0px;z-index:1000"
      placeholder="请输入想要搜索的地区"
      prefix-icon="el-icon-search"
      v-model="searchArea"
      @change="change"
    ></el-input>
    <div class="input-card">
      <div class="input-item">
        <input type="radio" name="func" checked value="marker" />
        <span class="input-text">画点</span>
        <input type="radio" name="func" value="polyline" />
        <span class="input-text">画折线</span>
        <input type="radio" name="func" value="polygon" />
        <span class="input-text" style="width:5rem;">画多边形</span>
      </div>
      <div class="input-item">
        <input type="radio" name="func" value="rectangle" />
        <span class="input-text">画矩形</span>
        <input type="radio" name="func" value="circle" />
        <span class="input-text">画圆</span>
      </div>
      <div class="input-item">
        <input id="clear" @click="clear" type="button" class="btn" value="清除" />
        <input id="close" @click="close" type="button" class="btn" value="关闭绘图" />
      </div>
    </div>
    <div id="container1" style="height:100vh;width:100%;"></div>
  </div>
</template>

<script>
import AMap from "AMap";
export default {
  data() {
    return {
      map: "",
      // 鼠标画覆盖物--start
      overlays: [],
      mouseTool: {},
      radios: [],
      //鼠标画覆盖物--end
      flag: true, //判断在地图上神魔时候开始和结束
      area: "", //点击某处显示当前地点的地名
      searchArea: "", //搜索输入的内容
      locationData: [],
      drawData: [], //存放鼠标在地图上戍边按下时的数据
      lnglatData: [
        {
          id: Math.random(),
          state: 1,
          position: [116.7, 39.52],
        },
        {
          id: Math.random(),
          state: 2,
          position: [116.4, 39.9],
        },
        {
          id: Math.random(),
          state: 3,
          position: [117.00634, 39.76133],
        },
      ],
    };
  },
  mounted() {
    this.map = new AMap.Map("container1", {
      zoom: 11, //级别
      resizeEnable: true,
      showLabel: true,
      // viewMode: "3D",
      center: [116.335183, 39.941735],
      expandZoomRange: true,
      //   center: [116.7, 39.52], //设置中心点坐标
    });
    this.map.clearMap(); //渲染之前先清一下覆盖物,防止覆盖物叠加
    // -------start   当需要监听某个事件,实时画marker时,将mass和marker定义为全局,每次先清空一下否则会出现图标叠加
    // _this.map.remove(this.mass);
    // _this.map.remove(this.marker);
    // -------end
    this.getAddressName(this.map);
    // this.addMoreMarkers(this.map); //使用AMap.Marker
    this.addMassMarks(this.map, this.lnglatData); //使用AMap.MassMarks
    this.addPolyline(this.map); //使用折线覆盖物
    // this.addPolygon(this.map); //多边形覆盖物
    // this.drawPoly(this.map); //实现在地图上画覆盖物
    // this.drawCanvasArc(this.map);
    // this.drawCanvasRect(this.map);
    this.useMouseDraw(this.map);
  },
  methods: {
    //   根据输入的内容定位到相应的位置---正向地理编码
    getLocation(searchArea, map) {
      const _this = this;
      map.clearMap(); //每次搜索的时候先清除地图,防止下次搜索还露着上次的 marker
      let geocoder = new AMap.Geocoder({
        // city 指定进行编码查询的城市,支持传入城市名、adcode 和 citycode
        city: "010",
      });
      geocoder.getLocation(searchArea, function (status, result) {
        if (status === "complete" && result.info === "OK") {
          // result中对应详细地理坐标信息
          let lng = result.geocodes[0].location.lng;
          let lat = result.geocodes[0].location.lat;
          map.setCenter([lng, lat]);
          let marker = new AMap.Marker({
            map: map,
            position: [lng, lat], // 经纬度对象,也可以是经纬度构成的一维数组[116.39, 39.9]
          });
        }
      });
    },
    // 在高德地图上点击某个点,获取当前点的地名--逆向地理编码
    getAddressName(map) {
      const _this = this;
      map.on("click", function (e) {
        let geocoder = new AMap.Geocoder({
          // city 指定进行编码查询的城市,支持传入城市名、adcode 和 citycode
          city: "010",
        });
        geocoder.getAddress([e.lnglat.lng, e.lnglat.lat], function (
          status,
          result
        ) {
          if (status === "complete" && result.info === "OK") {
            // result为对应的地理位置详细信息
            _this.area = result.regeocode.formattedAddress;
          }
        });
      });
    },
    // 为高德地图添加多个marker标记,使用这个方法绘制标记点会出出现marker覆盖label的问题,后期改为使用海量点
    addMoreMarkers(map) {
      const _this = this;
      for (let i = 0; i < this.lnglatData.length; i++) {
        let marker = new AMap.Marker({
          map: map,
          position: this.lnglatData[i].position,
        });
        // marker的点击事件
        marker.on("click", () => {
          console.log(this.lnglatData[i]);
        });
        // 鼠标经过marker
        marker.on("mouseover", () => {
          marker.setLabel({
            offset: new AMap.Pixel(20, 20), //设置文本标注偏移量
            content: `<div class='info'>${this.lnglatData[i].position}</div>`, //设置文本标注内容
            direction: "right", //设置文本标注方位
          });
        });
        // 鼠标离开marker
        marker.on("mouseout", () => {
          marker.setLabel(null);
        });
      }
    },
    // 添加海量点的方式,可以避免marker覆盖label
    addMassMarks(map, data) {
      let status = 0;
      const style = [
        {
          //state == 1 top-center anchor: new AMap.Pixel(16, 16),
          url: require("../../public/img/marks/weizhi.png"),
          anchor: new AMap.Pixel(0, 0),
          size: new AMap.Size(20, 20),
        },
        {
          //state == 2
          url: require("../../public/img/marks/jiaoda.png"),
          anchor: new AMap.Pixel(0, 0),
          size: new AMap.Size(20, 20),
        },
        {
          //state == 3
          url: require("../../public/img/marks/zhongda.png"),
          anchor: new AMap.Pixel(0, 0),
          size: new AMap.Size(20, 20),
        },
      ];
      for (let i = 0; i < data.length; i++) {
        if (data[i].state == 1) {
          status = 0;
        } else if (data[i].state == 2) {
          status = 1;
        } else {
          status = 2;
        }
        this.locationData.push({
          // position: data[i].position,  这里必须是lnglat,否则报// Error in mounted hook: "TypeError: Cannot read property 'Q' of undefined"
          lnglat: data[i].position,
          style: status,
          obj: data[i],
        });
      }
      let mass = new AMap.MassMarks(this.locationData, {
        opacity: 1,
        zIndex: 111,
        cursor: "pointer",
        style: style,
        // 表示是否在拖拽缩放过程中实时重绘,默认true,建议超过10000的时候设置false
        alwaysRender: true,
      });
      let marker = new AMap.Marker({
        content: " ",
        map: map,
        offset: new AMap.Pixel(0, -10),
      });
      mass.on("mouseover", function (e) {
        let arr = [e.data.lnglat.lng, e.data.lnglat.lat];
        marker.setPosition(arr);
        marker.setLabel({
          content: `<span>${e.data.obj.id}</span>`,
          direction: "top", //设置文本标注方位
        });
      });
      mass.on("mouseout", function (e) {
        let arr = [e.data.lnglat.lng, e.data.lnglat.lat];
        marker.setPosition(arr);
        marker.setLabel(null);
      });
      mass.on("click", function (e) {
        let arr = [e.data.lnglat.lng, e.data.lnglat.lat];
        // 做点击marker的处理
      });
      mass.setMap(map);
    },
    // 使用折线覆盖物   https://lbs.amap.com/api/javascript-api/guide/overlays/vector-overlay
    addPolyline(map) {
      var path = [
        ["116.368904", "39.913423"],
        ["116.382122", "39.901176"],
        ["116.387271", "39.912501"],
        ["116.398258", "39.9046"],
      ];
      var polyline = new AMap.Polyline({
        map: map,
        path: path, // 设置线覆盖物路径
        strokeColor: "#3366FF", // 线颜色
        strokeOpacity: 1, // 线透明度
        strokeWeight: 2, // 线宽
        strokeStyle: "solid", // 线样式
        strokeDasharray: [10, 5], // 补充线样式
        geodesic: true, // 绘制大地线
        lineJoin: "round", // 折线拐点连接处样式
      });
      // map.remove(polyline); //移除覆盖物
      // polyline.show(); //覆盖物的显示
      // polyline.hide(); //覆盖物的隐藏
    },
    // 多边形覆盖物
    addPolygon(map) {
      var path = [
        ["116.7", "39.52"],
        ["116.4", "39.9"],
        ["117.00634", "39.76133"],
      ];
      var polygon = new AMap.Polygon({
        map: map,
        path: path,
        fillColor: "#fff", // 多边形填充颜色
        borderWeight: 2, // 线条宽度,默认为 1
        strokeColor: "red", // 线条颜色
      });
    },
    // 实现在地图上画覆盖物
    drawPoly(map) {
      let drawPolyData = [];
      // 鼠标在地图上单击按下时触发
      map.on("mousedown", function (e) {
        this.flag = false;
        console.log([e.lnglat.lng, e.lnglat.lat], "mousedown");
      });
      // 鼠标在地图上移动时触发
      map.on("mousemove", function (e) {
        if (this.flag) {
          drawPolyData.push([e.lnglat.lng, e.lnglat.lat]);
          var polygon = new AMap.Polygon({
            map: map,
            path: drawPolyData,
            fillColor: "#fff", // 多边形填充颜色
            borderWeight: 2, // 线条宽度,默认为 1
            strokeColor: "red", // 线条颜色
          });
        }
      });
      map.on("mouseup", function (e) {
        this.flag = true;
      });
    },
    // 在高德地图上使用canvas图层,闪动圆点。自建图层https://lbs.amap.com/api/javascript-api/reference/self-own-layers#canvaslayer
    drawCanvasArc(map) {
      const _this = this;
      var bar = new AMap.ControlBar();
      map.addControl(bar);
      // 画canvas
      var draw = function (context, radious) {
        context.clearRect(0, 0, 400, 400);
        context.globalAlpha = (context.globalAlpha - 0.01 + 1) % 1;
        radious = (radious + 1) % 100;

        context.beginPath();
        context.arc(100, 100, radious, 0, 2 * Math.PI);
        context.fill();
        context.stroke();

        //2D视图时可以省略
        // CanvasLayer.reFresh();

        AMap.Util.requestAnimFrame(function () {
          draw(context, radious);
        });
      };
      var point = [
        [
          [116.328911, 39.937229],
          [116.342659, 39.946275],
        ],
        [
          [116.319384, 39.941683],
          [116.329384, 39.951683],
        ],
      ];
      var canvas = [];
      var CanvasLayer = [];
      var context = [];
      var radious = [];
      for (let i = 0; i < point.length; ++i) {
        canvas[i] = document.createElement("canvas");
        canvas[i].width = canvas[i].height = 200;
        context[i] = canvas[i].getContext("2d");
        context[i].fillStyle = "rgb(0,100,255)";
        context[i].strokeStyle = "white";
        context[i].globalAlpha = 1;
        context[i].lineWidth = 2;
        radious[i] = 0;
        CanvasLayer[i] = new AMap.CanvasLayer({
          canvas: canvas[i],
          bounds: new AMap.Bounds(point[i][0], point[i][1]),
          zooms: [3, 18],
        });
        CanvasLayer[i].setMap(map);
        draw(context[i], radious[i]);
      }
    },
    // 绘制矩形
    drawCanvasRect(map) {
      const _this = this;
      var bar = new AMap.ControlBar();
      map.addControl(bar);
      // 画canvas
      var draw = function (context, width, height) {
        context.clearRect(0, 0, 400, 400);
        context.globalAlpha = (context.globalAlpha - 0.01 + 1) % 1; //调节透明度
        width = (width + 1) % 100;
        height = (height + 1) % 100;
        context.beginPath();
        context.rect(20, 20, width, height);
        context.fill();
        context.stroke();

        //2D视图时可以省略
        // CanvasLayer.reFresh();

        AMap.Util.requestAnimFrame(function () {
          draw(context, width, height);
        });
      };
      var point = [
        [
          [116.328911, 39.937229],
          [116.342659, 39.946275],
        ],
        [
          [116.319384, 39.941683],
          [116.329384, 39.951683],
        ],
      ];
      var canvas = [];
      var CanvasLayer = [];
      var context = [];
      var width = [];
      var height = [];
      for (let i = 0; i < point.length; ++i) {
        canvas[i] = document.createElement("canvas");
        canvas[i].width = canvas[i].height = 200;
        context[i] = canvas[i].getContext("2d");
        context[i].fillStyle = "rgb(0,100,255)";
        context[i].strokeStyle = "white";
        context[i].globalAlpha = 1;
        context[i].lineWidth = 2;
        width[i] = 0;
        height[i] = 0;
        CanvasLayer[i] = new AMap.CanvasLayer({
          canvas: canvas[i],
          bounds: new AMap.Bounds(point[i][0], point[i][1]),
          zooms: [3, 18],
        });
        CanvasLayer[i].setMap(map);
        draw(context[i], width[i], height[i]);
      }
    },
    // 地图中使用鼠标绘制覆盖物
    // https://lbs.amap.com/api/javascript-api/example/mouse-operate-map/mouse-draw-overlayers
    // 鼠标工具插件 https://lbs.amap.com/api/javascript-api/reference/plugin#AMap.PolyEditor
    useMouseDraw(map) {
      const _this = this;
      this.mouseTool = new AMap.MouseTool(map);
      // 监听draw事件可获取画好的覆盖物
      this.overlays = [];
      this.mouseTool.on("draw", function (e) {
        // console.log(e)
        _this.overlays.push(e.obj);
      });
      this.radios = document.getElementsByName("func");
      for (let i = 0; i < this.radios.length; i++) {
        this.radios[i].onchange = (e) => {
          this.draw(e.target.value,this.mouseTool);
        };
      }
      map.on("click",function(e) {
        
        console.log([e.lnglat.lng,e.lnglat.lat],"click")
      })
    },
    draw(type,mouseTool) {
      // console.log(type,"type")
      switch (type) {
        case "marker": {
          mouseTool.marker({
            //同Marker的Option设置
          });
          break;
        }
        case "polyline": {
          mouseTool.polyline({
            strokeColor: "#80d8ff",
            //同Polyline的Option设置
          });
          break;
        }
        case "polygon": {
          mouseTool.polygon({
            fillColor: "#00b0ff",
            strokeColor: "#80d8ff",
            //同Polygon的Option设置
          });
          break;
        }
        case "rectangle": {
          mouseTool.rectangle({
            fillColor: "#00b0ff",
            strokeColor: "#80d8ff",
            //同Polygon的Option设置
          });
          break;
        }
        case "circle": {
          mouseTool.circle({
            fillColor: "#00b0ff",
            strokeColor: "#80d8ff",
            //同Circle的Option设置
          });
          break;
        }
      }
    },
    clear() {
      this.map.remove(this.overlays);
      this.overlays = [];
    },
    close() {
      this.mouseTool.close(true); //关闭并清除覆盖物
      for (let i = 0; i < this.radios.length; i++) {
        this.radios[i].checked = false;
      }
    },
    change(e) {
      //  e.lnglat.lng e.lnglat.lat
      this.getLocation(e, this.map);
    },
  },
};
</script>

<style lang="scss" scoped>
.input-card {
  width: 200px;
  right: 20px;
  bottom: 30px;
  z-index: 1000;
  padding: 10px 20px;
  position: absolute;
  background: #ffffff;
}
</style>

4、引用map组件 

<template>
  <div class="home">
    <myMap />
  </div>
</template>

<script>
// @ is an alias to /src
import myMap from "../components/mapdemo"

export default {
  name: 'home',
  components: {
    myMap
  }
}
</script>

 

  • 3
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值