百度地图定位

参考博主:vue3 Element plus 百度地图封装( 搜索定位功能,拖拽回显功能)_vue3 pc端实现定位回显位置信息-CSDN博客

运行环境:vue3+Ant Design

1,申请百度地图ak

网址:百度地图-百万开发者首选的地图服务商,提供专属的行业解决方案

登录/注册后点击右上角控制台,点击左侧【应用管理】下的【我的应用】【创建应用】申请ak

2,index.html内引入

<script type="text/javascript" src="https://api.map.baidu.com/api?v=2.0&ak=申请的ak值&s=1"></script>

3,画地图

<template>
  <!-- 这个是我这个框架里封装好的弹窗组件 -->
  <BasicModal
    width="1200px"
    v-bind="$attrs"
    :defaultFullscreen="true"
    :canFullscreen="false"
    @register="registerModal"
    title="定位"
    @ok="handleSubmit"
  >
    <!-- ----地图相关--- -->
    <!-- 表单用于搜索 -->
    <a-form class="formdom">
      <a-form-item label="详细地址">
        <a-auto-complete
          v-model:value="mapData.address"
          placeholder="请输入详细地址"
          :backfill="true"
          :options="optionsAll"
          @search="querySearch"
          @select="handleSelect"
        >
          <template #option="item">
            <div>
              <div>{{ item.title }}</div>
              <span style="font-size: 12px; color: #b4b4b4">{{ item.address }}</span>
            </div>
          </template>
        </a-auto-complete>
      </a-form-item>
      <!-- 显示经纬度 -->
      <a-form-item label="经纬度">
        <a-input v-model:value="mapData.point" :disabled="true" />
      </a-form-item>
    </a-form>
    <!-- 画的地图 -->
    <div id="map" style="width: 100%; height: 100%"></div>
  </BasicModal>
