From 1d552a3bad95caae4af15322df28e6240b797693 Mon Sep 17 00:00:00 2001
From: 罗广辉 <guanghui.luo@foxmail.com>
Date: Thu, 13 Aug 2026 15:32:06 +0800
Subject: [PATCH] feat: app视频封面图

---
 applications/drone-command/src/utils/cesium/publicCesium.js |  175 ++++++++++++++++++++++++++++++---------------------------
 1 files changed, 92 insertions(+), 83 deletions(-)

diff --git a/applications/drone-command/src/utils/cesium/publicCesium.js b/applications/drone-command/src/utils/cesium/publicCesium.js
index e0fe177..dd8d318 100644
--- a/applications/drone-command/src/utils/cesium/publicCesium.js
+++ b/applications/drone-command/src/utils/cesium/publicCesium.js
@@ -2,6 +2,7 @@
 import * as Cesium from 'cesium'
 import { Cartesian3, Terrain, Viewer } from 'cesium'
 import store from '@/store/index'
+import jaGeojsonRaw from '@/assets/geojson/ja.geojson?raw'
 
 import getBaseConfig from '@/buildConfig/config'
 
@@ -19,7 +20,6 @@
 } = getBaseConfig()
 
 import { addBlueFilter } from '@/utils/cesium/common'
-import { useBoundary } from '@/utils/cesium/useBoundary'
 
 let smallMpaCenterDistance = null
 let curCameraHpr = null
@@ -32,6 +32,36 @@
 /**
  * 公共的Cesium (蓝色,2d)
  */
+
+const DEFAULT_VIEW_RECTANGLE = (() => {
+	try {
+		const geojson = JSON.parse(jaGeojsonRaw)
+		let west = Infinity
+		let east = -Infinity
+		let south = Infinity
+		let north = -Infinity
+		const walk = coords => {
+			if (!Array.isArray(coords)) return
+			if (typeof coords[0] === 'number' && typeof coords[1] === 'number') {
+				const lng = coords[0]
+				const lat = coords[1]
+				if (!Number.isFinite(lng) || !Number.isFinite(lat)) return
+				west = Math.min(west, lng)
+				east = Math.max(east, lng)
+				south = Math.min(south, lat)
+				north = Math.max(north, lat)
+				return
+			}
+			coords.forEach(walk)
+		}
+		geojson?.features?.forEach(feature => walk(feature?.geometry?.coordinates))
+		if ([west, east, south, north].every(Number.isFinite)) {
+			return Cesium.Rectangle.fromDegrees(west, south, east, north)
+		}
+	} catch (error) {}
+	return Cesium.Rectangle.fromDegrees(66, 4, 135, 53.55)
+})()
+
 
 // 封装的不用管
 let cn = {
@@ -83,8 +113,10 @@
 		this.handlerRightEvents = { handler: null }
 		this.handlerMouseMoveEvents = { handler: null }
 		this.viewer = null
+		this.terrainProvider = null
+		this.terrainLoading = null
+		this.terrainEnabled = false
 		this.globalBaseMapLayers = []
-		this.boundary = null
 		this.init(options)
 	}
 
@@ -96,17 +128,11 @@
 			layerMode = 17,
 			contour = true,
 			flyToContour = false,
-			multiple = 1.4,
-			dockOptions = {},
-			boundaryChange,
 			terrainLoadCallback,
-			boundaryColor = '#7FFFD4',
-			dockRangeType = 1,
-			useDockHeight = false
 		} = options
 		Cesium.Camera.DEFAULT_VIEW_FACTOR = -0.45
 		// 西南东北,默认显示中国
-		Cesium.Camera.DEFAULT_VIEW_RECTANGLE = Cesium.Rectangle.fromDegrees(66, 4, 135, 53.55)
+		Cesium.Camera.DEFAULT_VIEW_RECTANGLE = DEFAULT_VIEW_RECTANGLE
 		const viewerOptions = {
 			infoBox: false, // 禁用沙箱,解决控制台报错
 			animation: false, // 左下角的动画仪表盘
@@ -132,72 +158,19 @@
 		this.viewer.shadows = false
 		this.viewer.shadowMap.darkness = 0.5
 
-		let time = new Date()
-		time.setHours(12, 0, 0, 0)
-		let utc = Cesium.JulianDate.fromDate(new Date(time))
+		this.setFixedNoonLighting()
 
-		this.viewer.clockViewModel.currentTime = Cesium.JulianDate.addHours(utc, 0, new Cesium.JulianDate())
-
-		// 边界,机巢
-		this.boundary = useBoundary(this.viewer, { multiple, dockOptions, boundaryChange, boundaryColor, dockRangeType, useDockHeight })
 		this.viewer?.imageryLayers.removeAll()
 		this.viewer._cesiumWidget._creditContainer.style.display = 'none'
 		handler = new Cesium.ScreenSpaceEventHandler(this.viewer?.scene.canvas)
 
 		this.viewer?.cesiumWidget.screenSpaceEventHandler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK) // 禁用双击
 
