|
@@ -1,5 +1,18 @@
|
|
|
<template>
|
|
|
<div id="cesiumContainer" style="height: 100%;width: 100%;"></div>
|
|
|
+ <!-- 自定义弹框组件 -->
|
|
|
+ <div v-if="selectedPoint" class="custom-popup" :style="{
|
|
|
+ left: `${popupPosition.x}px`,
|
|
|
+ top: `${popupPosition.y}px`,
|
|
|
+ display: selectedPoint ? 'block' : 'none'
|
|
|
+ }">
|
|
|
+ <div class="popup-content">
|
|
|
+ <h3>{{ selectedPoint.STNM || '未知点' }}</h3>
|
|
|
+ <p><strong>经度:</strong> {{ selectedPoint.LGTD }}</p>
|
|
|
+ <p><strong>纬度:</strong> {{ selectedPoint.LTTD }}</p>
|
|
|
+ <div class="popup-arrow"></div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
</template>
|
|
|
|
|
|
<script setup>
|
|
@@ -7,9 +20,11 @@ import { ref, onMounted, onUnmounted, getCurrentInstance } from 'vue'
|
|
|
import * as Cesium from 'cesium';
|
|
|
import "cesium/Build/CesiumUnminified/Widgets/widgets.css";
|
|
|
import JYLData from '@/assets/Data/THJYL.json'
|
|
|
-import { color } from 'echarts';
|
|
|
|
|
|
const TDTTK = "d9e7aa2ad204aba6aeedea6f5ab48ed9";
|
|
|
+const selectedPoint = ref(null);
|
|
|
+const popupPosition = ref({ x: 0, y: 0 });
|
|
|
+let handler = null;
|
|
|
|
|
|
onMounted(() => {
|
|
|
const viewer = new Cesium.Viewer('cesiumContainer', {
|
|
@@ -26,28 +41,25 @@ onMounted(() => {
|
|
|
infoBox: false,
|
|
|
});
|
|
|
|
|
|
- // 定义距离显示条件和缩放属性
|
|
|
+ // 定义距离显示条件和缩放属性
|
|
|
const distanceDisplayCondition = new Cesium.DistanceDisplayCondition(
|
|
|
0, // 最小显示距离(0表示始终显示)
|
|
|
10000000 // 最大显示距离(1000公里外不显示)
|
|
|
);
|
|
|
-
|
|
|
+
|
|
|
const pointNearFarScalar = new Cesium.NearFarScalar(
|
|
|
10000, 1.0, // 近点距离和缩放比例
|
|
|
1000000, 0.3 // 远点距离和缩放比例
|
|
|
);
|
|
|
-
|
|
|
+
|
|
|
const labelNearFarScalar = new Cesium.NearFarScalar(
|
|
|
10000, 1.0, // 近点距离和缩放比例
|
|
|
400000, 0 // 远点距离和缩放比例(50公里外完全隐藏)
|
|
|
);
|
|
|
|
|
|
- // const entitiesNearFarScalar = new Cesium.NearFarScalar(
|
|
|
- // 10000, 1.0, // 近点距离和缩放比例
|
|
|
- // 1000000, 0.1 // 远点距离和缩放比例(50公里外完全隐藏)
|
|
|
- // );
|
|
|
+ // 存储实体与数据的映射
|
|
|
+ const entityDataMap = new Map();
|
|
|
|
|
|
-
|
|
|
// 遍历数据并添加点和标签
|
|
|
JYLData.forEach((item) => {
|
|
|
const position = Cesium.Cartesian3.fromDegrees(
|
|
@@ -56,9 +68,8 @@ onMounted(() => {
|
|
|
);
|
|
|
|
|
|
// 创建组合了图标和标签的实体
|
|
|
- viewer.entities.add({
|
|
|
+ const entity = viewer.entities.add({
|
|
|
position: position,
|
|
|
- // scaleByDistance:entitiesNearFarScalar,
|
|
|
billboard: {
|
|
|
image: '/src/assets/icon/blue.png', // 图标路径
|
|
|
scale: 0.4,
|
|
@@ -86,32 +97,40 @@ onMounted(() => {
|
|
|
distanceDisplayCondition: distanceDisplayCondition,
|
|
|
scaleByDistance: labelNearFarScalar
|
|
|
},
|
|
|
+ // 添加一个唯一ID用于识别
|
|
|
+ id: `point-${item.STCD || item.LGTD + '-' + item.LTTD}`,
|
|
|
+ properties: {
|
|
|
+ data: item // 直接将数据附加到实体属性
|
|
|
+ }
|
|
|
});
|
|
|
- });
|
|
|
|
|
|
- // 天地图影像
|
|
|
- const tdtLayer = new Cesium.WebMapTileServiceImageryProvider({
|
|
|
- url: `http://t0.tianditu.com/img_w/wmts?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=img&STYLE=default&TILEMATRIXSET=w&FORMAT=tiles&TILEMATRIX={TileMatrix}&TILEROW={TileRow}&TILECOL={TileCol}&tk=${TDTTK}`,
|
|
|
- layer: "tdt",
|
|
|
- style: "default",
|
|
|
- format: "image/jpeg",
|
|
|
- tileMatrixSetID: "w",
|
|
|
- maximumLevel: 18,
|
|
|
- show: false,
|
|
|
- });
|
|
|
- viewer.imageryLayers.addImageryProvider(tdtLayer);
|
|
|
-
|
|
|
- // 天地图注记
|
|
|
- const tdtAnnotionLayer = new Cesium.WebMapTileServiceImageryProvider({
|
|
|
- url: `http://t0.tianditu.com/cia_w/wmts?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=cia&STYLE=default&TILEMATRIXSET=w&FORMAT=tiles&TILEMATRIX={TileMatrix}&TILEROW={TileRow}&TILECOL={TileCol}&tk=${TDTTK}`,
|
|
|
- layer: "tdtAnno",
|
|
|
- style: "default",
|
|
|
- format: "image/jpeg",
|
|
|
- tileMatrixSetID: "w",
|
|
|
- maximumLevel: 18,
|
|
|
- show: false,
|
|
|
+ // 存储实体与数据的映射关系
|
|
|
+ entityDataMap.set(entity.id, item);
|
|
|
});
|
|
|
|
|
|
+ // // 天地图影像
|
|
|
+ // const tdtLayer = new Cesium.WebMapTileServiceImageryProvider({
|
|
|
+ // url: `http://t0.tianditu.com/img_w/wmts?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=img&STYLE=default&TILEMATRIXSET=w&FORMAT=tiles&TILEMATRIX={TileMatrix}&TILEROW={TileRow}&TILECOL={TileCol}&tk=${TDTTK}`,
|
|
|
+ // layer: "tdt",
|
|
|
+ // style: "default",
|
|
|
+ // format: "image/jpeg",
|
|
|
+ // tileMatrixSetID: "w",
|
|
|
+ // maximumLevel: 18,
|
|
|
+ // show: false,
|
|
|
+ // });
|
|
|
+ // viewer.imageryLayers.addImageryProvider(tdtLayer);
|
|
|
+
|
|
|
+ // // 天地图注记
|
|
|
+ // const tdtAnnotionLayer = new Cesium.WebMapTileServiceImageryProvider({
|
|
|
+ // url: `http://t0.tianditu.com/cia_w/wmts?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=cia&STYLE=default&TILEMATRIXSET=w&FORMAT=tiles&TILEMATRIX={TileMatrix}&TILEROW={TileRow}&TILECOL={TileCol}&tk=${TDTTK}`,
|
|
|
+ // layer: "tdtAnno",
|
|
|
+ // style: "default",
|
|
|
+ // format: "image/jpeg",
|
|
|
+ // tileMatrixSetID: "w",
|
|
|
+ // maximumLevel: 18,
|
|
|
+ // show: false,
|
|
|
+ // });
|
|
|
+
|
|
|
// 移除默认水印
|
|
|
viewer.cesiumWidget.creditContainer.style.display = "none";
|
|
|
|
|
@@ -126,11 +145,95 @@ onMounted(() => {
|
|
|
|
|
|
viewer.imageryLayers.addImageryProvider(tdtAnnotionLayer);
|
|
|
|
|
|
+ // 添加点击事件处理
|
|
|
+ handler = new Cesium.ScreenSpaceEventHandler(viewer.canvas);
|
|
|
+
|
|
|
+// 在点击处理函数中增强错误处理
|
|
|
+handler.setInputAction((click) => {
|
|
|
+ const pickedObject = viewer.scene.pick(click.position);
|
|
|
+
|
|
|
+ console.log('Picked object:', pickedObject); // 调试用,检查拾取对象
|
|
|
+
|
|
|
+ if (Cesium.defined(pickedObject) && Cesium.defined(pickedObject.id)) {
|
|
|
+ const entityId = pickedObject.id.id;
|
|
|
+ const data = entityDataMap.get(entityId) || pickedObject.id.properties?.data?.getValue();
|
|
|
+
|
|
|
+ console.log('Entity ID:', entityId); // 调试用,检查实体ID
|
|
|
+ console.log('Entity data:', data); // 调试用,检查数据
|
|
|
+
|
|
|
+ if (data) {
|
|
|
+ // 显示弹框
|
|
|
+ selectedPoint.value = data;
|
|
|
+ popupPosition.value = {
|
|
|
+ x: click.position.x - 100,
|
|
|
+ y: click.position.y - 150
|
|
|
+ };
|
|
|
+
|
|
|
+ // 聚焦到选中的点
|
|
|
+ viewer.flyTo(pickedObject.id, {
|
|
|
+ offset: new Cesium.HeadingPitchRange(0, -0.5, 1500)
|
|
|
+ });
|
|
|
+ } else {
|
|
|
+ console.warn('No data found for clicked entity');
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ // 点击空白区域
|
|
|
+ selectedPoint.value = null;
|
|
|
+ }
|
|
|
+}, Cesium.ScreenSpaceEventType.LEFT_CLICK);
|
|
|
+
|
|
|
// 清理函数
|
|
|
onUnmounted(() => {
|
|
|
+ if (handler) {
|
|
|
+ handler.destroy();
|
|
|
+ handler = null;
|
|
|
+ }
|
|
|
+
|
|
|
if (viewer && !viewer.isDestroyed()) {
|
|
|
viewer.destroy();
|
|
|
}
|
|
|
});
|
|
|
})
|
|
|
-</script>
|
|
|
+</script>
|
|
|
+
|
|
|
+<style scoped>
|
|
|
+.custom-popup {
|
|
|
+ position: absolute;
|
|
|
+ z-index: 1000;
|
|
|
+ display: none;
|
|
|
+ pointer-events: none;
|
|
|
+}
|
|
|
+
|
|
|
+.popup-content {
|
|
|
+ background-color: white;
|
|
|
+ border-radius: 5px;
|
|
|
+ box-shadow: 0 2px 10px rgba(0, 0, 0, 0.2);
|
|
|
+ padding: 10px 15px;
|
|
|
+ width: 200px;
|
|
|
+ pointer-events: all;
|
|
|
+}
|
|
|
+
|
|
|
+.popup-arrow {
|
|
|
+ position: absolute;
|
|
|
+ bottom: -10px;
|
|
|
+ left: 50%;
|
|
|
+ transform: translateX(-50%);
|
|
|
+ width: 0;
|
|
|
+ height: 0;
|
|
|
+ border-left: 10px solid transparent;
|
|
|
+ border-right: 10px solid transparent;
|
|
|
+ border-top: 10px solid white;
|
|
|
+}
|
|
|
+
|
|
|
+.popup-content h3 {
|
|
|
+ margin-top: 0;
|
|
|
+ margin-bottom: 8px;
|
|
|
+ color: #333;
|
|
|
+}
|
|
|
+
|
|
|
+.popup-content p {
|
|
|
+ margin: 5px 0;
|
|
|
+ color: #666;
|
|
|
+ font-size: 14px;
|
|
|
+}
|
|
|
+</style>
|