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

vue基于高德地图实现城市管网压力点、管线、测距、测面积、绘制多边形、绘制圆代码

最近在研究城市管网gis系统是如何实现管网绘制的,于是基于高德地图研究了下管线和压力点、管线名称实现的逻辑,输出了一个简单的demo,最终效果如下:

1、定义标记点位

2、自定义绘制折线

3、绘制矩形

4、绘制多边形

5、绘制圆形

6、鼠标放大缩小

7、计算区域面积

8、测量距离

代码如下:

<template>
  <div id="amapContainer"></div>
</template>

<script>
import { getAngle } from '@/utils/index.js';
export default {
  name: 'amap3d',
  data () {
    return {
      makers: [
        { Lng: 116.501415, Lat: 39.926055 },
        { Lng: 116.474605, Lat: 39.946324 },
      ]
    };
  },
  mounted () {
    this.intAmap();
  },
  methods: {
    drawMap (city = '北京市', LngLats) {
      const AMap = this.AMap;
      const vm = this;
      const opts = {
        subdistrict: 0,
        extensions: 'all',
        level: 'city'
      };
      //利用行政区查询获取边界构建mask路径
      //也可以直接通过经纬度构建mask路径
      const district = new AMap.DistrictSearch(opts);
      district.search(city, function (status, result) {
        const bounds = result.districtList[0].boundaries;
        const mask = [];
        for (let i = 0; i < bounds.length; i += 1) {
          mask.push([bounds[i]]);
        }
        const map = new AMap.Map('amapContainer', {
          mask: mask,
          center: [116.501415, 39.926055],
          disableSocket: true,
          viewMode: '2D',
          showLabel: false,
          labelzIndex: 130,
          pitch: 0,
          zoom: 15,
          // mapStyle: "amap://styles/darkblue",
          // 卫星地图显示
          layers: [
            // new AMap.TileLayer.RoadNet({
            //   //rejectMapMask:true
            // }),
            // new AMap.TileLayer.Satellite()
          ]
        });


        // 添加压力监测点
        (LngLats || []).forEach(v => {
          const position = new AMap.LngLat(v.Lng, v.Lat);
          // 点标记显示内容,HTML要素字符串
          const markerContent = '' +
            `<div class="custom-content-marker zyc-marker-icon">
              <img src="//a.amap.com/jsapi_demos/static/demo-center/icons/dir-via-marker.png">
              <div class="content">
                <p>1#压力点:1.24 Mpa</p>
                <p>2#压力点:3.02 Mpa</p>
              </div>
            </div>`;

          new AMap.Marker({
            position: position,
            // 将 html 传给 content
            content: markerContent,
            // 以 icon 的 [center bottom] 为原点
            offset: new AMap.Pixel(-13, -30),
            map: map  // 添加到对应的map地图实例
          });
        });

        // 添加管线
        const path = vm.makers.map(v => [v.Lng, v.Lat]);
        const polyline = new AMap.Polyline({
          path: path,
          isOutline: true,
          outlineColor: '#ffeeff',
          borderWeight: 1,
          strokeColor: "red",
          strokeOpacity: 1,
          strokeWeight: 1,
          // 折线样式还支持 'dashed'
          strokeStyle: "solid",
          // strokeStyle是dashed时有效
          strokeDasharray: [10, 5],
          lineJoin: 'round',
          lineCap: 'round',
          zIndex: 50,
        });

        map.add([polyline]);

        // 添加管线名称
        const textLng = (vm.makers[0].Lng + vm.makers[1].Lng) / 2;
        const textLat = (vm.makers[0].Lat + vm.makers[1].Lat) / 2;
        // 根据两个压力点计算管线的方位角
        const textAngle = getAngle(vm.makers[0].Lng, vm.makers[0].Lat, vm.makers[1].Lng, vm.makers[1].Lat);
        const text = new AMap.Text({
          text: 'DN-125',
          anchor: 'center', // 设置文本标记锚点
          draggable: true,
          cursor: 'pointer',
          angle: textAngle + 90, // 必须要+ 90,不然名字和管线是垂直状态
          style: {
            'border-radius': '0',
            'background-color': 'white',
            'border-width': 0,
            'box-shadow': '0 2px 6px 0 rgba(114, 124, 245, .5)',
            'text-align': 'center',
            'font-size': '10px',
            'color': 'blue'
          },
          position: [textLng, textLat]
        });

        text.setMap(map); // 添加管线名称

      });
    },
    // 地图初始化
    intAmap (callBack) {
      this.AMap = window.AMap;
      this.AMap.plugin(['AMap.MouseTool', 'AMap.PolyEditor', 'AMap.ControlBar', 'AMap.DistrictSearch', 'Map3D', 'AMap.Object3DLayer'], function () {
        //TODO  创建控件并添加
      });

      if (callBack && typeof callBack == 'function') {
        callBack();
      }

      this.drawMap('北京市', this.makers);
    }
  }
};
</script>
<style lang="scss">
#amapContainer {
  .custom-content-marker {
    position: relative;
    width: 25px;
    height: 34px;

    img {
      width: 100%;
      height: 100%;
    }

    .close-btn {
      position: absolute;
      top: -6px;
      right: -8px;
      width: 15px;
      height: 15px;
      font-size: 12px;
      background: #ccc;
      border-radius: 50%;
      color: #fff;
      text-align: center;
      line-height: 15px;
      box-shadow: -1px 1px 1px rgba(10, 10, 10, 0.2);
    }

    .close-btn:hover {
      background: #666;
    }

    .content {
      position: absolute;
      left: 20px;
      top: 10px;
      height: 100px;
      width: 200px;
      background: rgba(10, 10, 10, 0.7);

      p {
        padding: 5px 10px;
        color: #fff;
        font-size: 14px;
        text-align: left;
      }
    }
  }
}
</style>
<style lang="scss" scoped>
#amapContainer {
  height: 800px;
  width: 100%;
  margin: 0 auto;
}
</style>

