2025-10-13 15:41:04 +08:00

262 lines
7.1 KiB
Vue

<template>
<div class="map-container">
<!-- 地图容器 -->
<a-form-item :label="'输入地址'">
<a-input-search v-model:value="searchValue" placeholder="输入需要查找的地址" enter-button @search="searchLocation" />
</a-form-item>
<a-form-item :label="'搜索结果'">
<a-select ref="select" v-model:value="selectValue" style="width: 100%" @focus="focus" @change="handleChange" >
<a-select-option v-for="item in searchList" :value="item.id">{{ item.name }}</a-select-option>
</a-select>
</a-form-item>
<div id="map" ref="mapContainer" style="height: calc(100% - 100px);"></div>
</div>
</template>
<script setup>
import { ref, onMounted, onUnmounted,defineEmits } from 'vue'
import AMapLoader from '@amap/amap-jsapi-loader'
defineOptions({
name: 'GxMap',
})
// 地图实例引用
const map = ref(null)
const mapContainer = ref(null)
const searchValue = ref('')
const searchResult = ref(null);
const markers = ref([]);
const locationMode = ref()
const locationData = ref({});
const infoWindow = ref(null);
const geocoder = ref(null);
const selectValue = ref('')
const searchList = ref([])
const emit = defineEmits(['handleGetLng']) //
onMounted(() => {
initMap()
})
onUnmounted(() => {
if (map.value) {
map.value.destroy()
}
})
const initMap = async () => {
try {
// 安全密钥配置(必须放在插件初始化前!)
window._AMapSecurityConfig = {
securityJsCode: 'df197447a4adc77f0cb376a44462272c' // 替换为你的jscode
};
// 加载地图 SDK
const AMap = await AMapLoader.load({
key: "38b334d84b1f89aa39d4efae76f0b341", // 替换你的高德Key
version: "2.0", // SDK 版本
plugins: ['AMap.ToolBar', 'AMap.Scale', 'AMap.Geocoder'] // 需要加载的插件
})
// 初始化地图
map.value = new AMap.Map(mapContainer.value, {
zoom: 13, // 缩放级别
center: [120.894522,31.981269], // 中心点坐标(北京)
viewMode: "3D" // 使用3D视图
})
// 添加控件
map.value.addControl(new AMap.ToolBar())
map.value.addControl(new AMap.Scale())
// 初始化地理编码器
geocoder.value = new AMap.Geocoder({
city: "全国"
});
// 添加标记点
const marker = new AMap.Marker({
position: [120.894522,31.981269],
title: "南通市人民政府"
})
map.value.add(marker)
// 添加地图点击事件
map.value.on('click', handleMapClick);
} catch (error) {
console.error("地图加载失败:", error)
}
}
// 处理地图点击事件
const handleMapClick = (e) => {
// 清除之前的标记
clearMarkers();
// 获取点击位置的经纬度
const lng = e.lnglat.getLng();
const lat = e.lnglat.getLat();
// 设置定位模式
locationMode.value = "点击定位";
// 存储坐标
locationData.value = {
lng: lng,
lat: lat,
name: "点击位置",
address: "正在获取地址..."
};
// 创建标记
const marker = new AMap.Marker({
position: [lng, lat],
title: "点击位置"
});
map.value.add(marker);
markers.value.push(marker);
// 设置地图中心
map.value.setCenter([lng, lat]);
// 使用逆地理编码获取地址信息
geocoder.value.getAddress([lng, lat], (status, result) => {
if (status === 'complete' && result.regeocode) {
const address = result.regeocode.formattedAddress;
locationData.value.address = address;
// 添加信息窗口
infoWindow.value = new AMap.InfoWindow({
content: `<div style="padding:10px;min-width:200px;">
<div style="font-weight:bold;margin-bottom:5px;">点击位置</div>
<div>${address}</div>
<div style="margin-top:8px;color:#666;">
<div>经度: ${lng.toFixed(6)}</div>
<div>纬度: ${lat.toFixed(6)}</div>
</div>
</div>`,
offset: new AMap.Pixel(0, -35)
});
const obj={address:address,lng:lng,lat:lat}
infoWindow.value.open(map.value, [lng, lat]);
emit('handleGetLng', obj)
} else {
locationData.value.address = "无法获取地址信息";
}
});
};
// 搜索地点
const searchLocation = () => {
if (!searchValue.value.trim()) {
alert('请输入搜索关键词');
return;
}
// 清除之前的标记
clearMarkers();
// 使用高德地图的搜索插件
AMap.plugin('AMap.PlaceSearch', () => {
const placeSearch = new AMap.PlaceSearch({
pageSize: 10,
pageIndex: 1,
city: '全国'
});
placeSearch.search(searchValue.value, (status, result) => {
if (status === 'complete' && result.poiList.pois.length) {
searchList.value = result.poiList.pois.map(item => {
return {
id: item.id,
name: item.name,
address: item.address,
location: {
lng: item.location.lng,
lat: item.location.lat
}
}
})
console.log(searchList.value)
const poi = result.poiList.pois[0];
// 存储搜索结果
searchResult.value = {
id: poi.id,
name: poi.name,
address: poi.address,
location: {
lng: poi.location.lng,
lat: poi.location.lat
}
};
// 创建标记
const marker = new AMap.Marker({
position: [poi.location.lng, poi.location.lat],
title: poi.name
});
map.value.add(marker);
markers.value.push(marker);
// 设置地图中心
map.value.setCenter([poi.location.lng, poi.location.lat]);
// 添加信息窗口
const infoWindow = new AMap.InfoWindow({
content: `<div style="padding:5px;min-width:150px;">
<div style="font-weight:bold;">${poi.name}</div>
<div>${poi.address}</div>
<div>经度: ${poi.location.lng.toFixed(6)}</div>
<div>纬度: ${poi.location.lat.toFixed(6)}</div>
</div>`,
offset: new AMap.Pixel(0, -30)
});
infoWindow.open(map.value, marker.getPosition());
// 点击标记打开信息窗口
marker.on('click', () => {
infoWindow.open(map.value, marker.getPosition());
});
} else {
alert('未找到相关地点,请尝试其他关键词');
searchResult.value = null;
}
});
});
};
// 清除所有标记
const clearMarkers = () => {
markers.value.forEach(marker => {
map.value.remove(marker);
});
markers.value = [];
searchResult.value = null;
};
const handleChange=(e)=>{
const item = searchList.value.find(item=>item.id===e)
const obj={
lng:item.location.lng,
lat:item.location.lat,
addres:item.address
}
emit('handleGetLng', obj)
}
</script>
<style scoped>
.map-container {
width: 100%;
height: 500px;
background-color: #eee;
padding: 20px;
border-radius: 10px;
}
#map {
width: 100%;
height: 100%;
border: 1px solid #eee;
}
</style>