<template>
<div style="width: 100%;">
<div id="container" class="map"></div>
<div class="search-box">
<!-- <el-select v-model="address" clearable placeholder="请输入关键词" style="width: 400px;" :remote-method="remoteMethod"-->
<!-- filterable remote @change="currentSelect" class="one-text" size="default">-->
<!-- <el-option v-for="(item, index) in areaList" :key="index" :label="item.district + item.name"-->
<!-- :value="item.district + item.name">-->
<!-- <span>{{ item.district }}</span> <span>{{ item.name }}</span>-->
<!-- </el-option>-->
<!-- </el-select>-->
<el-select
v-model="state.sPoiSearch"
filterable
remote
reserve-keyword
placeholder="请输入地名"
:no-data-text="'查询失败,请输入正确地名'"
:popper-class="'g-poi-search-popper'"
:remote-method="fnRemoteMethod"
:loading="state.bPoiSearchLoading"
@change="fnPoiSearchChange">
<el-option
v-for="item in state.aPoiSearchOptions"
:key="item.value"
:label="item.label"
:title="item.label"
:value="item.value">
</el-option>
</el-select>
</div>
</div>
</template>
<script setup>
import {defineEmits, defineProps, nextTick, onMounted, reactive, toRefs} from 'vue';
import AMapLoader from "@amap/amap-jsapi-loader";
// 定义子组件向父组件传值/事件
const emit = defineEmits(['addressClick']);
const props = defineProps({
addressClick: Function,
lat: {
type: String,
default: '',
},
lng: {
// 弹窗内容
type: String,
default: '',
},
})
onMounted(() => {
//密钥
window._AMapSecurityConfig = {
securityJsCode: '102bf56ec19c61303648f21db667ee14',//key密钥
}
let lat = props.lat === "" ? 39.566143 : Number(props.lat);
let lng = props.lng === "" ? 116.209253 : Number(props.lng);
//北京
// initMap([lng, lat])
initMap()
})
const state = reactive({
geolocation: null,
map: null,
placeSearch: null,
sPoiSearch: '', // 地图搜索关键词
aPoiSearchOptions: [], // 可选择地图列表
bPoiSearchLoading: false, // 地图搜索 loading
autoComplete: null,
marker: null,
form: {
address: '',
lng: '',
lat: '',
},
areaList: [],
address: ''
})
/*sPoiSearch: '', // 地图搜索关键词
aPoiSearchOptions: [], // 可选择地图列表
bPoiSearchLoading: false, // 地图搜索 loading*/
const {areaList, address, sPoiSearch, aPoiSearchOptions, bPoiSearchLoading} = toRefs(state)
function initMap(arr) {
console.log("initMap")
AMapLoader.load({
key: "6721b02b7cbd15b86d31e8d8d94d0882",//这里放你申请的key
version: "2.0",
plugins: ["AMap.ToolBar", "AMap.ControlBar", 'AMap.AutoComplete', 'AMap.PlaceSearch', 'AMap.Geocoder', 'AMap.Marker', 'AMap.Geolocation'],
}).then((AMap) => {
state.map = new AMap.Map('container', {
viewMode: "3D", // 是否为3D地图模式
zoom: 15,
center: arr,
resizeEnable: true
});
// 地图放大缩小插件
let toolBar = new AMap.ToolBar({
position: {
top: '120px',
right: '51px'
}
})
// 3D地图插件
let controlBar = new AMap.ControlBar({
position: {
top: '20px',
right: '20px',
},
});
state.geolocation = new AMap.Geolocation({
enableHighAccuracy: true, // 是否使用高精度定位,默认:true
//timeout: 10000, // 设置定位超时时间,默认:无穷大
offset: [10, 20], // 定位按钮的停靠位置的偏移量
zoomToAccuracy: true, // 定位成功后调整地图视野范围使定位位置及精度范围视野内可见,默认:false
position: 'RB' // 定位按钮的排放位置, RB表示右下
})
state.geoCoder = new AMap.Geocoder({
city: '010', //城市设为北京,默认:“全国”
radius: 1000 //范围,默认:500
})
// 正向地理编码
state.geocoder = new AMap.Geocoder({
city: state.address
})
//查询
state.placeSearch = new AMap.PlaceSearch({
position: {
top: '20px',
left: '20px',
},
type: "", // 数据类别
pageSize: 10, // 每页结果数,默认10
pageIndex: 1, // 请求页码,默认1
extensions: "base" //返回信息详略,默认为base(基本信息)
})
state.autoComplete = new AMap.AutoComplete({city: '全国'});
state.map.on('click', (e) => { // 点击地图事件
if (!e && !e.lnglat) {
return
}
console.log("onclick")
console.log(e)
state.form.lng = e.lnglat.lng
state.form.lat = e.lnglat.lat
removeMarker() // 先删除地图上标记点
setMapMarker() // 在添加新的标记点
toGetAddress() //关闭地图,返回父级组件
})
state.map.addControl(toolBar); // 添加右上角的放大缩小
state.map.addControl(controlBar); // 添加右上角的放大缩小
getLocation();//获取当前位置
}).catch((e) => {
console.error(e); //加载错误提示
}).finally(() => {
removeMarker()
setMapMarker()
})
}
function getLocation() {
state.geolocation.getCurrentPosition(function (status, result) {
console.log(status, result)
if (status === 'complete') {
onComplete(result)
} else {
onError(result)
}
});
}
/**
* 当前位置定位
* @param data
*/
function onComplete(data) {
// data是具体的定位信息
// console.log(data)
state.form.lng = data.position.lng;
state.form.lat = data.position.lat;
removeMarker() // 先删除地图上标记点
setMapMarker() // 在添加新的标记点
}
function onError(data) {
// 定位出错
}
/*
* @desc 地图远程搜索方法
* @param query {String} 查询字符
* */
function fnRemoteMethod(query) {
console.log(query)
state.placeSearch.search(query, (status, data) => {
console.log(data)
// 监听地图搜索查询完成
if (data.info === 'OK' && data.poiList && data.poiList.pois && data.poiList.pois.length) {
state.aPoiSearchOptions = data.poiList.pois.map(v => ({
value: v.id,
label: v.name,
location: v.location
}))
} else {
state.aPoiSearchOptions = [];
}
state.bPoiSearchLoading = false;
});
// if (query !== '' && this.oAddMapPlaceSearch) {
// this.bPoiSearchLoading = true;
// // 根据关键字获取对应城市里相关的POI信息
// this.oAddMapPlaceSearch.search(query);
// } else {
// this.aPoiSearchOptions = [];
// }
}
/*
* @desc 地图搜索关键词发生变化,并添加标记
* param val {String} 当前选中值
* */
function fnPoiSearchChange(val) {
console.log(val)
let oFindMap = state.aPoiSearchOptions.find(v => v.value === val);
if (oFindMap) {
state.form.lng = oFindMap.location.lng;
state.form.lat = oFindMap.location.lat;
removeMarker()
setMapMarker()
// state.map.setCenter( [oFindMap.location.lng, oFindMap.location.lat]);
// state.map.getAllOverlays('marker').forEach(marker => {
// // 移除地图中的 marker 覆盖物
// state.map.remove(marker);
// })
// // 定位到指定Poi
// // this.oAddMapMarker.setCenter([oFindMap.location.lng, oFindMap.location.lat]);
// // this.fnAddMapMarkerHandle([oFindMap.location.lng, oFindMap.location.lat]);
// state.marker = new AMap.Marker({
// map: state.map,
// position: [oFindMap.location.lng, oFindMap.location.lat],
// })
// // state.map.setFitView()
// state.map.add(state.marker)
}
// let oFindMap = this.aPoiSearchOptions.find(v=> v.value === val);
// if(oFindMap) {
// // 定位到指定Poi
// this.oAddMapMarker.setCenter([oFindMap.location.lng, oFindMap.location.lat]);
// this.fnAddMapMarkerHandle([oFindMap.location.lng, oFindMap.location.lat]);
// }
}
function setMapMarker() {
if (state.form.lng == '' && state.form.lat == '') {
return
}
state.map.setFitView()
state.marker = new AMap.Marker({
map: state.map,
position: [state.form.lng, state.form.lat],
})
state.map.setCenter([state.form.lng, state.form.lat]);
state.map.setFitView()
state.map.add(state.marker)
}
function removeMarker() {
if (state.marker) {
state.map.remove(state.marker)
}
}
function toGetAddress() {
let lnglat = [state.form.lng, state.form.lat]
state.geoCoder.getAddress(lnglat, (status, result) => {
if (status === 'complete' && result.regeocode) {
console.log(result)
state.form.address = result.regeocode.formattedAddress;
emit('addressClick', state.form);
//props.addressClick(result, state.form.lng, state.form.lat) // 返回位置信息以及经纬度
}
})
}
function remoteMethod(query) {
if (query !== '') {
setTimeout(() => {
state.autoComplete.search(query, (status, result) => {
state.areaList = result.tips
})
}, 500)
} else {
state.areaList = []
}
}
function currentSelect(val) {
if (!val) {
return
}
toGetCoordinate(val)
}
function toGetCoordinate(address) {
state.geocoder.getLocation(address, function (status, result) {
if (status === 'complete' && result.info === 'OK') {
initMap([result.geocodes[0].location.lng, result.geocodes[0].location.lat])
state.form.lng = result.geocodes[0].location.lng
state.form.lat = result.geocodes[0].location.lat
state.form.address = result.geocodes[0].formattedAddress
}
})
nextTick(function () {
removeMarker()
setMapMarker()
})
}
function fixed(lng, lat) {
initMap([lng, lat])
state.form.lng = lng
state.form.lat = lat
}
// 暴露方法
defineExpose({
fixed,
toGetCoordinate
});
</script>
<style scoped lang="scss">
.map {
width: 100%;
height: 400px;
}
.search-box {
position: absolute;
z-index: 9;
top: 20px;
left: 20px;
::v-deep(.el-select) {
width: 320px;
border-radius: 50px;
overflow: hidden;
.el-input__wrapper {
border-radius: 50px;
}
}
}
</style>
高德地图VUE3
最新推荐文章于 2024-05-25 16:31:05 发布