From f1e4e5843ff9ae37ccecd0ea391911f67de0e50d Mon Sep 17 00:00:00 2001
From: 罗广辉 <guanghui.luo@foxmail.com>
Date: Sat, 29 Mar 2025 16:02:53 +0800
Subject: [PATCH] feat: 机巢点击交互

---
 src/views/Home/useAggregation.js |   74 ++++++++++++++++++++++++++++++++-----
 1 files changed, 64 insertions(+), 10 deletions(-)

diff --git a/src/views/Home/useAggregation.js b/src/views/Home/useAggregation.js
index 32756bd..db6ec45 100644
--- a/src/views/Home/useAggregation.js
+++ b/src/views/Home/useAggregation.js
@@ -4,19 +4,24 @@
 import jiangxishi from '@/assets/geojson/jiangxishi.json';
 import jiangxi from '@/assets/geojson/jiangxi.json';
 import zg from '@/assets/geojson/zg.json';
+import MapPopUpBox from '@/views/Home/MapPopUpBox.vue';
+import { render } from 'vue';
 
 /**
  * 机巢聚合功能
  */
 export const useAggregation = () => {
-  let viewer = null;
   const scalingJudgment = [
     { name: '县', value: [0, 48651], gJson: null },
     { name: '市', value: [48651, 314863], gJson: jiangxishi },
     { name: '省', value: [314863, 1169651], gJson: jiangxi },
     { name: '国', value: [1169651, 37962800], gJson: zg },
   ];
+  let viewer = null;
   const active = ref('');
+  let handler = null;
+  let labelDiv = null;
+  let positionC3 = null;
   const init = () => {
     determineScaling();
     viewer.camera.moveEnd.addEventListener(() => {
@@ -24,18 +29,15 @@
     });
   };
 
-  const removeFun = () => {
-    viewer.dataSources.removeAll(true);
-    viewer.entities.removeAll();
-  };
-
+  // 确定缩放比例
   const determineScaling = () => {
     let height = viewer.camera.positionCartographic.height;
     // 根据高度展示对应的 gJson
     for (let item of scalingJudgment) {
       if (height > item.value[0] && height <= item.value[1]) {
         if (active.value !== item.name) {
-          removeFun();
+          removeEntities();
+          removeLabel();
           active.value = item.name;
           item.gJson ? aggregation(item) : splashed();
         }
@@ -83,6 +85,7 @@
       if (!feature.position) return;
       const position = Cesium.Cartesian3.fromDegrees(feature.position[0], feature.position[1]);
       viewer.entities.add({
+        id: feature.id,
         position: position,
         label: {
           // 随机整数
@@ -99,6 +102,12 @@
           image: new Cesium.ConstantProperty(data2),
           width: 24,
           height: 24,
+        },
+        properties: {
+          id: feature.id,
+          customData: {
+            name: feature.name,
+          },
         },
       });
     });
@@ -118,15 +127,60 @@
     });
   };
 
+  const getLabelDom = () => {
+    const vNode = h(MapPopUpBox, { data: '参数',removeLabel });
+    const tooltipContainer = document.createElement('div');
+    tooltipContainer.style.position = 'absolute';
+    tooltipContainer.style.transform = 'translateY(-50%)';
+    tooltipContainer.style.pointerEvents = 'none';
+    document.querySelector('.page-index').append(tooltipContainer);
+    render(vNode, tooltipContainer);
+    return tooltipContainer;
+  };
+
+  const labelBox = () => {
+    if (!labelDiv) {
+      labelDiv = getLabelDom();
+    }
+    const screenPosition = viewer.scene.cartesianToCanvasCoordinates(positionC3);
+    if (screenPosition) {
+      labelDiv.style.left = `${screenPosition.x}px`;
+      labelDiv.style.top = `${screenPosition.y}px`;
+    }
+  };
+
+  const clickFun = click => {
+    const pickedObject = viewer.scene.pick(click.position);
+    if (Cesium.defined(pickedObject) && pickedObject.id) {
+      const entity = pickedObject.id;
+      positionC3 = entity.position._value;
+      viewer.scene.postRender.addEventListener(labelBox);
+    }
+  };
+
+  const removeEntities = () => {
+    viewer.dataSources.removeAll(true);
+    viewer.entities.removeAll();
+  };
+  const removeLabel = () => {
+    viewer.scene.postRender.removeEventListener(labelBox);
+    if (labelDiv && labelDiv.parentNode) {
+      labelDiv.parentNode.removeChild(labelDiv);
+      labelDiv = null;
+    }
+  };
+
   onUnmounted(() => {
-    console.log('xiezai');
-    removeFun();
+    removeEntities();
+    removeLabel();
+    handler?.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK);
   });
 
   onMounted(() => {
-    console.log('触发');
     nextTick(() => {
       viewer = window.$viewer;
+      handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);
+      handler.setInputAction(clickFun, Cesium.ScreenSpaceEventType.LEFT_CLICK);
       init();
     });
   });

--
Gitblit v1.9.3