236 lines
6.8 KiB
Vue
236 lines
6.8 KiB
Vue
<template>
|
|
<div id="container" style="position: relative"> </div>
|
|
</template>
|
|
<script setup lang="ts">
|
|
import AMapLoader from '@amap/amap-jsapi-loader';
|
|
import mapKey from '/@/utils/mapKey';
|
|
import { onMounted, ref, watch } from 'vue';
|
|
|
|
const emit = defineEmits(['getMarkerInfo', 'getDetail']);
|
|
|
|
const record = ref({});
|
|
|
|
let BasicMap = null;
|
|
let SelfMap = null;
|
|
let marker = null;
|
|
const props = defineProps({
|
|
mapList: {
|
|
type: Array<any>,
|
|
default: () => [],
|
|
},
|
|
centerPosition: {
|
|
type: Array<any>,
|
|
default: () => [108.95, 34.33],
|
|
},
|
|
markerContent: {
|
|
type: String,
|
|
default: () =>
|
|
'<div><img style="width: 20px;height: 20px" src="//a.amap.com/jsapi_demos/static/demo-center/icons/poi-marker-red.png" alt=""></div>',
|
|
},
|
|
labelContent: {
|
|
type: String,
|
|
default: () => '<div></div>',
|
|
},
|
|
field: {
|
|
type: String,
|
|
default: () => '',
|
|
},
|
|
id: {
|
|
type: String,
|
|
default: () => 'id',
|
|
},
|
|
});
|
|
|
|
watch(
|
|
() => props.mapList,
|
|
(nV) => {
|
|
if (SelfMap) {
|
|
addMarker(nV);
|
|
}
|
|
},
|
|
{ immediate: true }
|
|
);
|
|
|
|
function initMap(mapList) {
|
|
AMapLoader.load({
|
|
key: mapKey, // 申请好的Web端开发者Key,首次调用 load 时必填
|
|
// version: '1.4.15', // 指定要加载的 JSAPI 的版本,缺省时默认为 1.4.15
|
|
version: '2.0', // 指定要加载的 JSAPI 的版本,缺省时默认为 1.4.15
|
|
plugins: ['AMap.Geocoder'], // 需要使用的的插件列表,如比例尺'AMap.Scale'等
|
|
})
|
|
.then((AMap) => {
|
|
SelfMap = AMap;
|
|
|
|
//设置地图容器id
|
|
BasicMap = new AMap.Map('container', {
|
|
viewMode: '3D', //是否为3D地图模式
|
|
zoom: 8, //初始化地图级别
|
|
center: getCenterP(mapList), //初始化地图中心点位置
|
|
resizeEnable: true,
|
|
});
|
|
addMarker(mapList);
|
|
|
|
let logo1 = document.getElementsByClassName('amap-logo')[0];
|
|
if (logo1) {
|
|
// 将logo位置设置在视野之外
|
|
logo1.style.position = 'absolute';
|
|
logo1.style.left = '-1000px';
|
|
}
|
|
let logo2 = document.getElementsByClassName('amap-copyright')[0];
|
|
if (logo2) {
|
|
// 将logo位置设置在视野之外
|
|
logo2.style.position = 'absolute';
|
|
logo2.style.left = '-1000px';
|
|
}
|
|
})
|
|
.catch((e) => {
|
|
console.log(e);
|
|
});
|
|
}
|
|
|
|
function getCenterP(mapList) {
|
|
let lng = [];
|
|
let lat = [];
|
|
mapList.map((item: any) => {
|
|
lng.push(item.longitude * 1);
|
|
lat.push(item.latitude * 1);
|
|
});
|
|
if (mapList.length === 1) {
|
|
return [lng[0], lat[0]];
|
|
}
|
|
if (mapList.length > 1) {
|
|
return getCenter(
|
|
lng.sort((a, b) => {
|
|
return a - b;
|
|
}),
|
|
lat.sort((a, b) => {
|
|
return a - b;
|
|
})
|
|
);
|
|
}
|
|
return props.centerPosition;
|
|
}
|
|
|
|
function selectInfo(v) {
|
|
try {
|
|
if (v && Object.keys(JSON.parse(v)).length > 0) {
|
|
const { longitude, latitude } = JSON.parse(v);
|
|
record.value = JSON.parse(v);
|
|
if (latitude && latitude) {
|
|
let lngLat = new SelfMap.LngLat(longitude, latitude);
|
|
BasicMap.setCenter(lngLat);
|
|
BasicMap.setZoom(12);
|
|
}
|
|
}
|
|
} catch (e) {
|
|
console.log(e);
|
|
}
|
|
}
|
|
let markerList = [];
|
|
function addMarker(list) {
|
|
removeMarker();
|
|
if (list.length === 0) return;
|
|
BasicMap.setCenter(getCenterP(list));
|
|
let marker = null;
|
|
markerList = list.map((item: any) => {
|
|
marker = new SelfMap.Marker({
|
|
position: new SelfMap.LngLat(item.longitude * 1, item.latitude * 1),
|
|
content: props.markerContent ? props.markerContent.replace('^&', item[props.field]) : item?.markerContent,
|
|
// icon: medicalResource,
|
|
maxZoom: 8,
|
|
});
|
|
marker.info = item;
|
|
marker.on('click', markerClick);
|
|
return marker;
|
|
});
|
|
BasicMap.add(markerList);
|
|
}
|
|
|
|
window.getDetail = () => {
|
|
event?.stopPropagation();
|
|
emit('getDetail', record.value);
|
|
};
|
|
function getCenter(lng, lat) {
|
|
let lngCenter = (lng[0] + lng[lng.length - 1]) / 2;
|
|
let latCenter = (lat[0] + lat[lat.length - 1]) / 2;
|
|
return [lngCenter, latCenter];
|
|
// let centerLngLat = new SelfMap.LngLat(lngCenter, latCenter);
|
|
// BasicMap.setCenter(centerLngLat); // 设置地图中心点坐标
|
|
}
|
|
function markerClick(e) {
|
|
if (marker?.info[props.id] !== e.target?.info[props.id]) {
|
|
if (marker) {
|
|
marker.setLabel({ content: ``, direction: 'right' });
|
|
|
|
marker.setzIndex(1);
|
|
}
|
|
marker = e.target;
|
|
emit('getMarkerInfo', e.target.info);
|
|
|
|
record.value = e.target.info;
|
|
}
|
|
console.log(e);
|
|
}
|
|
|
|
function setLabel(labelContent) {
|
|
marker.setzIndex(999);
|
|
marker.setLabel({
|
|
content: labelContent,
|
|
direction: 'right',
|
|
});
|
|
|
|
let logo1 = document.getElementsByClassName('amap-marker-label')[0];
|
|
if (logo1) {
|
|
logo1.style.left = marker._style.width;
|
|
}
|
|
}
|
|
|
|
function removeMarker() {
|
|
for (let i = 0; i < markerList.length; i++) {
|
|
markerList[i].setMap(null);
|
|
}
|
|
markerList = []; // 清空数组
|
|
marker = null;
|
|
}
|
|
|
|
function destroyMap() {
|
|
BasicMap.destroy();
|
|
}
|
|
|
|
defineExpose({
|
|
selectInfo,
|
|
initMap,
|
|
setLabel,
|
|
destroyMap,
|
|
});
|
|
</script>
|
|
<style scoped lang="less">
|
|
#container {
|
|
width: 100%;
|
|
height: 100%;
|
|
}
|
|
:deep(.ant-drawer) {
|
|
position: absolute !important;
|
|
}
|
|
|
|
:deep(.ant-drawer-header) {
|
|
background-color: #b4c7e7;
|
|
}
|
|
:deep(.jeecg-basic-title) {
|
|
font-weight: bold;
|
|
}
|
|
|
|
:deep(.amap-marker-label) {
|
|
background-color: transparent !important;
|
|
padding: 0 !important;
|
|
border: none !important;
|
|
cursor: pointer;
|
|
top: 0 !important;
|
|
}
|
|
|
|
:deep(.ant-drawer-content-wrapper) {
|
|
height: 90%;
|
|
margin-top: 2.5%;
|
|
}
|
|
</style>
|