Newer
Older
KaiFengH5 / src / views / components / GaodeMap.vue
@zhangdeliang zhangdeliang on 24 May 7 KB 项目初始化
<template>
  <!-- 地图选择位置,包括地图点击选点,搜索 -->
  <div class="StationMap">
    <van-nav-bar
      title="选择具体问题位置"
      fixed
      placeholder
      safe-area-inset-top
      left-text="确定"
      left-arrow
      @click-left="close"
    />
    <!-- 高德关键字搜索,个人每天限制100次调用,企业限值1000次 -->
    <div class="searchArea">
      <van-search v-model="searchVal" show-action label="地址" placeholder="请输入具体位置" @search="onSearch">
        <template #action>
          <div @click="onSearch">搜索</div>
        </template>
      </van-search>
      <van-dropdown-menu v-if="showsearchResult">
        <van-dropdown-item v-model="checkedVal" :options="positionArr" @change="searchPosition" />
      </van-dropdown-menu>
    </div>

    <!-- 地图容器 -->
    <div id="containerMap"></div>
  </div>
</template>
<script>
import { reactive, toRefs, onMounted } from 'vue';
import AMapLoader from '@amap/amap-jsapi-loader';
import pointImg from '@/assets/images/position.png';
import { useStore } from '@/pinia/store.js';
import { showFailToast } from 'vant';

// 添加高德安全密钥
window._AMapSecurityConfig = {
  securityJsCode: '3dd53164a25d70df97e74da0ef5ca5ec',
};
export default {
  setup(props, context) {
    const pinias = useStore();
    const allData = reactive({
      map: null,
      markers: null,
      positionObj: {
        lon: 110.78,
        lat: 32.65,
        address: '十堰市',
      },
      centerPosition: [], //默认显示当前定位
      searchVal: '十堰市',
      checkedVal: '',
      positionArr: [],
      placeSearchComponent: null,
      showsearchResult: false,
      ifSearchLimit: true, //超过100次调用后,搜索按钮隐藏
    });
    onMounted(() => {
      // 获取用户当前位置
      if (/(Android)/i.test(navigator.userAgent)) {
        let str = JSON.parse(window.android.requestLocation()).data;
        console.log('获取实时经纬度---', str);
        let lon = str.lng.toString().length < 9 ? str.lng : str.lng.toString().substring(0, 9);
        let lat = str.lat.toString().length < 9 ? str.lat : str.lat.toString().substring(0, 9);
        allData.centerPosition = [lon, lat];
      } else {
        allData.centerPosition = [allData.positionObj.lon, allData.positionObj.lat];
      }
      initMap(); //DOM初始化完成进行地图初始化
    });

    // 高德地图
    function initMap() {
      AMapLoader.load({
        key: '4ac67f3fcb1f42a7550128f9e7901a3f', // 申请好的开发者Key
        version: '2.0',
        plugins: ['AMap.Geocoder', 'AMap.Scale', 'AMap.PlaceSearch'],
      })
        .then((AMap) => {
          allData.map = new AMap.Map('containerMap', {
            resizeEnable: true,
            viewMode: '2D', //  是否为3D地图模式
            zoom: 15, // 初始化地图级别
            center: allData.centerPosition, //中心点坐标
            jogEnable: false, //是否使用缓动效果,关闭平移惯性感觉舒服一些
          });
          setMarker(allData.centerPosition); //设置当前点位显示
          getAdress(allData.centerPosition); //经纬度转位置
          onSearch(); //默认搜索
          allData.map.setFitView();
          // 地图添加点击事件
          allData.map.on('click', onMapClick);
          let controlBar = new AMap.Scale({
            position: {
              bottom: '30px',
              right: '10px',
            },
          });
          allData.map.addControl(controlBar); // 添加右下角的比例尺
        })
        .catch((err) => {
          console.log(err);
        });
    }
    // 地图点击定位
    function onMapClick(e) {
      console.log('地图点击定位--', e.lnglat.lng, e.lnglat.lat);
      allData.positionObj.lon = e.lnglat.lng;
      allData.positionObj.lat = e.lnglat.lat;
      setMarker([e.lnglat.lng, e.lnglat.lat]); //设置当前点位显示
      getAdress([e.lnglat.lng, e.lnglat.lat]); //经纬度转位置
      allData.map.setCenter([e.lnglat.lng, e.lnglat.lat]); //设置中心点
    }
    // 根据获取到的经纬度进行逆地理编码
    function getAdress(lonLat) {
      const Geocoder = new AMap.Geocoder();
      Geocoder.getAddress(lonLat, (status, result) => {
        console.log('getAdress--', status, result);
        if (status === 'complete' && result.info === 'OK') {
          // address即经纬度转换后的地点名称
          allData.searchVal = result.regeocode.formattedAddress || '十堰市';
          allData.positionObj.address = result.regeocode.formattedAddress || '十堰市';
        } else {
          console.log('经纬度转位置失败');
        }
      });
    }
    // 设置标注点位
    function setMarker(lonLat) {
      if (allData.markers) allData.map.remove(allData.markers);
      allData.markers = new AMap.Marker({
        position: lonLat,
        icon: pointImg, //标注点图片
        offset: new AMap.Pixel(-30, -50), //偏移量
        map: allData.map,
      });
    }
    // 搜索位置
    function onSearch() {
      //超过100次调用后,直接在地图上选点
      if (!allData.ifSearchLimit) {
        showFailToast('搜索超出限值,可直接在地图上点击选择');
        return false;
      }
      pinias.showLoading();
      allData.positionArr = [];
      allData.placeSearchComponent = new AMap.PlaceSearch();
      allData.placeSearchComponent.search(allData.searchVal, (status, result) => {
        console.log('onSearch---', status, result);
        if (status === 'complete' && result.info === 'OK') {
          allData.showsearchResult = true;
          result.poiList.pois.map((item) => {
            allData.positionArr.push({ text: item.address, value: item.id, location: item.location });
          });
          allData.checkedVal = allData.positionArr[0].value;
          allData.ifSearchLimit = true;
        } else {
          allData.showsearchResult = false;
          allData.ifSearchLimit = false;
          allData.positionArr = [];
          showFailToast('搜索超出限值,可直接在地图上点击选择');
        }
        pinias.hideLoading();
      });
    }
    // 搜索选择一个位置后
    function searchPosition(val) {
      let arr = allData.positionArr.filter((item) => item.value == val);
      allData.positionObj.address = arr[0].text;
      allData.positionObj.lon = arr[0].location.lng;
      allData.positionObj.lat = arr[0].location.lat;
      allData.map.setCenter([arr[0].location.lng, arr[0].location.lat]); //设置中心点
      setMarker([arr[0].location.lng, arr[0].location.lat]); //设置当前点位显示
      console.log('选择位置后---', arr);
    }
    // 关闭返回事件
    function close() {
      context.emit('close', allData.positionObj);
    }

    return {
      ...toRefs(allData),
      close,
      onSearch,
      searchPosition,
    };
  },
};
</script>
<style lang="less">
.StationMap {
  #containerMap {
    width: 100%;
    height: calc(100vh - 95px);
  }
  .searchArea {
    position: fixed;
    z-index: 999;
    left: 0px;
    top: 92px;
    width: 100%;
  }
  .amap-logo,
  .amap-copyright {
    display: none !important;
  }
}
</style>