vue引用高德地图电子围栏功能

文章描述了一个Vue组件用于在地图上绘制和编辑围栏的过程,包括初始化地图、绘制多边形、编辑和删除围栏的逻辑。在删除围栏时遇到问题,因多次渲染导致图层叠加,实际删除的只是最新图层。解决方案是初始化时清除所有图层,并通过右键菜单单个围栏进入编辑状态来处理编辑和删除操作。
摘要由CSDN通过智能技术生成

 

<template>

  <div class="main">

    <section class="section">

      <div class="ebox">

        <ButtonGroup>

          <Tooltip content="左键绘制围栏,右键绘制结束退出">

            <Button

              type="info"

              icon="ios-locate-outline"

              :disabled="addFlag"

              @click="drawRectangle"

            >

              绘制围栏</Button

            ></Tooltip

          >

          <!-- <Button

            type="primary"

            icon="ios-create-outline"

            @click="editRectangle"

            >编辑围栏</Button

          > -->

          <!-- <Button type="warning" icon="md-close" @click="cancelRectangle"

            >结束编辑</Button

          > -->

          <Button

            type="success"

            icon="md-checkmark-circle"

            @click="saveRectangle"

            >保存围栏</Button

          >

          <Tooltip content="清空未保存围栏">

            <Button type="error" icon="ios-trash-outline" @click="deleRectangle"

              >重新绘制</Button

            ></Tooltip

          >

        </ButtonGroup>

      </div>

      <!-- 地图 -->

      <div id="container" style="width: 100%; height: 100%" />

      <!-- 控制按钮组 -->

    </section>

  </div>

</template> 

<script>

import {

  addFence,

  getFence,

  setFence,

  delFence,

} from "@/api/totalEquipment/totalEquipmentRequest.js";