-		if (terrain) {
-			try {
-				const noTerrainMechanism = ['1962779164650135554']
-				if (noTerrainMechanism.includes(store.state.user.userInfo?.deptId)) {
-					// 使用Cesium World Terrain
-					Cesium.createWorldTerrainAsync({
-						requestWaterMask: false,    // 请求水域效果
-						requestVertexNormals: true // 请求光照和地形法线
-					}).then(terrainProvider => {
-						this.viewer.terrainProvider = terrainProvider
-						terrainLoadCallback?.()
-					})
-				} else {
-					/*// 正则:第一位非0,第二位任意数字,后10位都是0
-					const re = /^[1-9]\d0{10}$/
-
-					let result = null
-
-					// 1️⃣先判断 areaCode
-					if (re.test(store.state.user.userInfo.detail.areaCode)) {
-						result = store.state.user.userInfo.detail.areaCode.slice(0, 6)
-					} else {
-						// 2️⃣如果不满足,从 ancestors 里找
-						const matchedItems = store.state.user.userInfo.detail.ancestors
-							.split(',')
-							.filter(item => re.test(item)) // 过滤出符合条件的
-
-						// 取第一个符合条件的前6位(可以改成 last one 看需求)
-						if (matchedItems.length > 0) {
-							result = matchedItems[0].slice(0, 6)
-						}
-					}
-
-					// 使用公司地形
-					Cesium.CesiumTerrainProvider.fromUrl(`${import.meta.env.VITE_APP_TERRAIN_URL}${result}`, {
-						requestVertexNormals: true, // 启用地形法线增强立体感
-						requestWaterMask: true, // 启用水体遮罩效果
-					}).then(terrainProvider => {
-						this.viewer.terrainProvider = terrainProvider
-						terrainLoadCallback?.()
-					})*/
-				}
-			} catch (error) {
-				console.error('地形加载失败:', error)
-			}
-		}
+		this.setTerrainVisible(terrain, terrainLoadCallback)
 
 		this.viewer.scene.screenSpaceCameraController.maximumZoomDistance = 4500000
 		this.switchLayers(layerMode)
 		this.switchFlatMode(flatMode)
-		this.switchContour(contour)
-		flyToContour && this.flyToContour(contour)
 
 		if (Cesium.FeatureDetection.supportsImageRenderingPixelated()) {
 			let dpr = window.devicePixelRatio
@@ -208,6 +181,40 @@
 
 	getViewer () {
 		return this.viewer
+	}
+
+	async ensureTerrainProvider () {
+		if (this.terrainProvider) return this.terrainProvider
+		if (this.terrainLoading) return this.terrainLoading
+		this.terrainLoading = Cesium.CesiumTerrainProvider.fromUrl(
+			`${import.meta.env.VITE_APP_TERRAIN_URL}/360000`,
+			{
+				requestVertexNormals: true, // 启用地形法线增强立体感
+				requestWaterMask: true, // 启用水体遮罩效果
+			}
+		).then(provider => {
+			this.terrainProvider = provider
+			return provider
+		})
+		return this.terrainLoading
+	}
+
+	async setTerrainVisible (visible, terrainLoadCallback) {
+		if (!this.viewer) return
+		if (!visible) {
+			this.viewer.terrainProvider = new Cesium.EllipsoidTerrainProvider()
+			this.terrainEnabled = false
+			return
+		}
+		try {
+			const provider = await this.ensureTerrainProvider()
+			if (!this.viewer) return
+			this.viewer.terrainProvider = provider
+			this.terrainEnabled = true
+			terrainLoadCallback?.()
+		} catch (error) {
+			this.terrainEnabled = false
+		}
 	}
 
 	// 销毁viewer
@@ -258,25 +265,6 @@
 			cesiumContainer.remove() // 移除与地图相关的DOM元素
 			this.viewerDom = null
 		}
-	}
-
-	setShowDock (sns) {
-		this.boundary?.setShowDock(sns)
-	}
-	setDockCoverColor (sns) {
-		this.boundary?.setDockCoverColor(sns)
-	}
-	// 切换轮廓显示
-	async switchContour (open) {
-		if (open) {
-			await this.boundary?.openContour()
-		} else {
-			this.boundary?.closeContour()
-		}
-	}
-	// 飞向轮廓居中
-	flyToContour () {
-		this.boundary?.flyToBoundary()
 	}
 
 	// 飞行 flyto
@@ -881,4 +869,25 @@
 			this.viewer?.imageryLayers.remove(imageryLayers)
 		}
 	}
+
+	setFixedNoonLighting (utcOffsetHours = 8) {
+		if (!this.viewer) return
+		const now = new Date()
+		const utcNoon = Date.UTC(
+			now.getUTCFullYear(),
+			now.getUTCMonth(),
+			now.getUTCDate(),
+			12 - Number(utcOffsetHours || 0),
+			0,
+			0,
+			0
+		)
+		const julian = Cesium.JulianDate.fromDate(new Date(utcNoon))
+		this.viewer.clock.currentTime = julian
+		this.viewer.clockViewModel.currentTime = julian
+		this.viewer.clock.shouldAnimate = false
+		this.viewer.clock.multiplier = 0
+		this.viewer.clockViewModel.multiplier = 0
+		this.viewer.scene.requestRender()
+	}
 }

--
Gitblit v1.9.3