From e696ff74ab21f80a3edd350176940a3e1cf65f3f Mon Sep 17 00:00:00 2001
From: 罗广辉 <guanghui.luo@foxmail.com>
Date: Fri, 30 Jan 2026 15:27:36 +0800
Subject: [PATCH] Merge remote-tracking branch 'origin/master'

---
 applications/drone-command/src/views/areaManage/partition/FormDiaLog.vue |  117 +++++++++-------------------------------------------------
 1 files changed, 18 insertions(+), 99 deletions(-)

diff --git a/applications/drone-command/src/views/areaManage/partition/FormDiaLog.vue b/applications/drone-command/src/views/areaManage/partition/FormDiaLog.vue
index 5fc6010..92c6ef8 100644
--- a/applications/drone-command/src/views/areaManage/partition/FormDiaLog.vue
+++ b/applications/drone-command/src/views/areaManage/partition/FormDiaLog.vue
@@ -234,7 +234,13 @@
 import { fieldRules, geomAnalysis, getDictLabel } from '@ztzf/utils'
 import CommonCesiumMap from '@/components/map-container/common-cesium-map.vue'
 import { DrawManager, EditManager, buildEllipsePositions } from '@/utils/cesium/shapeTools'
-import { cartesian3Convert, getPointPositionsHeight } from '@/utils/cesium/mapUtil'
+import { cartesian3Convert } from '@/utils/cesium/mapUtil'
+import {
+	createDeviceRangePrimitive,
+	getDeviceLngLat,
+	normalizeDeviceRange,
+	resolveDeviceTerrainHeight,
+} from '@/utils/cesium/deviceRange'
 import * as Cesium from 'cesium'
 import { AREA_TYPE_STYLE_MAP, BUFFER_LEVEL_STYLES, DEFAULT_AREA_STYLE } from '@ztzf/constants'
 import { fwPoliceStationListApi } from '@/views/areaManage/precinctInfo/precinctInfoApi'
@@ -294,7 +300,6 @@
 let viewEntity
 let shapeDisplaySource
 const deviceRangePrimitiveMap = new Map()
-let deviceRangeMaterialRegistered = false
 const activeToolMode = ref('')
 
 const rules = {
@@ -455,42 +460,6 @@
 	return shapeDisplaySource
 }
 
