|
@@ -1,131 +1,96 @@
|
|
|
<template>
|
|
|
<div ref="containerRef" class="map-container">
|
|
|
- <div
|
|
|
- ref="mapRef"
|
|
|
- id="YztMap"
|
|
|
- class="map-container"
|
|
|
- :style="{
|
|
|
- width: width,
|
|
|
- height: height
|
|
|
- }"
|
|
|
- />
|
|
|
+ <div ref="mapRef" id="YztMap" class="map-container2" />
|
|
|
</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 {getPointInfoList} from '@/api/globalMap';
|
|
|
import { getDictLabel } from '@/utils/dict';
|
|
|
import { methodList, titleList } from '../data';
|
|
|
-import { pointDetailTemplate } from '../mapData';
|
|
|
+import { pointDetailTemplate } from '@/components/Map/mapData';
|
|
|
+import useMapStore from '@/store/modules/map';
|
|
|
|
|
|
-interface Props {
|
|
|
- activeMap: string;
|
|
|
- pointType: PointType[];
|
|
|
-}
|
|
|
-const containerScale = inject('containerScale');
|
|
|
-const props = withDefaults(defineProps<Props>(), {});
|
|
|
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
|
|
const { point_type } = toRefs<any>(proxy?.useDict('point_type'));
|
|
|
-const emits = defineEmits(['update:drawing', 'selectGraphics', 'handleShowWarehouse', 'handleShowVideo', 'handleShowPeople']);
|
|
|
+const mapStore = useMapStore();
|
|
|
+const emits = defineEmits(['handleShowWarehouse', 'handleShowVideo', 'handleShowPeople', 'closeDetailDialog', 'resize']);
|
|
|
|
|
|
const mapRef = ref(null);
|
|
|
-const mapState = reactive({
|
|
|
- center: [110.925175, 21.678955],
|
|
|
- zoom: 7.9,
|
|
|
- minZoom: 6,
|
|
|
- maxZoom: 16,
|
|
|
- isThreeDimensional: false,
|
|
|
- // 是否显示比例尺
|
|
|
- showScale: true
|
|
|
-});
|
|
|
const containerRef = ref();
|
|
|
-const width = ref('100%');
|
|
|
-const height = ref('100%');
|
|
|
let map, mapUtils;
|
|
|
|
|
|
-// 监听是否开启绘制
|
|
|
-watch(
|
|
|
- () => props.drawing,
|
|
|
- (value) => {
|
|
|
- if (value) {
|
|
|
- mapUtils.drawGraphics(props.graphicsType);
|
|
|
- } else {
|
|
|
- mapUtils.closeDraw();
|
|
|
- }
|
|
|
- }
|
|
|
-);
|
|
|
const mapList = reactive({
|
|
|
satellite2: [
|
|
|
- { layer: 'map', code: 'YZT1712111943104', zIndex: '-99', visible: true },
|
|
|
- { layer: 'annotation', code: 'YZT1695608158269', zIndex: '-98', visible: true }
|
|
|
+ { layer: 'map', layerType: 'WMTS', code: 'YZT1708679726700', zIndex: '-100', visible: true },
|
|
|
+ { layer: 'map', layerType: 'WFS', code: 'YZT1712111943104', zIndex: '-99', visible: true },
|
|
|
+ { layer: 'annotation', layerType: 'WMTS', code: 'YZT1695608158269', zIndex: '-98', visible: true }
|
|
|
],
|
|
|
satellite3: [
|
|
|
- { layer: 'map', code: 'YZT1708679726700', zIndex: '-99', visible: true },
|
|
|
- { layer: 'annotation', code: 'YZT1695608158269', zIndex: '-98', visible: true }
|
|
|
+ { layer: 'map', layerType: 'WMTS', code: 'YZT1708679726700', zIndex: '-99', visible: true },
|
|
|
+ { layer: 'annotation', layerType: 'WMTS', code: 'YZT1695608158269', zIndex: '-98', visible: true }
|
|
|
],
|
|
|
imageMap: [
|
|
|
- { layer: 'map', code: 'YZT1640925052482', zIndex: '-99' },
|
|
|
- { layer: 'annotation', code: 'YZT1695608158269', zIndex: '-98', visible: true }
|
|
|
+ { layer: 'map', layerType: 'WMTS', code: 'YZT1640925052482', zIndex: '-99' },
|
|
|
+ { layer: 'annotation', layerType: 'WMTS', code: 'YZT1695608158269', zIndex: '-98', visible: true }
|
|
|
],
|
|
|
imageMap2: [
|
|
|
- { layer: 'map', code: 'YZT1640925052482', zIndex: '-99', visible: true },
|
|
|
- { layer: 'annotation', code: 'YZT1695608158269', zIndex: '-98', visible: true }
|
|
|
+ { layer: 'map', layerType: 'JSON', code: 'gd', zIndex: '-99', visible: true },
|
|
|
+ { layer: 'annotation', layerType: 'WMTS', code: 'YZT1695608158269', zIndex: '-98', visible: true }
|
|
|
]
|
|
|
});
|
|
|
// 监听地图类型变化
|
|
|
watch(
|
|
|
- () => props.activeMap,
|
|
|
+ () => mapStore.activeMap,
|
|
|
() => {
|
|
|
if (!mapUtils) return;
|
|
|
- mapUtils.replaceLayers(mapList[props.activeMap]);
|
|
|
+ mapUtils.replaceLayers(mapList[mapStore.activeMap]);
|
|
|
+ }
|
|
|
+);
|
|
|
+watch(
|
|
|
+ () => mapStore.showMask,
|
|
|
+ () => {
|
|
|
+ if (mapStore.showMask) {
|
|
|
+ mapUtils.createVecByJson2(mmJson, { strokeWeight: 2 });
|
|
|
+ } else {
|
|
|
+ mapUtils.removeMask3(true);
|
|
|
+ }
|
|
|
}
|
|
|
);
|
|
|
-let scale;
|
|
|
const init = () => {
|
|
|
+ mapStore.setMapLoaded(false);
|
|
|
mapUtils = new olMap({
|
|
|
dom: mapRef.value,
|
|
|
- id: mapList[props.activeMap],
|
|
|
- center: mapState.center,
|
|
|
- zoom: mapState.zoom,
|
|
|
- minZoom: mapState.minZoom,
|
|
|
- maxZoom: mapState.maxZoom,
|
|
|
+ id: mapList[mapStore.activeMap],
|
|
|
+ center: mapStore.mapState.center,
|
|
|
+ zoom: mapStore.mapState.zoom,
|
|
|
+ minZoom: mapStore.mapState.minZoom,
|
|
|
+ maxZoom: mapStore.mapState.maxZoom,
|
|
|
+ showScale: true,
|
|
|
drawTool: {
|
|
|
- use: true,
|
|
|
- color: props.color,
|
|
|
- drawType: props.drawType,
|
|
|
- graphicsType: props.graphicsType,
|
|
|
- // 绘制完成事件
|
|
|
- onDrawCompleted: (data, overlaysData, obj) => {
|
|
|
- emits('selectGraphics', data, overlaysData.length.toString());
|
|
|
- // 点击空间分析
|
|
|
- obj.on('click', function () {
|
|
|
- // 没在编辑时
|
|
|
- if (!props.drawing) {
|
|
|
- emits('selectGraphics', data);
|
|
|
- }
|
|
|
- });
|
|
|
- }
|
|
|
+ use: true
|
|
|
},
|
|
|
// 加载完成事件
|
|
|
onLoadCompleted: (YztMap) => {
|
|
|
map = YztMap;
|
|
|
- // initMouseTool(mapUtils);
|
|
|
- scale = new ScaleLine();
|
|
|
- map.addControl(scale);
|
|
|
+ mapStore.setMapLoaded(true);
|
|
|
map.getView().on('change:resolution', () => {
|
|
|
- mapState.zoom = map.getView().getZoom().toFixed(2);
|
|
|
+ mapStore.setZoom(map.getView().getZoom().toFixed(2));
|
|
|
});
|
|
|
+ if (mapStore.showMask) {
|
|
|
+ mapUtils.createVecByJson2(mmJson, { strokeWeight: 2 });
|
|
|
+ }
|
|
|
+ // let drawTool = new DrawTool({ mapUtils, map });
|
|
|
handleResize();
|
|
|
},
|
|
|
onMarkerClick: (data) => {
|
|
|
// 多点位
|
|
|
if (data.type === '1') {
|
|
|
let path = [];
|
|
|
- props.pointType.forEach((item) => {
|
|
|
+ mapStore.pointType.forEach((item) => {
|
|
|
path.push(item.component);
|
|
|
});
|
|
|
getPointInfoList({
|
|
@@ -182,42 +147,40 @@ const handlePointDetails = (data) => {
|
|
|
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);
|
|
|
+ const objs = {
|
|
|
+ '2': {
|
|
|
+ title: '物资详情',
|
|
|
+ method: 'handleShowWarehouse'
|
|
|
+ },
|
|
|
+ '41': {
|
|
|
+ title: '人员列表',
|
|
|
+ method: 'handleShowPeople'
|
|
|
+ },
|
|
|
+ '43': {
|
|
|
+ title: '历史轨迹',
|
|
|
+ method: 'handleShowTrack'
|
|
|
+ }
|
|
|
+ };
|
|
|
+ let obj = objs[data.dataType];
|
|
|
+ if ([4, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58].includes(data.dataType)) {
|
|
|
+ obj = {
|
|
|
+ title: '附近视频',
|
|
|
+ method: 'handleShowVideo'
|
|
|
};
|
|
|
- btnBox.appendChild(btn);
|
|
|
- div.appendChild(btnBox);
|
|
|
- } else if (data.dataType === 41) {
|
|
|
+ }
|
|
|
+ if (!!obj) {
|
|
|
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.innerHTML = '<div class="video-icon"></div>' + obj.title + '<div></div>';
|
|
|
btn.onclick = () => {
|
|
|
- emits('handleShowPeople', data);
|
|
|
+ emits(obj.method, data);
|
|
|
};
|
|
|
btnBox.appendChild(btn);
|
|
|
div.appendChild(btnBox);
|
|
@@ -259,9 +222,14 @@ const handlePointDetails = (data) => {
|
|
|
div.appendChild(table);
|
|
|
let closeBtn = document.createElement('div');
|
|
|
closeBtn.className = 'close';
|
|
|
- closeBtn.onclick = () => mapUtils.hideInfo(true);
|
|
|
+ closeBtn.onclick = () => {
|
|
|
+ mapUtils.hideInfo(true);
|
|
|
+ emits('closeDetailDialog', data);
|
|
|
+ };
|
|
|
div.appendChild(closeBtn);
|
|
|
- mapUtils.showInfo(div, [data.longitude, data.latitude], true);
|
|
|
+ mapUtils.showInfo(div, [data.longitude, data.latitude], -data.scale * data.size[1], true);
|
|
|
+ } else if (data.dataType === 'video') {
|
|
|
+ emits('handleShowVideoDetail', res.data, true);
|
|
|
}
|
|
|
});
|
|
|
};
|
|
@@ -269,13 +237,14 @@ const filterTd = (obj, dataType) => {
|
|
|
let data = [];
|
|
|
let tempData = {};
|
|
|
let i = 0;
|
|
|
- for (let key in obj) {
|
|
|
- let keyLabel = pointDetailTemplate[dataType][key];
|
|
|
+ const pointDetailTemplateObj = pointDetailTemplate[dataType];
|
|
|
+ Object.keys(pointDetailTemplateObj).forEach((key) => {
|
|
|
+ let keyLabel = pointDetailTemplateObj[key];
|
|
|
if (!!keyLabel) {
|
|
|
if (i === 2) {
|
|
|
i = 0;
|
|
|
}
|
|
|
- const value = !!obj[key] ? obj[key] : '';
|
|
|
+ const value = !!obj && !!obj[key] ? obj[key] : '';
|
|
|
if (value && value.length > 8) {
|
|
|
if (i === 0) {
|
|
|
data.push({ type: 'longText', data: [{ label: keyLabel, value: value }] });
|
|
@@ -297,7 +266,7 @@ const filterTd = (obj, dataType) => {
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
- }
|
|
|
+ });
|
|
|
if (!!tempData && JSON.stringify(tempData) !== '{}') {
|
|
|
data.push(tempData);
|
|
|
}
|
|
@@ -312,22 +281,30 @@ const addMarker = (points) => {
|
|
|
const clearMarker = () => {
|
|
|
mapUtils.clearMarker();
|
|
|
};
|
|
|
+
|
|
|
+let inverseScale = ref({
|
|
|
+ inverseScaleX: 1,
|
|
|
+ inverseScaleY: 1
|
|
|
+});
|
|
|
const handleResize = () => {
|
|
|
- const containerWidth = containerRef.value.clientWidth * containerScale().scaleX;
|
|
|
- const containerHeight = containerRef.value.clientHeight * containerScale().scaleY;
|
|
|
- width.value = containerWidth + 'px';
|
|
|
- height.value = containerHeight + 'px';
|
|
|
+ if (!containerRef.value) return;
|
|
|
map.updateSize();
|
|
|
+ nextTick(() => {
|
|
|
+ emits('resize');
|
|
|
+ });
|
|
|
};
|
|
|
const getMap = () => {
|
|
|
return map;
|
|
|
};
|
|
|
-const getScale = () => {
|
|
|
- return scale;
|
|
|
-};
|
|
|
const getMapUtils = () => {
|
|
|
return mapUtils;
|
|
|
};
|
|
|
+const getDrawTool = () => {
|
|
|
+ return mapUtils.getDrawTool();
|
|
|
+};
|
|
|
+const addSearchMarker = (item) => {
|
|
|
+ return mapUtils.addSearchMarker(item);
|
|
|
+};
|
|
|
// 加载事件
|
|
|
onMounted(() => {
|
|
|
init();
|
|
@@ -337,89 +314,31 @@ onMounted(() => {
|
|
|
onUnmounted(() => {
|
|
|
window.removeEventListener('resize', handleResize);
|
|
|
});
|
|
|
-provide('getMapUtils', getMapUtils);
|
|
|
-provide('getMap', getMap);
|
|
|
-provide('getScale', getScale);
|
|
|
-defineExpose({ getMapUtils, addMarker, clearMarker });
|
|
|
+defineExpose({ getMap, getMapUtils, addSearchMarker, getDrawTool, addMarker, clearMarker });
|
|
|
</script>
|
|
|
|
|
|
<style scoped>
|
|
|
@import '../map.scss';
|
|
|
+.map-container2 {
|
|
|
+ width: 100%;
|
|
|
+ height: 100%;
|
|
|
+ position: relative;
|
|
|
+ overflow: hidden;
|
|
|
+}
|
|
|
.map-container {
|
|
|
width: 100%;
|
|
|
height: 100%;
|
|
|
position: relative;
|
|
|
- .zoom-text {
|
|
|
- position: absolute;
|
|
|
- bottom: 8px;
|
|
|
- right: 75px;
|
|
|
- font-size: 14px;
|
|
|
+ :deep(.ol-scale-line) {
|
|
|
+ left: unset;
|
|
|
+ bottom: 16px;
|
|
|
+ right: 48px;
|
|
|
+ background-color: transparent;
|
|
|
}
|
|
|
- .right-tool {
|
|
|
- position: absolute;
|
|
|
- bottom: 50px;
|
|
|
- right: 5px;
|
|
|
- }
|
|
|
- .model-btn {
|
|
|
- background-color: #022577;
|
|
|
- font-size: 14px;
|
|
|
- color: #889ee9;
|
|
|
- cursor: pointer;
|
|
|
- padding: 3px 3px;
|
|
|
- border-radius: 5px;
|
|
|
- }
|
|
|
- :deep(.amap-scalecontrol) {
|
|
|
- left: unset !important;
|
|
|
- background-color: unset !important;
|
|
|
- right: 74px;
|
|
|
- }
|
|
|
- :deep(.amap-scale-text) {
|
|
|
- width: 230px !important;
|
|
|
- text-align: left !important;
|
|
|
- font-size: 14px;
|
|
|
- padding-left: 20px;
|
|
|
- }
|
|
|
- :deep(.amap-scale-middle) {
|
|
|
- width: 228px !important;
|
|
|
- }
|
|
|
- :deep(.amap-scale-edgeright) {
|
|
|
- left: 228px !important;
|
|
|
- }
|
|
|
- :deep(.amap-logo),
|
|
|
- :deep(.amap-copyright) {
|
|
|
- display: none !important;
|
|
|
- }
|
|
|
- /* 自定义测距工具样式 */
|
|
|
- :deep(.amap-ranger) {
|
|
|
- background-color: #ffffff;
|
|
|
- border: 1px solid #888888;
|
|
|
- border-radius: 5px;
|
|
|
- padding: 5px;
|
|
|
- }
|
|
|
-
|
|
|
- :deep(.amap-ranger .amap-toolbar) {
|
|
|
- color: #333;
|
|
|
- font-size: 12px;
|
|
|
- padding: 5px;
|
|
|
- }
|
|
|
-
|
|
|
- :deep(.amap-ranger .amap-toolbar button) {
|
|
|
- background-color: #022577;
|
|
|
- color: #fff;
|
|
|
- border: none;
|
|
|
- border-radius: 4px;
|
|
|
- padding: 5px;
|
|
|
- margin-right: 5px;
|
|
|
- cursor: pointer;
|
|
|
- }
|
|
|
-
|
|
|
- :deep(.amap-ranger .amap-toolbar button:hover) {
|
|
|
- background-color: #1a3c75;
|
|
|
- }
|
|
|
-
|
|
|
- :deep(.amap-ranger .amap-toolbar .amap-toolbar-text) {
|
|
|
- color: #444;
|
|
|
- font-size: 14px;
|
|
|
+ :deep(.ol-scale-line-inner) {
|
|
|
+ color: #ffffff;
|
|
|
+ border: 1px solid #fff;
|
|
|
+ border-top: none;
|
|
|
}
|
|
|
}
|
|
|
</style>
|