From 055c8329a8e8f7bc50bb1f10711031ea0bccaf2f Mon Sep 17 00:00:00 2001
From: wujingjing <gersonwu@qq.com>
Date: 星期五, 17 一月 2025 10:30:18 +0800
Subject: [PATCH] 地图

---
 src/model/map/OLMap.ts                                                                       |   26 +++++---
 src/components/chat/chatComponents/summaryCom/components/recordSetTable/map/LayerControl.vue |   84 +++++++++++++++++++++++----
 src/utils/util.ts                                                                            |   12 ++++
 src/components/chat/chatComponents/summaryCom/components/recordSetTable/map/BasicMap.vue     |   14 ++--
 4 files changed, 106 insertions(+), 30 deletions(-)

diff --git a/src/components/chat/chatComponents/summaryCom/components/recordSetTable/map/BasicMap.vue b/src/components/chat/chatComponents/summaryCom/components/recordSetTable/map/BasicMap.vue
index 2c0a02b..a84920b 100644
--- a/src/components/chat/chatComponents/summaryCom/components/recordSetTable/map/BasicMap.vue
+++ b/src/components/chat/chatComponents/summaryCom/components/recordSetTable/map/BasicMap.vue
@@ -1,5 +1,5 @@
 <template>
-	<div class="relative">
+	<div class="relative bg-white">
 		<div ref="containerRef" class="h-full"></div>
 		<div ref="infoWindowRef" v-show="infoWindowIsShow">
 			<div