两个经纬度之间计算角度

//计算旋转角度
export function getAngle( lon1, lat1, lon2,lat2) {
  const deg2rad = Math.PI / 180;
  const dlat = (lat2 - lat1) * deg2rad;
  const dlon = (lon2 - lon1) * deg2rad;
  const y = Math.sin(dlon) * Math.cos(lat2 * deg2rad);
  const x = Math.cos(lat1 * deg2rad) * Math.sin(lat2 * deg2rad) - Math.sin(lat1 * deg2rad) * Math.cos(lat2 * deg2rad) * Math.cos(dlon);
  const angle = Math.atan2(y, x) * 180 / Math.PI;
  return angle;
}

 绘制覆盖物

 // 根据不同类型绘制不同覆盖物
    drawTypeInt (type, mouseTool) {
      switch (type) {
        // 点标记
        case 'marker': {
          mouseTool.marker({
            draggable: true,
            //同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({
            draggable: true,
            fillColor: '#00b0ff',
            strokeColor: '#80d8ff'
            //同Polygon的Option设置
          });
          break;
        }
        // 圆形
        case 'circle': {
          mouseTool.circle({
            draggable: true,
            fillColor: '#00b0ff',
            strokeColor: '#80d8ff'
            //同Circle的Option设置
          });
          break;
        }
        // 放大
        case 'zoomIn': {
          mouseTool.rectZoomIn({
            strokeColor: '#80d8ff',
            fillColor: '#80d8ff',
            fillOpacity: 0.3
            //同 Polygon 的 Option 设置

          });
          break;
        }
        // 缩小
        case 'zoomOut': {
          mouseTool.rectZoomOut({
            strokeColor: '#80d8ff',
            fillColor: '#80d8ff',
            fillOpacity: 0.3
            //同 Polygon 的 Option 设置
          });
          break;
        }

        // 计算面积
        case 'measureArea': {
          mouseTool.measureArea({
            strokeColor: '#80d8ff',
            fillColor: '#80d8ff',
            fillOpacity: 0.3
            //同 Polygon 的 Option 设置
          });
          break;
        }

        case 'rule': {
          // 测量尺
          mouseTool.rule({
            startMarkerOptions: {//可缺省
              icon: new AMap.Icon({
                size: new AMap.Size(19, 31),//图标大小
                imageSize: new AMap.Size(19, 31),
                image: "//webapi.amap.com/theme/v1.3/markers/b/start.png"
              }),
              offset: new AMap.Pixel(-5, -31)
            },
            endMarkerOptions: {//可缺省
              icon: new AMap.Icon({
                size: new AMap.Size(19, 31),//图标大小
                imageSize: new AMap.Size(19, 31),
                image: "//webapi.amap.com/theme/v1.3/markers/b/end.png"
              }),
              offset: new AMap.Pixel(-9, -31)
            },
            midMarkerOptions: {//可缺省
              icon: new AMap.Icon({
                size: new AMap.Size(19, 31),//图标大小
                imageSize: new AMap.Size(19, 31),
                image: "//webapi.amap.com/theme/v1.3/markers/b/mid.png"
              }),
              offset: new AMap.Pixel(-9, -31)
            },
            lineOptions: {//可缺省
              strokeStyle: "solid",
              strokeColor: "#FF33FF",
              strokeOpacity: 1,
              strokeWeight: 2
            }
            //同 RangingTool 的 自定义 设置,缺省为默认样式
          });
        }
      }
    },
