> 技术文档 > 高德地图 Web 端开发详解:高德地图 API 最佳实践指南(安装、marker添加、逆向地理编码、实际业务案例实操)

高德地图 Web 端开发详解:高德地图 API 最佳实践指南(安装、marker添加、逆向地理编码、实际业务案例实操)


文章目录

    • 1、引入高德地图的准备工作
    • 2、高德地图 JS API 使用方式
      • 2.1 JS API Loader
        • 2.1.1 使用 script 标签加载loader
        • 2.1.2 NPM 安装loader
      • 2.2 script 标签加载 JS API 脚本
        • 2.2.1 同步加载
        • 2.2.2 异步加载
    • 3、在 vue3 项目中使用
      • 3.1 安装 js api loader
      • 3.2 在组件中使用
    • 4、实际应用
      • 4.1 点击地图获取经纬度、设置地图中心点、添加 marker、获取省市区及详细地址
        • 4.1.1 准备变量
        • 4.1.2 地图点击事件的监听
        • 4.1.3 地图添加 marker
        • 4.1.4 地图清理 marker的方式
        • 4.1.5 调整地图中心点
        • 4.1.6 根据经纬度获取详细位置
      • 4.2 搜索地点 点击后获取所有信息、设置地图中心点、marker
        • 4.2.1 增加输入框、变量
        • 4.2.2 POI 搜索
        • 4.2.3 处理 点击每个POI 跳转
    • 6、完整代码
    • 7、总结

1、引入高德地图的准备工作

1、成为 开发者

需要在这个网址上,注册高德开放平台 的 账号。 高德开放平台官网

2、创建应用
高德地图 Web 端开发详解:高德地图 API 最佳实践指南(安装、marker添加、逆向地理编码、实际业务案例实操)

3、创建 Key

找到刚刚创建的应用,然后点击 添加Key, 选择 web端 js api ,这个地方,需要自己起一个名字,然后提交即可

高德地图 Web 端开发详解:高德地图 API 最佳实践指南(安装、marker添加、逆向地理编码、实际业务案例实操)

成功提交 以后,会在刚刚创建的应用里面,显示出来对应的 key密钥

高德地图 Web 端开发详解:高德地图 API 最佳实践指南(安装、marker添加、逆向地理编码、实际业务案例实操)

2、高德地图 JS API 使用方式

高德地图的加载方式有好几种,高德地图官方 JS API 引入方式

2.1 JS API Loader

这种方式是官方推荐的引入方式 ,这种方式主要分为以下俩种

2.1.1 使用 script 标签加载loader
<script src=\"https://webapi.amap.com/loader.js\"></script><script type=\"text/javascript\"> window._AMapSecurityConfig = { securityJsCode: \"「你申请的安全密钥」\", }; AMapLoader.load({ key: \"替换为你申请的 key\", //申请好的 Web 端开发 Key,首次调用 load 时必填 version: \"2.0\", //指定要加载的 JS API 的版本,缺省时默认为 1.4.15 plugins: [\"AMap.Scale\"], //需要使用的的插件列表,如比例尺\'AMap.Scale\',支持添加多个如:[\'AMap.Scale\',\'...\',\'...\'] AMapUI: { //是否加载 AMapUI,缺省不加载 version: \"1.1\", //AMapUI 版本 plugins: [\"overlay/SimpleMarker\"], //需要加载的 AMapUI ui 插件 }, Loca: { //是否加载 Loca, 缺省不加载 version: \"2.0\", //Loca 版本 }, }) .then((AMap) => { var map = new AMap.Map(\"container\"); //\"container\"为 
容器的 id map.addControl(new AMap.Scale()); //添加比例尺组件到地图实例上 }) .catch((e) => { console.error(e); //加载错误提示 });</script>
2.1.2 NPM 安装loader
npm i @amap/amap-jsapi-loader --save

这种方式更多常见于工程化项目中 ,下面演示的时候,也是使用这种方式进行安装 , 也可以使用 pnpm 都可以

import AMapLoader from \"@amap/amap-jsapi-loader\";window._AMapSecurityConfig = { securityJsCode: \"「你申请的安全密钥」\",};AMapLoader.load({ key: \"替换为你申请的 key\", //申请好的 Web 端开发者 Key,首次调用 load 时必填 version: \"2.0\", //指定要加载的 JS API 的版本,缺省时默认为 1.4.15 plugins: [\"AMap.Scale\"], //需要使用的的插件列表,如比例尺\'AMap.Scale\',支持添加多个如:[\'AMap.Scale\',\'...\',\'...\']}) .then((AMap) => { var map = new AMap.Map(\"container\"); //\"container\"为 
容器的 id }) .catch((e) => { console.log(e); });

2.2 script 标签加载 JS API 脚本

