Vue3 + 百度地图实现位置选择,获取地址经纬度

news2024/11/25 2:05:12

Vue3 + 百度地图实现位置选择,获取地址经纬度

  • 需求:添加传感器时,需要选择传感器所在的省、市、区、详细地址、以及传感器的经纬度信息。
  • 解决方案:集成百度地图API,通过在地图上搜索或者点击获取传感器的具体位置信息。

百度地图选择地址效果

  • 具体效果如下图所示

集成百度地图的具体实现

  • 技术方案: Vue + ElementUI + 百度地图 JavaScript API v3.0
  • 申请成为百度地图开发者并获取秘钥
    • 参考文档:https://lbsyun.baidu.com/index.php?title=jspopular3.0/guide/getkey

第一步:引入百度地图 JavaScript API v3.0 文件

export function BMPGL(ak) {
  return new Promise(function (resolve, reject) {
    window.init = function () {
      // eslint-disable-next-line
      resolve(BMapGL);
    };
    const script = document.createElement("script");
    script.type = "text/javascript";
    script.src = `http://api.map.baidu.com/api?v=3.0&type=webgl&ak=${ak}&callback=init`;
    script.onerror = reject;
    document.head.appendChild(script);
  });
}

第二步:编写百度地图选择位置组件

<template>
  <div class="bmapgl">
    <p>搜索地址获取地址的经纬度</p>
    <el-button @click="show" style="margin-bottom: 20px">打开地图</el-button>
    <el-form label-width="80px">
      <el-row>
        <el-col :span="10">
          <el-form-item label="当前地点">
            <el-input
              size="small"
              type="text"
              readonly
              v-model="addressInfo.address"
            />
          </el-form-item>
        </el-col>
        <el-col :span="7">
          <el-form-item label="位置经度">
            <el-input
              size="small"
              type="text"
              v-model="addressInfo.longitude"
              readonly
            />
          </el-form-item>
        </el-col>
        <el-col :span="7">
          <el-form-item label="位置纬度">
            <el-input
              size="small"
              type="text"
              v-model="addressInfo.latitude"
              readonly
            />
          </el-form-item>
        </el-col>
      </el-row>
    </el-form>
    <el-dialog
      v-model="openMap"
      title="位置选择"
      width="1000px"
      :close-on-click-modal="false"
      destroy-on-close
    >
      <el-form label-width="80px">
        <el-row>
          <el-col :span="10">
            <el-form-item label="当前地点">
              <el-input
                size="small"
                type="text"
                id="suggestId"
                v-model="addressInfo.address"
                placeholder="请输入地点"
              />
            </el-form-item>
          </el-col>
          <el-col :span="7">
            <el-form-item label="位置经度">
              <el-input
                size="small"
                type="text"
                v-model="addressInfo.longitude"
                readonly
              />
            </el-form-item>
          </el-col>
          <el-col :span="7">
            <el-form-item label="位置纬度">
              <el-input
                size="small"
                type="text"
                v-model="addressInfo.latitude"
                readonly
              />
            </el-form-item>
          </el-col>
        </el-row>
      </el-form>
      <div
        class="baidu"
        ref="mapRef"
        id="baidumap"
        style="width: 100%; height: 450px"
      ></div>
      <template #footer>
        <span class="dialog-footer">
          <el-button @click="cancel">取 消</el-button>
          <el-button type="primary" @click="confirmSelect"> 确 定 </el-button>
        </span>
      </template>
    </el-dialog>
  </div>
</template>

<script setup lang="ts">
import { BMPGL } from "@/utils/loadBMap.ts";
import { onMounted, watch, ref, reactive } from "vue";
import { ElMessage } from "element-plus";
const emit = defineEmits(["confirmMapAddress"]);