export default {

  props: { iotId: String, tabName: String },

  data() {

    return {

      companyId: window.sessionStorage.getItem("companyId"),

      // 地图对象

      map: null,

      // 右键菜单对象

      contextMenu: null,

      centerArr: [113.756232, 23.055855], //地图中心位置,不能为空数组【为空数组会报错】

      path: [], //以前绘制的数据

      paths: [], // 当前绘制的多边形经纬度数组

      polygonItem: [], // 地图上绘制的所有多边形对象

      polyEditors: [], // 新增数据=>所有编辑对象数组

      addFlag: false,

      editFlag: false,

      // 编辑参数对象

      editParams: [],

      // 围栏删除ID

      deleteID: "",

    };

  },

  watch: {},

  created() {},

  mounted() {

    setTimeout(() => {

      //异步加载(否则报错initMap is not defined)

      this.initMap();

      // 初始化数据

      this.init();

    }, 100);

  },

  methods: {

    // 地图初始化

    initMap() {

      this.map = new AMap.Map("container", {

        resizeEnable: true, // 窗口大小调整

        center: this.centerArr, // 中心

        zoom: 15, //放大级别

        showLabel: true, // 是否显示地图文字标记

        willReadFrequency: true,

      });

      // 创建右键菜单

      this.contextMenu = new AMap.ContextMenu();

      const that = this;

      this.contextMenu.addItem(

        "编辑",

        function () {

          that.editParams.map((item) => {

            that.editRectangle(item);

          });

        },

        0

      );

      this.contextMenu.addItem(

        "删除",

        function () {

          if (that.editParams != "" && that.editParams.length > 1) {

            that.$Modal.confirm({

              title: "删除确认",

              content: "<p>还有正在编辑的电子围栏尚未保存,请问是否保存?</p>",

              okText: "继续删除",

              cancelText: "保存",

              onOk: () => {

                this.delFence();

              },

              onCancel: () => {

                that.saveRectangle(that.deleteID);

              },

            });

          } else {

            this.delFence();

          }

        },

        1

      );

      // 添加工具栏

      this.map.plugin(["AMap.ToolBar", "AMap.Scale", "AMap.Geocoder"], () => {

        const toolbar = new AMap.ToolBar(); // 工具条

        const scale = new AMap.Scale(); // 比例尺

        this.map.addControl(toolbar);

        this.map.addControl(scale);

        new AMap.Geocoder({

          radius: 1000,

        });

      });

    },

    // 绘制多边形

    drawRectangle() {

      this.addFlag = true;

      const This = this;

      let mouseTool = new AMap.MouseTool(This.map);

      mouseTool.polygon({

        //polygon:绘制多边形【线段:polyline;矩形:rectangle;圆:circle】

        strokeColor: "red",

        strokeOpacity: 0.4,

        strokeWeight: 6,

        fillColor: "#1791fc",

        fillOpacity: 0.2,

        // strokeStyle还支持 solid

        strokeStyle: "solid",

        // strokeDasharray: [30,10],

      });

      mouseTool.on("draw", function (event) {

        // console.log(event);

        // event.obj 为绘制出来的覆盖物对象

        let polygonItem = event.obj;

        let paths = polygonItem.getPath(); //取得绘制的多边形的每一个点坐标

        // console.log('覆盖物对象绘制完成各个点的坐标', paths, event);

        let path = []; // 编辑的路径

        paths.forEach((v) => {

          path.push([v.lng, v.lat]);

        });

        This.paths.push(path); //将新增数据放入paths数组里

        // This.editRectangle();//绘制完成,默认进入编辑状态

        // mouseTool.close();

        // This.mapNaNpxove(event.obj); // 删除多边形

      });

    },

    // 编辑围栏

    editRectangle(obj) {

      const path = obj.deviceFence;

      //新增的进入编辑状态

      let polygon = new AMap.Polygon({

        path: path,

        strokeColor: "#FF33FF",

        strokeWeight: 6,

        strokeOpacity: 0.2,

        fillOpacity: 0.2,

        fillColor: "#1791fc",

        zIndex: 50,

      });

      this.map.add(polygon);

      this.polygonItem.push(polygon);

      // 缩放地图到合适的视野级别

      this.map.setFitView([polygon]);

      const that = this;

      this.polyEditor = new AMap.PolyEditor(this.map, polygon);

      this.polyEditor.open();

      this.polyEditors.push(this.polyEditor);

      this.polyEditor.on("end", function (event) {

        // console.info("触发事件: end", event);

        // console.info("end修改后的经纬度:", polygon.getPath());

        const paths = []; //编辑的路径

        let path = polygon.getPath();

        path.forEach((v) => {

          paths.push([v.lng, v.lat]);

        });

        that.editParams.map((item) => {

          if (item.id == obj.id) {

            item.deviceFence = paths;

          }

        });

      });

    },

    // 删除围栏

    delFence() {

      delFence(this.deleteID).then((res) => {

        // console.log(res);

        this.$Message.success(res.msg);

        this.deleteID = "";

        that.editParams = [];

        this.init();

      });

    },

    // 结束编辑状态

    cancelRectangle() {

      this.polyEditors.forEach((item) => {

        item.close();

      });

    },

    //保存围栏

    saveRectangle(val) {

      // 结束编辑状态

      this.polyEditors.forEach((item) => {

        item.close();

      });

      // console.log(this.path);

      // console.log(this.paths);

      if (this.editParams != "") {

        if (val && val == this.deleteID) {

          let i = this.editParams.findIndex((item) => item.id == val);

          this.editParams.splice(i, 1);

          // console.log(this.editParams);

        }

        setFence(this.editParams).then((res) => {

          // console.log(res);

          this.$Message.success(res.msg);

          this.editParams = [];

          if (this.paths == "") {

            this.init();

          }

        });

      }

      if (this.paths != "") {

        var num = this.path.length + this.paths.length;

        if (num > 3) {

          return this.$Message.info("请勿保存超过3个电子围栏!");

        }

        var params = {

          companyId: this.companyId,

          iotId: this.iotId,

        };

        addFence(params, this.paths).then((res) => {

          // console.log(res);

          this.paths = [];

          this.polygonItem = [];

          this.init();

          this.$Message.success(res.msg);

        });

      }

    },

    // 重新绘制

    deleRectangle() {

      // 结束编辑状态

      this.polyEditors.forEach((item) => {

        item.close();

      });

      this.init();

    },

    //获取后台数据

    init() {

      const that = this;

      let params = {

        iotId: this.iotId,

        companyId: this.companyId,

      };

      that.path = [];

      getFence(params).then((res) => {

        that.map.clearMap();

        this.marker = new AMap.Marker({

          position: this.centerArr,

          offset: new AMap.Pixel(-13, -30),

          icon: new AMap.Icon({

            image:

              "http://a.amap.com/jsapi_demos/static/demo-center/icons/poi-marker-default.png",

            size: new AMap.Size(28, 35), //图标大小

            imageSize: new AMap.Size(28, 35),

          }),

        });

        this.marker.setMap(this.map);

        // console.log(res);

        res.map((item) => {

          var polygon = new AMap.Polygon({

            path: item.deviceFence,         

            strokeColor: "#FF33FF",

            strokeWeight: 6,

            strokeOpacity: 0.2,

            fillOpacity: 0.4,

            fillColor: "#1791fc",

            zIndex: 50,

          });

          that.path.push(item.deviceFence);

          that.map.add(polygon);

          //创建右键菜单

          polygon.on("rightclick", function (e) {

            // 设置右键菜单位置

            that.contextMenu.open(that.map, e.lnglat);

            that.editParams.push(item);

            that.deleteID = item.id;

          });

          that.map.setFitView();

        });

      });

    },

  },

};

