三、前端高德地图、测量两个点之前的距离

news2024/11/15 23:44:11

点击测距工具可以开启测量,再次点击关闭测量,清除地图上的点、连线、文字

在这里插入图片描述
在这里插入图片描述

再次点击测量工具的时候清除。

首先

上面的功能条河下面的地图我搞成了两个组件,他们作为兄弟组件存在,所以简单用js写了个事件监听触发的对象,
eventObj.js

const eventBus = {
    evnetList: [],
    // 监听事件
    $on(callbackFun, name) {
        this.evnetList.push({
            name,
            callbackFun
        })
    },
    //触发事件
    $emit(name, data) {
        this.evnetList.forEach(element => {
            if (name === element.name) {
                element.callbackFun(data)
            }
        });
    },
}
export default eventBus

我们在头部工具栏组件中引入:

import eventBus from './eventObj';

点击的dom

<div
   onClick={()=>this.clickFlagFun()}
   className={this.state.clickFlag ? 'rightBox1click' : 'rightBox1 '}
 >
   <Icon type="discount-o" style={{ marginRight: '4px' }} />AB间距
 </div>

事件:
clickFlag: 需要再 state 中提前声明 为 false 默认为关闭

  clickFlagFun() {
    this.setState({
      clickFlag: !this.state.clickFlag,
    },()=>{
      Toast.prompt({
        content: this.state.clickFlag ? '已开启测量工具' : '已关闭测量工具',
        duration: 5000,
        size: 'large'
      });
      //主动触发自定义事件
      eventBus.$emit('changclickFlag',this.state.clickFlag)
    });
  }

在地图盒子中:
我们需要在挂载的时候就进行监听这个事件:
执行相应的逻辑(这个一会说)

    eventBus.$on((flag) => {
      this.setState(
        {
          isCanClickMarkerLineFlag: flag,
        },
        () => {
          if (!flag) {
            //   清楚line  和 text
            this.map.remove([
              ...this.state.textAndlineObj,
              ...this.state.currentClickMarkerList,
            ]);
            this.setState({
              currentClickMarkerList: [],
              currentClickOptionsList: [],
              textAndlineObj: [],
            });
            this.map.off('click', clickHandler);
            return false;
          }
          // 测量距离方法
          flag && this.map.on('click', clickHandler);
        }
      );
    }, 'changclickFlag');

看地图组件全部代码,里面有对应注释(其实代码很low 但是不想整理 因为它能跑):

import React, { Component } from 'react';
import { Icon } from '@alife/aisc';
import AMapLoader from '@amap/amap-jsapi-loader';
import '../index.scss';
import eventBus from './eventObj';
import { base64PNG, sanjiaoSVG, gray, red, green } from './base64png.js';
const content = `<div style="width:auto;padding:3px;background:gray;color:#000;border:none">EU126,租凭<br/>XX.XX MW</div>`;
class MapComponent extends Component {
  constructor() {
    super();
    this.map = {};
    this.AMap = null;
    this.state = {
      isCanClickMarkerLineFlag: false,
      zoom: 10,
      datalist: [
        {
          icon: 1,
          position: [121.487899486, 31.24916171],
          title: 'aaaaa',
          zoom: 3,
          content,
        },
        {
          icon: 2,
          position: [121.287899486, 31.34916171],
          title: 'bbb',
          zoom: 3,
          content,
        },
        {
          icon: 3,
          position: [121.387899486, 31.44916171],
          title: 'ccc',
          zoom: 3,
          content,
        },
        {
          icon: 3,
          position: [121.487899486, 31.44916171],
          title: 'ddd',
          zoom: 3,
          content,
        },
        {
          icon: 3,
          position: [121.487899486, 31.54916171],
          title: 'eee',
          zoom: 3,
          content,
        },
      ],
      currentClickMarkerList: [],
      currentClickOptionsList: [],
      textAndlineObj: [],
    };
  }

