鼠标工具绘制(电子围栏,矢量图形,矢量编辑) 高德地图

539 阅读1分钟

仅前端

电子围栏 根据高德地图API实现简单的前端效果

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <meta http-equiv="X-UA-Compatible" content="chrome=1" />
    <meta
      name="viewport"
      content="initial-scale=1.0, user-scalable=no, width=device-width"
    />
    <link
      rel="stylesheet"
      href="https://a.amap.com/jsapi_demos/static/demo-center/css/demo-center.css"
      type="text/css"
    />
    <style>
      html,
      body,
      #container {
        height: 100%;
      }
      .input-item {
        height: 2.2rem;
      }
      .btn {
        width: 6rem;
        margin: 0 1rem 0 2rem;
      }
      .input-text {
        width: 4rem;
        margin-right: 1rem;
      }

      #clearAlone {
        position: fixed;
        bottom: 6rem;
        background-color: white;
        border-width: 0;
        right: 1rem;
        box-shadow: 0 2px 6px 0 rgb(114 124 245 / 50%);
        display: flex;
        flex-direction: column;
        border-radius: 0.4rem;
      }

      #clearAlone .btn {
        margin: 1rem 1rem 0rem 1rem;
      }

      #clearAlone .btn:last-child {
        margin-bottom: 1rem;
      }
    </style>
    <title>鼠标工具绘制(电子围栏,矢量图形,矢量编辑)</title>
    <script src="https://webapi.amap.com/maps?v=2.0&key=替换key&plugin=AMap.MouseTool,AMap.PolygonEditor"></script>
    <script src="https://a.amap.com/jsapi_demos/static/demo-center/js/demoutils.js"></script>
  </head>
  <body>
    <div id="container"></div>
    <div class="info">
      操作说明:圆和矩形通过拖拽来绘制,其他覆盖物通过点击来绘制
    </div>

    <div id="clearAlone"></div>

    <div class="input-card" style="width: 24rem">
      <div class="input-item">
        <input id="clear" type="button" class="btn" value="清除" />
        <input id="get" type="button" class="btn" value="获取坐标" />
      </div>
    </div>
    <script type="text/javascript">
      // 获取本地有没有 start
      let previous = localStorage.getItem("previous");
      if (previous) previous = JSON.parse(previous);
      // 获取本地有没有 end

      let map = new AMap.Map("container", {
        zoom: 14,
      });

      let mouseTool = new AMap.MouseTool(map);
      // 监听draw事件可获取画好的覆盖物
      let overlays = []; // 覆盖物存储 (用于最终获取坐标)
      let polyArr = []; // 编辑的坐标存储 (用于清除的时候也清除编辑的点)

      mouseTool.on("draw", function (e) {
        let hex = randomHexColor();
        overlays.push(e.obj); // 存储信息

        let polyEditor = new AMap.PolygonEditor(
          map,
          e.obj,
          polygonOptFun({
            strokeColor: hex,
            editOptions: {
              strokeColor: hex,
            },
          })
        ); // 编辑插件
        polyEditor.open(); // 打开编辑
        polyArr.push(polyEditor); // 存储编辑
        applyCurFun();
      });

      mouseTool.polygon(polygonOptFun());

      if (previous && previous instanceof Array) {
        previous.forEach((item) => {
          let polygon = new AMap.Polygon(polygonOptFun({ ...item }));

          map.add([...overlays, polygon]); // 添加图层`
          overlays.push(polygon);

          let polyEditor = new AMap.PolygonEditor(
            map,
            polygon,
            polygonOptFun({
              strokeColor: item.strokeColor,
              editOptions: {
                strokeColor: item.strokeColor,
              },
            })
          ); // 编辑插件
          polyEditor.open(); // 打开编辑
          polyArr.push(polyEditor); // 存储编辑
        });

        applyCurFun();
      }

      // 清除全部的
      document.getElementById("clear").onclick = function () {
        polyArr.forEach((item) => {
          item.close(); // 不执行该操作 会留下编辑的点
        });

        map.remove(overlays);
        overlays = [];
        applyCurFun();
      };

      // ---------------- 获取当前所有的电子围栏坐标 start ------------------------
      document.getElementById("get").onclick = function () {
        let allArr = [];
        let arr = [];
        overlays.forEach((item) => {
          let obj = {
            strokeColor: item._opts.strokeColor,
            editOptions: item._opts.editOptions,
          };

          allArr.push(item.getPath());

          let path = [];
          item.getPath().forEach((gItem) => {
            path.push([gItem.lng, gItem.lat]);
          });

          arr.push({ ...obj, path });
        });

        // 存储到本地
        localStorage.setItem("previous", JSON.stringify(arr));
      };

      // ---------------- 获取当前所有的电子围栏坐标 end ------------------------

      // ---------------- 删除 start ------------------------
      // 事件委托 点击删除事件
      document.getElementById("clearAlone").onclick = function (e) {
        e = e || window.event;
        let target = e.target || e.srcElement;
        if (target.nodeName.toLowerCase() == "input") {
          aloneDel(target.dataset.index);
        }
      };

      // 单独删除 方法
      function aloneDel(index) {
        polyArr[index].close(); // 不执行该操作 会留下编辑的点
        map.remove(overlays[index]); // 删除覆盖物
        overlays.splice(index, 1);
        polyArr.splice(index, 1);

        applyCurFun(); // 重新渲染删除按钮
      }

      // ---------------- 删除 end ------------------------

      // ---------------- 其他方法 start ------------------------
      /**
       * ! polygon 的参数集合方法
       * @param { object } obj 自定义配置项
       */
      function polygonOptFun(obj) {
        return {
          zIndex: 50, // 多边形覆盖物的叠加顺序。地图上存在多个多边形覆盖物叠加时,通过该属性使级别较高的多边形覆盖物在上层显示
          // bubble : '', // 是否将覆盖物的鼠标或touch等事件冒泡到地图上(自v1.3 新增)
          // cursor : '',  // 指定鼠标悬停时的鼠标样式,自定义cursor,IE仅支持cur/ani/ico格式,Opera不支持自定义cursor
          strokeColor: "#1E9FFF", // 线条颜色,使用16进制颜色代码赋值。默认值为#00D3FC
          strokeOpacity: 1, // 轮廓线透明度,取值范围 [0,1] ,0表示完全透明,1表示不透明。默认为0.9
          strokeWeight: 2, // 轮廓线宽度
          fillColor: "#1E9FFF", // 多边形填充颜色,使用16进制颜色代码赋值,如:#00B2D5
          fillOpacity: 0.1, // 多边形填充透明度,取值范围 [0,1] ,0表示完全透明,1表示不透明。默认为0.5
          draggable: false, // 设置多边形是否可拖拽移动,默认为false
          strokeStyle: "solid", // 轮廓线样式,实线:solid, 虚线:dashed
          ...obj,
        };
      }

      // 渲染当前的删除按钮(单独按钮)
      function applyCurFun() {
        // 如果有了
        if (overlays.length > 0) {
          // 则判断最后一个的标点是否小于 2
          if (overlays[overlays.length - 1].getPath().length < 2) {
            aloneDel(overlays.length - 1);
          }
        }

        let str = "";
        overlays.forEach((item, index) => {
          str += `
            <input style="color: ${item._opts.strokeColor}; border-color: ${
            item._opts.strokeColor
          };" type="button" class="btn" name="aloneDel" data-index="${index}" value="删除围栏${
            index + 1
          }" />
          `;
        });

        document.getElementById("clearAlone").innerHTML = str;
      }

      // 随机生成十六进制颜色
      // 参考 https://www.jb51.net/article/102109.htm ||||||||||| https://blog.csdn.net/TheFirstTest/article/details/121945046
      function randomHexColor() {
        var hex = Math.floor(Math.random() * 16777216).toString(16); // 生成 ffffff 以内16进制数
        while (hex.length < 6) {
          hex = "0" + hex; // while循环判断hex位数,少于6位前面加0凑够6位
        }
        return "#" + hex; //返回 '#' 开头16进制颜色
      }
      // ---------------- 其他方法 end ------------------------
    </script>
  </body>
</html>

有用的话 点个赞