</script>

问题点:

1.当处理删除时,接口调用全删了,但是界面只清除掉一个围栏图层,init重新调用获取数据接口,也清不掉

2.要按照每个围栏去记录编辑和删除的结果,必定调用接口,但是绘制渲染围栏时,返回结果只有经纬度,并无法携带标识ID

解决:

1.在init()获取数据,渲染地图图层的时候 调用map.clearMap()方法清掉所有图层

2.进入编辑模式时,单击围栏编辑,单个围栏数据对应收集操作,避免所有围栏同时进入编辑模式

原因:1.每次初始化数据时,都会再在地图上渲染一遍图层,而且每删除或编辑新增一个电子围栏的时候,都会初始化一个图层,所以一个电子围栏可能覆盖了很多图层,但是删除围栏的时候只是删掉了一个最新的图层,然后初始化之后就又会覆盖一层,所以初始化渲染围栏时要先把旧的图层清掉

2.当电子围栏进入编辑模式时,只携带了path经纬度,

 所以返回的时候自然不会有Id,所以只能设置右键菜单,单个围栏进入编辑状态,以便调用接口处理编辑逻辑

Vue是一个流行的JavaScript框架,可以用于构建用户界面。高德地图是一种流行的地图服务,它提供了丰富的地图功能和API。电子围栏是一种边界区域,当特定的设备或人员进入或离开该区域时会触发警报或其他特定操作。 在Vue中使用高德地图电子围栏,首先需要在Vue项目中引入高德地图JavaScript API,可以通过在index.html文件中引入相应的脚本来实现,然后在组件中使用Vue的生命周期钩子函数进行初始化和销毁。 在组件中,我们可以使用高德地图的API创建一个地图实例,并设置地图的中心点和缩放级别。然后,我们可以使用地图的绘图工具来创建电子围栏的多边形或圆形,可以通过监听绘图结束事件来获取围栏的坐标信息。 接下来,我们可以使用高德地图的围栏服务API来创建电子围栏。可以通过调用相应的方法,传入围栏的名称、坐标信息和其他参数来创建电子围栏。可以根据需求设置围栏的类型,如圆形、多边形等,以及警报触发的条件和动作。 在Vue中,可以通过使用指令或绑定事件来实现与电子围栏的交互。可以使用v-on指令来监听电子围栏的进入或离开事件,并触发相应的方法或动作。可以在方法中实现警报、通知或其他功能,以响应电子围栏的状态变化。 总之,Vue高德地图电子围栏可以通过使用高德地图的API和Vue的生命周期钩子函数,实现在Vue项目中创建和管理电子围栏及其交互的功能。通过结合Vue的灵活性和高德地图的丰富功能,可以实现各种场景下的电子围栏应用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值