  // 2.dom渲染成功后进行map对象的创建
  componentDidMount() {
    const that = this
    var clickHandler =  function (e) {
        // 最多生成两个标记点
        if (that.state.currentClickOptionsList.length <= 2) {
          let arrList = [];
          // 只能点击两个坐标
          if (that.state.currentClickOptionsList.length !== 0) {
            // 第一个 +  第二个标记点坐标
            arrList = [
              that.state.currentClickOptionsList[0],
              [e.lnglat.getLng(), e.lnglat.getLat()],
            ];
          } else {
            // 第一标记点坐标
            arrList = [[e.lnglat.getLng(), e.lnglat.getLat()]];
          }
          // 为了避免重复渲染
          //   清楚line  和 text
          that.map.remove([
            ...that.state.textAndlineObj,
            ...that.state.currentClickMarkerList,
          ]);
          that.setState(
            {
              // 坐标存起来  目前没有用到 只是做长度判断使用
              currentClickOptionsList: arrList,
            },
            () => {
              // 循环生成点击两次的坐标点
              const currentClickOptionsList = arrList;
              let arr = [];
              currentClickOptionsList.map((i, idx) => {
                var marker1 = new AMap.Marker({
                  icon: 'https://webapi.amap.com/theme/v1.3/markers/n/mark_b.png',
                  position: new AMap.LngLat(i[0], i[1]),
                  zoom: 888,
                  // 是否拖拽
                  draggable: true,
                  // clickable: true,
                  extData: {
                    flag: idx,
                  },
                  // 图标大小
                  offset: [-10, -31],
                });
                //   存起来两个标点对象
                arr = [...arr, marker1];
              });
              // 标点对象为两个的时候 展示 line  和 Text
              if (arr.length == 2) {
                that.lineAndTextFun(that, arr);
              }
              // 存储标记点
              that.setState({
                currentClickMarkerList: arr,
              });
              // map
              that.map.add(arr);
            }
          );
        }
      }
    eventBus.$on((flag) => {
      this.setState(
        {
          isCanClickMarkerLineFlag: flag,
        },
        () => {
          if (!flag) {
            //   清楚line  和 text
            this.map.remove([
              ...this.state.textAndlineObj,
              ...this.state.currentClickMarkerList,
            ]);
            this.setState({
              currentClickMarkerList: [],
              currentClickOptionsList: [],
              textAndlineObj: [],
            });
            this.map.off('click', clickHandler);
            return false;
          }
          // 测量距离方法
          flag && this.map.on('click', clickHandler);
        }
      );
    }, 'changclickFlag');
    AMapLoader.reset(); //需要把这个reset一下
    AMapLoader.load({
      key: 'xxxxxxxxxxxxxx', // 申请好的Web端开发者Key,首次调用 load 时必填
      version: '2.0', // 指定要加载的 JSAPI 的版本,缺省时默认为 1.4.15
      plugins: [''], // 需要使用的的插件列表,如比例尺'AMap.Scale'等
    })
      .then((AMap) => {
        console.log(AMap, 'AMap');
        this.AMap = AMap;
        this.renderMapFun();
      })
      .catch((e) => {
        console.log(e);
      });
  }
  renderMapFun() {
    // 生成容器
    this.map = new this.AMap.Map('container111', {
      zoom: this.state.zoom, //初始化地图级别
      center: [121.487899486, 31.24916171], //初始化地图中心点位置-上海
    });
    const obj = {
      1: green,
      2: red,
      3: gray,
    };
    // 生成 默认点
    let arr = [];
    this.state.datalist.map((i) => {
      var marker1 = new AMap.Marker({
        icon: obj[i.icon],
        position: i.position,
        title: i.title,
        zoom: i.zoom,
      });
      marker1.setLabel({
        content: i.content,
        offset: new AMap.Pixel(-20, 28),
      });
      arr = [...arr, marker1];
    });
    this.map.add(arr);
  }
  //   划线 和 展示 text
  lineAndTextFun = (that, arr) => {
    var line = new AMap.Polyline({
      strokeColor: '#80d8ff',
      isOutline: true,
      outlineColor: 'white',
    });
    that.map.add(line);
    var text = new AMap.Text({
      text: '',
      style: {
        'background-color': '#29b6f6',
        'border-color': '#e1f5fe',
        'font-size': '12px',
      },
    });
    function computeDis() {
      var p1 = arr[0].getPosition();
      var p2 = arr[1].getPosition();
      var textPos = p1.divideBy(2).add(p2.divideBy(2));
      var distance = Math.round(p1.distance(p2));
      var path = [p1, p2];
      line.setPath(path);
      text.setText('两点相距' + distance + '米');
      text.setPosition(textPos);
    }
    computeDis();
    arr[0].on('dragging', computeDis);
    arr[1].on('dragging', computeDis);
    that.map.add(text);
    that.setState({
      textAndlineObj: [text, line],
    });
  };
  addFun = () => {
    const { zoom } = this.state;
    if (zoom !== 18) {
      this.setState(
        {
          zoom: zoom + 1,
        },
        () => {
          // 设置地图显示的缩放级别,在PC上,参数zoom可设范围:[3,18];
          // 在移动端:参数zoom可设范围:[3,19]。3D地图下,可将zoom设置为浮点数。/
          this.map.setZoom(this.state.zoom);
        }
      );
    }
  };
  downFun = () => {
    const { zoom } = this.state;
    if (zoom !== 3) {
      this.setState(
        {
          zoom: zoom - 1,
        },
        () => {
          this.map.setZoom(this.state.zoom);
        }
      );
    }
  };
  render() {
    // 1.初始化创建地图容器,div标签作为地图容器,同时为该div指定id属性;
    return (
      <div style={{ width: '100%', height: '100%' }}>
        <div id="container111" className="map">
          <div className="leftBox">
            <div className="top">
              <Icon type="add" onClick={this.addFun} />
              {this.state.zoom} <Icon type="minus" onClick={this.downFun} />
            </div>
            <div className="bottom">
              <div className="box">
                <img src={gray} alt="" />
                预计裁撤
              </div>
              <div className="box">
                <img src={red} alt="" />
                建设中
              </div>
              <div className="box">
                <img src={green} alt="" />
                预计保留
              </div>
            </div>
          </div>
        </div>
      </div>
    );
  }
}
//导出地图组建类
export default MapComponent;

