vue引入高德地图,poi搜索,点击选点,标记点

这篇博客详细介绍了如何在Vue项目中集成高德地图API,包括设置安全密钥、引入必要的插件,以及在模板中创建输入框获取关键字。通过监听用户输入,利用AMap.Autocomplete和AMap.PlaceSearch插件实现地点的联想搜索。同时,展示了在地图上点击事件获取经纬度,并进行地址解析,转换为城市编码。此外,还涵盖了逆向地理编码插件AMap.Geocoder的使用,用于将坐标转换为详细地址。整个过程覆盖了地图交互、数据处理和事件响应的多个环节。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.在public/index.html,用script标签引入的,如果需要poi搜索务必加上密匙和plugin=AMap.Autocomplete,AMap.PlaceSearch,否则不会显示

    <script type="text/javascript">
      window._AMapSecurityConfig = {
          securityJsCode:'你的密匙',
      }
</script>
    <script type="text/javascript" src="https://webapi.amap.com/maps?v=1.4.15&key=你的key&plugin=AMap.Autocomplete,AMap.PlaceSearch"></script> 
    <script type="text/javascript" src="https://webapi.amap.com/demos/js/liteToolbar.js"></script>

2.上代码

<template>
  <div>
    <el-input
      id="keyword"
      v-model="addres"
      placeholder="输入关键字选取地点"
      style="width: 300px"
    />
    <div id="container_jinfeishuju"></div>
  </div>
</template>
<script>
export default {
  props: {
    form: Object,
  },
  data() {
    return {
      addres: "",
      districtList: "",
      cityCode: "",
    };
  },
  mounted() {
    this.initMap();
  },
  methods: {
    //  递归查询城市编码换算区域编码
    recursion(list, code) {
      for (let i = 0; i < list.length; i++) {
        if (list[i].citycode == code) {
          this.cityCode = list[i].adcode;
          return ;
        }
        if (list[i].districtList && list[i].districtList.length > 0) {
          this.recursion(list[i].districtList, code);
        }
      }
    },
    // 初始化加载地图
    initMap() {
      let that = this;
      let map = new AMap.Map("container_jinfeishuju", {
        center: [113.618917, 34.748348],
        zoom: 13,
        resizeEnable: true,
      });
      //实时路况图层
      let trafficLayer = new AMap.TileLayer.Traffic({
        zIndex: 10,
      });
      // 将创建的点标记添加到已有的地图实例:
      map.add(trafficLayer); //添加图层到地图
      map.on("click", function (ev) {
        console.log(ev);
        that.marker(ev.lnglat.lng, ev.lnglat.lat, map, false);
        that.getCode(ev.lnglat.lng, ev.lnglat.lat, false, "");
      });
      // 父组件传值解析地址 并回显
      if (that.form.id !== 0) {
        that.addres = that.form.placeName;
        that.marker(that.form.placeLon, that.form.placeLat, map, true);
      }

      AMap.plugin(
        ["AMap.Autocomplete", "AMap.PlaceSearch", "AMap.DistrictSearch"],
        function () {
          let autoOptions = {
            city: "郑州", //城市,默认全国
            input: "keyword", //使用联想输入的input的id
            extensions: "all",
          };
          let autocomplete = new AMap.Autocomplete(autoOptions);
          let placeSearch = new AMap.PlaceSearch({
            city: "郑州",
            //   map: map,
            extensions: "base",
          });
          AMap.event.addListener(autocomplete, "select", function (e) {
            console.log(e);
            //TODO 针对选中的poi实现自己的功能
            placeSearch.setCity(e.poi.adcode);
            placeSearch.search(e.poi.name);
            that.getCode(
              e.poi.location.lng,
              e.poi.location.lat,
              true,
              e.poi.name
            );
            //   that.$emit("MapObj", obj);
            that.marker(e.poi.location.lng, e.poi.location.lat, map, true);
          });
          // 获取城市编码和区域编码
          let districtSearch = new AMap.DistrictSearch({
            // 关键字对应的行政区级别,country表示国家
            subdistrict: 2,
            level: "country", //查询行政级别为 市
            extensions: "all",// 基础信息base,all是返回信息
          });
          districtSearch.search("中国", function (status, result) {
            // 查询成功时,result即为对应的行政区信息
            that.districtList = result.districtList[0].districtList;
            console.log(status, result, "区域");
          });
        }
      );
    },
    // 解析地址
    getCode(lng, lat, type, name) {
      let that = this;
      let district = null;
      AMap.plugin(["AMap.Geocoder", "AMap.DistrictSearch"], function () {
        // 引入 Geocoder 逆向地理编码插件,把经纬度转为地址
        const geocoder = new AMap.Geocoder({
          radius: 1000, // 以给定坐标为中心点,单位:米。取值范围:0-3000。默认值:1000
          extensions: "all", // 返回信息的详略。默认值:base,返回基本地址信息;取值为:all,返回地址信息及附近poi、道路、道路交叉口等信息
          batch: true,
        });
        const lnglat = [lng, lat];
        console.log(lnglat);
        geocoder.getAddress(lnglat, async (status, result) => {
          await that.recursion(
            that.districtList,
            result.regeocode.addressComponent.citycode
          );
          // 传入经纬度,根据给定坐标进行解析,把经纬度转为地址
          let obj = {
            placeName: type ? name : result.regeocode.pois[0].name,
            cityCode: that.cityCode,
            placeLon: lng,
            placeLat: lat,
          };

          that.$emit("MapObj", obj);
          that.addres = type ? name : result.regeocode.pois[0].name;
        });
      });
    },
    // 根据点击事件或者搜索事件生成坐标点
    marker(lat, lng, map, type) {
      let marker = new AMap.Marker({
        position: new AMap.LngLat(lat, lng), // 经纬度对象,也可以是经纬度构成的一维数组[116.39, 39.9]
        title: "当前位置",
      });
      if (type) {
        map.setCenter([lat, lng]);
      }
      map.clearMap(); //清除所有遮罩物
      map.add(marker);
    },
  },
};
</script>
<style scoped>
#container_jinfeishuju {
  padding: 0px;
  margin: 0px;
  width: 100%;
  height: 500px;
  margin-top: 15px;
}
#keyword {
  z-index: 1000000000000000;
}
</style>
<style>
.auto-item {
  font-size: 14px;
  letter-spacing: 1px;
}
</style>

