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


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

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

    百度地图选择地址效果

    • 具体效果如下图所示

    集成百度地图的具体实现

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

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

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

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

    1. <script setup lang="ts">
    2. import { BMPGL } from "@/utils/loadBmap.ts";
    3. import { onMounted, watch, ref, reactive } from "vue";
    4. import { ElMessage } from "element-plus";
    5. const emit = defineEmits(["confirmMapAddress"]);
    6. let map = ref(null);
    7. const mapZoom = ref(15);
    8. const ak = ref("填百度地图密钥");
    9. let openMap = ref(false);
    10. let addressInfo = reactive({
    11. // 地址信息
    12. longitude: "", // 经度
    13. latitude: "", // 纬度
    14. province: "", // 省
    15. city: "", // 市
    16. district: "", // 区
    17. address: "", // 详细地址
    18. });
    19. watch(
    20. () => [openMap],
    21. () => {
    22. if (!openMap.value) {
    23. map.value && map.value.destroy();
    24. }
    25. },
    26. { deep: true }
    27. );
    28. onMounted(() => {
    29. initMap();
    30. });
    31. const initMap = () => {
    32. map.value = null;
    33. BMPGL(ak.value).then((BMapGL: any) => {
    34. map.value = new BMapGL.Map("baidumap");
    35. var ac = new BMapGL.Autocomplete({
    36. //建立一个自动完成的对象
    37. input: "suggestId",
    38. location: map.value,
    39. });
    40. var zoomCtrl = new BMapGL.ZoomControl(); // 添加缩放控件
    41. map.value.addControl(zoomCtrl);
    42. var cityCtrl = new BMapGL.CityListControl(); // 添加城市列表控件
    43. map.value.addControl(cityCtrl);
    44. var LocationControl = new BMapGL.LocationControl(); // 添加定位控件,用于获取定位
    45. map.value.addControl(LocationControl);
    46. var scaleCtrl = new BMapGL.ScaleControl(); // 添加比例尺控件
    47. map.value.addControl(scaleCtrl);
    48. map.value.setMapType(); // 设置地图类型为标准地图模式;
    49. var localcity = new BMapGL.LocalCity();
    50. localcity.get((e: { name: any }) => {
    51. map.value.centerAndZoom(e.name, mapZoom.value);
    52. });
    53. let point: any;
    54. //初始化的时候如果有经纬度,需要先在地图上添加点标记
    55. if (addressInfo.longitude && addressInfo.latitude) {
    56. point = new BMapGL.Point(addressInfo.longitude, addressInfo.latitude);
    57. map.value.centerAndZoom(point, mapZoom.value);
    58. var marker2 = new BMapGL.Marker(point);
    59. //在地图上添加点标记
    60. map.value.addOverlay(marker2);
    61. }
    62. map.value.enableScrollWheelZoom(true);
    63. map.value.setHeading(64.5);
    64. map.value.setTilt(73);
    65. //点击下拉框的值
    66. map.value.addEventListener(
    67. "click",
    68. function (e: { latlng: { lng: string; lat: string } }) {
    69. map.value.clearOverlays();
    70. var point1 = new BMapGL.Point(e.latlng.lng, e.latlng.lat);
    71. // 创建点标记
    72. var marker1 = new BMapGL.Marker(point1);
    73. // 在地图上添加点标记
    74. map.value.addOverlay(marker1);
    75. addressInfo.longitude = e.latlng.lng;
    76. addressInfo.latitude = e.latlng.lat;
    77. var geoc = new BMapGL.Geocoder(); // 创建地址解析器的实例
    78. geoc.getLocation(point1, (rs: { addressComponents: any }) => {
    79. let adr = rs.addressComponents;
    80. addressInfo.address =
    81. adr.province +
    82. adr.city +
    83. adr.district +
    84. adr.street +
    85. adr.streetNumber; // 省市区街道门牌号
    86. });
    87. }
    88. );
    89. ac.addEventListener("onconfirm", function (e: { item: { value: any } }) {
    90. //鼠标点击下拉列表后的事件
    91. var _value = e.item.value;
    92. addressInfo.address =
    93. _value.province +
    94. _value.city +
    95. _value.district +
    96. _value.street +
    97. _value.business;
    98. // 搜索
    99. map.value.clearOverlays(); //清除地图上所有覆盖物
    100. //智能搜索
    101. var local = new BMapGL.LocalSearch(map.value, {
    102. onSearchComplete: () => {
    103. //获取第一个智能搜索的结果
    104. const pp = local.getResults().getPoi(0).point;
    105. map.value.centerAndZoom(pp, mapZoom.value);
    106. map.value.addOverlay(new BMapGL.Marker(pp)); //添加标注
    107. addressInfo.longitude = pp.lng;
    108. addressInfo.latitude = pp.lat;
    109. },
    110. });
    111. local.search(addressInfo.address);
    112. });
    113. });
    114. };
    115. /** 打开地图选择 */
    116. const show = () => {
    117. openMap.value = true;
    118. initMap();
    119. };
    120. /**
    121. * 确认选择
    122. */
    123. const confirmSelect = () => {
    124. if (addressInfo.address == "") {
    125. ElMessage({
    126. message: "请选择位置",
    127. type: "error",
    128. center: true,
    129. });
    130. return;
    131. }
    132. emit("confirmMapAddress", addressInfo);
    133. openMap.value = false;
    134. };
    135. /**
    136. * 取消选择
    137. */
    138. const cancel = () => {
    139. openMap.value = false;
    140. };
    141. script>
    142. <style>
    143. .tangram-suggestion {
    144. z-index: 99999;
    145. }
    146. style>
    147. <style scoped lang="scss">
    148. :deep(.BMap_cpyCtrl) {
    149. display: none !important;
    150. }
    151. :deep(.BMap_cpyCtrl) {
    152. display: none !important;
    153. }
    154. :deep(.el-dialog__header),
    155. :deep(.el-dialog__footer) {
    156. padding: 15px 20px;
    157. }
    158. :deep(.el-dialog__body) {
    159. border-top: 1px solid #e8eaec;
    160. border-bottom: 1px solid #e8eaec;
    161. padding: 20px;
    162. }
    163. :deep(.el-dialog__headerbtn) {
    164. top: 0;
    165. font-size: 18px;
    166. }
    167. :deep(.el-dialog) {
    168. border-radius: 8px;
    169. }
    170. style>

    项目中需要使用到Bmap模糊地址查询的功能,但是发现搜索出的结果展示被遮挡。已经搜索到结果但是被dialog给遮挡住了。

    解决方式:

    需要修改autocomplete的样式,调整css z-index设置元素的堆叠顺序:

    注意不要踩坑的是:

    要去掉style标签的 scoped,这样的话重写的css样式才能生效。

    百度地图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

  • 相关阅读:
    WPF/C#:显示分组数据的两种方式
    Java日志框架log4j、logback、jul这么多?到底如何选择,他们之间有有什么关联?如何整合使用?
    计算机图形学 实验四:线段裁剪
    【JVS低代码开发平台】支持纯手工配置的数据加工、处理、展现的数据仓库
    3ds Max 基于PC系统的3D建模渲染和制作软件
    UE4 粒子特效基础学习 (01-将粒子效果挂载到角色身上)
    RPA是什么?推荐让电商运营10倍提效的自动化工具
    Fedora 35 部署DNS主从和分离解析 —— 筑梦之路
    使用消息队列解决RTOS多线程同时打印串口乱序问题
    第七章:Vue3(上)
  • 原文地址:https://blog.csdn.net/weixin_42775304/article/details/132763151