1、申请密钥
2、安装@amap/amap-jsapi-loader
3、新增组件AMapLocation.vue
<template>
<div style="text-align: center">
<a-form :model="form" layout="inline" size="large" style="justify-content: center">
<a-form-item field="startAddress" label="起点地址">
<a-input v-model="form.startAddress" placeholder="输入起点地址" />
</a-form-item>
<a-form-item field="endAddress" label="终点地址">
<a-input v-model="form.endAddress" placeholder="输入终点地址" />
</a-form-item>
<a-form-item>
<a-button type="primary" @click="searchRoute">规划路线</a-button>
</a-form-item>
</a-form>
</div>
<div id="container" ref="mapRef" class="map"></div>
<div id="panel"></div>
</template>
<script setup lang="ts">
import AMapLoader from '@amap/amap-jsapi-loader';
import { nextTick, onMounted, reactive, ref, watch } from 'vue';
const map = ref<AMap.Map | null>(null);
const mapRef = ref(null);
const props = defineProps({
deviceList: {
type: Array,
default: () => [],
},
setCurrentDeviceName: {
type: Function,
default: null,
},
});
const emits = defineEmits(['changeDeivce']);
const form = reactive({
startAddress: '',
endAddress: '',
});
const startAddress = ref('');
const endAddress = ref('');
const isDeviceListLoaded = ref(false); // 用于标记 deviceList 是否已加载
// 新增:地理编码服务
let geocoder: AMap.Geocoder | null = null;
const currentDeviceName = ref(''); // 当前选中的设备名称
const transfer = ref<AMap.Transfer | null>(null); // 公交路线规划实例
const showInfoM = (e) => {
emits('changeDeivce', e.target.getExtData());
const lonlat = e.target.getExtData().location;
console.log('当前设备名称:', lonlat);
getAddress([lonlat.longitude, lonlat.latitude]);
};
const getAddress = (location: [number, number]) => {
geocoder.getAddress(location, (status, result) => {
if (status === 'complete' && result.regeocode) {
console.log(`设备的地址是:`, result.regeocode.formattedAddress);
// 这里可以根据需要处理地址信息,比如更新到UI上
currentDeviceName.value = result.regeocode.formattedAddress;
if (props.setCurrentDeviceName) {
props.setCurrentDeviceName(result.regeocode.formattedAddress);
}
}
});
};
const addMarkersToMap = (deviceList, AMap) => {
console.log(deviceList, 'deviceList');
geocoder = new AMap.Geocoder(); // 初始化地理编码服务
const device = deviceList[0];
if (device && device.location) {
// 新增:获取地址信息
getAddress([device.location.longitude, device.location.latitude]);
// 添加设备标记点
const markers: any[] = [];
deviceList.forEach((deviceItem) => {
const marker = new AMap.Marker({
position: new AMap.LngLat(
Number(deviceItem.location.longitude),
Number(deviceItem.location.latitude)
),
// content: `<div style="background-color: white; padding: 5px; border-radius: 5px;">${device.name}</div>`,
offset: new AMap.Pixel(-10, -10), // 标记点上的内容偏移量
// icon: '//vdata.amap.com/icons/b18/1/2.png', // 添加 Icon 图标 URL
icon: new AMap.Icon({
// 添加图标设置
imageSize: new AMap.Size(45, 50), // 设置图标大小
// 如果需要,还可以设置图标的其他属性,如image、imageSize等
// image: '//vdata.amap.com/icons/b18/1/2.png', // 图标图片URL
// imageSize: new AMap.Size(20, 20), // 图标图片大小
}),
title: deviceItem.name,
extData: { name: deviceItem.name, location: deviceItem.location }, // 自定义属性,用于存储 name
});
marker.on('click', showInfoM);
markers.push(marker);
});
map.value?.add(markers);
map.value?.setFitView(markers);
// 执行路线规划 经纬度
// transfer.search(
// new AMap.LngLat(deviceList[0].location.longitude, deviceList[0].location.latitude),
// new AMap.LngLat(deviceList[1].location.longitude, deviceList[1].location.latitude),
// (status, result) => {
// if (status === 'complete') {
// console.log('路线规划结果:', result);
// } else {
// console.error('路线规划失败:', result);
// }
// }
// );
}
};
onMounted(async () => {
(window as any)._AMapSecurityConfig = {
securityJsCode: 'f518996f228c64a9767dda6fcaccc4a4',
};
await nextTick();
AMapLoader.load({
key: '9076cee5b9c4acf4ec2c159a0f65c3c0', // 申请好的Web端开发者Key,首次调用 load 时必填
version: '2.0', // 指定要加载的 JSAPI 的版本,缺省时默认为 1.4.15
plugins: [
'AMap.HawkEye',
// 'AMap.ControlBar',
'AMap.MapType',
'AMap.Geocoder',
'AMap.Transfer',
], // 需要使用的的插件列表,如比例尺'AMap.Scale'等
})
.then((AMap) => {
map.value = new AMap.Map(mapRef.value, {
// 设置地图容器id
// viewMode: '2D', //设置地图模式
zoom: 13, // 初始化地图级别
center: [116.397428, 39.90923], // 初始化地图中心点位置
});
// 监听 deviceList 的变化
watch(
() => props.deviceList,
(newDeviceList) => {
if (newDeviceList.length > 0) {
isDeviceListLoaded.value = true; // 标记 deviceList 已加载
addMarkersToMap(newDeviceList, AMap); // 添加标记到地图
}
},
{ immediate: true } // 深度监听,确保对象内部属性的变化也能触发更新
);
const HawkEye = new AMap.HawkEye();
map.value.addControl(HawkEye);
// const ControlBar = new AMap.ControlBar();
// map.value!.addControl(ControlBar);
const MapType = new AMap.MapType();
map.value.addControl(MapType);
// 创建公交路线规划实例
transfer.value = new AMap.Transfer({
map: map.value,
panel: 'panel',
city: '成都', // 设置城市
policy: AMap.TransferPolicy.LEAST_TIME, // 最少时间策略
});
})
.catch((e) => {
console.log(e);
});
});
const searchRoute = () => {
if (!form.startAddress || !form.endAddress) return alert('请输入起始和终点地址!');
// 创建公交路线规划实例 地点
transfer.value.search(
[{ keyword: form.startAddress }, { keyword: form.endAddress }],
(status, result) => {
if (status === 'complete') {
console.log('路线规划结果:', result);
} else {
console.error('路线规划失败:', result);
}
}
);
};
</script>
<style lang="less" scoped>
#container {
height: 500px;
margin: 0 auto;
}
@media screen and (max-width: @screen-md) {
#container {
width: 100%;
height: 400px;
}
}
#panel {
position: absolute;
left: 0;
top: 114px;
height: 450px;
overflow-x: hidden;
overflow-y: scroll;
}
</style>
使用组件
<AMapLocation
:device-list="deviceList"
:set-current-device-name="setCurrentDeviceName"
@change-deivce="changeDeivce"
/>