实现目标:h5实现位置的搜索,地图任意选点,获取经纬度及位置信息;
第一步:安装 @amap/amap-jsapi-loader插件:npm i @amap/amap-jsapi-loader --save;
第二步:
<template>
<!-- 地图选择位置,包括地图点击选点,搜索 -->
<div class="StationMap">
<van-nav-bar
title="选择具体问题位置"
fixed
placeholder
safe-area-inset-top
left-text="返回"
left-arrow
@click-left="close"
/>
<!-- 高德关键字搜索,个人每天限制100次调用,企业限值1000次 -->
<div class="searchArea">
<van-search v-model="searchVal" show-action label="地址" placeholder="请输入具体位置" @search="onSearch">
<template #action>
<div @click="onSearch">搜索</div>
</template>
</van-search>
<van-dropdown-menu v-if="showsearchResult">
<van-dropdown-item v-model="checkedVal" :options="positionArr" @change="searchPosition" />
</van-dropdown-menu>
</div>
<!-- 地图容器 -->
<div id="containerMap"></div>
</div>
</template>
<script>
import { reactive, toRefs, onMounted } from 'vue';
import AMapLoader from '@amap/amap-jsapi-loader';
import pointImg from '@/assets/images/common/position.png';
import { useStore } from '@/pinia/store.js';
import { showFailToast } from 'vant';
// 添加高德安全密钥(需要去高德开发平台注册申请)
window._AMapSecurityConfig = {
securityJsCode: '*********',
};
export default {
setup(props, context) {
const pinias = useStore();
const allData = reactive({
map: null,
markers: null,
positionObj: {
lon: 106.532,
lat: 29.573,
address: '江北区',
},
centerPosition: [], //默认显示当前定位
searchVal: '江北区',
checkedVal: '',
positionArr: [],
placeSearchComponent: null,
showsearchResult: false,
ifSearchLimit: true, //超过100次调用后,搜索按钮隐藏
});
onMounted(() => {
// 获取用户当前位置
if (/(Android)/i.test(navigator.userAgent)) {
let str = JSON.parse(window.android.requestLocation()).data;
let lon = str.lng.toString().length < 9 ? str.lng : str.lng.toString().substring(0, 9);
let lat = str.lat.toString().length < 9 ? str.lat : str.lat.toString().substring(0, 9);
allData.centerPosition = [lon, lat];
} else {
allData.centerPosition = [106.532, 29.573];
}
initMap(); //DOM初始化完成进行地图初始化
});
// 高德地图
function initMap() {
AMapLoader.load({
key: '*********', // 申请好的开发者Key
version: '2.0',
plugins: ['AMap.Geocoder', 'AMap.Scale', 'AMap.PlaceSearch'],
})
.then((AMap) => {
allData.map = new AMap.Map('containerMap', {
resizeEnable: true,
viewMode: '2D', // 是否为3D地图模式
zoom: 15, // 初始化地图级别
center: allData.centerPosition, //中心点坐标
jogEnable: false, //是否使用缓动效果,关闭平移惯性感觉舒服一些
});
setMarker(allData.centerPosition); //设置当前点位显示
getAdress(allData.centerPosition); //经纬度转位置
onSearch(); //默认搜索
allData.map.setFitView();
// 地图添加点击事件
allData.map.on('click', onMapClick);
let controlBar = new AMap.Scale({
position: {
bottom: '30px',
right: '10px',
},
});
allData.map.addControl(controlBar); // 添加右下角的比例尺
})
.catch((err) => {
console.log(err);
});
}
// 地图点击定位
function onMapClick(e) {
console.log('地图点击定位--', e.lnglat.lng, e.lnglat.lat);
allData.positionObj.lon = e.lnglat.lng;
allData.positionObj.lat = e.lnglat.lat;
setMarker([e.lnglat.lng, e.lnglat.lat]); //设置当前点位显示
getAdress([e.lnglat.lng, e.lnglat.lat]); //经纬度转位置
}
// 根据获取到的经纬度进行逆地理编码
function getAdress(lonLat) {
const Geocoder = new AMap.Geocoder();
Geocoder.getAddress(lonLat, (status, result) => {
console.log('getAdress--', status, result);
if (status === 'complete' && result.info === 'OK') {
// address即经纬度转换后的地点名称
allData.searchVal = result.regeocode.formattedAddress || '江北区';
allData.positionObj.address = result.regeocode.formattedAddress || '江北区';
} else {
console.log('经纬度转位置失败');
}
});
}
// 设置标注点位
function setMarker(lonLat) {
if (allData.markers) allData.map.remove(allData.markers);
allData.markers = new AMap.Marker({
position: lonLat,
icon: pointImg, //标注点图片
offset: new AMap.Pixel(-30, -50), //偏移量
map: allData.map,
});
}
// 搜索位置
function onSearch() {
//超过100次调用后,直接在地图上选点
if (!allData.ifSearchLimit) {
console.log(allData.searchVal);
showFailToast('搜索超出限值,可直接在地图上点击选择');
return false;
}
pinias.showLoading();
allData.positionArr = [];
allData.placeSearchComponent = new AMap.PlaceSearch();
allData.placeSearchComponent.search(allData.searchVal, (status, result) => {
console.log('onSearch---', status, result);
if (status === 'complete' && result.info === 'OK') {
allData.showsearchResult = true;
result.poiList.pois.map((item) => {
allData.positionArr.push({ text: item.address, value: item.id, location: item.location });
});
allData.checkedVal = allData.positionArr[0].value;
allData.ifSearchLimit = true;
} else {
allData.showsearchResult = false;
allData.ifSearchLimit = false;
allData.positionArr = [];
showFailToast('搜索超出限值,可直接在地图上点击选择');
}
pinias.hideLoading();
});
}
// 搜索选择一个位置后
function searchPosition(val) {
let arr = allData.positionArr.filter((item) => item.value == val);
allData.positionObj.address = arr[0].text;
allData.positionObj.lon = arr[0].location.lng;
allData.positionObj.lat = arr[0].location.lat;
allData.map.setCenter([arr[0].location.lng, arr[0].location.lat]);
setMarker([arr[0].location.lng, arr[0].location.lat]); //设置当前点位显示
console.log('选择位置后---', arr);
}
// 关闭返回事件
function close() {
context.emit('close', allData.positionObj);
}
return {
...toRefs(allData),
close,
onSearch,
searchPosition,
};
},
};
</script>
<style lang="less">
.StationMap {
#containerMap {
width: 100%;
height: calc(100vh - 95px);
}
.searchArea {
position: fixed;
z-index: 999;
left: 0px;
top: 92px;
width: 100%;
}
.amap-logo,
.amap-copyright {
display: none !important;
}
}
</style>
最终实现效果:
![](https://img-blog.csdnimg.cn/img_convert/f6d259c418b043414c4fbba2615c8c54.png)
![](https://img-blog.csdnimg.cn/img_convert/0962ba0b3f02f6b8e6e9f2a9dd313384.png)