基于高德JSAPI的H5选址组件
一、需求
- 可以切换城市
- 可以检索城市下的地址
- 拖拽地图选点
- 显示选点附件的poi
- 双指缩放时以地图的中心点为中心
二、效果如图
三、准备
成为开发者并创建 key,为了正常调用 API ,请先注册成为高德开放平台开发者,并申请 web 平台(JS API)的 key 和安全密钥,点击 具体操作。
2021年12月02日后创建的 key 必须配备安全密钥一起使用,具体用法参见JS API 安全密钥使用
四、开发
初始化
<template><view id="container"></view><view class="result-list footer"><van-list :finished="finished"><van-cell v-for="(item, index) in resultList" :key="index" center :title="item.name" :label="item.address"@click="handleClickAddress(item)"><template #extra><span class="map-distance">{{ handleDistance(item.distance) }}</span></template></van-cell></van-list></view>
</template>
initMap() {// 初始化地图const _this = thislet map = null;positionPicker = null;AMapLoader.load({"key": "您的key", // 申请好的Web端开发者Key,首次调用 load 时必填"version": "2.0", // 指定要加载的 JSAPI 的版本,缺省时默认为 1.4.15"plugins": ['AMap.Geolocation', // 定位插件'AMap.AutoComplete', // 输入提示与POI搜索'AMap.ToolBar', // 缩放工具条'AMap.Scale', // 比例尺插件],"Loca": { // 是否加载 Loca, 缺省不加载"version": '2.0.0' // Loca 版本,缺省 1.3.2},}).then(async (AMap) => {await this.asyncLoadAmapUI()map = new AMap.Map('container', {zoom: 18,scrollWheel: true,// viewMode: '3D', // 3D 模式视图,// mapStyle: 'amap://styles/macaron', // 地图样式设置})window.map = mapAMapUI.loadUI(['misc/MobiCityPicker',], (MobiCityPicker,) => {this.handleCityPicker(MobiCityPicker, map)});const geolocation = new AMap.Geolocation({// 是否使用高精度定位,默认:trueenableHighAccuracy: true,// 设置定位超时时间,默认:无穷大timeout: 6000,position: 'RB',showButton: true,panToLocation: true,zoomToAccuracy: true})map.addControl(geolocation);const scale = new AMap.Scale();map.addControl(scale);// 有初始值, 逆向地理编码查询地理位置详细信息// 没有初始值,进行GPS定位查询})},handleCityPicker() {// 处理点击左上角切换城市this.cityPicker = new MobiCityPicker({//设置主题(同名的className会被添加到外层容器上)theme: "light"});//监听城市选中事件this.cityPicker.on("citySelected", (cityInfo) => {this.cityPicker.hideImmediately(); //立即隐藏console.log(cityInfo); //选中的城市信息const { adcode, name, lat, lng } = cityInfothis.curCityName = namethis.curCityCode = adcode// map.setCenter([lng, lat])});},handlePositionPicker(map, PositionPicker, SimpleInfoWindow) {positionPicker = new PositionPicker({mode: 'dragMap',// 设定为拖拽地图模式,可选'dragMap'、'dragMarker',默认为'dragMap'// dragMap模式,通过拖动地图来选择需要的点。marker一直位于地图的中心点// dragMarker模式,通过拖动marker来选择需要的点map: map, // 依赖地图对象iconStyle: { //自定义外观url: '//webapi.amap.com/ui/1.0/assets/position-picker2.png',ancher: [24, 40],size: [40, 40]}});if (this.point.lng) {// 初始化positionPickerpositionPicker.start([this.point.lng, this.point.lat]);}// 选址结束后的回调函数positionPicker.on('success', res => {// 拖动地图后,选点成功回调})positionPicker.on('fail', res => {// 拖动地图后,选点失败回调})},handleSearchValueChange(val) {// 搜索事件处理// 主要逻辑const autoComplete = new AMap.Autocomplete({city: this.curCityName,citylimit: true});autoComplete.search(val, (status, result) => {// 搜索成功时,result即是对应的匹配数据let resAddress = [];if (status == 'complete') {// 检索的结果console.log(result.tips);}})}
五、问题
https
地图要使用点击定位到当前位置,必须是https协议。
1. https+IP
chrome https+IP时,需要翻墙才能定位到当前位置,firefox和edge不需要翻墙也可以直接定位到当前。
2. https+域名
无需其他任何操作,生产一定要使用https+域名
安全密钥
2021年12月02日以后申请的key需要配合您的安全密钥一起使用。也就是说2021年12月02日以后申请到key由一对组成,一个时key,一个是安全密钥。
注意:
1. 您这个设置必须是在JS API 脚本加载之前进行设置,否则设置无效。
2. 将key和安全密钥都写在前端代码中是很不安全的,生产需要将安全密钥配置到nginx。
具体如何配置请参考[JS API 安全密钥使用](https://lbs.amap.com/api/javascript-api-v2/guide/abc/jscode)。
3. 如果开发测试是http协议,需要转发到https对应的端口,或者直接使用https的端口。
4. 如果https的证书是自签的,在浏览器中打开。需要手动信任这个证书一次,否则会报net::ERR_CERT_COMMON_NAME_INVALID的错误
5. 如果https的证书是自签的,在APP 的webview中打开,需要APP配置一下白名单。
中心点缩放
双指缩放的时候,本来想要的目标点位于地图中心,可是一缩放,目标点就跑了,不位于地图中心了。
那能想到的方法就是,监听地图缩放事件,通过setCenter,把中心位置重新设置成目标点。但是bug一大把,缩放的时候,地图会莫名其妙的滑动很长的距离。
之后还是通过查看API发现了方法,由此骂自己千百遍,叫你不看API!!!只知道面向百度(现在变成了面向chatgpt,但是问不对要点也没有太大用处)开发。
map = new AMap.Map('container', {zoom: 18,scrollWheel: true,touchZoomCenter: 1, // 可缺省,当touchZoomCenter=1的时候,手机端双指缩放的以地图中心为中心,否则默认以双指中间点为中心
})
touchZoomCenter
这个属性,针对移动端,为1的时候,双指缩放会以地图的中心为中心进行缩放。这样就保证了缩放的时候位于中心的目标点不会跑。
还有个奇怪的问题:在我集成的app的webveiw中,当地图放大到比例尺小于等于1:25级以上(具体多少zoom值没有看,18以上吧)时,地图的瓦片就加载不出来了。微信中打开地图页面的链接时,放到到最大1:10时展示也是正常的。
最后,再重申一下,一定要看API,不要拿来就用,就百度。
参考
1. JS API 安全密钥使用
2. 高德地图 JS API 2.0教程
3.Geolocation.getCurrentPosition
本文链接:https://my.lmcjl.com/post/12871.html
4 评论