|
@@ -1,13 +1,26 @@
|
|
|
<template>
|
|
|
<div ref="containerRef" class="map-container">
|
|
|
- <div ref="mapRef" id="YztMap" class="map-container" :style="{ width: width, height: height }"></div>
|
|
|
+ <div
|
|
|
+ ref="mapRef"
|
|
|
+ id="YztMap"
|
|
|
+ class="map-container"
|
|
|
+ :style="{
|
|
|
+ width: width,
|
|
|
+ height: height
|
|
|
+ }"
|
|
|
+ />
|
|
|
</div>
|
|
|
</template>
|
|
|
|
|
|
<script setup lang="ts">
|
|
|
-import 'ol/ol.css';
|
|
|
+import mmJson from '@/assets/json/mm2.json';
|
|
|
import { olMap } from '@/utils/olMap/olMap';
|
|
|
import { PointType } from '@/api/globalMap/type';
|
|
|
+import { ScaleLine } from 'ol/control';
|
|
|
+import { getPointInfoList } from '@/api/globalMap';
|
|
|
+import { getDictLabel } from '@/utils/dict';
|
|
|
+import { methodList, titleList } from '../data';
|
|
|
+import { pointDetailTemplate } from '../mapData';
|
|
|
|
|
|
interface Props {
|
|
|
activeMap: string;
|
|
@@ -15,7 +28,9 @@ interface Props {
|
|
|
}
|
|
|
const containerScale = inject('containerScale');
|
|
|
const props = withDefaults(defineProps<Props>(), {});
|
|
|
-const emits = defineEmits(['update:drawing', 'selectGraphics']);
|
|
|
+const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
|
|
+const { point_type } = toRefs<any>(proxy?.useDict('point_type'));
|
|
|
+const emits = defineEmits(['update:drawing', 'selectGraphics', 'handleShowWarehouse', 'handleShowVideo', 'handleShowPeople']);
|
|
|
|
|
|
const mapRef = ref(null);
|
|
|
const mapState = reactive({
|
|
@@ -30,35 +45,38 @@ const mapState = reactive({
|
|
|
const containerRef = ref();
|
|
|
const width = ref('100%');
|
|
|
const height = ref('100%');
|
|
|
-let yztMap, map;
|
|
|
+let map, mapUtils;
|
|
|
|
|
|
// 监听是否开启绘制
|
|
|
watch(
|
|
|
- () => props.drawing,
|
|
|
- (value) => {
|
|
|
- if (value) {
|
|
|
- map.drawGraphics(props.graphicsType);
|
|
|
- } else {
|
|
|
- map.closeDraw();
|
|
|
+ () => props.drawing,
|
|
|
+ (value) => {
|
|
|
+ if (value) {
|
|
|
+ mapUtils.drawGraphics(props.graphicsType);
|
|
|
+ } else {
|
|
|
+ mapUtils.closeDraw();
|
|
|
+ }
|
|
|
}
|
|
|
- }
|
|
|
);
|
|
|
-
|
|
|
+const mapList = reactive({
|
|
|
+ satellite2: ['YZT1715739306532', 'YZT1695608158269'],
|
|
|
+ satellite3: ['YZT1708679726700', 'YZT1695608158269'],
|
|
|
+ imageMap: ['YZT1640925052482', 'YZT1695608158269'],
|
|
|
+ imageMap2: ['YZT1640925052482', 'YZT1695608158269']
|
|
|
+});
|
|
|
// 监听地图类型变化
|
|
|
watch(
|
|
|
- () => props.activeMap,
|
|
|
- () => {
|
|
|
- if (!map) return;
|
|
|
- const id = props.activeMap === 'satellite2' ? ['YZT1715739306532', 'YZT1695608158269'] : ['YZT1708679726700', 'YZT1695608158269'];
|
|
|
- map.replaceLayers(id);
|
|
|
- }
|
|
|
+ () => props.activeMap,
|
|
|
+ () => {
|
|
|
+ if (!mapUtils) return;
|
|
|
+ mapUtils.replaceLayers(mapList[props.activeMap]);
|
|
|
+ }
|
|
|
);
|
|
|
-
|
|
|
+let scale;
|
|
|
const init = () => {
|
|
|
- const id = props.activeMap === 'satellite2' ? ['YZT1715739306532', 'YZT1695608158269'] : ['YZT1708679726700', 'YZT1695608158269'];
|
|
|
- map = new olMap({
|
|
|
+ mapUtils = new olMap({
|
|
|
dom: mapRef.value,
|
|
|
- id: id,
|
|
|
+ id: mapList[props.activeMap],
|
|
|
center: mapState.center,
|
|
|
zoom: mapState.zoom,
|
|
|
minZoom: mapState.minZoom,
|
|
@@ -81,54 +99,222 @@ const init = () => {
|
|
|
}
|
|
|
},
|
|
|
// 加载完成事件
|
|
|
- onLoadCompleted: (yMap) => {
|
|
|
- yztMap = yMap;
|
|
|
- // initMouseTool(map);
|
|
|
+ onLoadCompleted: (YztMap) => {
|
|
|
+ map = YztMap;
|
|
|
+ // initMouseTool(mapUtils);
|
|
|
+ scale = new ScaleLine();
|
|
|
+ map.addControl(scale);
|
|
|
+ map.getView().on('change:resolution', () => {
|
|
|
+ mapState.zoom = map.getView().getZoom().toFixed(2);
|
|
|
+ });
|
|
|
handleResize();
|
|
|
+ },
|
|
|
+ onMarkerClick: (data) => {
|
|
|
+ // 多点位
|
|
|
+ if (data.type === '1') {
|
|
|
+ let path = [];
|
|
|
+ props.pointType.forEach((item) => {
|
|
|
+ path.push(item.component);
|
|
|
+ });
|
|
|
+ getPointInfoList({
|
|
|
+ option: path.toString(),
|
|
|
+ longitude: data.longitude.toString(),
|
|
|
+ latitude: data.latitude.toString()
|
|
|
+ }).then((res) => {
|
|
|
+ const data2 = res.data.list;
|
|
|
+ let content = document.createElement('div');
|
|
|
+ // content.style.cssText = 'transform: scale(' + containerScale().scaleX + ');';
|
|
|
+ content.className = 'point-info';
|
|
|
+ let content2 = '';
|
|
|
+ content2 += '<div class="title-box"><div class="gradient-text">多点位信息</div></div>';
|
|
|
+ content2 += '<div class="icon1"></div>';
|
|
|
+ content2 += '<div class="icon2"></div>';
|
|
|
+ content2 += '<div class="icon3"></div>';
|
|
|
+ content2 += '<div class="icon4"></div>';
|
|
|
+ content.innerHTML = content2;
|
|
|
+ let tableBox = document.createElement('div');
|
|
|
+ tableBox.className = 'table-box';
|
|
|
+ let table = document.createElement('div');
|
|
|
+ table.className = 'table';
|
|
|
+ table.innerHTML = '<div class="point-item"><div class="td3">主题</div><div class="td3">名称</div></div>';
|
|
|
+ data2.forEach((item) => {
|
|
|
+ item.longitude = data.longitude;
|
|
|
+ item.latitude = data.latitude;
|
|
|
+ const div = document.createElement('div');
|
|
|
+ div.className = 'point-item point-item-hover';
|
|
|
+ div.innerHTML =
|
|
|
+ '<div class="td4">' + getDictLabel(point_type.value, item.dataType.toString()) + '</div><div class="td4">' + item.name + '</div>';
|
|
|
+ div.addEventListener('click', () => {
|
|
|
+ handlePointDetails(item);
|
|
|
+ });
|
|
|
+ table.appendChild(div);
|
|
|
+ });
|
|
|
+ tableBox.appendChild(table);
|
|
|
+ content.appendChild(tableBox);
|
|
|
+ let closeBtn = document.createElement('div');
|
|
|
+ closeBtn.className = 'close';
|
|
|
+ closeBtn.onclick = () => mapUtils.hideInfo(true);
|
|
|
+ content.appendChild(closeBtn);
|
|
|
+ mapUtils.showInfo(content, [data.longitude, data.latitude], true);
|
|
|
+ });
|
|
|
+ } else {
|
|
|
+ handlePointDetails(data);
|
|
|
+ }
|
|
|
}
|
|
|
});
|
|
|
};
|
|
|
-const addMarker = (points) => {
|
|
|
- map.addMarker(points);
|
|
|
+const handlePointDetails = (data) => {
|
|
|
+ let method = methodList[data.dataType];
|
|
|
+ let title = !!titleList[data.dataType] ? titleList[data.dataType] : '信息';
|
|
|
+ if (!method) return;
|
|
|
+ method(data.id).then((res) => {
|
|
|
+ if (!!pointDetailTemplate[data.dataType]) {
|
|
|
+ let div = document.createElement('div');
|
|
|
+ // div.style.cssText = 'transform: scale(' + containerScale().scaleX + ');';
|
|
|
+ div.className = 'point-info';
|
|
|
+ let titleDom = document.createElement('div');
|
|
|
+ titleDom.className = 'title-box';
|
|
|
+ titleDom.innerHTML = '<div class="gradient-text">' + title + '</div></div>';
|
|
|
+ div.appendChild(titleDom);
|
|
|
+ if (data.dataType === 2) {
|
|
|
+ let btnBox = document.createElement('div');
|
|
|
+ let btn = document.createElement('div');
|
|
|
+ btnBox.className = 'flex';
|
|
|
+ btn.className = 'btn';
|
|
|
+ btn.innerHTML = '<div class="video-icon"></div><div>物资详情</div>';
|
|
|
+ btn.onclick = () => {
|
|
|
+ emits('handleShowWarehouse', data);
|
|
|
+ };
|
|
|
+ btnBox.appendChild(btn);
|
|
|
+ div.appendChild(btnBox);
|
|
|
+ } else if (data.dataType === 4) {
|
|
|
+ let btnBox = document.createElement('div');
|
|
|
+ let btn = document.createElement('div');
|
|
|
+ btnBox.className = 'flex';
|
|
|
+ btn.className = 'btn';
|
|
|
+ btn.innerHTML = '<div class="video-icon"></div><div>附近视频</div>';
|
|
|
+ btn.onclick = () => {
|
|
|
+ emits('handleShowVideo', data);
|
|
|
+ };
|
|
|
+ btnBox.appendChild(btn);
|
|
|
+ div.appendChild(btnBox);
|
|
|
+ } else if (data.dataType === 41) {
|
|
|
+ let btnBox = document.createElement('div');
|
|
|
+ let btn = document.createElement('div');
|
|
|
+ btnBox.className = 'flex';
|
|
|
+ btn.className = 'btn';
|
|
|
+ btn.innerHTML = '<div class="video-icon"></div><div>人员列表</div>';
|
|
|
+ btn.onclick = () => {
|
|
|
+ emits('handleShowPeople', data);
|
|
|
+ };
|
|
|
+ btnBox.appendChild(btn);
|
|
|
+ div.appendChild(btnBox);
|
|
|
+ }
|
|
|
+ let icon1 = document.createElement('div');
|
|
|
+ icon1.className = 'icon1';
|
|
|
+ let icon2 = document.createElement('div');
|
|
|
+ icon2.className = 'icon2';
|
|
|
+ let icon3 = document.createElement('div');
|
|
|
+ icon3.className = 'icon3';
|
|
|
+ let icon4 = document.createElement('div');
|
|
|
+ icon4.className = 'icon4';
|
|
|
+ div.appendChild(icon1);
|
|
|
+ div.appendChild(icon2);
|
|
|
+ div.appendChild(icon3);
|
|
|
+ div.appendChild(icon4);
|
|
|
+ let table = document.createElement('div');
|
|
|
+ table.className = 'table-box';
|
|
|
+ let content = '';
|
|
|
+ content += '<div class="table">';
|
|
|
+ const newData = filterTd(res.rows[0], data.dataType);
|
|
|
+ newData.forEach((item) => {
|
|
|
+ if (item.type === 'shortText') {
|
|
|
+ content += '<div class="tr">';
|
|
|
+ item.data.forEach((item2) => {
|
|
|
+ content += '<div class="point-item">';
|
|
|
+ content += '<div class="td1">' + item2.label + '</div><div class="td2">' + item2.value + '</div>';
|
|
|
+ content += '</div>';
|
|
|
+ });
|
|
|
+ content += '</div>';
|
|
|
+ } else {
|
|
|
+ content += '<div class="point-item2">';
|
|
|
+ content += '<div class="td1">' + item.data[0].label + '</div><div class="td2">' + item.data[0].value + '</div>';
|
|
|
+ content += '</div>';
|
|
|
+ }
|
|
|
+ });
|
|
|
+ content += '</div>';
|
|
|
+ table.innerHTML = content;
|
|
|
+ div.appendChild(table);
|
|
|
+ let closeBtn = document.createElement('div');
|
|
|
+ closeBtn.className = 'close';
|
|
|
+ closeBtn.onclick = () => mapUtils.hideInfo(true);
|
|
|
+ div.appendChild(closeBtn);
|
|
|
+ mapUtils.showInfo(div, [data.longitude, data.latitude], true);
|
|
|
+ }
|
|
|
+ });
|
|
|
};
|
|
|
-// 设置地图层级
|
|
|
-const setMapZoom = (value) => {
|
|
|
- if (!yztMap) return;
|
|
|
- const view = yztMap.map.getView();
|
|
|
- if (value === 1) {
|
|
|
- view.setCenter([113.280637, 23.125178]);
|
|
|
- view.setZoom(7);
|
|
|
- } else if (value === 2) {
|
|
|
- view.setCenter([110.925175, 21.678955]);
|
|
|
- view.setZoom(11);
|
|
|
- } else if (value === 3) {
|
|
|
- view.setCenter([110.925175, 21.678955]);
|
|
|
- view.setZoom(12);
|
|
|
- } else if (value === 4) {
|
|
|
- view.setCenter([110.925175, 21.678955]);
|
|
|
- view.setZoom(15);
|
|
|
- } else if (value === 5) {
|
|
|
- view.setCenter([110.925175, 21.678955]);
|
|
|
- view.setZoom(16);
|
|
|
+const filterTd = (obj, dataType) => {
|
|
|
+ let data = [];
|
|
|
+ let tempData = {};
|
|
|
+ let i = 0;
|
|
|
+ for (let key in obj) {
|
|
|
+ let keyLabel = pointDetailTemplate[dataType][key];
|
|
|
+ if (!!keyLabel) {
|
|
|
+ if (i === 2) {
|
|
|
+ i = 0;
|
|
|
+ }
|
|
|
+ const value = !!obj[key] ? obj[key] : '';
|
|
|
+ if (value && value.length > 8) {
|
|
|
+ if (i === 0) {
|
|
|
+ data.push({ type: 'longText', data: [{ label: keyLabel, value: value }] });
|
|
|
+ i = 0;
|
|
|
+ } else {
|
|
|
+ tempData = { type: 'longText', data: [{ label: keyLabel, value: value }] };
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ if (i === 0) {
|
|
|
+ data.push({ type: 'shortText', data: [{ label: keyLabel, value: value }] });
|
|
|
+ } else {
|
|
|
+ data[data.length - 1].data.push({ label: keyLabel, value: value });
|
|
|
+ }
|
|
|
+ i++;
|
|
|
+ if (!!tempData && JSON.stringify(tempData) !== '{}') {
|
|
|
+ data.push(tempData);
|
|
|
+ tempData = {};
|
|
|
+ i = 0;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
+ if (!!tempData && JSON.stringify(tempData) !== '{}') {
|
|
|
+ data.push(tempData);
|
|
|
+ }
|
|
|
+ if (data[data.length - 1].data && data[data.length - 1].data.length === 1 && data[data.length - 1].type === 'shortText') {
|
|
|
+ data[data.length - 1].data[1] = { label: '', value: '' };
|
|
|
+ }
|
|
|
+ return data;
|
|
|
};
|
|
|
-// 切换2D、3D
|
|
|
-const switchThreeDimensional = () => {
|
|
|
- const view = yztMap.map.getView();
|
|
|
- mapState.isThreeDimensional = !mapState.isThreeDimensional;
|
|
|
- const pitch = mapState.isThreeDimensional ? 45 : 0;
|
|
|
- view.setPitch(pitch);
|
|
|
+const addMarker = (points) => {
|
|
|
+ mapUtils.addMarker(points);
|
|
|
};
|
|
|
const clearMarker = () => {
|
|
|
- this.map.clearMarker();
|
|
|
+ mapUtils.clearMarker();
|
|
|
};
|
|
|
-defineExpose({ addMarker, clearMarker });
|
|
|
const handleResize = () => {
|
|
|
const containerWidth = containerRef.value.clientWidth * containerScale().scaleX;
|
|
|
const containerHeight = containerRef.value.clientHeight * containerScale().scaleY;
|
|
|
width.value = containerWidth + 'px';
|
|
|
height.value = containerHeight + 'px';
|
|
|
- yztMap.updateSize();
|
|
|
+ map.updateSize();
|
|
|
+};
|
|
|
+const getMap = () => {
|
|
|
+ return map;
|
|
|
+};
|
|
|
+const getScale = () => {
|
|
|
+ return scale;
|
|
|
+};
|
|
|
+const getMapUtils = () => {
|
|
|
+ return mapUtils;
|
|
|
};
|
|
|
// 加载事件
|
|
|
onMounted(() => {
|
|
@@ -139,9 +325,14 @@ onMounted(() => {
|
|
|
onUnmounted(() => {
|
|
|
window.removeEventListener('resize', handleResize);
|
|
|
});
|
|
|
+provide('getMapUtils', getMapUtils);
|
|
|
+provide('getMap', getMap);
|
|
|
+provide('getScale', getScale);
|
|
|
+defineExpose({ getMapUtils, addMarker, clearMarker });
|
|
|
</script>
|
|
|
|
|
|
<style scoped>
|
|
|
+@import '../map.scss';
|
|
|
.map-container {
|
|
|
width: 100%;
|
|
|
height: 100%;
|