当前位置: 首页 > article >正文

【天地图-点线面最全功能】天地图实现功能:回显、绘制、编辑、删除任意点线面

实现效果图

在这里插入图片描述

完整代码:

<!DOCTYPE html>
<html>

<head>
  <meta http-equiv="content-type" content="text/html; charset=utf-8" />
  <title>回显、绘制、编辑、删除任意点线面</title>
  <script src="http://api.tianditu.gov.cn/api?v=4.0&amp;tk=应用KEY值"
    type="text/javascript"></script>
  <style type="text/css">
    body,
    html {
      width: 100%;
      height: 100%;
      margin: 0;
      font-family: '微软雅黑';
    }

    #map {
      height: 400px;
      width: 100%;
    }

    input {
      margin-top: 10px;
      margin-left: 5px;
      font-size: 14px;
    }

    #contextMenu {
      position: absolute;
      background: white;
      border: 1px solid #ccc;
      box-shadow: 2px 2px 3px rgba(0, 0, 0, 0.2);
      z-index: 1000;
      display: none;
    }

    .context-menu-item {
      padding: 2px 12px;
      cursor: pointer;
      font-size: 14px;
    }

    .context-menu-item:hover {
      background: #f0f0f0;
    }
  </style>
  <script>
    var map, zoom = 10, handler;
    let isEdit = false; // 是否启用编辑
    // 右键菜单相关变量
    let contextMenu = null;
    let currentFeature = null; // 当前右键点击的元素
    let currentIndex = -1;     // 当前元素的索引
    let featureType = '';      // 元素类型:point/line/polygon

    // 点数据
    let pointOriginalArr = [
      [120.2536, 30.27093]
    ]
    // 线数据
    let lineOriginalArr = [
      [
        [119.86084, 30.41702],
        [119.96796, 30.47353],
        [119.98718, 30.36758],
      ],
      [
        [119.91714, 30.1855],
        [120.10666, 30.27923],
      ]
    ]
    // 面数据
    let polygonOriginalArr = [
      [
        [119.5752, 30.35392],
        [119.72488, 30.35273],
        [119.65347, 30.26025],
      ],
      [
        [120.49118, 30.29109],
        [120.70541, 30.30532],
        [120.50629, 30.20211],
        [120.69855, 30.22703]
      ]
    ]

    function onLoad () {
      // 创建右键菜单
      createContextMenu();
      //初始化地图对象
      map = new T.Map("map");
      //设置显示地图的中心点和级别
      map.centerAndZoom(new T.LngLat(120.216329, 30.252589), zoom);
      // 绑定地图点击事件隐藏菜单
      map.addEventListener('click', hideContextMenu);
      // 初始显示
      showPoint()
      showPolyLine()
      showPolygon()
    }

    // 创建右键菜单
    function createContextMenu () {
      contextMenu = document.createElement('div');
      contextMenu.id = 'contextMenu';
      contextMenu.innerHTML = `
        <div class="context-menu-item" onclick="deleteFeature()">删除</div>
      `;
      document.body.appendChild(contextMenu);
    }

    // 显示右键菜单
    function showContextMenu (e, feature, index, type) {
      // 获取天地图事件中的原生事件对象
      const originalEvent = e.originalEvent || e.event || e;
      if (originalEvent.preventDefault) {
        originalEvent.preventDefault();
      }

      currentFeature = feature;
      currentIndex = index;
      featureType = type;

      contextMenu.style.display = 'block';
      // 使用原生事件的坐标,定位菜单项
      contextMenu.style.left = originalEvent.clientX + 'px';
      contextMenu.style.top = originalEvent.clientY + 'px';
    }

    // 隐藏右键菜单
    function hideContextMenu () {
      contextMenu.style.display = 'none';
    }

    // 删除要素
    function deleteFeature () {
      if (currentIndex === -1) return;

      switch (featureType) {
        case 'point':
          pointOriginalArr.splice(currentIndex, 1);
          break;
        case 'line':
          lineOriginalArr.splice(currentIndex, 1);
          break;
        case 'polygon':
          polygonOriginalArr.splice(currentIndex, 1);
          break;
      }
      refreshMap();
      hideContextMenu();
    }

    // 刷新地图
    function refreshMap () {
      map.clearOverLays();
      showPoint();
      showPolyLine();
      showPolygon();
    }

    // 显示点
    function showPoint () {
      let pointArr = [];
      pointOriginalArr.forEach((item, index) => {
        let arr = []
        arr.push(new T.LngLat(item[0], item[1]))
        pointArr.push(arr);
      })
      pointArr.forEach((item, index) => {
        var marker = new T.Marker(item[0], {
          icon: new T.Icon({
            iconUrl: './imgs/marker-icon.png',
          }),
        });
        map.addOverLay(marker);

        // 修改事件绑定(添加event参数传递)
        marker.addEventListener('contextmenu', function (apiEvent) {
          showContextMenu(apiEvent, marker, index, 'point');
        });

        if (!isEdit) return;
        marker.enableDragging();
        marker.addEventListener('dragend', function (e) {
          updatePointOriginalList([e.lnglat.lng, e.lnglat.lat], index)
        })
      })
    }

    // 更新点的数据,用于最后保存
    function updatePointOriginalList (arr, index) {
      pointOriginalArr[index] = arr
    }

    // 显示线
    function showPolyLine () {
      let lineArr = []
      lineOriginalArr.forEach((item, index) => {
        let arr = []
        item.forEach((item1) => {
          arr.push(new T.LngLat(item1[0], item1[1]))
        })
        lineArr.push(arr)
      })
      lineArr.forEach((item, index) => {
        var line = new T.Polyline(item);
        map.addOverLay(line);

        // 修改事件绑定(添加event参数传递)
        line.addEventListener('contextmenu', function (apiEvent) {
          showContextMenu(apiEvent, line, index, 'line');
        });

        if (!isEdit) return
        line.enableEdit();
        line.addEventListener('edit', function (e) {
          const ht = line.getLngLats()
          let arr = []
          ht.forEach((item) => {
            arr.push([item.lng, item.lat])
          })
          updateLineOriginalList(arr, index)
        })
      })
    }

    // 更新线的数据,用于最后保存
    function updateLineOriginalList (arr, index) {
      lineOriginalArr[index] = arr
    }

    // 显示面
    function showPolygon () {
      let polygonArr = []
      polygonOriginalArr.forEach((item, index) => {
        let arr = []
        item.forEach((item1) => {
          arr.push(new T.LngLat(item1[0], item1[1]))
        })
        polygonArr.push(arr)
      })
      polygonArr.forEach((item, index) => {
        var polygon = new T.Polygon(item);
        map.addOverLay(polygon);

        // 修改事件绑定(添加event参数传递)
        polygon.addEventListener('contextmenu', function (apiEvent) {
          showContextMenu(apiEvent, polygon, index, 'polygon');
        });

        if (!isEdit) return
        polygon.enableEdit();
        polygon.addEventListener('edit', function (e) {
          const ht = polygon.getLngLats()[0]
          let arr = []
          ht.forEach((item) => {
            arr.push([item.lng, item.lat])
          })
          updatePolygonOriginalList(arr, index)
        })
      })
    }

    // 更新面的数据,用于最后保存
    function updatePolygonOriginalList (arr, index) {
      polygonOriginalArr[index] = arr
    }

    // 打点
    function openMarkerTool () {
      if (handler) handler.close();
      handler = new T.MarkTool(map, {
        follow: true,
        icon: new T.Icon({
          iconUrl: './imgs/marker-icon.png',
          // iconSize: new T.Point(24, 28), // 图标可视区域的大小
        }),
      });
      handler.open();
      handler.addEventListener('mouseup', function (e) {
        // 这里可以获取到当前点位的坐标
        pointOriginalArr.push([e.currentLnglat.lng, e.currentLnglat.lat])
        // 重新绘制地图,否则编辑不了
        refreshMap();
        handler.clear()
      })
    }

    // 画线
    function openPolylineTool () {
      if (handler) handler.close();
      handler = new T.PolylineTool(map);
      handler.open();
      handler.addEventListener('draw', function (e) {
        const currentLnglats = e.currentLnglats
        let arr = []
        currentLnglats.forEach((item, index) => {
          arr.push([item.lng, item.lat])
        })
        lineOriginalArr.push(arr)
        // 重新绘制地图,否则编辑不了
        refreshMap();
        handler.clear()
      })
    }

    // 画面
    function openPolygonTool () {
      if (handler) handler.close();
      handler = new T.PolygonTool(map);
      handler.open();
      handler.addEventListener('draw', function (e) {
        const currentLnglats = e.currentLnglats
        let arr = []
        currentLnglats.forEach((item, index) => {
          arr.push([item.lng, item.lat])
        })
        polygonOriginalArr.push(arr)
        // 重新绘制地图,否则编辑不了
        refreshMap();
        handler.clear()
      })
    }

    // 开启编辑
    function editClick () {
      isEdit = true
      map.clearOverLays()
      showPoint()
      showPolyLine()
      showPolygon()
    }
    // 保存
    function saveClick () {
      console.log("点数据:", pointOriginalArr); // 两层结构:大数组中,包含点的小数组
      console.log("线数据:", lineOriginalArr); // 三层结构:大数组中包含线的数组,线的数组中包含经纬度小数组
      console.log("面数据:", polygonOriginalArr); // 三层结构:大数组中包含面的数组,面的数组中包含经纬小数组
      isEdit = false
      map.clearOverLays()
      showPoint()
      showPolyLine()
      showPolygon()

    }
    // 清空画布
    function clearClick () {
      isEdit = false
      map.clearOverLays()
      pointOriginalArr = []
      lineOriginalArr = []
      polygonOriginalArr = []
    }

  </script>