let map = reactive({});
const mapZoom = ref(15);
const ak = ref(""); // 百度地图密钥
let openMap = ref(false);
let addressInfo = reactive({
  // 地址信息
  longitude: "", // 经度
  latitude: "", // 纬度
  province: "", // 省
  city: "", // 市
  district: "", // 区
  address: "", // 详细地址
});
watch(
  () => [openMap],
  () => {
    if (!openMap.value) {
      map && map.destroy();
    }
  },
  { deep: true }
);
onMounted(() => {
  initMap();
});
const initMap = () => {
  BMPGL(ak.value).then((BMapGL: any) => {
    map = new BMapGL.Map("baidumap");
    var ac = new BMapGL.Autocomplete({
      //建立一个自动完成的对象
      input: "suggestId",
      location: map,
    });
    var zoomCtrl = new BMapGL.ZoomControl(); // 添加缩放控件
    map.addControl(zoomCtrl);
    var cityCtrl = new BMapGL.CityListControl(); // 添加城市列表控件
    map.addControl(cityCtrl);
    var LocationControl = new BMapGL.LocationControl(); // 添加定位控件,用于获取定位
    map.addControl(LocationControl);
    var scaleCtrl = new BMapGL.ScaleControl(); // 添加比例尺控件
    map.addControl(scaleCtrl);
    map.setMapType(); // 设置地图类型为标准地图模式;
    var localcity = new BMapGL.LocalCity();
    localcity.get((e: { name: any }) => {
      map.centerAndZoom(e.name, mapZoom.value);
    });

    let point: any;

    //初始化的时候如果有经纬度,需要先在地图上添加点标记
    if (addressInfo.longitude && addressInfo.latitude) {
      point = new BMapGL.Point(addressInfo.longitude, addressInfo.latitude);
      map.centerAndZoom(point, mapZoom.value);
      var marker2 = new BMapGL.Marker(point);
      //在地图上添加点标记
      map.addOverlay(marker2);
    }

    map.enableScrollWheelZoom(true);
    map.setHeading(64.5);
    map.setTilt(73);

    //点击下拉框的值
    map.addEventListener(
      "click",
      function (e: { latlng: { lng: string; lat: string } }) {
        map.clearOverlays();
        var point1 = new BMapGL.Point(e.latlng.lng, e.latlng.lat);
        // 创建点标记
        var marker1 = new BMapGL.Marker(point1);
        // 在地图上添加点标记
        map.addOverlay(marker1);
        addressInfo.longitude = e.latlng.lng;
        addressInfo.latitude = e.latlng.lat;
        var geoc = new BMapGL.Geocoder(); // 创建地址解析器的实例
        geoc.getLocation(point1, (rs: { addressComponents: any }) => {
          let adr = rs.addressComponents;
          addressInfo.address =
            adr.province +
            adr.city +
            adr.district +
            adr.street +
            adr.streetNumber; // 省市区街道门牌号
        });
      }
    );
    ac.addEventListener("onconfirm", function (e: { item: { value: any } }) {
      //鼠标点击下拉列表后的事件
      var _value = e.item.value;
      addressInfo.address =
        _value.province +
        _value.city +
        _value.district +
        _value.street +
        _value.business;
      // 搜索
      map.clearOverlays(); //清除地图上所有覆盖物
      //智能搜索
      var local = new BMapGL.LocalSearch(map, {
        onSearchComplete: () => {
          //获取第一个智能搜索的结果
          const pp = local.getResults().getPoi(0).point;
          map.centerAndZoom(pp, mapZoom.value);
          map.addOverlay(new BMapGL.Marker(pp)); //添加标注
          addressInfo.longitude = pp.lng;
          addressInfo.latitude = pp.lat;
        },
      });
      local.search(addressInfo.address);
    });
  });
};
/** 打开地图选择 */
const show = () => {
  openMap.value = true;
  initMap();
};
/**
 * 确认选择
 */
const confirmSelect = () => {
  if (addressInfo.address == "") {
    ElMessage({
      message: "请选择位置",
      type: "error",
      center: true,
    });
    return;
  }
  emit("confirmMapAddress", addressInfo);
  openMap.value = false;
};
/**
 * 取消选择
 */
const cancel = () => {
  openMap.value = false;
};
</script>

<style scoped lang="scss">
:deep(.BMap_cpyCtrl) {
  display: none !important;
}
:deep(.BMap_cpyCtrl) {
  display: none !important;
}

:deep(.el-dialog__header),
:deep(.el-dialog__footer) {
  padding: 15px 20px;
}

:deep(.el-dialog__body) {
  border-top: 1px solid #e8eaec;
  border-bottom: 1px solid #e8eaec;
  padding: 20px;
}
:deep(.el-dialog__headerbtn) {
  top: 0;
  font-size: 18px;
}
:deep(.el-dialog) {
  border-radius: 8px;
}
</style>

