高德地图-电子围栏-多边形增删改

该文章提供了一个实现高德地图上多边形电子围栏的完整代码,包括多边形的初始渲染、编辑功能(添加、删除、选中编辑)、以及多边形label的居中显示。用户可以直接复制代码并替换自己的APIkey进行使用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

史上最完整的实现高德地图多边形电子围栏:

主要功能:多边形的初始渲染,点击编辑进入编辑状态,方可进行添加、右击删除、双击选中编辑,以及每个多边形的label名称居中展示

来先看效果图,嘻嘻~~~

--------------------------------------------------

 好了,直接上代码,直接复制即可用

注意:只要替换成自己的key值就好

<!doctype html>
<html>
<head>
  <meta charset="utf-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="initial-scale=1.0, user-scalable=no, width=device-width">
  <style>
    html,
    body,
    #container {
      width: 100%;
      height: 100%;
    }
  </style>
  <title>高德地图-电子围栏-多边形增删改</title>
  <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=2.0&key=你的key&plugin=AMap.PolygonEditor"></script>
</head>
<body>
  <div id="container"></div>
  <div class="input-card" style="width: 120px;bottom: 150px">
    <button class="btn" onclick="editPolygon()" >编辑图形</button>
  </div>
  <div class="input-card" style="width: 120px">
    <button class="btn" onclick="addPolygon()" style="margin-bottom: 5px">添加图形</button>
    <button class="btn" onclick="submitData(1)" style="margin-bottom: 5px">取消</button>
    <button class="btn" onclick="submitData(2)" style="margin-bottom: 5px">保存</button>
  </div>
  <script type="text/javascript">
    var map  = null;
    var polyEditor = null; //多边形编辑器
    var pathArr = []; //获取后台模拟数据
    var polygonArr = []; //地图上所有的多边形
    var labelArr = [] //地图上所有多边形所对应的名称
    var isEdit = false; //是否处于可编辑状态

    initMap(); //初始化地图
    //初始化地图
    function initMap() {
      map = new AMap.Map("container", {
        center: [116.400274, 39.905812],
        zoom: 14
      });
      getInitMapData() //获取初始地图多边形数据
    }
    //获取初始地图多边形数据
    function getInitMapData() {
      var path1 = [[116.475334, 39.997534], [116.476627, 39.998315], [116.478603, 39.99879], [116.478529, 40.000296], [116.475082, 40.000151], [116.473421, 39.998717]]
      var path2 = [[116.474595, 40.001321], [116.473526, 39.999865], [116.476284, 40.000917]]
      pathArr = [
        {
          path: path1,
          mapId: 1,
        }, 
        {
          path: path2,
          mapId: 2,
        }, 
      ]
      showInitPolygon(); //初始展示所有多边形
    }
    //初始展示所有多边形
    function showInitPolygon() {
      var dealPolygonArr = []
      var dealLabelArr = []
      pathArr && pathArr.forEach((el, index) => {
        var polygon = new AMap.Polygon({
          path: el.path,
          fillColor: "#FF8D8D",
          fillOpacity: 0.3,
          strokeWeight: 3,
          strokeColor: "#FF8D8D",
          strokeOpacity: 1,
          zIndex: 1,
          extData: {
            mapId: el.mapId,
          }
        })
        var label = showText(polygon); //每个多边形添加label
        //
        dealPolygonArr.push(polygon)
        polygonArr = dealPolygonArr
        //
        dealLabelArr.push(label)
        labelArr = dealLabelArr
      })
      map.add(polygonArr);
      // 缩放地图到合适的视野级别
      map.setFitView(polygonArr)
    }
    //每个多边形添加label
    function showText(polygon) {
      var point = getCenterPoint(polygon.getPath());  //获得中心点
      var label = new AMap.Text({
        text: 'labelname',
        anchor: 'center', // 设置文本标记锚点
        style: {
          'background-color': 'transparent',
          'border-width': 0,
          'text-align': 'center',
          'font-size': '14px',
          'color': '#444444',
        },
        // offset: new AMap.Pixel(0, 0),
        position: point
      });
      label.setMap(map);
      return label;
    }
    // 获得图形的中心点
    function getCenterPoint(path) {
      var x = 0.0;
      var y = 0.0;
      for (var i = 0; i < path.length; i++) {
        x = x + parseFloat(path[i].lng);
        y = y + parseFloat(path[i].lat);
      }
      x = x / path.length;
      y = y / path.length;
      return new AMap.LngLat(x, y);
    }
    //添加多边形
    function addPolygon() {
      drawPolygon();
    }
    //绘制多边形
    function drawPolygon() {
      polyEditor.close();
      polyEditor.setTarget();
      polyEditor.open();
    }
    //开启多边形编辑
    function editPolygon() {
      initEditor(); //初始化地图编辑器
      isEdit = true;
      // polyEditor.open();
    }
    //初始化地图编辑器
    function initEditor() {
      polyEditor = new AMap.PolygonEditor(map)
      polyEditor.addAdsorbPolygons(polygonArr);
      polyEditor._opt.createOptions = { // 创建区域的样式
        fillColor: "#FF8D8D",
        fillOpacity: 0.3,
        strokeWeight: 3,
        strokeColor: "#FF8D8D",
        strokeOpacity: 1,
      };
      polyEditor._opt.editOptions = {// 编辑区域的样式
        fillColor: "#FF8D8D",
        fillOpacity: 0.3,
        strokeWeight: 3,
        strokeColor: "#FF8D8D",
        strokeOpacity: 1,
      };
      // polyEditor.midControlPoint = { // 点位样式
      //   fillColor: "#FF8D8D",
      //   fillOpacity: 1,
      //   strokeWeight: 2,
      //   strokeColor: "#FF8D8D",
      //   bubble: false,
      //   clickable: true,
      //   cursor: "pointer",
      // };
      // polyEditor.controlPoint = {// 点位样式
      //   fillOpacity: 1,
      //   strokeWeight: 2,
      //   strokeColor: "#FF8D8D",
      //   bubble: false,
      //   clickable: true,
      //   cursor: "pointer",
      // };

      polygonArr && polygonArr.forEach((polygon, index) => {
        //多边形添加双击事件
        polygon.on('dblclick', () => {
          if (polyEditor) {
            polyEditor.setTarget(polygon);
            polyEditor.open();
          }
        })
        //绑定右击事件——弹出右键菜单
        polygon.on('rightclick', function (e) {
          clearOne(e.lnglat, polygon, labelArr[index]); //创建右键菜单menu 删(删除多边形)
        });
        // //鼠标高亮效果
        // polygon.on('mouseover', function (e) {
        //   polygon.setOptions({
        //     fillColor: '#1791fc',
        //   })
        // });
        // polygon.on('mouseout', function (e) {
        //   polygon.setOptions({
        //     fillColor: '#FF8D8D',
        //   })
        // });
      })


      //多边形添加
      polyEditor.on('add', function (data) {
        console.log('add');
        var polygon = data.target;
        //
        polyEditor.addAdsorbPolygons(polygon);
        polygonArr.push(polygon);
        //
        var label = showText(polygon); //每个多边形添加label
        labelArr.push(label)
        // 双击图层进行编辑
        polygon.on('dblclick', () => {
          if (polyEditor) {
            polyEditor.setTarget(polygon);
            polyEditor.open();
          }
        })
        //绑定右击事件——弹出右键菜单
        polygon.on('rightclick', function (e) {
          clearOne(e.lnglat, polygon, label); //创建右键菜单menu 删(删除多边形)
        });
        // setTimeout(() => {
        //   addPolygon(); //添加多边形
        // }, 400)
      })

    }
    //创建右键菜单 删(删除多边形)
    function clearOne(lnglat, onePolygon, oneLabel) {
      var rightMenu = new AMap.ContextMenu();
      rightMenu.addItem('删除', function (e) {
        // if (that.isEdit) {
        removePolygon(onePolygon, oneLabel);
        rightMenu.close()
        // } else {
        //   that.$messageBlock('error', '当前未在编辑状态');
        // }
      }, 0);
      rightMenu.open(map, lnglat);
    }
    //删除某个多边形
    function removePolygon(onePolygon, oneLabel) {
      polyEditor.close(); //关闭编辑器
      map.remove(onePolygon);
      map.remove(oneLabel);
      // 获取覆盖物
      var overlays = map.getAllOverlays('polygon');
      polygonArr = overlays
    }
    //保存绘制数据
    function submitData(flag) {
      if (flag == 1) { //取消
        polyEditor.close();
        polyEditor = null;
        isEdit = false;
        map.clearMap(); // 清除地图上所有添加的覆盖物
        getInitMapData() //获取初始地图多边形数据
      } else if (flag == 2) { //保存
        console.log(polygonArr)
      }
    }
  </script>