</head>

<body onLoad="onLoad()">
  <div id="map"></div>
  <div class="line-btn">
    <input type="button" value="点工具" onClick="openMarkerTool() " />
    <input type="button" value="线工具" onClick="openPolylineTool() " />
    <input type="button" value="面工具" onClick="openPolygonTool() " />
    <input type="button" value="编辑" onClick="editClick() " />
    <input type="button" value="保存" onClick="saveClick() " />
    <input type="button" value="清除" onClick="clearClick() " />
  </div>
</body>

</html>

复制上面代码,替换应用KEY值即可看到功能效果。


http://www.kler.cn/a/564121.html

相关文章:

  • Linux 文件操作与 Socket 编程核心知识详解
  • JVM的初步学习
  • Chapter 4 Noise performance of elementary transistor stages
  • windows 下 使用Python OpenCV针对 压缩的tiff 图像进行解压缩 并转换成多张jpeg 图像
  • 部署Flink1.20.1
  • nginx 搭建 IPv6 -> IPv4 反向代理服务器
  • 淘宝商品搜索API实战:Elasticsearch分词与排序算法优化
  • 【数字图像处理三】图像变换与频域处理
  • 矩阵营销的 AI 进化:DeepSeek 如何助力批量运营账号?
  • 使用 Apache Dubbo 释放 DeepSeek R1 的全部潜力
  • Linux nc 命令详解
  • 如何下载MinGW-w64到MATLAB
  • Java集合性能优化面试题
  • 【Linux】CentOS7停服之后配置yum镜像源
  • Ubuntu 下通过 Docker 部署 Nginx 服务器
  • Ubuntu指令(一)
  • 如何优化Redis性能:从理论到实践
  • 苹果折叠屏iPhone突破折痕难题 或将在2026年发布
  • git 常用功能
  • AI快速变现之路,AI视频创作