ts/src/hooks/entity.ts

370 lines
11 KiB
TypeScript
Raw Normal View History

2025-02-19 08:06:46 +00:00
import { reactive } from 'vue'
2025-01-13 08:45:08 +00:00
import { getMubiaoHisTraj } from '@/api/Mubiao'
2025-01-06 01:18:58 +00:00
const baseMap = new Map()
const mubiaoMap = new Map()
2025-02-19 08:06:46 +00:00
const mubiaoConicMap = new Map()
2025-01-06 01:18:58 +00:00
const satelliteMap = new Map()
const satelliteBeamMap = new Map()
2025-02-19 08:06:46 +00:00
const mbPayloadShowMap = reactive(new Map())
// const satDetectingPayloadMap = reactive(new Map())
// const satCommunicationPayloadMap = reactive(new Map())
const satellitePayloadShowMap = reactive(new Map())
2025-01-06 01:18:58 +00:00
export const useEntity = () => {
return {
baseMap,
mubiaoMap,
2025-02-19 08:06:46 +00:00
mubiaoConicMap,
2025-01-06 01:18:58 +00:00
satelliteMap,
satelliteBeamMap,
2025-02-19 08:06:46 +00:00
mbPayloadShowMap,
// satDetectingPayloadMap,
// satCommunicationPayloadMap,
satellitePayloadShowMap,
2025-01-13 08:45:08 +00:00
showEntity,
getHisTraj,
getMBEntityOpt,
2025-02-19 08:06:46 +00:00
createMBConicSensor,
2025-01-23 01:05:13 +00:00
iconOrModel,
2025-01-13 08:45:08 +00:00
changeIconOrModel,
2025-02-14 08:33:28 +00:00
showOrHideLoad,
changeShowOrHideLoad,
2025-01-06 01:18:58 +00:00
}
}
2025-01-13 08:45:08 +00:00
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({
2025-01-13 08:45:08 +00:00
id,
targetType,
country,
2025-02-19 08:06:46 +00:00
extendInfo,
2025-01-13 08:45:08 +00:00
}: {
id: string
targetType: string
country: string
2025-02-19 08:06:46 +00:00
extendInfo?: { detectingPayload: Record<string, number> }
2025-01-13 08:45:08 +00:00
}) {
const mubiaoDict = window.settings.mbDict[targetType]
const countryColor = window.settings.mbCountryDict[country]
2025-01-13 08:45:08 +00:00
// const headingPitchRoll = new Cesium.HeadingPitchRoll(
// heading,
// pitch,
// roll
// )
// const newOrientation = Cesium.Transforms.headingPitchRollQuaternion(
// obj.position,
// headingPitchRo11
// )
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
}
2025-02-19 08:06:46 +00:00
if (extendInfo) {
const {
angle,
maximumCone,
minimumCone,
minimumClock,
maximumClock,
radius,
} = extendInfo.detectingPayload
if (maximumClock || minimumClock || minimumCone) {
2025-02-19 08:06:46 +00:00
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)
2025-01-13 08:45:08 +00:00
return {
label: {
text: `${id}`,
font: '12pt sans-serif',
fillColor: Cesium.Color.fromCssColorString(countryColor),
// fillColor: Cesium.Color.YELLOW,
2025-01-13 08:45:08 +00:00
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),
},
// 新增 name 标签(例如显示在 id 下方)
nameLabel: {
text: '99999999999', // 假设 name 是传入的变量
font: '12pt sans-serif',
fillColor: Cesium.Color.WHITE, // 白色文字
outlineColor: Cesium.Color.BLACK,
outlineWidth: 2,
style: Cesium.LabelStyle.FILL_AND_OUTLINE,
pixelOffset: new Cesium.Cartesian2(20, -40), // 调整位置(在 id 下方)
pixelOffsetScaleByDistance: new Cesium.NearFarScalar(7000000, 1.0, 18000000, 0.4),
scaleByDistance: new Cesium.NearFarScalar(7000000, 1.0, 18000000, 0.4),
show: true // 默认显示
2025-01-13 08:45:08 +00:00
},
billboard: {
2025-01-23 01:05:13 +00:00
show: !iconOrModel.value,
image: image.img,
// image: mubiaoDict.icon,
width: 35,
height: (+image.height / +image.width) * 35,
// height: 30,
color: Cesium.Color.fromCssColorString(countryColor),
2025-01-13 08:45:08 +00:00
scaleByDistance: new Cesium.NearFarScalar(7000000, 1.0, 18000000, 0.4),
},
...(flag ? {
orientation: staticOrientation.orientation,
properties: staticOrientation.properties
} : {}),
2025-01-13 08:45:08 +00:00
model: {
2025-01-23 01:05:13 +00:00
show: iconOrModel.value,
2025-01-13 08:45:08 +00:00
uri: mubiaoDict.model,
scale: 50,
minimumPixelSize: 25,
2025-01-13 08:45:08 +00:00
},
2025-02-19 08:06:46 +00:00
...ellipsoid,
2025-01-13 08:45:08 +00:00
}
}
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 }
}
2025-02-19 08:06:46 +00:00
function createMBConicSensor({
entity,
angle,
show,
radius,
heading,
pitch,
2025-02-19 08:06:46 +00:00
}: {
entity: Cesium.Entity
angle: number
show: boolean
radius: number
heading: number
pitch: number
2025-02-19 08:06:46 +00:00
}) {
console.log('entity', angle, radius, heading, pitch)
2025-02-19 08:06:46 +00:00
const conicSensor = new CesiumSensorVolumes.ConicSensorGraphics({
show,
radius: radius * 1000,
2025-02-19 08:06:46 +00:00
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)
2025-02-19 08:06:46 +00:00
) // 初始朝向
),
conicSensor: conicSensor,
})
return mbConic
}
2025-01-23 01:05:13 +00:00
const iconOrModel = ref(false)
2025-01-13 08:45:08 +00:00
function changeIconOrModel() {
2025-01-23 01:05:13 +00:00
iconOrModel.value = !iconOrModel.value
;[...mubiaoMap.values(), ...baseMap.values()].forEach(entity => {
2025-01-13 08:45:08 +00:00
entity.model.show = !entity.model.show._value
entity.billboard.show = !entity.billboard.show._value
})
}
2025-02-14 08:33:28 +00:00
2025-02-19 08:06:46 +00:00
const showOrHideLoad = ref(false)
2025-02-14 08:33:28 +00:00
2025-02-19 08:06:46 +00:00
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)
2025-02-19 08:06:46 +00:00
mubiaoMap.get(key).ellipsoid && (mubiaoMap.get(key).ellipsoid.show = show)
mubiaoConicMap.get(key)?.conicSensor &&
(mubiaoConicMap.get(key).conicSensor.show = show)
}
2025-02-14 08:33:28 +00:00
})
2025-02-19 08:06:46 +00:00
;[...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
}
2025-02-14 08:33:28 +00:00
})
2025-02-19 08:06:46 +00:00
})
function changeShowOrHideLoad() {
showOrHideLoad.value = !showOrHideLoad.value
// ;[...mubiaoMap.values()].forEach(entity => {
// entity.ellipsoid.show = !entity.ellipsoid.show._value
// })
console.log(showOrHideLoad.value)
2025-02-19 08:06:46 +00:00
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
// })
2025-02-14 08:33:28 +00:00
}