index.vue
4.14 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
<script lang="ts" setup>
import { ComponentPropsConfigType } from '/@/views/visual/packages/index.type';
import { option } from './config';
import { useBaiduMapSDK } from '../../../hook/useBaiduMapSDK';
import { ref, unref } from 'vue';
import { buildUUID } from '/@/utils/uuid';
import { Spin } from 'ant-design-vue';
import { computed } from 'vue';
import { useMapTrackPlayBack } from './useMapTrackPlayback';
import { useMultipleDataFetch } from '../../../hook/socket/useSocket';
import { MultipleDataFetchUpdateFn } from '../../../hook/socket/useSocket.type';
const props = defineProps<{
config: ComponentPropsConfigType<typeof option>;
}>();
const wrapRef = ref<Nullable<Recordable>>(null);
const mapInstance = ref<Nullable<Recordable>>(null);
const wrapId = `bai-map-${buildUUID()}`;
const getDeviceId = computed(() => {
return props.config.option.dataSource?.at(0)?.deviceId;
});
const getDesign = computed(() => {
const { option } = props.config;
const { dataSource } = option || {};
return {
dataSource: dataSource,
};
});
/**
* @description 经度key
*/
const getLngKey = computed(() => {
return props.config.option.dataSource?.at(0)?.attribute || '';
});
/**
* @description 纬度key
*/
const getLatKey = computed(() => {
return props.config.option.dataSource?.at(1)?.attribute || '';
});
const validEffective = (value = '') => {
return !!(value && !isNaN(value as unknown as number));
};
const getTwoMap = (message, deviceId) => {
if (unref(getDeviceId) !== deviceId) return;
const { data = {} } = message;
const bindMessage = data[deviceId];
const lngData = bindMessage[unref(getLngKey)] || [];
const [lngLatest] = lngData;
const [, lng] = lngLatest || [];
const latData = bindMessage[unref(getLatKey)] || [];
const [latLatest] = latData;
const [, lat] = latLatest || [];
if (validEffective(lng) && validEffective(lat)) {
drawLine({ lng: Number(lng), lat: Number(lat) });
}
};
const getOneMap = (message, deviceId) => {
if (unref(getDeviceId) !== deviceId) return;
const { longitude, latitude, attribute } = unref(getDesign)?.dataSource?.[0] || {};
const { data } = message || {};
const bindMessage = data[deviceId];
const [, values] = attribute && bindMessage?.[attribute][0];
const mapValues = values ? JSON.parse(values) : {};
const lng = longitude && mapValues[longitude];
const lat = latitude && mapValues[latitude];
if (validEffective(lng) && validEffective(lat)) {
drawLine({ lng: Number(lng), lat: Number(lat) });
}
};
const updateFn: MultipleDataFetchUpdateFn = (message, deviceId) => {
const { lal } = unref(getDesign)?.dataSource?.[0] || {};
// 属性选择结构体类型时
if (lal && unref(getDesign)?.dataSource?.length == 1) {
getOneMap(message, deviceId);
return;
}
// 选择两个属性时
getTwoMap(message, deviceId);
};
useMultipleDataFetch(props, updateFn);
const { drawLine } = useMapTrackPlayBack(mapInstance);
const initMap = () => {
const wrapEl = unref(wrapRef);
if (!wrapEl) return;
if (!Reflect.has(window, 'BMapGL')) return;
const BMapGL = (window as any).BMapGL;
mapInstance.value = new BMapGL.Map(wrapId);
// 定位当前城市
const localcity = new BMapGL.LocalCity();
localcity.get(
(e: { center: Record<'lat' | 'lng', number>; code: number; level: number; name: string }) => {
const { center } = e;
const { lat, lng } = center;
const point = new BMapGL.Point(lng, lat);
unref(mapInstance)!.centerAndZoom(point, 15);
}
);
unref(mapInstance)!.enableScrollWheelZoom(true);
};
const { loading } = useBaiduMapSDK(initMap);
</script>
<template>
<main class="w-full h-full flex flex-col p-2 justify-center items-center">
<Spin
:spinning="loading"
wrapper-class-name="map-spin-wrapper !w-full !h-full !flex justify-center items-center pointer-events-none"
tip="地图加载中..."
/>
<div v-show="!loading" ref="wrapRef" :id="wrapId" class="w-full h-full no-drag"> </div>
</main>
</template>