总结一下吧:
1、点击开启测距
2、点出两个距离点的时候展示测出的距离描述(Line、Text)
3、再点击其他区域,会再次生成一个新的
4、可以实现拖拽效果,重新测出距离
5、再次点击开始测距,关闭,同时清除map上的距离点、line、text。

看的有点蒙的话 可以先看看前两篇:
一、前端高德地图注册、项目中引入、渲染标记(Marker)and覆盖物(Circle)
二、前端高德地图、渲染标记(Marker)引入自定义icon,手动设置zoom

另外献上官方连接:
1、https://lbs.amap.com/demo/javascript-api/example/map-componets/map-overlays
2、https://lbs.amap.com/demo/javascript-api/example/event/map-click-event
3、https://lbs.amap.com/demo/javascript-api/example/event/event-map-drag

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/815122.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

JavaScript三元运算符

条件运算符&#xff08;三元运算符&#xff09;的基本结构 条件 &#xff1f; true:false例如&#xff1a; const age 20; age > 18 ? console.log("你已经成年了"):console.log("你还是一个孩子&#xff01;");我们这里把条件运算符和IF来做个区分…

高等数学中如何求间断点

高等数学中求间断点是一项重要的技巧&#xff0c;特别适用于分析函数的性质和图像的特征。在本文中&#xff0c;我们将深入探讨如何在给定函数中找到间断点&#xff0c;并解释其数学原理和实际应用。 什么是间断点&#xff1f; 在高等数学中&#xff0c;间断点是指函数在某个点…

Trello的功能、优缺点、国内使用体验,及4大类似的项目工具

1、Trello是什么软件&#xff0c;有哪些功能&#xff1b; 2、Trello的价格及国内用户的使用体验&#xff1b; 3、盘点国内同类型的项目管理软件&#xff1b; 4、对比国内工具Worktile、Teambition等工具如何。 一、Trello是什么软件&#xff0c;有哪些功能&#xff1f; 【官网…

Pytorch 最全入门介绍,Pytorch入门看这一篇就够了

本文通过详细且实践性的方式介绍了 PyTorch 的使用&#xff0c;包括环境安装、基础知识、张量操作、自动求导机制、神经网络创建、数据处理、模型训练、测试以及模型的保存和加载。 1. Pytorch简介 在这一部分&#xff0c;我们将会对Pytorch做一个简单的介绍&#xff0c;包括它…

uniapp打包本地资源使用原生安卓打包

Android安装打包 1. 安装sdk 2.安装解压openjdk到D盘 3.安装编辑器 在D盘新建文件 Androidstudio 将编辑器安装到这个Androidstudio 文件内 配置sdk路径 打包步骤&#xff1a; 1. 打开项目&#xff0c;如图&#xff1a; 2. uniapp的本地打包资源可以在 这里替换apps包下 再修…

java+springboot+mysql疫情物资管理系统

项目介绍&#xff1a; 使用javaspringbootmysql开发的疫情物资管理系统&#xff0c;系统包含超级管理员&#xff0c;系统管理员、员工角色&#xff0c;功能如下&#xff1a; 超级管理员&#xff1a;管理员管理&#xff1b;部门管理&#xff1b;职位管理&#xff1b;员工管理&…

港联证券:股市降印花税是什么意思?股市降印花税利好还是利空?

在股票买卖过程中&#xff0c;需求交纳必定的印花税、佣钱费用和过户费用&#xff0c;那么&#xff0c;股市降印花税是什么意思&#xff1f;股市降印花税利好仍是利空&#xff1f;下面港联证券为我们预备了相关内容&#xff0c;以供参阅。 股票降印花税是指下调投资者买卖股票的…

计算机毕设 深度学习实现行人重识别 - python opencv yolo Reid

文章目录 0 前言1 课题背景2 效果展示3 行人检测4 行人重识别5 其他工具6 最后 0 前言 &#x1f525; 这两年开始毕业设计和毕业答辩的要求和难度不断提升&#xff0c;传统的毕设题目缺少创新和亮点&#xff0c;往往达不到毕业答辩的要求&#xff0c;这两年不断有学弟学妹告诉…