@@ -71,7 +71,8 @@
 };
 const showInfoWindow = (overlay: Overlay) => {
 	const position = overlay.getPosition();
-	const row = overlay.get('extData');
+	const row = overlay.get('extData')?.value;
+	if(!row) return;
 	lastOverlay && setMarkerIcon(lastOverlay, equipPic);
 	infoWindowIsShow.value = true;
 	infoWindowOverlay.setPosition(position);
@@ -90,7 +91,6 @@
 const addMarkerLayer = () => {
 	const map = props.data.map;
 	if (map.pos_x == null && map.pos_y == null) return;
-
 	const dataList = (props.data?.values ?? []).map((item) => {
 		const x = item[map.pos_x];
 		const y = item[map.pos_y];
@@ -98,8 +98,10 @@
 		return {
 			position: [x, y],
 			// textColor: item.color,
-			extData: item,
-			title: item.title,
+			extData: {
+				value:item,
+				recordSetTable:props.data
+			},
 		};
 	});
 	olMap.value.addMarkerLayer(dataList, {
@@ -109,7 +111,7 @@
 				size: 30,
 				selectUrl: equipSelectPic,
 			},
-			click(e, label, item, position) {
+			click(e, label, extData, position) {
 				showInfoWindow(label);
 			},
 		},
diff --git a/src/components/chat/chatComponents/summaryCom/components/recordSetTable/map/LayerControl.vue b/src/components/chat/chatComponents/summaryCom/components/recordSetTable/map/LayerControl.vue
index 8ea5098..45d3017 100644
--- a/src/components/chat/chatComponents/summaryCom/components/recordSetTable/map/LayerControl.vue
+++ b/src/components/chat/chatComponents/summaryCom/components/recordSetTable/map/LayerControl.vue
@@ -14,7 +14,6 @@
 				:style="layerControlCardStyle"
 				@mousedown="startDrag"
 			>
-
 				<el-icon class="absolute top-2 right-2 cursor-pointer z-10" @click="closePanel">
 					<Close />
 				</el-icon>
@@ -44,12 +43,30 @@
 							:filter-node-method="filterNode"
 							ref="overlayTreeRef"
 							@check="handleCheck"
+							@node-click="handleNodeClick"
 						>
 							<template #default="{ node, data }">
 								<span>{{ node.label }}</span>
 							</template>
 						</el-tree>
 					</el-tab-pane>
+					<!-- <el-tab-pane label="瑕嗙洊灞�" name="overlays">
+						<el-tree
+							class="w-full"
+							:data="treeData"
+							:props="defaultProps"
+							show-checkbox
+							node-key="id"
+							default-expand-all
+							:filter-node-method="filterNode"
+							ref="overlayTreeRef"
+							@check="handleCheck"
+						>
+							<template #default="{ node, data }">
+								<span>{{ node.label }}</span>
+							</template>
+						</el-tree>
+					</el-tab-pane> -->
 				</el-tabs>
 			</el-card>
 		</div>
@@ -57,12 +74,14 @@
 </template>
 
 <script setup lang="ts">
-import { Close, Folder, FolderOpened, Search } from '@element-plus/icons-vue';
+import { Close } from '@element-plus/icons-vue';
+import { ElTree } from 'element-plus';
+import type Overlay from 'ol/Overlay';
 import { onMounted, ref, watch } from 'vue';
 import { useDrag } from '/@/hooks/useDrag';
 import type { GaoDeSourceType, OLMap } from '/@/model/map/OLMap';
 import { gaoDeSourceTypeMap } from '/@/model/map/OLMap';
-import { ElTree } from 'element-plus';
+import { sleep } from '/@/utils/util';
 const searchText = ref('');
 const activeTab = ref('components');
 const treeRef = ref();
@@ -70,7 +89,15 @@
 const props = defineProps<{
 	olMap: OLMap;
 }>();
-
+enum ROOT_OVERLAY_TYPE {
+	Marker = 'marker',
+}
+type TreeData = {
+	id: string;
+	label: string;
+	checked?: boolean;
+	children?: TreeData[];
+};
 const activeSourceType = ref(props.olMap.activeSourceType);
 
 const changeSourceType = (val: GaoDeSourceType) => {
@@ -79,26 +106,51 @@
 
 const overlayTreeRef = ref<InstanceType<typeof ElTree>>();
 
-const treeData = [
+const treeData = ref<TreeData[]>([
 	{
-		id: 1,
+		id: ROOT_OVERLAY_TYPE.Marker,
 		label: '璁惧',
 		checked: props.olMap.overlayIsVisible.value,
 	},
-];
+]);
 const initTreeChecked = () => {
-	treeData.forEach((item) => {
+	treeData.value.forEach((item) => {
 		if (item.checked) {
 			overlayTreeRef.value?.setCheckedKeys([item.id]);
 		}
 	});
 };
-const handleCheck = (data: any, node: any) => {
-	const checkedKeys = node.checkedKeys;
-	const isVisible = checkedKeys.includes(1);
-	props.olMap.toggleMarkerOverlayVisible(isVisible);
+
+const handleNodeClick = (data: any, node: any) => {
+	if (data.id === ROOT_OVERLAY_TYPE.Marker) {
+		const overlays = props.olMap.map.getOverlays().getArray();
+		props.olMap.adjustViewToOverlays(overlays);
+	}
 };
 
+const iniTreeData = async () => {
+	await sleep(0.4);
+	const foundMarker = treeData.value.find((item) => item.id === ROOT_OVERLAY_TYPE.Marker);
+	if (!foundMarker) {
+		return;
+	}
+	foundMarker.children = props.olMap.map
+		.getOverlays()
+		.getArray()
+		.map((item) => {
+			const extData = item.get('extData');
+			return {
+				id: item.getId() as string,
+				label: extData?.name,
+				// checked: item.getVisible(),
+			};
+		});
+};
+const handleCheck = (data: any, node: any) => {
+	const checkedKeys = node.checkedKeys;
+	const isVisible = checkedKeys.includes(ROOT_OVERLAY_TYPE.Marker);
+	props.olMap.toggleMarkerOverlayVisible(isVisible);
+};
 
 const layerControlCard = ref<HTMLDivElement>(null);
 
@@ -126,8 +178,10 @@
 	treeRef.value?.filter(val);
 });
 onMounted(() => {
-
 	initTreeChecked();
+	// iniTreeData();
+	// window.olMap = props.olMap;
+	// window.map = props.olMap.map;
 });
 defineEmits(['close']);
 </script>
@@ -163,4 +217,8 @@
 :deep(.el-card) {
 	cursor: inherit;
 }
+
+:deep(.el-tree-node__expand-icon.is-leaf) {
+	display: none;
+}
 </style>
diff --git a/src/model/map/OLMap.ts b/src/model/map/OLMap.ts
index 66f46bb..7434965 100644
--- a/src/model/map/OLMap.ts
+++ b/src/model/map/OLMap.ts
@@ -123,14 +123,14 @@
 		const markers: Overlay[] = [];
 
 		// 鍒涘缓鏍囪鐐�
-		dataList.forEach((item) => {
-			const marker = this.createMarker(item, markerOpt);
+		dataList.forEach((item, index) => {
+			const marker = this.createMarker(`marker-${index}`, item, markerOpt);
 			markers.push(marker);
 			this.map.addOverlay(marker);
 		});
 
 		// 璁$畻骞惰皟鏁磋鍥捐寖鍥�
-		this.adjustViewToMarkers(dataList);
+		this.adjustViewToOverlays(markers);
 	}
 
 	createEleOverlay(dom: string | HTMLElement, position = [0, 0]) {
@@ -148,7 +148,8 @@
 		return eleOverlay;
 	}
 
-	private createMarker(item: any, markerOpt: any): Overlay {
+	
+	private createMarker(id: string, item: any, markerOpt: any): Overlay {
 		// 鍒涘缓鍥剧墖鍏冪礌
 		const markerImg = document.createElement('img');
 		markerImg.src = markerOpt.icon.url;
@@ -161,6 +162,7 @@
 
 		// 鍒涘缓 Overlay
 		const overlay = new MarkerOverlay({
+			id,
 			className: MARKER_OVERLAY_CLASS_NAME,
 			element: markerImg,
 			position: position,
@@ -174,23 +176,22 @@
 			if (markerOpt.icon.selectUrl) {
 				markerImg.src = markerOpt.icon.selectUrl;
 			}
-			markerOpt.click?.(event, overlay, item, position);
+			markerOpt.click?.(event, overlay, item.extData, position);
 		});
 
 		return overlay;
 	}
 
-	private adjustViewToMarkers(dataList: any[]) {
-		// 璁$畻鎵�鏈夌偣鐨勮寖鍥�
-		const extent = dataList.reduce((ext, item) => {
-			const coord = fromLonLat(item.position);
+	 adjustViewToOverlays(overlays: Overlay[]) {
+		const extent = overlays.reduce<number[] | null>((ext, item) => {
+			const coord = item.getPosition();
+
 			if (!ext) {
 				return [coord[0], coord[1], coord[0], coord[1]];
 			}
 			return [Math.min(ext[0], coord[0]), Math.min(ext[1], coord[1]), Math.max(ext[2], coord[0]), Math.max(ext[3], coord[1])];
 		}, null);
 
-		// 璋冩暣瑙嗗浘浠ラ�傚簲鏍囪鐐硅寖鍥�
 		if (extent) {
 			this.fitExtend(extent);
 		}
@@ -221,7 +222,10 @@
 		const overlays = this.map.getOverlays();
 		overlays.forEach((overlay) => {
 			if (overlay instanceof MarkerOverlay) {
-				overlay.setVisible(visible);
+				const overlayElement = overlay.getElement();
+				if (overlayElement) {
+					overlayElement.style.visibility = visible ? 'visible' : 'hidden';
+				}
 			}
 		});
 		this.overlayIsVisible.value = visible;
diff --git a/src/utils/util.ts b/src/utils/util.ts
index d92279e..80f11c4 100644
--- a/src/utils/util.ts
+++ b/src/utils/util.ts
@@ -750,3 +750,15 @@
 	}
 	return decodedData;
 }
+
+
+/**
+ * 浼戠湢鎸囧畾绉掓暟
+ * @param seconds 浼戠湢绉掓暟
+ * @returns Promise
+ */
+export const sleep = (seconds: number): Promise<void> => {
+	return new Promise((resolve) => {
+		setTimeout(resolve, seconds * 1000);
+	});
+};

--
Gitblit v1.9.3