百度地图Web开发
JavaScript API v3.0 (2D地图 标准版)
API文档地址:https://lbsyun.baidu.com/index.php?title=jspopular3.0
示例地址:https://lbsyun.baidu.com/index.php?title=open/jsdemo3.0
JavaScript API v2.0 (没有维护了)
JavaScript API v1.0(没有维护了)
JavaScript API Lite v1.0 (2D地图 移动端H5版)
API文档地址:https://lbsyun.baidu.com/index.php?title=jspopularLiteV1
示例地址:https://lbsyun.baidu.com/index.php?title=open/jsdemoLite
JavaScript API GL v1.0 (3D地图 )
API文档地址:https://lbsyun.baidu.com/index.php?title=jspopularGL
示例地址:https://lbsyun.baidu.com/jsdemo.htm

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

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

相关文章

什么是敏捷工作流程?如何实施?

依赖传统的项目管理流程&#xff08;即使它们效率不高&#xff09;&#xff0c;会阻碍团队协作&#xff0c;难以管理不断变化的项目需求。 而另一方面&#xff0c;现代项目管理方法&#xff08;如敏捷工作流程&#xff09;为项目带来了简单性、自主性和高效性。它能帮助你了解…

TSINGSEE青犀视频AI算法助力构建城市市容·街面秩序管理解决方案

随着城市化进程加快&#xff0c;未经合理规划设置自然形成的马路市场越来越多&#xff0c;这不仅存在交通安全隐患&#xff0c;也造成了市容秩序混乱&#xff0c;严重影响城市市容面貌。 TSINGSEE青犀AI智能分析网关V3内部部署了几十种算法&#xff0c;包括人脸、人体、车辆、…

fastjson漏洞复现

文章目录 启动环境漏洞复现下载bp插件漏洞扫描dnslog测试是否向外请求资源用工具构造rmi服务器 反弹shell 启动环境 到vulhub目录下 cd vulhub/fastjson/1.2.24-rce安装环境并启动&#xff1a; sudo docker-compose up -d && sudo docker-compose up -d启动成功&…

索尼 toio™ 应用创意开发征文|toio™——激发儿童创造力的创意玩具

导语&#xff1a; toio™是一种激发儿童创造力的创意玩具&#xff0c;它以简洁的设计和多功能性能为特点&#xff0c;为孩子们提供了一个探索和发展创意的平台。本文将探讨toio™玩具的创意方向&#xff0c;以及它如何帮助儿童开发创造力和想象力。 toio™——激发儿童创造力的…

苹果电脑好用的剪切板管理工具 Paste激活中文版最新

Paste是一款剪切板工具&#xff0c;可帮助用户更有效地管理和利用剪贴板中的内容。Paste支持Mac和iOS设备&#xff0c;并提供了一系列功能和特点&#xff0c;以提高工作效率和组织性。 以下是Paste的主要特点和功能&#xff1a; 1. 剪贴板历史记录&#xff1a;Paste记录并存储…

性能测试 —— 吞吐量和并发量的关系? 有什么区别?

吞吐量&#xff08;Throughput&#xff09;和并发量&#xff08;Concurrency&#xff09;是性能测试中常用的两个指标&#xff0c;它们描述了系统处理能力的不同方面。 吞吐量&#xff08;Throughput&#xff09; 是指系统在单位时间内能够处理的请求数量或事务数量。它常用于…

电器布线电线电缆外贸出口UL758测试标准

UL 758&#xff0c;第 3 版&#xff0c;2014 年 5 月 2 日- UL 安全电器布线材料标准 这些要求涵盖了电器布线材料 (AWM)&#xff0c;形式为单绝缘导体、多导体电缆、光纤、独立绝缘导体和光纤用作多芯电缆组件的构件。 本标准要求所涵盖的器具布线材料仅用作器具和其他设备整…

【设计模式】一、设计模式七大原则

文章目录 设计模式概述设计模式七大原则设计模式的目的设计模式七大原则1. 单一职责原则2. 接口隔离原则3. 依赖倒转(倒置)原则4. 里氏替换原则5. 开闭原则&#xff08;Open-Closed Principle简称OCP原则&#xff09;6. 迪米特法则7. 合成复用原则&#xff08;Composite Reuse …

深入探讨Java Stream流:数据处理的新思维