2.2.1 同步加载
<div id=\"container\"></div><script type=\"text/javascript\"> window._AMapSecurityConfig = { securityJsCode: \"「你申请的安全密钥」\", };</script><script type=\"text/javascript\" src=\"https://webapi.amap.com/maps?v=2.0&key=你申请的key值\"></script><script type=\"text/javascript\"> //地图初始化应该在地图容器 
已经添加到 DOM 树之后 var map = new AMap.Map(\"container\", { zoom: 12, });</script>
2.2.2 异步加载

我们项目中就是用的这个方式,但是这个方式会出现略微的卡顿,因为浏览器要下载下来这个js 文件,然后解析

<script> //设置你的安全密钥 window._AMapSecurityConfig = { securityJsCode: \"「你申请的安全密钥」\", }; //声明异步加载回调函数 window.onLoad = function () { var map = new AMap.Map(\"container\"); //\"container\"为
容器的id }; var url =\"https://webapi.amap.com/maps?v=2.0&key=你申请的key值&callback=onLoad\"; var jsapi = document.createElement(\"script\"); jsapi.charset = \"utf-8\"; jsapi.src = url; document.head.appendChild(jsapi);</script>

3、在 vue3 项目中使用

3.1 安装 js api loader

安装 npm 包

npm i @amap/amap-jsapi-loader --save

3.2 在组件中使用

新建一个空白的 vue 组件,里面要写一个 div ,然后设置以下,ID ,然后处理以下这个DIV 的样式,要保证有高度,然后就引入,具体的代码如下

<template> <div id=\"MapContainer\" ref=\"mapContainerRef\"></div></template><script setup>import { onMounted, onUnmounted, ref } from \"vue\";import AMapLoader from \"@amap/amap-jsapi-loader\";let map = null;const mapContainerRef = ref(null);onMounted(() => { console.log(\"mapContainerRef\", mapContainerRef); window._AMapSecurityConfig = { securityJsCode: \"\", // 「你申请的安全密钥」 }; AMapLoader.load({ key: \"\", // 申请好的Web端开发者Key,首次调用 load 时必填 version: \"2.0\", // 指定要加载的 JSAPI 的版本,缺省时默认为 1.4.15 }) .then((AMap) => { map = new AMap.Map(\"MapContainer\", { // map = new AMap.Map(mapContainerRef.value, { viewMode: \"3D\", // 是否为3D地图模式 zoom: 11, // 初始化地图级别 center: [116.397428, 39.90923], // 初始化地图中心点位置 defaultCursor: \"pointer\", }); }) .catch((e) => { console.log(e); });});onUnmounted(() => { map?.destroy();});</script><style scoped>#MapContainer { width: 100%; height: 800px;}</style>

注意

new AMap.Map 的第一个参数,可以是 DOM元素或者 此元素的ID,在vue中你可以使用 ID 或者 ref 来操作这个

高德地图 Web 端开发详解:高德地图 API 最佳实践指南(安装、marker添加、逆向地理编码、实际业务案例实操)

defaultCursor 这个属性是配置用户鼠标移入到地图上,显示的图标,就是 css 的 cursor: pointer;

高德地图 Web 端开发详解:高德地图 API 最佳实践指南(安装、marker添加、逆向地理编码、实际业务案例实操)

4、实际应用

以下列举,我在实际开发中,遇到的一些需求点

4.1 点击地图获取经纬度、设置地图中心点、添加 marker、获取省市区及详细地址

需求:用户 点击地图上的一个后,要添加一个 定位的图标 ,然后 显示出来 用户点击的经纬度、省市区、详细地址。具体的效果看下面这个 GIF

高德地图 Web 端开发详解:高德地图 API 最佳实践指南(安装、marker添加、逆向地理编码、实际业务案例实操)

4.1.1 准备变量

代码编写

先初始化一个对象,用来存放这些信息