</body>

</html>

2024.12.19补充:

编辑器的所有监听事件:

// 初始化编辑器
const polyEditor = new AMap.PolygonEditor(map, polygon);

// 1. 开始编辑时触发
polyEditor.on('add', function(data) {
  console.log('开始绘制多边形');
});

// 2. 编辑过程中触发,即每次点击添加一个点时触发
polyEditor.on('addnode', function(data) {
  console.log('添加节点');
  console.log(data.target.getPath()); // 获取所有顶点坐标
});

// 3. 调整节点位置时触发
polyEditor.on('adjust', function(data) {
  console.log('调整节点位置');
  console.log(data.target.getPath());
});

// 4. 删除节点时触发
polyEditor.on('removenode', function(data) {
  console.log('删除节点');
  console.log(data.target.getPath());
});

// 5. 编辑完成时触发
polyEditor.on('end', function(data) {
  console.log('结束编辑');
  const path = data.target.getPath();
  console.log('最终围栏坐标:', path);
});

// 6. 右键单击事件,通常用于结束绘制
map.on('rightclick', function() {
  polyEditor.close();
});

最后,如果有用,点个赞啦~~~ 哈哈哈

<think>我们正在使用Vue3和Element-Plus框架,并集成高德地图来实现电子围栏功能。电子围栏通常指在地图上绘制一个封闭区域(多边形),并判断某个点是否在该区域内。我们将使用高德地图JavaScriptAPI,特别是多边形绘制和编辑功能。步骤概述:1.在项目中引入高德地图JavaScriptAPI。2.在Vue组件中创建地图容器。3.初始化地图。4.使用高德地图的插件(如Polygon,PolyEditor)来绘制和编辑多边形电子围栏)。5.保存围栏的坐标数据,以便后续使用(比如判断点是否在围栏内)。根据引用[2],我们需要先在项目中注册高德地图,可以使用`vue-amap`库,但注意该库是为Vue2设计的,对于Vue3,我们可以使用官方JSAPI或者寻找Vue3的封装(如`@vuemap/vue-amap`)。不过,为了更直接的控制,我们将直接使用高德地图JavaScript API。因此,我们选择不使用`vue-amap`,而是直接通过`<script>`标签引入高德地图API,或者使用npm包`@amap/amap-jsapi-loader`。这里我们使用`@amap/amap-jsapi-loader`来加载高德地图API。实现步骤:步骤1:安装依赖首先,安装`@amap/amap-jsapi-loader`:```bashnpminstall @amap/amap-jsapi-loader --save```步骤2:在Vue组件中初始化地图在组件的`<template>`中创建地图容器:```html<template><div class="map-container"><div id="map-container"style="width:100%;height:500px;"></div></div></template> ```步骤3:在组件的`<script>`部分初始化地图并添加电子围栏功能我们将使用Composition API。注意:高德地图要求先申请key,并在初始化时使用。步骤4:绘制多边形电子围栏)并启用编辑功能步骤5:保存绘制的围栏数据具体代码实现:我们将创建一个Vue组件,组件加载时初始化地图,并添加绘制多边形的功能。同时,我们使用ElementPlus的按钮来控制绘制和保存。参考引用[4]中的代码片段,我们可以知道如何构造多边形的路径。另外,引用[3]提到使用`GeneralPath`类来判断点是否在多边形内,但这在JavaScript中不适用。高德地图提供了`AMap.GeometryUtil`类,其中包含`isPointInRing`等方法,可以用来判断点是否在多边形内。不过,我们这里主要实现绘制和编辑功能,判断点是否在围栏内可以在需要时使用高德地图的工具方法。代码示例:注意:由于高德地图JS API的安全要求,我们可能需要设置安全密钥(在2021年12月02日后,需要同时设置key和安全密钥)。具体请参考高德地图官网。以下是组件的示例代码:</think>在 Vue3 和 Element-Plus 框架中集成高德地图实现电子围栏功能,可通过以下步骤实现: ### 实现步骤 1. **初始化高德地图** ```vue <template> <div id="map-container" style="width:100%; height:500px"></div> </template> <script setup> import { onMounted } from 'vue'; import AMapLoader from '@amap/amap-jsapi-loader'; let map = null; let polygonEditor = null; let fencePolygon = null; onMounted(async () => { await AMapLoader.load({ key: '您的高德地图Key', version: '2.0', plugins: ['AMap.Polygon', 'AMap.PolyEditor'] }); map = new AMap.Map('map-container', { zoom: 13, center: [116.397428, 39.90923] // 默认中心点 }); }); </script> ``` 2. **绘制电子围栏** ```javascript const drawFence = () => { // 创建多边形围栏 fencePolygon = new AMap.Polygon({ path: [ [116.368904, 39.913423], [116.382122, 39.901176], [116.387271, 39.922501] ], strokeColor: "#FF33FF", fillColor: "#1791fc", fillOpacity: 0.2 }); map.add(fencePolygon); // 启用编辑功能 polygonEditor = new AMap.PolyEditor(map, fencePolygon); polygonEditor.open(); }; ``` 3. **实现围栏判断功能** ```javascript const checkInFence = (lnglat) => { if (!fencePolygon) return false; return fencePolygon.contains(lnglat); }; // 示例:检查坐标点是否在围栏内 const point = [116.378028, 39.907192]; console.log(checkInFence(point)); // 返回 true/false ``` 4. **集成 Element-Plus UI 控件** ```vue <template> <el-button @click="drawFence">绘制围栏</el-button> <el-button @click="saveFence">保存围栏</el-button> <div id="map-container" ...></div> </template> ``` 5. **保存围栏数据** ```javascript const saveFence = () => { if (!fencePolygon) return; const path = fencePolygon.getPath(); console.log('围栏坐标:', path); // 发送到后端保存 }; ``` ### 关键配置说明 1. **高德 Key 申请** - 前往[高德开放平台](https://lbs.amap.com/)申请 JavaScript API Key - 安全密钥配置(2021年后必需): ```javascript window._AMapSecurityConfig = { securityJsCode: '您的安全密钥' }; ``` 2. **插件依赖** - 必需插件:`AMap.Polygon`(多边形)、`AMap.PolyEditor`(多边形编辑器) - 推荐插件:`AMap.MouseTool`(绘图工具) ### 注意事项 1. 使用 `@amap/amap-jsapi-loader` 替代旧版 `vue-amap`(Vue2专用) 2. 围栏路径需闭合:首尾坐标点相同 3. 编辑状态管理:通过 `polygonEditor.open()`/`.close()` 控制编辑模式 4. 性能优化:复杂围栏建议使用 `WebWorker` 进行计算[^3] ### 效果增强建议 - 添加围栏顶点拖拽提示(Element Plus 的 `el-tooltip`) - 实现围栏层级管理(使用 `el-tree` 展示多围栏结构) - 添加围栏区域面积计算 - 集成地理围栏报警功能(监听 `map.on('moveend')` 事件) > 电子围栏的核心是判断点与多边形的位置关系,高德地图的 `Polygon.contains()` 方法使用射线法算法实现此功能[^3]。对于复杂场景,建议后端使用 JTS 库进行精确地理计算。
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

仰望半月

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值