文章目录 1. 流式思想1.1 输入流与输出流1.2 Stream流 2. 使用Stream流的步骤3. 获取Stream流3.1 容器3.2 数组 4. Stream流中间操作方法4.1 filter(Predicate<? super T> predicate)4.2 limit(long maxSize)4.3 skip(long n)4.4 distinct()4.5 sorted() 和 sorted(Comp…

记录一次IDEA非法字符‘\ufeff‘报错

✅作者简介&#xff1a;大家好&#xff0c;我是Leo&#xff0c;热爱Java后端开发者&#xff0c;一个想要与大家共同进步的男人&#x1f609;&#x1f609; &#x1f34e;个人主页&#xff1a;Leo的博客 &#x1f49e;当前专栏&#xff1a; 报错以及Bug ✨特色专栏&#xff1a; …

Python之作业(二)

Python之作业&#xff08;二&#xff09; 作业 求100以内的奇数和求100以内斐波那契数列 其数值为&#xff1a;1、1、2、3、5、8、13、21、34&#xff0c;从第三位数开始&#xff0c;每个数都是前两个数相加的和。 求斐波那契数列第101项打印如下菱形 ********* ************…

ctfshow-web-红包题 耗子尾汁

0x00 前言 CTF 加解密合集CTF Web合集网络安全知识库 文中工具皆可关注 皓月当空w 公众号 发送关键字 工具 获取 0x01 题目 0x02 Write Up 首先看到又是一道代码审计的题目。有两个参数一个是a一个是b&#xff0c;判断a是否调用限制方法&#xff0c;如果没有则将b当做参数给…

计算机硬件基础与CPU工作原理

应用开发&#xff1a; 使用系统提供的接口&#xff08;API&#xff09;&#xff0c;做上层应用程序的开发 底层开发&#xff1a; 即做操作系统本身的开发&#xff1b; Linux子系统&#xff08;5部分&#xff09;&#xff1a; 1.进程管理&#xff1a;管理进程的创建、调度、…

关于测试的思考-测试驱动开发

一、TDD实践 2、灵活应用活文档 推荐书籍《活文档与代码共同演进》

idea2021.1.3版本双击启动,没反应

今天打开电脑&#xff0c;点开idea&#xff0c;界面悬在这里&#xff0c;几秒然后就是没了。然后就一直打不开idea了。 然后又是卸载重装&#xff0c;又是删除缓存文件。我把电脑关于idea的文件全都删除了 。重新安装后&#xff08;首次运行倒是可以打开&#xff0c;但是关掉id…

波卡生态重要动态一览:w3ndi 推出,首尔、新加坡、里斯本活动接踵而至

Web3 市场冷却&#xff0c;但新的社区合作与推进仍在发生&#xff0c;技术和产品依然不断迭代。OneBlock 为你介绍波卡生态近期值得你关注的动态&#xff0c;以及接下来重要的行业活动。 波卡生态重要进展 1、最新 Referendum#110&#xff0c;提议对验证器配置进行多项修改&a…

如何解决国标GB28181视频平台EasyGBS国标云服务平台设备在线,通道却显示离线的情况

EasyGBS是基于国标GB28181协议的视频平台&#xff0c;可支持视频直播、录像、云存储、检索与回放、云台控制、告警上报、语音对讲等功能。EasyGBS平台功能全面、综合性强、视频能力灵活&#xff0c;能够涵盖所有视频监控领域的需求&#xff0c;已经在大量的项目中落地应用&…

【计算机网络】UDP协议详解

目录 前言 端口号的拓展 端口号范围划分 netstat pidof UDP协议 UDP协议端格式 UDP的特点 面向数据报 UDP的缓冲区 UDP使用注意事项 基于UDP的应用层协议 前言 我们前面讲完了http和https协议&#xff0c;它们都属于应用层&#xff0c;按照TCP/IP五层模…

核心实验14_mux vlan_ENSP

项目场景&#xff1a; 核心实验14_mux vlan_ENSP 相关概念&#xff1a; mux vlan 概述 MUX VLAN提供了一种通过VLAN进行网络资源控制的机制。它既可实现VLAN间用户通信&#xff0c;也可实现VLAN内的用户相互隔离。常见的场景有宾馆酒店&#xff0c;小区宽带接入和企业内部。 他…

【C#项目实战】控制台游戏勇士斗恶龙(1)——游戏初始设置以及开始界面

君兮_的个人主页 即使走的再远&#xff0c;也勿忘启程时的初心 C/C 游戏开发 Hello,米娜桑们&#xff0c;这里是君兮_&#xff0c;最近开始正式的步入学习游戏开发的正轨&#xff0c;想要通过写博客的方式来分享自己学到的知识和经验&#xff0c;这就是开设本专栏的目的。希望…