-function registerDeviceRangeMaterial () {
-	if (deviceRangeMaterialRegistered || !Cesium?.Material) return
-	deviceRangeMaterialRegistered = true
-	Cesium.Material._materialCache.addMaterial('DeviceRangeEllipsoid', {
-		fabric: {
-			type: 'DeviceRangeEllipsoid',
-			uniforms: {
-				color: new Cesium.Color(1.0, 0.0, 0.0, 0.7),
-				speed: 3.0,
-			},
-			source: `
-				uniform vec4 color;
-				uniform float speed;
-				czm_material czm_getMaterial(czm_materialInput materialInput){
-					czm_material material = czm_getDefaultMaterial(materialInput);
-					vec2 st = materialInput.st;
-					float time = fract(czm_frameNumber * speed / 1000.0);
-					float alpha = abs(smoothstep(0.5,1.,fract( -st.t - time)));
-					alpha += .1;
-					material.alpha = alpha;
-					material.diffuse = color.rgb;
-					return material;
-				}
-			`,
-		},
-		translucent: () => true,
-	})
-}
-
-function createDeviceRangeMaterial () {
-	registerDeviceRangeMaterial()
-	return Cesium.Material.fromType('DeviceRangeEllipsoid', {
-		color: Cesium.Color.fromBytes(0, 255, 255, 155),
-	})
-}
-
 function clearDeviceRangePrimitives () {
 	if (!viewer || !deviceRangePrimitiveMap.size) return
 	for (const primitive of deviceRangePrimitiveMap.values()) {
@@ -499,67 +468,13 @@
 	deviceRangePrimitiveMap.clear()
 }
 
-function normalizeDeviceRange (value) {
-	const range = Number(value)
-	if (!Number.isFinite(range) || range <= 0) return 2000
-	return range
-}
-
-function getDeviceLngLat (device) {
-	const lngRaw = device?.longitude ?? device?.lng ?? device?.lon
-	const latRaw = device?.latitude ?? device?.lat
-	const lng = Number(lngRaw)
-	const lat = Number(latRaw)
-	if (!Number.isFinite(lng) || !Number.isFinite(lat)) return null
-	return { lng, lat }
-}
-
-async function resolveDeviceTerrainHeight (position) {
-	if (!viewer) return 0
-	try {
-		const results = await getPointPositionsHeight([{ lng: position.lng, lat: position.lat }], viewer)
-		const height = Number(results?.[0]?.ASL)
-		return Number.isFinite(height) ? height : 0
-	} catch (error) {
-		return 0
-	}
-}
-
-async function createDeviceRangePrimitive (device) {
-	if (!viewer) return null
-	if (!device) return null
-	const position = getDeviceLngLat(device)
-	if (!position) return null
-	const rangeMeters = normalizeDeviceRange(device.effectiveRangeKm)
-	const centerHeight = await resolveDeviceTerrainHeight(position)
-	const center = Cesium.Cartesian3.fromDegrees(position.lng, position.lat, centerHeight)
-	const radii = new Cesium.Cartesian3(rangeMeters, rangeMeters, rangeMeters)
-	const geometry = new Cesium.EllipsoidGeometry({
-		radii,
-		vertexFormat: Cesium.MaterialAppearance.MaterialSupport.TEXTURED?.vertexFormat
-			|| Cesium.VertexFormat.POSITION_AND_NORMAL,
-	})
-	const instance = new Cesium.GeometryInstance({
-		geometry,
-		modelMatrix: Cesium.Transforms.eastNorthUpToFixedFrame(center),
-	})
-	return new Cesium.Primitive({
-		geometryInstances: instance,
-		appearance: new Cesium.MaterialAppearance({
-			material: createDeviceRangeMaterial(),
-			closed: true,
-			translucent: true,
-			flat: true,
-			faceForward: true,
-		}),
-		asynchronous: false
-	})
-}
-
 async function renderDeviceRangeSingle (device) {
 	if (!viewer) return
 	clearDeviceRangePrimitives()
-	const primitive = await createDeviceRangePrimitive(device)
+	const position = getDeviceLngLat(device)
+	if (!position) return
+	const rangeMeters = normalizeDeviceRange(device.effectiveRangeKm)
+	const primitive = await createDeviceRangePrimitive(viewer, position, rangeMeters)
 	if (!primitive) return
 	deviceRangePrimitiveMap.set(String(device?.id ?? Date.now()), primitive)
 	viewer.scene.primitives.add(primitive)
@@ -582,7 +497,10 @@
 	if (!pendingRows.length) return
 	const primitives = await Promise.all(
 		pendingRows.map(async row => {
-			const primitive = await createDeviceRangePrimitive(row)
+			const position = getDeviceLngLat(row)
+			if (!position) return { row, primitive: null }
+			const rangeMeters = normalizeDeviceRange(row.effectiveRangeKm)
+			const primitive = await createDeviceRangePrimitive(viewer, position, rangeMeters)
 			return { row, primitive }
 		})
 	)
@@ -598,8 +516,9 @@
 	if (!viewer) return
 	const position = getDeviceLngLat(device)
 	if (!position) return
-	const height = await resolveDeviceTerrainHeight(position)
-	const destination = Cesium.Cartesian3.fromDegrees(position.lng, position.lat, height + device.effectiveRangeKm * 3)
+	const height = await resolveDeviceTerrainHeight(viewer, position)
+	const rangeMeters = normalizeDeviceRange(device?.effectiveRangeKm)
+	const destination = Cesium.Cartesian3.fromDegrees(position.lng, position.lat, height + rangeMeters * 3)
 	viewer.camera.flyTo({
 		destination,
 		orientation: {

--
Gitblit v1.9.3