高德地图 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、创建应用
3、创建 Key
找到刚刚创建的应用,然后点击
添加Key
, 选择web端 js api
,这个地方,需要自己起一个名字,然后提交
即可
成功
提交
以后,会在刚刚创建的应用里面,显示出来对应的key
和密钥
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
来操作这个

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

4、实际应用
以下列举,我在实际开发
中,遇到的一些需求点
4.1 点击地图获取经纬度、设置地图中心点、添加 marker、获取省市区及详细地址
需求
:用户 点击地图上的一个后,要添加一个 定位的图标 ,然后 显示出来 用户点击的经纬度、省市区、详细地址。具体的效果看下面这个 GIF

4.1.1 准备变量
代码编写
先初始化一个对象,用来存放这些信息
let positionInfo = ref({ lng: 0, // 经度 lat: 0, // 纬度 provinceCode: \"\", // 省份编号 provinceName: \"\", // 省份名称 cityCode: \"\", // 市编号 cityName: \"\", // 市名称 countyCode: \"\", // 区编号 countyName: \"\", // 区名称 address: \"\", // 详细地址});
4.1.2 地图点击事件的监听
第一步,肯定是要先看看高德地图
的api ,有没有鼠标点击
事件,可以看到在高德地图的参考手册上 Map 是可以绑定点击事件的

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

/** * 处理用户点击 地图的点,就拿到经纬度、省市区、详细地址,并且添加 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 是纬度;高德地图点击事件官方文档

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?)
第一个参数是经度
,第二个参数是 纬度

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

4.1.4 地图清理 marker的方式
这个清除 marker
目前我发现有三种方式,分别如下
第一种方式
把这个地图的所有的 marker
都存起来,然后 挨个删除
map 实例上,getAllOverlays 需要接收一个参数(覆盖物的类型
,比如:marker、circle、polyline、polygon),返回值是一个数组
map 实例上,remove 需要接收 一个或者多个 覆盖物,要么是一个数组,要么是一个覆盖物


- 高德地图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 调整地图中心点

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

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
方法即可,具体的效果如下

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

第一种方式
在控制台,可以输入 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; } }); }); });}
逆向地理编码的 返回值如下
主要使用的就是 formattedAddress
、adcode
、province
、city
、 district
,这几个是最常用的,adcode 是行政区编码,其他值的含义在这个链接里面 逆向地理编码 返回值 解释

到这里就实现了,第一个需求
4.2 搜索地点 点击后获取所有信息、设置地图中心点、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 官方解释

这个POI 也是有多种使用方式
第一种
通过 window 上的 AMap.plugin 来获取POI
官方地址:https://lbs.amap.com/api/javascript-api-v2/guide/services/autocomplete

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

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

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

这个地方,我是用的是 第一种方式,但是这个方式好像是异步
的,所以又封装了以下,这里的思路就是 根据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 搜索的返回值
、逆向地理编码的返回值
。
还有一个比较常见,就是获取用户当前的位置,这个是要获取 读取位置
的权限
的,然后拿到 经纬度
,还是要通过 逆向地理编码
拿到具体的地址

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