</template>
<script lang="ts">
  import { defineComponent, ref } from 'vue';
  import { BasicModal, useModalInner } from '/@/components/Modal'; //框架自带的弹窗组件可忽略
  import { SearchOutlined } from '@ant-design/icons-vue'; //我用的是Ant Design组件库,这个是引入搜索图标
  export default defineComponent({
    name: 'AppModal',
    components: {
      BasicModal, //可忽略
    },
    emits: ['success'],
    setup(props, { emit }) {
      const isUpdate = ref(true); //可忽略
      // 初始经度,纬度
      const lat = ref(36.67411054692821);
      const lng = ref(117.10358591219932);
      // 搜索框下拉选项
      const optionsAll = ref([]);
      // 初始化地图
      let Map = null;
      // 初始图标
      let mk = null;
      // 地图缩放级别
      let zoom = 12;
      // 先定义一个全局变量后面用
      const BMap = window.BMap;
      // 坐标信息
      const mapData = ref({
        address: '', //详细地址
        point: '', //经纬度
        lat: '', //经度
        lng: '', //纬度
      });
      // 初始函数
      const [registerModal, { setModalProps, closeModal }] = useModalInner(async (data) => {
        //我这一行引入的都是BasicModal弹窗组件封装好的与地图无关
        // 把值都清空
        mapData.value.address = '';
        mapData.value.point = '';
        mapData.value.lat = '';
        mapData.value.lng = '';
        if (data.isUpdate) {
          // 编辑-因为我这个是弹窗打开地图,可能是编辑可能是添加,也就坐标和地址回显
          lat.value = data.records.lat;
          lng.value = data.records.lng;
          mapData.value.lat = data.records.lat;
          mapData.value.lng = data.records.lng;
          mapData.value.address = data.records.address;
          mapData.value.point = data.records.lng + ',' + data.records.lat;
        }
        // 弹窗初始化
        setModalProps({ confirmLoading: false }); //与地图无关
        isUpdate.value = !!data?.isUpdate; //与地图无关
        //初始化地图 禁用地图默认点击弹框
        Map = new BMap.Map('map', { enableMapClick: false });
        var point = new BMap.Point(lng.value, lat.value);
        // 初始化 地图经纬度 层级12代表缩放zoom
        Map.centerAndZoom(point, zoom);
        Map.enableScrollWheelZoom(true); //滚动缩放

        //创建一个图像标注实例 启用拖拽 默认为false
        mk = new BMap.Marker(point, { enableDragging: true });
        // 图标图片尺寸设置
        mk.z.Bj.size.height = 100;
        mk.z.Bj.size.width = 100;

        Map.addOverlay(mk); //将覆盖物添加到地图中
        // 地图拖动事件
        Map.addEventListener('dragend', function (e) {
          Map.panTo(e.point); //将地图的中心点更改为给定的点
          getAddrByPoint(e.point); //拖拽结束后调用逆地址解析函数,e.point为拖拽后的地理坐标
        });
        // 图标拖动事件
        mk.addEventListener('dragend', function (e) {
          getAddrByPoint(e.point); //拖拽结束后调用逆地址解析函数,e.point为拖拽后的地理坐标
        });
      });
      // 逆解析函数
      async function getAddrByPoint(point) {
        var geco = new BMap.Geocoder();
        geco.getLocation(point, function (res) {
          mapData.value = {
            address: res.address,
            point: point.lng + ' , ' + point.lat,
            lat: point.lat,
            lng: point.lng,
          };
          mk.setPosition(point); //重新设置标注的地理坐标
          // Map.panTo(point); //将地图的中心点更改为给定的点
        });
      }
      // 搜索函数
      const querySearch = (str) => {
        var options = {
          //检索完成后的回调函数
          onSearchComplete: function (res) {
            var arr = [];
            if (local.getStatus() == BMAP_STATUS_SUCCESS) {
              for (var i = 0; i < res.getCurrentNumPois(); i++) {
                arr.push(res.getPoi(i));
              }
            }
            //拿到数据之后回显给搜索框的下拉框
            optionsAll.value = arr;
            optionsAll.value.forEach((item) => {
              item.value = item.address;
            });
          },
        };
        var local = new BMap.LocalSearch(Map, options);
        local.search(str);
      };
      // 搜索框的下拉框,选中某项会触发的-选择函数
      const handleSelect = (val, options) => {
        // 保存当前数据
        mapData.value = {
          address: options.address,
          point: options.point.lng + ' , ' + options.point.lat,
          lat: options.point.lat,
          lng: options.point.lng,
        };
        mk.setPosition(options.point); //重新设置标注的地理坐标
        Map.panTo(options.point); //将地图的中心点更改为给定的点
      };
      // 弹窗保存--把值传回去
      async function handleSubmit() {
        const latlng = {
          lat: mapData.value.lat,
          lng: mapData.value.lng,
        };
        emit('success', {
          positonStr: mapData.value.address,
          latlng: latlng,
        });
        closeModal();
      }
      return {
        registerModal,
        handleSubmit,
        handleSelect,
        querySearch,
        mapData,
        optionsAll,
        SearchOutlined,
      };
    },
  });
</script>
<style scoped lang="scss">
  .formdom {
    position: absolute;
    top: 0;
    background-color: #fff;
    z-index: 10;
    display: flex;
    justify-content: space-evenly;
    align-items: center;
    width: 100%;
    ::v-deep(.ant-row) {
      width: 30%;
    }
  }
</style>

4,可能报错,我在本地跑的时候是正常的,但是放到线上之后就有问题了"报错BMap is not defined"并且地图是空白的,细心的话在最开始还会有下面这张图上的错误,查了一下解决办法就是在index.html引入的时候在末尾加上&s=1因为我最开始是http为了以防万一我也改成https了

相关推荐
anuily.2 个月前
vue3+vue-baidu-map-3x 实现地图定位
vue·1024程序员节·vuebaidumap3x·百度地图定位