在这里插入图片描述
在这里插入图片描述

<think>好的,我现在需要帮助用户解决在Vue3和TypeScript中结合高德地图实现地图选点组件的问题。首先,我应该回顾用户提供的引用内容,看看有没有相关的示例或指导。用户引用了几个关于Vue高德地图的资源,特别是引用3和4提到了地图选点的实现步骤和代码结构。 首先,用户的需求是使用Vue3和TypeScript,所以我要确保提供的代码符合这两个技术的要求。引用3中提到了在beforeMount生命周期加载地图API,这很重要,因为高德地图的初始化需要在组件挂载前完成。同时,引用4提到了引入高德地图JS文件的步骤,但用户可能更倾向于使用npm包,这样更符合Vue3的项目结构。 接下来,我需要考虑如何将高德地图JavaScript API与Vue3的Composition API和TypeScript结合。可能需要使用官方提供的@vuemap/vue-amap库,或者直接使用高德的JavaScript API。根据引用3,使用@vuemap/vue-amap库的话,需要在beforeMount中初始化,这可能是一个关键点。 然后,地图选点的功能通常包括点击地图获取坐标、搜索选址、显示标记等。引用5提到了输入框的模糊查询和信息回显,这可能需要使用高德的搜索插件,比如AMap.PlaceSearch。同时,引用1中的示例代码可能有组件结构可以参考,比如GaoDeMap.vue的布局。 在TypeScript方面,需要定义事件参数的类型,比如地图点击事件的参数,以及坐标点的接口。确保类型安全,避免any类型,提高代码质量。 可能还需要处理地图的初始化,确保API正确加载,避免重复加载的问题。引用3中的initMapApi函数可能在工具类中定义,用于初始化地图的配置,比如key和插件。 最后,整合这些部分,构建一个完整的组件,包括模板中的地图容器、事件绑定、方法实现,以及TypeScript的类型定义。同时,可能需要处理样式,确保地图正确显示,如引用5中的CSS设置容器的高度和宽度。 现在,我需要验证这些步骤是否可行,确保代码示例正确,并且符合用户的需求。可能还需要测试代码,确保地图选点功能正常工作,包括点击事件和搜索功能。如果有遗漏的部分,比如处理异步加载或错误处理,也需要补充进去。</think>以下是如何在Vue3 + TypeScript中实现高德地图选点组件的完整解决方案: ### 一、基础环境配置 1. 安装依赖: ```bash npm install @vuemap/vue-amap @vuemap/vue-amap-types ``` 2. 地图初始化(src/utils/map.ts): ```typescript import { initAMapApiLoader } from '@vuemap/vue-amap' export const initMapApi = () => { initAMapApiLoader({ key: '您的高德地图Key', securityJsCode: '您的安全密钥', plugins: ['AMap.PlaceSearch', 'AMap.AutoComplete'] }) } ``` ### 二、地图选点组件实现(MapPicker.vue) ```vue <template> <div class="map-container"> <el-input v-model="searchText" @input="handleSearch"> <template #append> <el-button @click="handleSelfLocation"> <el-icon><Location /></el-icon> </el-button> </template> </el-input> <div class="map-wrapper"> <el-amap ref="mapRef" :zoom="zoom" :center="center" @click="handleMapClick" > <el-amap-marker :position="markerPosition" /> </el-amap> </div> </div> </template> <script setup lang="ts"> import { ref, onBeforeMount } from 'vue' import { initMapApi } from '@/utils/map' import { ElMessage } from 'element-plus' interface Coordinate { lng: number lat: number } // 地图配置 const zoom = ref(15) const center = ref<Coordinate>({ lng: 116.397428, lat: 39.90923 }) const markerPosition = ref<Coordinate | null>(null) const searchText = ref('') const mapRef = ref() // 初始化地图API onBeforeMount(() => { initMapApi() }) // 地图点击事件 const handleMapClick = (e: any) => { const { lnglat } = e markerPosition.value = { lng: lnglat.lng, lat: lnglat.lat } emit('select', markerPosition.value) } // 自动完成搜索 let autoComplete: AMap.AutoComplete const handleSearch = (val: string) => { if (!autoComplete) { autoComplete = new AMap.AutoComplete({ input: 'searchText' }) } autoComplete.search(val, (status, result) => { if (status === 'complete' && result.tips.length) { const poi = result.tips[0] center.value = { lng: poi.location.lng, lat: poi.location.lat } } }) } // 自我定位 const handleSelfLocation = () => { AMap.plugin('AMap.Geolocation', () => { const geolocation = new AMap.Geolocation({ enableHighAccuracy: true, timeout: 10000 }) geolocation.getCurrentPosition((status, result) => { if (status === 'complete') { center.value = { lng: result.position.lng, lat: result.position.lat } } else { ElMessage.error('定位失败') } }) }) } defineExpose({ getPosition: () => markerPosition.value }) </script> <style scoped> .map-container { height: 500px; position: relative; } .map-wrapper { height: calc(100% - 40px); margin-top: 10px; } </style> ``` ### 三、核心功能说明 1. **地图初始化**:通过`initAMapApiLoader`初始化地图服务[^3] 2. **点击选址**:通过监听地图的click事件获取坐标点[^4] 3. **搜索选址**:集成高德AutoComplete实现输入提示[^5] 4. **自我定位**:使用AMap.Geolocation插件实现定位功能[^4] 5. **类型安全**:使用TypeScript定义坐标点接口和组件参数 ### 四、使用示例 ```vue <template> <MapPicker @select="handleSelect" /> </template> <script setup lang="ts"> const handleSelect = (coord: Coordinate) => { console.log('选中坐标:', coord) } </script> ```
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值