Vue3使用vxetable进行表格的编辑、删除与新增

效果图如下: vxetable4传送门 一、引入插件 package.json中加入"vxe-table": "4.0.23",终端中执行npm i导入import {VXETable, VxeTableInstance

YouIcons-矢量图标、LOGO和插图素材下载 48000000+

YouIcons是一个免费下载矢量图标、LOGO和插图素材下的网站&#xff0c;图标量高达千万级别&#xff0c;目前共收录48109736个&#xff0c;是世界领先的创意徽标logo社区&#xff0c;供创意人员下载、分享、成长和使用&#xff0c;是设计师获取灵感、发现并与全球设计师联系的社…

大模型中的注意力机制——MHA、GQA、MQA

注意力机制是Transformer模型的核心组件。考虑到注意力机制的计算效率问题&#xff0c;研究人员也进行了许多研究。代表的就是以下三种模式&#xff1a; MHA&#xff08;Multi-head Attention&#xff09;是标准的多头注意力机制&#xff0c;包含h个Query、Key 和 Value 矩阵。…

DM数据库Linux安装

创建用户账号密码 groupadd dinstalluseradd -g dinstall -m -d /home/dmdba -s /bin/bash dmdbapasswd dmdba安装前必须创建 dmdba 用户&#xff0c;禁止使用 root 用户安装数据库。 dmdba ncayu123456修改文件打开最大数 vi /etc/security/limits.conf在最后添加四条语句dm…

Siamese+Resnet进行相似度计算

SiameseResnet进行相似度计算 基本介绍效果肺部resnet34肺部Resnet50人脸自定义网络 完整代码 基本介绍 使用SiameseNet进行肺部相似度计算&#xff0c;同样可以用于人脸识别等场景。 特征提取网络结果为Resnet&#xff0c;可以为Resnet34、Resnet50等。 数据组织结构如下图所…

基于STM32设计的数码相册

一、项目介绍 项目是基于STM32设计的数码相册&#xff0c;能够通过LCD显示屏解码显示主流的图片&#xff0c;支持bmp、jpg、gif等格式。用户可以通过按键或者触摸屏来切换图片&#xff0c;同时还可以旋转显示&#xff0c;并能够自适应居中显示&#xff0c;小尺寸图片居中显示&…

复习之kickstart无人职守安装脚本

一、kickstart简介 kickstart是红帽发行版中的一种安装方式&#xff0c;它通过以配置文件的方式来记录linux系统安装的各项参数和想要安装的软件。只要配置正确&#xff0c;整个安装过程中无需人工交互参与&#xff0c;达到无人值守安装的目的。 二、kickstar文件的生成 进入/…

销售易和管易云接口打通对接实战

销售易和管易云接口打通对接实战 来源系统:销售易 销售易CRM支持企业从营销、销售到服务的全流程自动化业务场景&#xff0c;创新性地利用AI、大数据、物联网等新型互联网技术打造双中台型CRM&#xff1b;既能帮助B2B企业连接外部经销商、服务商、产品以及最终用户&#xff0c;…

提升稳定性与动态响应,深入探究PID串级多闭环控制的应用价值

引言&#xff1a; PID&#xff08;比例-积分-微分&#xff09;控制作为自动控制系统中常用的控制算法&#xff0c;可以通过对系统的反馈进行调整&#xff0c;实现目标状态的稳定控制。而PID串级多闭环控制是在基本PID控制的基础上&#xff0c;引入多个PID控制器&#xff0c;形成…

某coin数据加密接口分析

新建项目&#xff0c;然后添加frida代码提示 frida 代码提示安装--vscode / node npm i types/frida-gum 任务 : sign 和 data&#xff0c;止于mobilekey是设备号&#xff0c;测试可以随机 sign 加密在 native 层 动态调试配置: 把ida 的 dbsgv 文件下的 android_server 复…

SFL218、SFL214、SFL216、SFL218B双喷嘴挡板两级电液伺服阀

SFZ141直接驱动式伺服阀 SFL317电反馈三级伺服阀 SFL316电反馈三级伺服阀 SFL218A双喷嘴挡板两级电液伺服阀 SFL218双喷嘴挡板两级电液伺服阀 SFL214双喷嘴挡板两级电液伺服阀 SFL216双喷嘴挡板两级电液伺服阀 SFL218B双喷嘴挡板两级电液伺服阀 SFL212B双喷嘴挡板两级电…

HTSA101伺服流量阀放大器

电液伺服阀放大器HTSA101特点&#xff1a; 可用拨码方式选择比例、积分(PI)控制前面板有电源、阀电流和继电器指示灯可开关选择阀电流的输出电流范围可选输出电流或者电压信号来匹配伺服阀或者比例阀采用标准 DIN rail 规格带有颤振信号、颤振信号的幅值和频率可调标准的DIN 导…