let positionInfo = ref({ lng: 0, // 经度 lat: 0, // 纬度 provinceCode: \"\", // 省份编号 provinceName: \"\", // 省份名称 cityCode: \"\", // 市编号 cityName: \"\", // 市名称 countyCode: \"\", // 区编号 countyName: \"\", // 区名称 address: \"\", // 详细地址});
4.1.2 地图点击事件的监听

第一步,肯定是要先看看高德地图的api ,有没有鼠标点击事件,可以看到在高德地图的参考手册上 Map 是可以绑定点击事件的

高德地图 Web 端开发详解:高德地图 API 最佳实践指南(安装、marker添加、逆向地理编码、实际业务案例实操)

第二步,代码编写,先新建一个 handleAMapClick 方法,然后在 地图初始化完成后,进行调用,便于下面演示其他的操作

高德地图 Web 端开发详解:高德地图 API 最佳实践指南(安装、marker添加、逆向地理编码、实际业务案例实操)

/** * 处理用户点击 地图的点,就拿到经纬度、省市区、详细地址,并且添加 marker */function handleAMapClick() { map.on(\"click\", function (e) { console.log(\"地图:点击事件\", e); positionInfo.value.lng = e.lnglat.getLng(); positionInfo.value.lat = e.lnglat.getLat(); }}

其实这个点击事件,是有一个参数的 ,里面就有经纬度信息,在高德地图参考手册中,这个 lnglat 是非常常见的, lng 就是经度,lat 是纬度;高德地图点击事件官方文档

高德地图 Web 端开发详解:高德地图 API 最佳实践指南(安装、marker添加、逆向地理编码、实际业务案例实操)

4.1.3 地图添加 marker

这个时候,其实已经是拿到了,经纬度信息,然后就是要添加一个标记点,,添加标记点,需要用到 AMap.Marker 方法;高德地图 marker 官方文档

function handleAMapClick() { map.on(\"click\", function (e) { console.log(\"地图:点击事件\", e); positionInfo.value.lng = e.lnglat.getLng(); positionInfo.value.lat = e.lnglat.getLat(); let marker = new AMap.Marker({ position: new AMap.LngLat(positionInfo.value.lng, positionInfo.value.lat), }); map.add(marker); });}

这个方法核心就是,你要先创建一个 marker ,然后吧 maker 添加到地图上。AMap.Marker方法接收一个对象,这个对象,最主要的参数就是 position ,需要传递一个 LngLat 类型的数据进去

Lnglat 类型

它是高德地图的一个基础类,具体的使用如下

new AMap.LngLat(lng: Number?, lat: Number?, noWrap: Boolean?)

第一个参数是经度,第二个参数是 纬度

高德地图 Web 端开发详解:高德地图 API 最佳实践指南(安装、marker添加、逆向地理编码、实际业务案例实操)

这样的话,就已经 实现了, 添加 marker ,但是这个地图还存在一个问题,每次点击都会生成一个新的 marker ,需要每次点击的时候,把之前的 marker 全部清除掉

高德地图 Web 端开发详解:高德地图 API 最佳实践指南(安装、marker添加、逆向地理编码、实际业务案例实操)

4.1.4 地图清理 marker的方式

这个清除 marker 目前我发现有三种方式,分别如下

第一种方式

把这个地图的所有的 marker 都存起来,然后 挨个删除

map 实例上,getAllOverlays 需要接收一个参数(覆盖物的类型,比如:marker、circle、polyline、polygon),返回值是一个数组
map 实例上,remove 需要接收 一个或者多个 覆盖物,要么是一个数组,要么是一个覆盖物

高德地图 Web 端开发详解:高德地图 API 最佳实践指南(安装、marker添加、逆向地理编码、实际业务案例实操)
高德地图 Web 端开发详解:高德地图 API 最佳实践指南(安装、marker添加、逆向地理编码、实际业务案例实操)

  • 高德地图API Map.getAllOverlays 文档
  • 高德地图API Map.remove 文档
// 这里的map 就是 new AMap.Map 的返回值 const markers = map.getAllOverlays(\"marker\"); // 获取地图上的所有 marker markers.forEach((f) => map.remove(f));

第二种方式

暴力解决,直接把当前地图的所有覆盖物,全部删除

  • 高德地图API Map.clearMap 文档
// 这里的map 就是 new AMap.Map 的返回值 map.clearMap(); // 删除地图上所有的覆盖物

第三种方式

使用 Marker 对象的 remove 方法 ,这个方法存在一个缺点,你需要在添加 marker 以后,要找一个地方存储起来

// 这里的 marker 指的是, nwe AMap.Marker 的返回值marker.remove()
  • 高德地图API Marker.remove 文档

第四种方式

使用 Marker 对象的 setMap 方法,

// 这里的 marker 指的是, nwe AMap.Marker 的返回值marker.setMap(null) // 这里需要传递 null 
  • 高德地图API Marker.setMap 文档

到目前位置代码如下

function handleAMapClick() { map.on(\"click\", function (e) { console.log(\"地图:点击事件\", e); positionInfo.value.lng = e.lnglat.getLng(); positionInfo.value.lat = e.lnglat.getLat(); const markers = map.getAllOverlays(\"marker\"); // 获取地图上的所有 marker markers.forEach((f) => map.remove(f)); let marker = new AMap.Marker({ position: new AMap.LngLat(positionInfo.value.lng, positionInfo.value.lat), }); map.add(marker); });}
4.1.5 调整地图中心点

高德地图 Web 端开发详解:高德地图 API 最佳实践指南(安装、marker添加、逆向地理编码、实际业务案例实操)

用户点击后,这个 marker ,已经是到了屏幕的右下角,这个时候就需要调整地图的中心点,让用户始终感觉当前的 marker 在 正中心,这个地方,目前发现俩个处理方式,一个是 Map.setCenter ,另一个是Map.setZoomAndCenter ,但这个地方更建议使用 setCenter 因为另一个方法需要传递一个 zoom,就是地图的缩放等级

高德地图 Web 端开发详解:高德地图 API 最佳实践指南(安装、marker添加、逆向地理编码、实际业务案例实操)

function handleAMapClick() { map.on(\"click\", function (e) { console.log(\"地图:点击事件\", e); positionInfo.value.lng = e.lnglat.getLng(); positionInfo.value.lat = e.lnglat.getLat(); const markers = map.getAllOverlays(\"marker\"); // 获取地图上的所有 marker markers.forEach((f) => map.remove(f)); let marker = new AMap.Marker({ position: new AMap.LngLat(positionInfo.value.lng, positionInfo.value.lat), }); map.add(marker); map.setCenter(new AMap.LngLat(positionInfo.value.lng, positionInfo.value.lat)); });}

在添加 marker 以后,再调 setCenter 方法即可,具体的效果如下

高德地图 Web 端开发详解:高德地图 API 最佳实践指南(安装、marker添加、逆向地理编码、实际业务案例实操)

4.1.6 根据经纬度获取详细位置

设置好地图中心点以后,就要根据经纬度 获取 详细的地址
根据经纬度获取 详细地址 / 根据详细地址获取经纬度, 这两个操作在高德官方 api 文档上,称为正向地理编码逆向地理编码

  • 正向地理编码:详细地址 => 经纬度
  • 逆向地理编码:经纬度 => 详细地址

我们现在要用的就是 逆向地理编码

高德地图 Web 端开发详解:高德地图 API 最佳实践指南(安装、marker添加、逆向地理编码、实际业务案例实操)

第一种方式

在控制台,可以输入 AMap ,高德地图会在window上挂在这个key

//引入插件,此示例采用异步引入,更多引入方式 https://lbs.amap.com/api/javascript-api-v2/guide/abc/pluginsAMap.plugin(\"AMap.Geocoder\", function () { var geocoder = new AMap.Geocoder({ city: \"010\", // city 指定进行编码查询的城市,支持传入城市名、adcode 和 citycode }); var lnglat = [116.396574, 39.992706]; geocoder.getAddress(lnglat, function (status, result) { if (status === \"complete\" && result.info === \"OK\") { // result为对应的地理位置详细信息 console.log(result); } });});

第二种方式

高德地图API AMap.Geocoder 文档

// 这里的 mapObj 就是创建的 Map 实例,也就是 new AMap.Map 的返回值var geocoder;//加载地理编码插件mapObj.plugin([\"AMap.Geocoder\"], function() { //加载地理编码插件 geocoder = new AMap.Geocoder({ radius: 1000, //以已知坐标为中心点,radius为半径,返回范围内兴趣点和道路信息 extensions: \"all\" //返回地址描述以及附近兴趣点和道路信息,默认“base” }); //返回地理编码结果 geocoder.on(\"complete\", geocoder_CallBack); //逆地理编码 geocoder.getAddress(new AMap.LngLat(116.359119, 39.972121));});

第三种方式

高德地图api 逆向地理编码调用接口的方式获取

// 调这个接口,传入对应的参数https://restapi.amap.com/v3/geocode/regeo?output=xml&location=116.310003,39.991957&key=<用户的key>&radius=1000&extensions=all 

这里,使用第二种方式,具体的代码如下

/** * 处理用户点击 地图的点,就拿到经纬度、省市区、详细地址,并且添加 marker */function handleAMapClick() { map.on(\"click\", function (e) { console.log(\"地图:点击事件\", e); positionInfo.value.lng = e.lnglat.getLng(); positionInfo.value.lat = e.lnglat.getLat(); // 这个地方,也需要吧原来的 marker 都清空 // 第一种方式 // map.clearMap(); // 删除地图上所有的覆盖物 // 第二种方式 const markers = map.getAllOverlays(\"marker\"); // 获取地图上的所有 marker markers.forEach((f) => map.remove(f)); let marker = new AMap.Marker({ position: new AMap.LngLat(positionInfo.value.lng, positionInfo.value.lat), }); map.add(marker); console.log(\"marker\", marker); map.setCenter(new AMap.LngLat(positionInfo.value.lng, positionInfo.value.lat)); map.plugin(\"AMap.Geocoder\", function () { let geocoder = new AMap.Geocoder({}); geocoder.getAddress(new AMap.LngLat(positionInfo.value.lng, positionInfo.value.lat), function (status, res) { if (status === \"complete\" && res.info === \"OK\") { // res 为对应的地理位置详细信息 console.log(\"地图:地图点击 逆向地理编码返回值\", res); positionInfo.value.address = res.regeocode.formattedAddress; positionInfo.value.provinceCode = res.regeocode.addressComponent.adcode.slice(0, 2); positionInfo.value.provinceName = res.regeocode.addressComponent.province; positionInfo.value.cityCode = res.regeocode.addressComponent.adcode.slice(2, 4); positionInfo.value.cityName = res.regeocode.addressComponent.city || res.regeocode.addressComponent.province; positionInfo.value.countyCode = res.regeocode.addressComponent.adcode.slice(4, 6); positionInfo.value.countyName = res.regeocode.addressComponent.district; } }); }); });}

逆向地理编码的 返回值如下
主要使用的就是 formattedAddressadcodeprovincecitydistrict ,这几个是最常用的,adcode 是行政区编码,其他值的含义在这个链接里面 逆向地理编码 返回值 解释

高德地图 Web 端开发详解:高德地图 API 最佳实践指南(安装、marker添加、逆向地理编码、实际业务案例实操)

到这里就实现了,第一个需求

4.2 搜索地点 点击后获取所有信息、设置地图中心点、marker

高德地图 Web 端开发详解:高德地图 API 最佳实践指南(安装、marker添加、逆向地理编码、实际业务案例实操)

4.2.1 增加输入框、变量

下面这个就是完成 4.1 之后,又添加 输入框的布局、变量,之后的代码
注意:这次使用的是 UI库是 ant-design-vue 4.x 版本

<template> <div class=\"MapPage\"> <a-row class=\"MapPage-search\"> <a-input-search v-model:value=\"poiValue\" placeholder=\"输入关键词\" size=\"large\" @search=\"handleSearchClick\" /> <div class=\"MapPage-search-poi\"> <a-row v-for=\"item in poiList\" :key=\"item.ID\" style=\"cursor: pointer; margin-bottom: 5px\" @click=\"handlePOIItemClick(item)\" > {{ item.Name }}【{{ item.Address }}】 </a-row> </div> </a-row> <div id=\"MapContainer\" ref=\"mapContainerRef\"></div> <div class=\"MapPage-footer\"> <a-row> 经度: {{ positionInfo.lng }} , 纬度: {{ positionInfo.lat }} </a-row> <a-row>省份编号: {{ positionInfo.provinceCode }} 省份名称: {{ positionInfo.provinceName }} </a-row> <a-row>市编号: {{ positionInfo.cityCode }} 市名称: {{ positionInfo.cityName }} </a-row> <a-row>区编号: {{ positionInfo.countyCode }} 区名称: {{ positionInfo.countyName }} </a-row> <a-row>地址: {{ positionInfo.address }} </a-row> </div> </div></template><script setup>import { onMounted, onUnmounted, ref } from \"vue\";import AMapLoader from \"@amap/amap-jsapi-loader\";let map = null;const mapContainerRef = ref(null);let positionInfo = ref({ lng: 0, lat: 0, provinceCode: \"\", provinceName: \"\", cityCode: \"\", cityName: \"\", countyCode: \"\", countyName: \"\", address: \"\",});let poiValue = ref(\"\");let poiList = ref([]);onMounted(() => { console.log(\"mapContainerRef\", mapContainerRef); window._AMapSecurityConfig = { securityJsCode: \"f22de8e155d91e514b61904b9b10e05a\", // 「你申请的安全密钥」 }; AMapLoader.load({ key: \"6d4f7a678203e93f42c21145a3b16d43\", // 申请好的Web端开发者Key,首次调用 load 时必填 version: \"2.0\", // 指定要加载的 JSAPI 的版本,缺省时默认为 1.4.15 }) .then((AMap) => { map = new AMap.Map(\"MapContainer\", { // map = new AMap.Map(mapContainerRef.value, { viewMode: \"3D\", // 是否为3D地图模式 zoom: 15, // 初始化地图级别 center: [116.397428, 39.90923], // 初始化地图中心点位置 defaultCursor: \"pointer\", }); console.log(\"地图:实例\", map); handleAMapClick(); }) .catch((e) => { console.log(e); });});onUnmounted(() => { map?.destroy();});/** * 处理用户点击 地图的点,就拿到经纬度、省市区、详细地址,并且添加 marker */function handleAMapClick() { map.on(\"click\", function (e) { console.log(\"地图:点击事件\", e); positionInfo.value.lng = e.lnglat.getLng(); positionInfo.value.lat = e.lnglat.getLat(); // 这个地方,也需要吧原来的 marker 都清空 // 第一种方式 // map.clearMap(); // 删除地图上所有的覆盖物 // 第二种方式 const markers = map.getAllOverlays(\"marker\"); // 获取地图上的所有 marker markers.forEach((f) => map.remove(f)); let marker = new AMap.Marker({ position: new AMap.LngLat(positionInfo.value.lng, positionInfo.value.lat), }); map.add(marker); console.log(\"marker\", marker); map.setCenter(new AMap.LngLat(positionInfo.value.lng, positionInfo.value.lat)); map.plugin(\"AMap.Geocoder\", function () { let geocoder = new AMap.Geocoder({}); geocoder.getAddress(new AMap.LngLat(positionInfo.value.lng, positionInfo.value.lat), function (status, res) { if (status === \"complete\" && res.info === \"OK\") { // res 为对应的地理位置详细信息 console.log(\"地图:地图点击 逆向地理编码返回值\", res); positionInfo.value.address = res.regeocode.formattedAddress; positionInfo.value.provinceCode = res.regeocode.addressComponent.adcode.slice(0, 2); positionInfo.value.provinceName = res.regeocode.addressComponent.province; positionInfo.value.cityCode = res.regeocode.addressComponent.adcode.slice(2, 4); positionInfo.value.cityName = res.regeocode.addressComponent.city || res.regeocode.addressComponent.province; positionInfo.value.countyCode = res.regeocode.addressComponent.adcode.slice(4, 6); positionInfo.value.countyName = res.regeocode.addressComponent.district; } }); }); });}</script><style scoped>#MapContainer { width: 100%; height: 700px;}.MapPage-footer { padding: 0 20px;}.MapPage-search { position: relative;}.MapPage-search-poi { position: absolute; z-index: 2; top: 32px; width: 100%; background-color: #fff;}</style>
4.2.2 POI 搜索

这个 POI 就是 兴趣点的意思,也可以理解为 大多数人想搜索的 地点。官方的解释如下,关于POI 官方解释

高德地图 Web 端开发详解:高德地图 API 最佳实践指南(安装、marker添加、逆向地理编码、实际业务案例实操)

这个POI 也是有多种使用方式

第一种

通过 window 上的 AMap.plugin 来获取POI
官方地址:https://lbs.amap.com/api/javascript-api-v2/guide/services/autocomplete

高德地图 Web 端开发详解:高德地图 API 最佳实践指南(安装、marker添加、逆向地理编码、实际业务案例实操)
第二种

通过 地图实例的 plugin 进行加载
官方地址:https://lbs.amap.com/api/javascript-api-v2/documentation#placesearch

高德地图 Web 端开发详解:高德地图 API 最佳实践指南(安装、marker添加、逆向地理编码、实际业务案例实操)
第三种

通过调接口的形式进行获取 POI
官方地址:https://lbs.amap.com/api/webservice/guide/api-advanced/search

高德地图 Web 端开发详解:高德地图 API 最佳实践指南(安装、marker添加、逆向地理编码、实际业务案例实操)

POI 的返回值如下,这个返回值结构还是比较简单的,如若设置了 extensions: \"all\" 返回值就会变得复杂了

高德地图 Web 端开发详解:高德地图 API 最佳实践指南(安装、marker添加、逆向地理编码、实际业务案例实操)

这个地方,我是用的是 第一种方式,但是这个方式好像是异步的,所以又封装了以下,这里的思路就是 根据POI 拿到对应的 经纬度,然后通过经纬度获取具体的地址信息

const handleSearchClick = () => { console.log(\"地图:POI 关键字\", poiValue.value); AMap.plugin(\"AMap.PlaceSearch\", function () { var placeSearch = new AMap.PlaceSearch({ extensions: \"base\", // base | all ,base 是返回基本信息,all 是返回 完整信息 }); placeSearch.search(poiValue.value, async function (status, res) { //查询成功时, res 即对应匹配的 POI 信息 console.log(\"地图:POI 搜索返回值\", status, res, res.poiList.pois); if (status === \"complete\" && res.info == \"OK\") { let formatList = []; for (const f of res.poiList.pois) { let item = {}; item.ID = f.id; item.LngLat = f.location.lng + \",\" + f.location.lat; item.Name = f.name; // 根据经纬度 获取 详细地址 let res = await getAddressByLnglat([f.location.lng, f.location.lat]); item.Address = res.regeocode.formattedAddress; formatList.push(item); } poiList.value = formatList; } }); });};/** * 处理 根据经纬度 获取 详细地址 * @param {Array} lnglat * @returns {Promise} res */function getAddressByLnglat(lnglat) { return new Promise((resolve, reject) => { AMap.plugin(\"AMap.Geocoder\", function () { let geocoder = new AMap.Geocoder({}); geocoder.getAddress(lnglat, function (status, result) { if (status === \"complete\" && result.info === \"OK\") { // result为对应的地理位置详细信息 // item.Address = result.regeocode.formattedAddress; resolve(result); } }); }); });}
4.2.3 处理 点击每个POI 跳转
// 点击每一个 POI 的时候const handlePOIItemClick = (item) => { console.log(\"地图:POI 点击事件\", item, item.LngLat.split(\",\")); positionInfo.value.lng = item.LngLat.split(\",\")[0]; positionInfo.value.lat = item.LngLat.split(\",\")[1]; const markers = map.getAllOverlays(\"marker\"); // 获取地图上的所有 marker markers.forEach((f) => map.remove(f)); let marker = new AMap.Marker({ position: new AMap.LngLat(positionInfo.value.lng, positionInfo.value.lat), }); map.add(marker); map.setCenter(new AMap.LngLat(positionInfo.value.lng, positionInfo.value.lat)); map.plugin(\"AMap.Geocoder\", function () { let geocoder = new AMap.Geocoder({}); geocoder.getAddress(new AMap.LngLat(positionInfo.value.lng, positionInfo.value.lat), function (status, res) { if (status === \"complete\" && res.info === \"OK\") { // res 为对应的地理位置详细信息 positionInfo.value.address = res.regeocode.formattedAddress; positionInfo.value.provinceCode = res.regeocode.addressComponent.adcode.slice(0, 2); positionInfo.value.provinceName = res.regeocode.addressComponent.province; positionInfo.value.cityCode = res.regeocode.addressComponent.adcode.slice(2, 4); positionInfo.value.cityName = res.regeocode.addressComponent.city || res.regeocode.addressComponent.province; positionInfo.value.countyCode = res.regeocode.addressComponent.adcode.slice(4, 6); positionInfo.value.countyName = res.regeocode.addressComponent.district; } poiList.value = []; poiValue.value = \"\"; }); });};

6、完整代码

实现上面两个需求的完整代码如下

<template> <div class=\"MapPage\"> <a-row class=\"MapPage-search\"> <a-input-search v-model:value=\"poiValue\" placeholder=\"输入关键词\" size=\"large\" @search=\"handleSearchClick\" /> <div class=\"MapPage-search-poi\"> <a-row v-for=\"item in poiList\" :key=\"item.ID\" style=\"cursor: pointer; margin-bottom: 5px\" @click=\"handlePOIItemClick(item)\" > {{ item.Name }}【{{ item.Address }}】 </a-row> </div> </a-row> <div id=\"MapContainer\" ref=\"mapContainerRef\"></div> <div class=\"MapPage-footer\"> <a-row> 经度: {{ positionInfo.lng }} , 纬度: {{ positionInfo.lat }} </a-row> <a-row>省份编号: {{ positionInfo.provinceCode }} 省份名称: {{ positionInfo.provinceName }} </a-row> <a-row>市编号: {{ positionInfo.cityCode }} 市名称: {{ positionInfo.cityName }} </a-row> <a-row>区编号: {{ positionInfo.countyCode }} 区名称: {{ positionInfo.countyName }} </a-row> <a-row>地址: {{ positionInfo.address }} </a-row> </div> </div></template><script setup>import { onMounted, onUnmounted, ref } from \"vue\";import AMapLoader from \"@amap/amap-jsapi-loader\";let map = null;const mapContainerRef = ref(null);let positionInfo = ref({ lng: 0, lat: 0, provinceCode: \"\", provinceName: \"\", cityCode: \"\", cityName: \"\", countyCode: \"\", countyName: \"\", address: \"\",});let poiValue = ref(\"\");let poiList = ref([]);onMounted(() => { console.log(\"mapContainerRef\", mapContainerRef); window._AMapSecurityConfig = { securityJsCode: \"f22de8e155d91e514b61904b9b10e05a\", // 「你申请的安全密钥」 }; AMapLoader.load({ key: \"6d4f7a678203e93f42c21145a3b16d43\", // 申请好的Web端开发者Key,首次调用 load 时必填 version: \"2.0\", // 指定要加载的 JSAPI 的版本,缺省时默认为 1.4.15 }) .then((AMap) => { map = new AMap.Map(\"MapContainer\", { // map = new AMap.Map(mapContainerRef.value, { viewMode: \"3D\", // 是否为3D地图模式 zoom: 15, // 初始化地图级别 center: [116.397428, 39.90923], // 初始化地图中心点位置 defaultCursor: \"pointer\", }); console.log(\"地图:实例\", map); handleAMapClick(); }) .catch((e) => { console.log(e); });});onUnmounted(() => { map?.destroy();});/** * 处理用户点击 地图的点,就拿到经纬度、省市区、详细地址,并且添加 marker */function handleAMapClick() { map.on(\"click\", function (e) { console.log(\"地图:点击事件\", e); positionInfo.value.lng = e.lnglat.getLng(); positionInfo.value.lat = e.lnglat.getLat(); // 这个地方,也需要吧原来的 marker 都清空 // 第一种方式 // map.clearMap(); // 删除地图上所有的覆盖物 // 第二种方式 const markers = map.getAllOverlays(\"marker\"); // 获取地图上的所有 marker markers.forEach((f) => map.remove(f)); let marker = new AMap.Marker({ position: new AMap.LngLat(positionInfo.value.lng, positionInfo.value.lat), }); map.add(marker); console.log(\"marker\", marker); map.setCenter(new AMap.LngLat(positionInfo.value.lng, positionInfo.value.lat)); map.plugin(\"AMap.Geocoder\", function () { let geocoder = new AMap.Geocoder({}); geocoder.getAddress(new AMap.LngLat(positionInfo.value.lng, positionInfo.value.lat), function (status, res) { if (status === \"complete\" && res.info === \"OK\") { // res 为对应的地理位置详细信息 console.log(\"地图:地图点击 逆向地理编码返回值\", res); positionInfo.value.address = res.regeocode.formattedAddress; positionInfo.value.provinceCode = res.regeocode.addressComponent.adcode.slice(0, 2); positionInfo.value.provinceName = res.regeocode.addressComponent.province; positionInfo.value.cityCode = res.regeocode.addressComponent.adcode.slice(2, 4); positionInfo.value.cityName = res.regeocode.addressComponent.city || res.regeocode.addressComponent.province; positionInfo.value.countyCode = res.regeocode.addressComponent.adcode.slice(4, 6); positionInfo.value.countyName = res.regeocode.addressComponent.district; } }); }); });}/** * 处理 搜索按钮点击的时候 */const handleSearchClick = () => { console.log(\"地图:POI 关键字\", poiValue.value); AMap.plugin(\"AMap.PlaceSearch\", function () { var placeSearch = new AMap.PlaceSearch({ extensions: \"base\", // base | all ,base 是返回基本信息,all 是返回 完整信息 }); placeSearch.search(poiValue.value, async function (status, res) { //查询成功时, res 即对应匹配的 POI 信息 console.log(\"地图:POI 搜索返回值\", status, res, res.poiList.pois); if (status === \"complete\" && res.info == \"OK\") { let formatList = []; for (const f of res.poiList.pois) { let item = {}; item.ID = f.id; item.LngLat = f.location.lng + \",\" + f.location.lat; item.Name = f.name; // 根据经纬度 获取 详细地址 let res = await getAddressByLnglat([f.location.lng, f.location.lat]); item.Address = res.regeocode.formattedAddress; formatList.push(item); } poiList.value = formatList; } }); });};/** * 处理 根据经纬度 获取 详细地址 * @param {Array} lnglat * @returns {Promise} res */function getAddressByLnglat(lnglat) { return new Promise((resolve, reject) => { AMap.plugin(\"AMap.Geocoder\", function () { let geocoder = new AMap.Geocoder({}); geocoder.getAddress(lnglat, function (status, result) { if (status === \"complete\" && result.info === \"OK\") { // result为对应的地理位置详细信息 // item.Address = result.regeocode.formattedAddress; resolve(result); } }); }); });}// 点击每一个 POI 的时候const handlePOIItemClick = (item) => { console.log(\"地图:POI 点击事件\", item, item.LngLat.split(\",\")); positionInfo.value.lng = item.LngLat.split(\",\")[0]; positionInfo.value.lat = item.LngLat.split(\",\")[1]; const markers = map.getAllOverlays(\"marker\"); // 获取地图上的所有 marker markers.forEach((f) => map.remove(f)); let marker = new AMap.Marker({ position: new AMap.LngLat(positionInfo.value.lng, positionInfo.value.lat), }); map.add(marker); map.setCenter(new AMap.LngLat(positionInfo.value.lng, positionInfo.value.lat)); map.plugin(\"AMap.Geocoder\", function () { let geocoder = new AMap.Geocoder({}); geocoder.getAddress(new AMap.LngLat(positionInfo.value.lng, positionInfo.value.lat), function (status, res) { if (status === \"complete\" && res.info === \"OK\") { // res 为对应的地理位置详细信息 positionInfo.value.address = res.regeocode.formattedAddress; positionInfo.value.provinceCode = res.regeocode.addressComponent.adcode.slice(0, 2); positionInfo.value.provinceName = res.regeocode.addressComponent.province; positionInfo.value.cityCode = res.regeocode.addressComponent.adcode.slice(2, 4); positionInfo.value.cityName = res.regeocode.addressComponent.city || res.regeocode.addressComponent.province; positionInfo.value.countyCode = res.regeocode.addressComponent.adcode.slice(4, 6); positionInfo.value.countyName = res.regeocode.addressComponent.district; } poiList.value = []; poiValue.value = \"\"; }); });};</script><style scoped>#MapContainer { width: 100%; height: 700px;}.MapPage-footer { padding: 0 20px;}.MapPage-search { position: relative;}.MapPage-search-poi { position: absolute; z-index: 2; top: 32px; width: 100%; background-color: #fff;}</style>

7、总结

其实对于前端开发来说,最常用的就是 JS API ,但是这个地方,对于一些插件的介绍不完整,特别是 返回值,比如 POI 搜索的返回值逆向地理编码的返回值
还有一个比较常见,就是获取用户当前的位置,这个是要获取 读取位置权限的,然后拿到 经纬度,还是要通过 逆向地理编码 拿到具体的地址

高德地图 Web 端开发详解:高德地图 API 最佳实践指南(安装、marker添加、逆向地理编码、实际业务案例实操)

常用的 链接,整理如下

  • 高德 JS API 官方文档
  • 高德 JS API 结合 vue 使用 官方文档
  • 高德 JS API 地理编码 与 逆地理编码 官方文档
  • 高德 Web 服务 API 官方文档 (插件的返回值都在这里)
  • 高德 API 参考手册
  • 高德 常见问题汇总