高德地图poi+vue3

116 阅读1分钟

效果图

image.png

<template>
  <div class="map-demo1">
    <van-search v-model="keyword" clearable autofocus show-action placeholder="请输入位置" id="searchId" @search="onSearch">
      <template #action>
        <div @click="onClickButton">搜索</div>
      </template>
    </van-search>

    <div id="container1"></div>
    <div class="info-window" style="width: 80vw;" v-show="infoWindowShow" ref="infoWindowRef">
      <van-cell-group>
        <van-cell title="名称" :value="poi.name" />
        <van-cell title="详细地址" :value="`${poi.cityname}-${poi.cityname}-${poi.name}`" />
        <van-cell title="电话" :value="poi.tel" />
        <van-cell title="类型" :value="poi.type" />
      </van-cell-group>
    </div>

  </div>
</template>

<script setup lang="ts" name="MapDemo1">
// @ts-nocheck  
import AMapLoader from '@amap/amap-jsapi-loader';
import { ref, onMounted,nextTick  } from 'vue';
import { showNotify } from 'vant';
window._AMapSecurityConfig = {
  securityJsCode: 'jscode',
}
const keyword = ref('');
const onSearch = async (val) => {
  if (!val) return showNotify({ type: 'warning', message: '请先输入搜索词' });
  const r = await handlePlaceSearch(val)
  console.log('r', r)

}
const onClickButton = async () => {
  if (!keyword.value) return showNotify({ type: 'warning', message: '请先输入搜索词' });
  const r = await handlePlaceSearch(keyword.value)
  console.log('r', r)

}
let AMap = null
let map = null
let marker = null
let infoWindow = null
let autoComplete = null // Autocomplete进行联想输入。
let placeSearch = null //poi
const poi = ref({}) //弹窗里面数据
const infoWindowRef = ref() //infoWindow弹窗ref
const infoWindowShow = ref(false) //控制是否弹窗显示


const initMap = async () => {

  AMap = await AMapLoader.load({
    key: "your key",             // 申请好的Web端开发者Key,首次调用 load 时必填
    version: "2.0",      // 指定要加载的 JSAPI 的版本,缺省时默认为 1.4.15
    plugins: ['AMap.AutoComplete', 'AMap.PlaceSearch'], //AutoComplete调用每天只有20次,好坑
    resizeEnable: true,
    Loca: {
      version: "2.0.0"
    },      // 需要使用的的插件列表,如比例尺'AMap.Scale'等
  }).catch(err => {
    showNotify('地图加载失败,请重试')
  })
  map = new AMap.Map('container1', {
    zoom: 8,           //初始化地图级别
    center: [114.304569, 30.593354], //初始化地图中心点位置
    mapStyle: 'amap://styles/fresh', //设置地图的显示样式
  })
  return map

}

//注册地图点击事件
const initEvent = () => {
  map.on('click', closeInfoWindow)
}
const closeInfoWindow = e => {
  infoWindowShow.value = false
}



const initInfoWindow = () => {
  infoWindow = new AMap.InfoWindow({
    isCustom: true, //自定义弹窗 
    autoMove: true,
    offset: { x: 0, y: -30 },
    anchor: 'bottom-center',
  });
}



const initAutoComplete = () => {
  autoComplete = new AMap.AutoComplete({
    city: '',
    citylimit: true,
    input: 'searchId'
  });

  autoComplete.search('wuhan', (a, b) => {
    if (b === 'USER_DAILY_QUERY_OVER_LIMIT') showNotify({ type: 'warning', message: '注意:搜索联想达到当日调用量最大限制' });
  })
  /**  autoComplete鼠标点击或者回车选中某个POI信息时触发此事件 */
  autoComplete.on('select', autoCompleteSelect)

}

const initPlaceSearch = () => {
  placeSearch = new AMap.PlaceSearch({
    pageSize: 5, // 单页显示结果条数
    pageIndex: 1, // 页码
    children: 0, //不展示子节点数据
    map: map, // 展现结果的地图实例
    autoFitView: true // 是否自动调整地图视野使绘制的 Marker点都处于视口的可见范围
  });
  placeSearch.on('markerClick', handlePlaceSearchMarkerClick)
}


/**
 * autoComplete鼠标点击或者回车选中某个POI信息时触发此事件
 * @param e 
 */
const autoCompleteSelect = e => {
  console.log('e', e)
  const { adcode, name } = e.poi
  keyword.value = name
  placeSearch.setCity(adcode) // 设置查询城市, 支持cityname(中文或中文全拼)、citycode、adcode
  handlePlaceSearch(name)
}

/**
 * placeSearch搜索功能,
 * @param val  搜索关键词
 */
const handlePlaceSearch = val => {
  return new Promise((resolve, reject) => {
    placeSearch.search(val, (result, data) => {
      if (result !== 'result') {
        resolve(data)
      }
      else reject(data)
    })

  })
}



const handlePlaceSearchMarkerClick = (data) => {
  poi.value = data.data
  infoWindowShow.value = true
  nextTick(() => {
    infoWindow.setContent(infoWindowRef.value)
    infoWindow.open(map, data.marker.getPosition())

  })
}


onMounted(async () => {
  await initMap()
  initEvent()
  initInfoWindow()
  initAutoComplete()
  initPlaceSearch()
})

</script>


<style scoped>
#container1 {
  padding: 0px;
  margin: 0px;
  width: 100vw;
  height: 60vh;

}
</style>