// 切换覆盖物绘制
    changeType (type) {
      this.closeMouseTools();
      this.drawTypeInt(type, this.mouseTool);
    },
    // 关闭鼠标编辑器
    closeMouseTools () {
      this.mouseTool.close(true);
      this.clearAllMaker();
    },
    // 清空覆盖物
    clearAllMaker () {
      this.map.remove(this.overlays);
      this.overlays = [];
      this.$message.success('清除成功');
    },
    // 鼠标事件初始化
    mouseInt (map = this.map) {
      const vm = this;
      const AMap = window?.AMap;
      const mouseTool = new AMap.MouseTool(map);
      //监听draw事件可获取画好的覆盖物
      this.overlays = [];
      mouseTool.on('draw', function (e) {
        vm.overlays.push(e.obj);
        console.log('----当前覆盖物对象---', e.obj);
      });

      this.mouseTool = mouseTool;

      // 默认绘制点
      vm.drawTypeInt('marker', mouseTool);
    },


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

相关文章:

  • 网络爬虫——常见问题与调试技巧
  • 基于CNN+RNNs(LSTM, GRU)的红点位置检测(pytorch)
  • 20.100ASK_T113-PRO 开发板开机自动QT程序简单的方法一
  • 科研深度学习:如何精选GPU以优化服务器性能
  • 并行IO接口8255
  • vue2-代理服务器插槽
  • React 组件生命周期
  • uniapp调整webview的大小与位置,解决遮挡问题
  • ElementUI之el-date-picker禁选配置
  • ESP8266 AP模式TCP服务器 电脑手机网络调试助手
  • 设计模式-创建型-原型模式
  • aws 小白入门,VPC 子网、路由表、互联网网关
  • 链表算法速成计划
  • 探索C++中的map和set容器
  • 【jvm】从字节码角度看待对象创建流程
  • Claude Opus MetaPrompt 系统详解
  • 论文阅读 SimpleNet: A Simple Network for Image Anomaly Detection and Localization
  • 【C++】踏上C++学习之旅(十):深入“类和对象“世界,掌握编程黄金法则(五)(最终篇,内含初始化列表、静态成员、友元以及内部类等等)
  • Spring 中的 ProxyFactory 创建代理对象
  • i春秋-123(文件上传绕过,双写绕过)
  • Vue + Websocket播放PCM(base64转ArrayBuffer、 字符串转ArrayBuffer)
  • RabbitMQ 篇-深入了解延迟消息、MQ 可靠性(生产者可靠性、MQ 可靠性、消费者可靠性)
  • GitLab使用示例
  • 储能场站安全风险挑战
  • OceanBase数据库产品与工具介绍
  • 深入探讨 Puppeteer 如何使用 X 和 Y 坐标实现鼠标移动