ts/src/hooks/entity.ts

347 lines
10 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { reactive } from 'vue'
import { getMubiaoHisTraj } from '@/api/Mubiao'
const baseMap = new Map()
const mubiaoMap = new Map()
const mubiaoConicMap = new Map()
const satelliteMap = new Map()
const satelliteBeamMap = new Map()
const mbPayloadShowMap = reactive(new Map())
// const satDetectingPayloadMap = reactive(new Map())
// const satCommunicationPayloadMap = reactive(new Map())
const satellitePayloadShowMap = reactive(new Map())
export const useEntity = () => {
return {
baseMap,
mubiaoMap,
mubiaoConicMap,
satelliteMap,
satelliteBeamMap,
mbPayloadShowMap,
// satDetectingPayloadMap,
// satCommunicationPayloadMap,
satellitePayloadShowMap,
showEntity,
getHisTraj,
getMBEntityOpt,
createMBConicSensor,
iconOrModel,
changeIconOrModel,
showOrHideLoad,
changeShowOrHideLoad,
}
}
function showEntity(show: boolean) {
;[...mubiaoMap.values()].forEach(entity => {
entity.show = show
})
}
async function getHisTraj({
id,
timeRange,
}: {
id: string
timeRange: string[]
}) {
const [timeBegin, timeEnd] = timeRange
const { code, data: result } = await getMubiaoHisTraj({
target_id: id,
timeBegin,
timeEnd,
})
if (code !== '200') {
return
}
const timeArray = result.map(item => {
return new Date(item.time).getTime()
})
const posArray = result.map(item => item.position).flat(Infinity)
const points = result.reduce<TPoints>((acc, point, index, array) => {
const { time, position } = point
const cartesian3 = Cesium.Cartesian3.fromDegrees(...position)
if (index === 0) {
acc.push({ time: 0, position: cartesian3 })
} else {
acc.push({
time:
(new Date(time).getTime() - new Date(array[0].time).getTime()) / 1000,
position: cartesian3,
})
}
return acc
}, [])
return { points, posArray, timeArray }
}
async function getMBEntityOpt({
id,
targetType,
country,
extendInfo,
}: {
id: string
targetType: string
country: string
extendInfo?: { detectingPayload: Record<string, number> }
}) {
const mubiaoDict = window.settings.mbDict[targetType]
const countryColor = window.settings.mbCountryDict[country]
// console.log(country, countryColor)
const staticOrientation = {
position: Cesium.Cartesian3.fromDegrees(116.0, 39.9, 10000), // 初始位置北京附近高度10km
orientation: Cesium.Transforms.headingPitchRollQuaternion(
Cesium.Cartesian3.fromDegrees(116.0, 39.9, 10000),
new Cesium.HeadingPitchRoll(
Cesium.Math.toRadians(90), // 航向正东方向0=正北90=正东)
Cesium.Math.toRadians(-90), // 俯仰:轻微下倾(模拟地球曲率)
Cesium.Math.toRadians(0) // 滚转:保持水平
)
),
properties: {
velocity: 800, // 飞行速度km/h
heading: 90.0, // 当前航向(度)
pitch: -90, // 当前俯仰(度)
roll: 0.0, // 当前滚转(度)
altitude: 10000 // 当前高度(米)
}
};
// console.log(country, countryColor)
let ellipsoid;
console.log(extendInfo,targetType,id,'----exteninfo')
let flag = false ;
if(id == 'xx19' || id == 'xx42' || id == 'xx42' || id == 'xxx1' || id == 'xx14' || id == 'xx30' || id == 'xx48' || id == 'xx24' || id == 'xx'){
flag = true
}
if (extendInfo) {
const {
angle,
maximumCone,
minimumCone,
minimumClock,
maximumClock,
radius,
} = extendInfo.detectingPayload
if (maximumClock || minimumClock || minimumCone) {
ellipsoid = {
ellipsoid: {
show: mbPayloadShowMap.get(id)?.detectingPayload?.show || false,
radii: new Cesium.Cartesian3(radius, radius, radius),
innerRadii: new Cesium.Cartesian3(1.0, 1.0, 1.0),
maximumCone: Cesium.Math.toRadians(90),
minimumCone: Cesium.Math.toRadians(minimumCone),
minimumClock: Cesium.Math.toRadians(minimumClock),
maximumClock: Cesium.Math.toRadians(maximumClock),
material: Cesium.Color.fromCssColorString('#00dcff44'),
outline: true,
outlineColor: Cesium.Color.fromCssColorString('#00dcff'),
outlineWidth: 1,
distanceDisplayCondition: new Cesium.DistanceDisplayCondition(
0.0,
10.5e8
),
slicePartitions: 24,
stackPartitions: 36,
},
}
}
}
const image = await getImageByColor({
img: mubiaoDict.icon,
color: countryColor,
})
// console.log(image.img, (+image.height / +image.width) * 30)
return {
label: {
text: `${id}`,
font: '12pt sans-serif',
fillColor: Cesium.Color.fromCssColorString(countryColor),
// fillColor: Cesium.Color.YELLOW,
outlineColor: Cesium.Color.BLACK,
outlineWidth: 2,
style: Cesium.LabelStyle.FILL_AND_OUTLINE,
pixelOffset: new Cesium.Cartesian2(20, -20),
pixelOffsetScaleByDistance: new Cesium.NearFarScalar(
7000000,
1.0,
18000000,
0.4
),
scaleByDistance: new Cesium.NearFarScalar(7000000, 1.0, 18000000, 0.4),
},
billboard: {
show: !iconOrModel.value,
image: image.img,
// image: mubiaoDict.icon,
width: 35,
height: (+image.height / +image.width) * 35,
// height: 30,
color: Cesium.Color.fromCssColorString(countryColor),
scaleByDistance: new Cesium.NearFarScalar(7000000, 1.0, 18000000, 0.4),
},
model: {
show: iconOrModel.value,
uri: mubiaoDict.model,
scale: 100,
minimumPixelSize: 5,
},
...(flag ? {
orientation: staticOrientation.orientation,
properties: staticOrientation.properties
} : {}),
...ellipsoid,
}
}
async function getImageByColor({ img: url, color: newColor }) {
// 步骤 1: 获取 SVG 内容
const svg = await fetch(url)
const svgContent = await svg.text()
// 步骤 2: 修改 SVG 的颜色
const parser = new DOMParser()
const svgDoc = parser.parseFromString(svgContent, 'image/svg+xml')
// 修改所有路径、圆形、矩形等元素的填充颜色
const elements = svgDoc.querySelectorAll('path, circle, rect, polygon, line')
elements.forEach(element => {
// 修改 fill 属性
element.setAttribute('fill', newColor)
// 也可以修改 stroke 颜色,防止可能的边框颜色问题
element.setAttribute('stroke', newColor)
})
const svgElement = svgDoc.documentElement
// console.log(svgElement)
// const transformValue = `rotate(${90}, 50, 50)`
// svgElement.setAttribute('transform', transformValue)
// 获取 SVG 的宽度和高度
const width = svgElement.getAttribute('width')
const height = svgElement.getAttribute('height')
// 步骤 3: 转换为 Base64 编码
const serializer = new XMLSerializer()
const modifiedSVG = serializer.serializeToString(svgDoc.documentElement)
// 输出修改后的 SVG确保颜色正确
const base64SVG = 'data:image/svg+xml;base64,' + btoa(modifiedSVG)
console.log(base64SVG)
return { img: base64SVG, width, height }
}
function createMBConicSensor({
entity,
angle,
show,
radius,
heading,
pitch,
}: {
entity: Cesium.Entity
angle: number
show: boolean
radius: number
heading: number
pitch: number
}) {
console.log('entity', angle, radius, heading, pitch)
const conicSensor = new CesiumSensorVolumes.ConicSensorGraphics({
show,
radius: radius * 1000,
innerHalfAngle: 0,
outerHalfAngle: Cesium.Math.toRadians(angle / 2),
minimumClockAngle: 0,
maximumClockAngle: 2 * Math.PI,
showIntersection: true,
intersectionColor: new Cesium.Color(1, 1, 1, 1),
intersectionWidth: 3,
lateralSurfaceMaterial: new Cesium.Color(0.0, 1.0, 1.0, 0.3),
})
const mbConic = viewer.entities.add({
position: entity.position,
orientation:
entity.position &&
Cesium.Transforms.headingPitchRollQuaternion(
entity.position._value,
new Cesium.HeadingPitchRoll(
// Cesium.Math.toRadians(heading),
Cesium.Math.toRadians(heading),
Cesium.Math.toRadians(pitch),
0
// Cesium.Math.toRadians(pitch)
) // 初始朝向
),
conicSensor: conicSensor,
})
return mbConic
}
const iconOrModel = ref(false)
function changeIconOrModel() {
iconOrModel.value = !iconOrModel.value
;[...mubiaoMap.values(), ...baseMap.values()].forEach(entity => {
entity.model.show = !entity.model.show._value
entity.billboard.show = !entity.billboard.show._value
})
}
const showOrHideLoad = ref(false)
watch([mbPayloadShowMap, satellitePayloadShowMap], ([newMb, newSatellite]) => {
;[...newMb.keys()].forEach(key => {
let show = false
if (newMb.get(key).detectingPayload) {
show = newMb.get(key).detectingPayload.show
}
if (mubiaoMap.has(key)) {
// console.log(mubiaoMap.get(key).ellipsoid)
mubiaoMap.get(key).ellipsoid && (mubiaoMap.get(key).ellipsoid.show = show)
mubiaoConicMap.get(key)?.conicSensor &&
(mubiaoConicMap.get(key).conicSensor.show = show)
}
})
;[...newSatellite.keys()].forEach(key => {
let show = false
if (newSatellite.get(key).detectingPayload) {
show = newSatellite.get(key).detectingPayload.show
// console.log(newSatellite.get(key).detectingPayload.show)
}
if (satelliteMap.has(key)) {
satelliteMap.get(key).sensor = show
}
})
})
function changeShowOrHideLoad() {
showOrHideLoad.value = !showOrHideLoad.value
// ;[...mubiaoMap.values()].forEach(entity => {
// entity.ellipsoid.show = !entity.ellipsoid.show._value
// })
console.log(showOrHideLoad.value)
for (const [key] of mbPayloadShowMap.entries()) {
mbPayloadShowMap.get(key).detectingPayload.show = showOrHideLoad.value
}
for (const [key] of satellitePayloadShowMap.entries()) {
satellitePayloadShowMap.get(key).detectingPayload &&
(satellitePayloadShowMap.get(key).detectingPayload.show =
showOrHideLoad.value)
satellitePayloadShowMap.get(key).communicationPayload &&
(satellitePayloadShowMap.get(key).communicationPayload.show =
showOrHideLoad.value)
}
// ;[...satelliteMap.values()].forEach(satellite => {
// satellite.sensor = showOrHideLoad.value
// })
}