4-17
BIN
public/images/icons/详情.png
Normal file
After Width: | Height: | Size: 654 B |
BIN
public/images/icons/轨迹回放.png
Normal file
After Width: | Height: | Size: 571 B |
616812
public/json/timezone.geojson
Normal file
BIN
src/assets/image/icon/excel.png
Normal file
After Width: | Height: | Size: 652 B |
BIN
src/assets/image/icon/photo.png
Normal file
After Width: | Height: | Size: 519 B |
BIN
src/assets/image/icon/word.png
Normal file
After Width: | Height: | Size: 605 B |
BIN
src/assets/image/icon/zip.png
Normal file
After Width: | Height: | Size: 593 B |
BIN
src/assets/image/详情.png
Normal file
After Width: | Height: | Size: 654 B |
@ -26,6 +26,8 @@ export const useEntity = () => {
|
|||||||
showEntity,
|
showEntity,
|
||||||
getHisTraj,
|
getHisTraj,
|
||||||
getMBEntityOpt,
|
getMBEntityOpt,
|
||||||
|
getEllipsoidEntity,
|
||||||
|
getMBEntityOptOther,
|
||||||
createMBConicSensor,
|
createMBConicSensor,
|
||||||
iconOrModel,
|
iconOrModel,
|
||||||
changeIconOrModel,
|
changeIconOrModel,
|
||||||
@ -186,18 +188,259 @@ async function getMBEntityOpt({
|
|||||||
),
|
),
|
||||||
scaleByDistance: new Cesium.NearFarScalar(7000000, 1.0, 18000000, 0.4),
|
scaleByDistance: new Cesium.NearFarScalar(7000000, 1.0, 18000000, 0.4),
|
||||||
},
|
},
|
||||||
// 新增 name 标签(例如显示在 id 下方)
|
billboard: {
|
||||||
nameLabel: {
|
show: !iconOrModel.value,
|
||||||
text: '99999999999', // 假设 name 是传入的变量
|
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),
|
||||||
|
},
|
||||||
|
...(flag ? {
|
||||||
|
orientation: staticOrientation.orientation,
|
||||||
|
properties: staticOrientation.properties
|
||||||
|
} : {}),
|
||||||
|
model: {
|
||||||
|
show: iconOrModel.value,
|
||||||
|
uri: mubiaoDict.model,
|
||||||
|
scale: 50,
|
||||||
|
minimumPixelSize: 25,
|
||||||
|
},
|
||||||
|
properties: { // 添加自定义属性
|
||||||
|
zhName: '目标中文名称',
|
||||||
|
show: iconOrModel.value,
|
||||||
|
},
|
||||||
|
...ellipsoid,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
async function getEllipsoidEntity({
|
||||||
|
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]
|
||||||
|
|
||||||
|
// 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
|
||||||
|
}
|
||||||
|
if (extendInfo) {
|
||||||
|
const {
|
||||||
|
angle,
|
||||||
|
maximumCone,
|
||||||
|
minimumCone,
|
||||||
|
minimumClock,
|
||||||
|
maximumClock,
|
||||||
|
radius,
|
||||||
|
} = extendInfo.detectingPayload
|
||||||
|
if (maximumClock || minimumClock || minimumCone) {
|
||||||
|
ellipsoid = {
|
||||||
|
ellipsoid: {
|
||||||
|
|
||||||
|
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(extendInfo.detectingPayload?.zhName,'---extendInfo')
|
||||||
|
console.log(mbPayloadShowMap.get(id)?.detectingPayload?.show,'---iconOrModel.value')
|
||||||
|
|
||||||
|
|
||||||
|
// console.log(image.img, (+image.height / +image.width) * 30)
|
||||||
|
return {
|
||||||
|
show: mbPayloadShowMap.get(id)?.detectingPayload?.show || false,
|
||||||
|
label: {
|
||||||
|
text: `${extendInfo.detectingPayload?.zhName}`,
|
||||||
font: '12pt sans-serif',
|
font: '12pt sans-serif',
|
||||||
fillColor: Cesium.Color.WHITE, // 白色文字
|
fillColor: Cesium.Color.fromCssColorString(countryColor),
|
||||||
|
// fillColor: Cesium.Color.YELLOW,
|
||||||
outlineColor: Cesium.Color.BLACK,
|
outlineColor: Cesium.Color.BLACK,
|
||||||
outlineWidth: 2,
|
outlineWidth: 2,
|
||||||
style: Cesium.LabelStyle.FILL_AND_OUTLINE,
|
style: Cesium.LabelStyle.FILL_AND_OUTLINE,
|
||||||
pixelOffset: new Cesium.Cartesian2(20, -40), // 调整位置(在 id 下方)
|
pixelOffset: new Cesium.CallbackProperty(() => {
|
||||||
pixelOffsetScaleByDistance: new Cesium.NearFarScalar(7000000, 1.0, 18000000, 0.4),
|
const radius = ellipsoid.ellipsoid.radii.y;
|
||||||
|
return new Cesium.Cartesian2(-radius * 0.08,0); // 偏移到椭球体顶部
|
||||||
|
}, false),
|
||||||
|
// pixelOffset: new Cesium.Cartesian2(0, -20),
|
||||||
|
// pixelOffsetScaleByDistance: new Cesium.NearFarScalar(
|
||||||
|
// 7000000,
|
||||||
|
// 1.0,
|
||||||
|
// 18000000,
|
||||||
|
// 0.4
|
||||||
|
// ),
|
||||||
|
// scaleByDistance: new Cesium.NearFarScalar(7000000, 1.0, 18000000, 0.4),
|
||||||
|
},
|
||||||
|
|
||||||
|
...ellipsoid,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
async function getMBEntityOptOther({
|
||||||
|
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]
|
||||||
|
|
||||||
|
// 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
|
||||||
|
}
|
||||||
|
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),
|
scaleByDistance: new Cesium.NearFarScalar(7000000, 1.0, 18000000, 0.4),
|
||||||
show: true // 默认显示
|
|
||||||
},
|
},
|
||||||
billboard: {
|
billboard: {
|
||||||
show: !iconOrModel.value,
|
show: !iconOrModel.value,
|
||||||
@ -219,7 +462,11 @@ async function getMBEntityOpt({
|
|||||||
scale: 50,
|
scale: 50,
|
||||||
minimumPixelSize: 25,
|
minimumPixelSize: 25,
|
||||||
},
|
},
|
||||||
...ellipsoid,
|
// properties: { // 添加自定义属性
|
||||||
|
// zhName: '目标中文名称',
|
||||||
|
// show: iconOrModel.value,
|
||||||
|
// },
|
||||||
|
// ...ellipsoid,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,6 +3,9 @@ import moment from 'moment-timezone'
|
|||||||
import { useRoute } from 'vue-router'
|
import { useRoute } from 'vue-router'
|
||||||
import { time2FormatWithTimezone } from '@/utils/date'
|
import { time2FormatWithTimezone } from '@/utils/date'
|
||||||
import WidgetNav from '../WidgetNav'
|
import WidgetNav from '../WidgetNav'
|
||||||
|
import axios from 'axios'
|
||||||
|
import { get } from 'lodash'
|
||||||
|
|
||||||
|
|
||||||
const timeZoneList1 = [
|
const timeZoneList1 = [
|
||||||
{ label: '中国/北京', value: 'Asia/Shanghai' },
|
{ label: '中国/北京', value: 'Asia/Shanghai' },
|
||||||
@ -53,7 +56,10 @@ const timeZoneList = [
|
|||||||
];
|
];
|
||||||
const timezone = ref('UTC+8')
|
const timezone = ref('UTC+8')
|
||||||
const worldTime = ref()
|
const worldTime = ref()
|
||||||
|
let currentDataSource = ref(null); // 存储当前加载的数据源
|
||||||
|
let highlightedEntities =ref([]); // 存储高亮实体
|
||||||
function adjustTime(targetValue) {
|
function adjustTime(targetValue) {
|
||||||
|
|
||||||
// 解析目标时区偏移量
|
// 解析目标时区偏移量
|
||||||
const match = targetValue.match(/UTC([+-])(\d+)/);
|
const match = targetValue.match(/UTC([+-])(\d+)/);
|
||||||
if (!match) throw new Error('Invalid timezone format');
|
if (!match) throw new Error('Invalid timezone format');
|
||||||
@ -93,13 +99,12 @@ function getAdjustedTime(targetValue) {
|
|||||||
// });
|
// });
|
||||||
}
|
}
|
||||||
|
|
||||||
// 使用示例
|
|
||||||
console.log('调整后时间:', getAdjustedTime('UTC+9'));
|
|
||||||
// 输出:2023/10/15 13:30:00
|
// 输出:2023/10/15 13:30:00
|
||||||
const getTime = () => {
|
const getTime = () => {
|
||||||
// const date = moment(new Date()).tz(timezone.value)
|
// const date = moment(new Date()).tz(timezone.value)
|
||||||
// console.log(date)
|
// console.log(date)
|
||||||
|
|
||||||
|
|
||||||
worldTime.value = getAdjustedTime(timezone.value)
|
worldTime.value = getAdjustedTime(timezone.value)
|
||||||
// console.log(timezone.value,'---timezone.value')
|
// console.log(timezone.value,'---timezone.value')
|
||||||
// worldTime.value = time2FormatWithTimezone(new Date(), timezone.value)
|
// worldTime.value = time2FormatWithTimezone(new Date(), timezone.value)
|
||||||
@ -113,12 +118,164 @@ const getLocalTime = () => {
|
|||||||
localeTime.value = getAdjustedTime(timezone.value)
|
localeTime.value = getAdjustedTime(timezone.value)
|
||||||
|
|
||||||
requestAnimationFrame(getLocalTime)
|
requestAnimationFrame(getLocalTime)
|
||||||
|
}
|
||||||
|
const handleTimezoneChange = (selectedValue) => {
|
||||||
|
console.log('当前选择:', selectedValue)
|
||||||
|
|
||||||
|
// 执行高亮逻辑(调用之前实现的 highlightZone 函数)
|
||||||
|
highlightZone(selectedValue)
|
||||||
|
}
|
||||||
|
|
||||||
|
const processCoordinates = (rawCoords) => {
|
||||||
|
// 过滤无效数据并转换
|
||||||
|
return rawCoords
|
||||||
|
.filter(point =>
|
||||||
|
Array.isArray(point) &&
|
||||||
|
point.length >= 2 &&
|
||||||
|
!isNaN(point[0]) &&
|
||||||
|
!isNaN(point[1])
|
||||||
|
)
|
||||||
|
.map(point => {
|
||||||
|
// 处理极地坐标限制
|
||||||
|
const clampedLat = Math.max(-89.9999, Math.min(89.9999, point[1]))
|
||||||
|
|
||||||
|
// 创建笛卡尔坐标
|
||||||
|
return Cesium.Cartesian3.fromDegrees(
|
||||||
|
Number(point[0]),
|
||||||
|
clampedLat,
|
||||||
|
0
|
||||||
|
)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// const processCoordinates = (rawCoords) => {
|
||||||
|
// // 验证输入有效性
|
||||||
|
// if (!Array.isArray(rawCoords)) {
|
||||||
|
// throw new Error('坐标数据必须是数组')
|
||||||
|
// }
|
||||||
|
|
||||||
|
// return rawCoords.map((point, index) => {
|
||||||
|
// if (point.length < 2) {
|
||||||
|
// throw new Error(`第 ${index + 1} 个坐标点格式错误`)
|
||||||
|
// }
|
||||||
|
|
||||||
|
// // 处理极地坐标(纬度强制限制在 ±89.9999° 以内)
|
||||||
|
// const safeLat = Math.max(-89.9999, Math.min(89.9999, point[1]))
|
||||||
|
|
||||||
|
// return Cesium.Cartesian3.fromDegrees(
|
||||||
|
// parseFloat(point[0]),
|
||||||
|
// safeLat,
|
||||||
|
// 0
|
||||||
|
// )
|
||||||
|
// })
|
||||||
|
// }
|
||||||
|
|
||||||
|
const getData = () => {
|
||||||
|
return axios.get("./json/timezone.geojson").then(res => {
|
||||||
|
if (res.status === 200) {
|
||||||
|
return Promise.resolve(res.data)
|
||||||
|
} else {
|
||||||
|
console.log('获取TLE失败')
|
||||||
|
return Promise.reject(res.statusText)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
// 加载GeoJSON并高亮
|
||||||
|
// 时区格式转换函数
|
||||||
|
const getZoneKey = (utcValue) => {
|
||||||
|
if(utcValue == 'UTC'){
|
||||||
|
return '0'
|
||||||
|
}
|
||||||
|
// 示例输入: "UTC+8" → 输出: "+8"
|
||||||
|
const sign = utcValue.includes('+') ? '+' : '-'
|
||||||
|
const num = utcValue.replace(/\D/g, '') // 提取数字部分
|
||||||
|
return `${sign}${num}`
|
||||||
|
}
|
||||||
|
const getCoordinates = (data,zoneKey) =>{
|
||||||
|
return data.features.filter(item=>{
|
||||||
|
return item.properties.name == zoneKey
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const highlightZone = async (zoneValue) => {
|
||||||
|
if (!viewer) return
|
||||||
|
|
||||||
|
|
||||||
|
// 2. 转换时区标识
|
||||||
|
const zoneKey = getZoneKey(zoneValue) // "UTC+8" → "+8"
|
||||||
|
console.log(zoneKey,'---zone')
|
||||||
|
|
||||||
|
await getData().then(async data => {
|
||||||
|
|
||||||
|
try {
|
||||||
|
const features= getCoordinates(data,zoneKey);
|
||||||
|
|
||||||
|
|
||||||
|
// 2. 构造新数据源
|
||||||
|
const geoJsonObject = {
|
||||||
|
type: "FeatureCollection",
|
||||||
|
name: "timezone",
|
||||||
|
crs: {
|
||||||
|
type: "name",
|
||||||
|
properties: { name: "urn:ogc:def:crs:OGC:1.3:CRS84" }
|
||||||
|
},
|
||||||
|
features: features // 确保features变量已定义
|
||||||
|
};
|
||||||
|
|
||||||
|
// 3. 加载新数据
|
||||||
|
currentDataSource.value = await Cesium.GeoJsonDataSource.load(geoJsonObject, {
|
||||||
|
stroke: Cesium.Color.WHITE,
|
||||||
|
fill: Cesium.Color.TRANSPARENT
|
||||||
|
});
|
||||||
|
|
||||||
|
// 4. 筛选并高亮
|
||||||
|
currentDataSource.value.entities.values.forEach(entity => {
|
||||||
|
const featureName = entity.properties?.name?.getValue();
|
||||||
|
if (featureName === zoneKey) {
|
||||||
|
entity.polygon.material = Cesium.Color.YELLOW.withAlpha(0.7);
|
||||||
|
entity.polygon.outline = false;
|
||||||
|
highlightedEntities.value.push(entity);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
isHeight.value=true
|
||||||
|
|
||||||
|
// 5. 添加新数据到场景
|
||||||
|
viewer.dataSources.add(currentDataSource.value);
|
||||||
|
|
||||||
|
// 6. 安全定位
|
||||||
|
const coordinates = currentDataSource.value.entities.values[0].polygon.hierarchy.getValue().positions
|
||||||
|
viewer.camera.flyTo({
|
||||||
|
destination: Cesium.Rectangle.fromCartesianArray(coordinates)
|
||||||
|
})
|
||||||
|
} catch (error) {
|
||||||
|
console.error('时区加载失败:', error);
|
||||||
|
// viewer.camera.flyTo({
|
||||||
|
// destination: Cesium.Rectangle.fromDegrees(104.0, 22.0, 107.0, 25.0)
|
||||||
|
// });
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
// console.log(moment.tz.names())
|
// console.log(moment.tz.names())
|
||||||
getTime()
|
getTime()
|
||||||
getLocalTime()
|
getLocalTime()
|
||||||
})
|
})
|
||||||
|
const isHeight=ref(false);
|
||||||
|
const btnClick=()=>{
|
||||||
|
console.log('---btnClick')
|
||||||
|
if(isHeight.value){
|
||||||
|
isHeight.value= !isHeight.value
|
||||||
|
if (currentDataSource.value) {
|
||||||
|
viewer.dataSources.remove(currentDataSource.value); // 从场景移除
|
||||||
|
// currentDataSource.value.destroy(); // 销毁实例释放内存
|
||||||
|
currentDataSource.value = null;
|
||||||
|
}
|
||||||
|
highlightedEntities.value = []; // 清空高亮实体数组
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const route = useRoute()
|
const route = useRoute()
|
||||||
</script>
|
</script>
|
||||||
@ -135,8 +292,9 @@ const route = useRoute()
|
|||||||
v-model:value="timezone"
|
v-model:value="timezone"
|
||||||
:options="timeZoneList"
|
:options="timeZoneList"
|
||||||
trigger="click"
|
trigger="click"
|
||||||
|
@update:value="handleTimezoneChange"
|
||||||
>
|
>
|
||||||
<div class="time-title cursor-pointer">
|
<div class="time-title cursor-pointer" :class="{ 'bg-color': isHeight }" @click="btnClick">
|
||||||
{{
|
{{
|
||||||
timeZoneList.find(item => item.value === timezone).label ||
|
timeZoneList.find(item => item.value === timezone).label ||
|
||||||
'东八区'
|
'东八区'
|
||||||
@ -157,6 +315,7 @@ const route = useRoute()
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style type="scss" scoped>
|
<style type="scss" scoped>
|
||||||
|
|
||||||
.time-bg {
|
.time-bg {
|
||||||
background-color: var(--color-bg);
|
background-color: var(--color-bg);
|
||||||
box-shadow: 0 0 0 4px linear-gradient(to right, #ff0000, #00ff00);
|
box-shadow: 0 0 0 4px linear-gradient(to right, #ff0000, #00ff00);
|
||||||
@ -170,6 +329,10 @@ const route = useRoute()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.bg-color{
|
||||||
|
background-color: #397294;
|
||||||
|
/* opacity: 0.5; */
|
||||||
|
}
|
||||||
|
|
||||||
.bgc-animation {
|
.bgc-animation {
|
||||||
background: var(--gradient-bg);
|
background: var(--gradient-bg);
|
||||||
|
@ -30,6 +30,8 @@ const data = ref<Record<string, any>[]>([])
|
|||||||
const {
|
const {
|
||||||
mubiaoMap,
|
mubiaoMap,
|
||||||
getMBEntityOpt,
|
getMBEntityOpt,
|
||||||
|
getEllipsoidEntity,
|
||||||
|
getMBEntityOptOther,
|
||||||
createMBConicSensor,
|
createMBConicSensor,
|
||||||
mubiaoConicMap,
|
mubiaoConicMap,
|
||||||
mbPayloadShowMap,
|
mbPayloadShowMap,
|
||||||
@ -81,7 +83,7 @@ export const useMubiao = () => {
|
|||||||
mbPos.find(item => item.target_id === id) ?? {}
|
mbPos.find(item => item.target_id === id) ?? {}
|
||||||
const pos = parseWKT(target_geom).coordinates
|
const pos = parseWKT(target_geom).coordinates
|
||||||
|
|
||||||
const mbEntity = await addMubiaoEntity({
|
const [ellipsoidEntity,otherOptEntity] = await addMubiaoEntity({
|
||||||
id,
|
id,
|
||||||
position: pos,
|
position: pos,
|
||||||
target_time,
|
target_time,
|
||||||
@ -89,11 +91,14 @@ export const useMubiao = () => {
|
|||||||
targetType: data.targetType,
|
targetType: data.targetType,
|
||||||
extendInfo: data.extendInfo,
|
extendInfo: data.extendInfo,
|
||||||
})
|
})
|
||||||
|
if(ellipsoidEntity){
|
||||||
|
addEventSub(`${id}_model`, ellipsoidEntity, data)
|
||||||
|
mubiaoMap.set(`${id}_model`, ellipsoidEntity)
|
||||||
|
}
|
||||||
// console.log(mbEntity, 'mbEntity')
|
// console.log(mbEntity, 'mbEntity')
|
||||||
addEventSub(id, mbEntity, data)
|
|
||||||
|
|
||||||
mubiaoMap.set(id, mbEntity)
|
addEventSub(id, otherOptEntity, data)
|
||||||
|
mubiaoMap.set(id, otherOptEntity)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -112,25 +117,88 @@ export const useMubiao = () => {
|
|||||||
}: Record<string, string | number | number[]>) => {
|
}: Record<string, string | number | number[]>) => {
|
||||||
// 添加目标实体
|
// 添加目标实体
|
||||||
// console.log(window.settings, targetType, '-----')
|
// console.log(window.settings, targetType, '-----')
|
||||||
const mbEntityOpt = await getMBEntityOpt({
|
// const mbEntityOpt = await getMBEntityOpt({
|
||||||
|
// id,
|
||||||
|
// country,
|
||||||
|
// targetType,
|
||||||
|
// extendInfo,
|
||||||
|
// })
|
||||||
|
|
||||||
|
// const mubiaoEntity = viewer.entities.add({
|
||||||
|
// name: id,
|
||||||
|
// position: Cesium.Cartesian3.fromDegrees(
|
||||||
|
// ...(position as number[]),
|
||||||
|
// targetType === '甲' ? 20000 : 0
|
||||||
|
// ),
|
||||||
|
// ...mbEntityOpt,
|
||||||
|
// })
|
||||||
|
let ellipsoid=null;
|
||||||
|
let ellipsoidEntity=null;
|
||||||
|
|
||||||
|
if(extendInfo?.detectingPayload){
|
||||||
|
ellipsoid = await getEllipsoidEntity({
|
||||||
|
id,
|
||||||
|
country,
|
||||||
|
targetType,
|
||||||
|
extendInfo,
|
||||||
|
})
|
||||||
|
ellipsoidEntity = viewer.entities.add({
|
||||||
|
name: id,
|
||||||
|
position: Cesium.Cartesian3.fromDegrees(
|
||||||
|
...(position as number[]),
|
||||||
|
targetType === '甲' ? 20000 : 0
|
||||||
|
),
|
||||||
|
...ellipsoid,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const otherOpt = await getMBEntityOptOther({
|
||||||
id,
|
id,
|
||||||
country,
|
country,
|
||||||
targetType,
|
targetType,
|
||||||
extendInfo,
|
extendInfo,
|
||||||
})
|
})
|
||||||
|
const otherOptEntity = viewer.entities.add({
|
||||||
const mubiaoEntity = viewer.entities.add({
|
|
||||||
name: id,
|
name: id,
|
||||||
position: Cesium.Cartesian3.fromDegrees(
|
position: Cesium.Cartesian3.fromDegrees(
|
||||||
...(position as number[]),
|
...(position as number[]),
|
||||||
targetType === '甲' ? 20000 : 0
|
targetType === '甲' ? 20000 : 0
|
||||||
),
|
),
|
||||||
...mbEntityOpt,
|
...otherOpt,
|
||||||
})
|
})
|
||||||
|
// const mubiaoEntity = viewer.entities.add({
|
||||||
|
// name: id,
|
||||||
|
// position: Cesium.Cartesian3.fromDegrees(
|
||||||
|
// ...(position as number[]),
|
||||||
|
// targetType === '甲' ? 20000 : 0
|
||||||
|
// ),
|
||||||
|
// ...mbEntityOpt,
|
||||||
|
// })
|
||||||
|
// console.log( mubiaoEntity.position.getValue(),'===== mubiaoEntity.position.getValue()')
|
||||||
|
// console.log( mubiaoEntity.properties.zhName.getValue(),'===== mubiaoEntity.position.getValue()')
|
||||||
|
// console.log( mubiaoEntity.model.show.getValue(),'===== mubiaoEntity.model.show.getValue())')
|
||||||
|
|
||||||
|
|
||||||
|
// const zhNameEntity = viewer.entities.add({
|
||||||
|
// position: new Cesium.CallbackProperty(() => mubiaoEntity.position.getValue(), false),
|
||||||
|
// label: {
|
||||||
|
// text: new Cesium.CallbackProperty(() =>
|
||||||
|
// mubiaoEntity.properties.zhName.getValue(), false
|
||||||
|
// ),
|
||||||
|
// show: new Cesium.CallbackProperty(() =>
|
||||||
|
// mubiaoEntity.model.show.getValue(), false // 与模型显示状态同步
|
||||||
|
// ),
|
||||||
|
// font: '12pt 黑体',
|
||||||
|
// fillColor: Cesium.Color.WHITE,
|
||||||
|
// outlineColor: Cesium.Color.BLACK,
|
||||||
|
// pixelOffset: new Cesium.Cartesian2(40, -40), // 在模型右上方
|
||||||
|
// scaleByDistance: new Cesium.NearFarScalar(7000000, 1.0, 18000000, 0.4)
|
||||||
|
// }
|
||||||
|
// });
|
||||||
if (extendInfo?.detectingPayload?.angle) {
|
if (extendInfo?.detectingPayload?.angle) {
|
||||||
const conic = createMBConicSensor({
|
const conic = createMBConicSensor({
|
||||||
entity: mubiaoEntity,
|
entity: otherOptEntity,
|
||||||
radius: extendInfo?.detectingPayload?.radius,
|
radius: extendInfo?.detectingPayload?.radius,
|
||||||
|
|
||||||
angle: extendInfo?.detectingPayload?.angle,
|
angle: extendInfo?.detectingPayload?.angle,
|
||||||
@ -140,7 +208,7 @@ export const useMubiao = () => {
|
|||||||
})
|
})
|
||||||
mubiaoConicMap.set(id, conic)
|
mubiaoConicMap.set(id, conic)
|
||||||
}
|
}
|
||||||
return mubiaoEntity
|
return [ellipsoidEntity,otherOptEntity]
|
||||||
}
|
}
|
||||||
|
|
||||||
const addEventSub = (
|
const addEventSub = (
|
||||||
@ -268,7 +336,7 @@ function getAllNodesToPayload() {
|
|||||||
const { dataId, data: nodeData } = node
|
const { dataId, data: nodeData } = node
|
||||||
const { extendInfo } = nodeData
|
const { extendInfo } = nodeData
|
||||||
const detectingShow =
|
const detectingShow =
|
||||||
mbPayloadShowMap.get(dataId)?.detectingPayload?.show || false
|
mbPayloadShowMap.get(dataId)?.detectingPayload?.show || false;
|
||||||
if (extendInfo) {
|
if (extendInfo) {
|
||||||
mbPayloadShowMap.set(dataId, {
|
mbPayloadShowMap.set(dataId, {
|
||||||
data: toRaw(nodeData),
|
data: toRaw(nodeData),
|
||||||
|
@ -26,6 +26,7 @@ export const useMubiaoDetail = () => {
|
|||||||
minimumCone: null,
|
minimumCone: null,
|
||||||
maximumCone: null,
|
maximumCone: null,
|
||||||
show: false,
|
show: false,
|
||||||
|
zhName:''
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
} else if (payLoadType === 'airplaneConic') {
|
} else if (payLoadType === 'airplaneConic') {
|
||||||
@ -129,6 +130,7 @@ export const useMubiaoDetail = () => {
|
|||||||
function updateMbLoad({ mbData, detection }) {
|
function updateMbLoad({ mbData, detection }) {
|
||||||
const { getMubiaoData } = useMubiao()
|
const { getMubiaoData } = useMubiao()
|
||||||
const { id, show, ...detectionData } = detection[0]
|
const { id, show, ...detectionData } = detection[0]
|
||||||
|
console.log('------------')
|
||||||
|
|
||||||
if (
|
if (
|
||||||
Object.values(detectionData).some(
|
Object.values(detectionData).some(
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { h } from 'vue'
|
import { h } from 'vue'
|
||||||
import { NButton } from 'naive-ui'
|
import { NButton ,NIcon} from 'naive-ui'
|
||||||
import type { TreeOption } from 'naive-ui'
|
import type { TreeOption } from 'naive-ui'
|
||||||
// import type { DataTableColumns, DataTableRowKey } from 'naive-ui'
|
// import type { DataTableColumns, DataTableRowKey } from 'naive-ui'
|
||||||
import Tree from '@/components/Tree/index.vue'
|
import Tree from '@/components/Tree/index.vue'
|
||||||
@ -61,15 +61,49 @@ const renderSuffix = ({ option }: { option: TreeOption }) => {
|
|||||||
return undefined
|
return undefined
|
||||||
}
|
}
|
||||||
return h('div', { class: 'flex items-center gap-2 pr-2' }, [
|
return h('div', { class: 'flex items-center gap-2 pr-2' }, [
|
||||||
|
// h(
|
||||||
|
// NButton,
|
||||||
|
// {
|
||||||
|
// text: true,
|
||||||
|
// size: 'tiny',
|
||||||
|
// type: 'info',
|
||||||
|
// onClick: () => showDetailsMubiao(option.data),
|
||||||
|
// },
|
||||||
|
// { default: () => '详情' }
|
||||||
|
// ),
|
||||||
h(
|
h(
|
||||||
NButton,
|
NIcon,
|
||||||
{
|
{
|
||||||
text: true,
|
size: 18,
|
||||||
size: 'tiny',
|
class: 'cursor-pointer text-gray-500 hover:text-blue-600',
|
||||||
type: 'info',
|
onClick: (e) => {
|
||||||
onClick: () => showDetailsMubiao(option.data),
|
e.stopPropagation()
|
||||||
|
showDetailsMubiao(option.data)
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{ default: () => '详情' }
|
{
|
||||||
|
default: () => h('img', {
|
||||||
|
src: './images/icons/详情.png',
|
||||||
|
class: 'w-[18px] h-[18px]'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
),
|
||||||
|
h(
|
||||||
|
NIcon,
|
||||||
|
{
|
||||||
|
size: 18,
|
||||||
|
class: 'cursor-pointer text-gray-500 hover:text-blue-600',
|
||||||
|
onClick: (e) => {
|
||||||
|
e.stopPropagation()
|
||||||
|
showOrHideHisTraj(option.data)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
default: () => h('img', {
|
||||||
|
src: './images/icons/轨迹回放.png',
|
||||||
|
class: 'w-[18px] h-[18px]'
|
||||||
|
})
|
||||||
|
}
|
||||||
),
|
),
|
||||||
// option.data.targetType === '丙' &&
|
// option.data.targetType === '丙' &&
|
||||||
// h(
|
// h(
|
||||||
@ -83,16 +117,16 @@ const renderSuffix = ({ option }: { option: TreeOption }) => {
|
|||||||
// { default: () => '试验配置' }
|
// { default: () => '试验配置' }
|
||||||
// ),
|
// ),
|
||||||
// option.data.targetType !== '丙' &&
|
// option.data.targetType !== '丙' &&
|
||||||
h(
|
// h(
|
||||||
NButton,
|
// NButton,
|
||||||
{
|
// {
|
||||||
text: true,
|
// text: true,
|
||||||
size: 'tiny',
|
// size: 'tiny',
|
||||||
type: 'info',
|
// type: 'info',
|
||||||
onClick: () => showOrHideHisTraj(option.data),
|
// onClick: () => showOrHideHisTraj(option.data),
|
||||||
},
|
// },
|
||||||
{ default: () => '轨迹回放' }
|
// { default: () => '轨迹回放' }
|
||||||
),
|
// ),
|
||||||
])
|
])
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { NDataTable, NButton, NSelect, NInputNumber, NSwitch } from 'naive-ui'
|
import { NDataTable, NButton, NSelect, NInputNumber, NSwitch,NInput } from 'naive-ui'
|
||||||
import { useEntity } from '@/hooks/entity'
|
import { useEntity } from '@/hooks/entity'
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
@ -22,6 +22,19 @@ export default defineComponent({
|
|||||||
|
|
||||||
const detectingPayloadColumns = {
|
const detectingPayloadColumns = {
|
||||||
radar: [
|
radar: [
|
||||||
|
{
|
||||||
|
title: '载荷名称',
|
||||||
|
key: 'zhName',
|
||||||
|
// width: 140,
|
||||||
|
render(row) {
|
||||||
|
return (
|
||||||
|
<NInput
|
||||||
|
v-model:value={row.zhName}
|
||||||
|
// disabled={['光学', '雷达'].includes(row.type)}
|
||||||
|
></NInput>
|
||||||
|
)
|
||||||
|
},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
title: '垂直起始角',
|
title: '垂直起始角',
|
||||||
key: 'minimumClock',
|
key: 'minimumClock',
|
||||||
|
@ -42,23 +42,64 @@ const textClick = item => {
|
|||||||
titleString: item.title,
|
titleString: item.title,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
const getIconChange=(item,type)=>{
|
||||||
|
|
||||||
|
console.log(item,'-----item',type)
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="w-h-full">
|
<div class="w-h-full">
|
||||||
<n-scrollbar>
|
<n-scrollbar>
|
||||||
<!-- <vue3-seamless-scroll :list="list" :hover="true" :step="0.2" :copyNum="3"> -->
|
<div
|
||||||
<div
|
class="cursor-pointer leading-8 hover:text-blue-400"
|
||||||
class="cursor-pointer leading-8 hover:text-blue-400"
|
v-for="(item, index) in list"
|
||||||
v-for="(item, index) in list"
|
:key="item.title"
|
||||||
:key="item.title"
|
@click="textClick(item)"
|
||||||
@click="textClick(item)"
|
>
|
||||||
>
|
<!-- 新增 flex 容器使文字和图标水平排列 -->
|
||||||
<span class="inline-block w-6">{{ index + 1 }}. </span>
|
<div class="flex items-center justify-between">
|
||||||
|
<div class="flex items-center">
|
||||||
|
<span class="inline-block w-6">{{ index + 1 }}.</span>
|
||||||
{{ item.title }}
|
{{ item.title }}
|
||||||
</div>
|
</div>
|
||||||
<!-- </vue3-seamless-scroll> -->
|
<div class="flex items-center">
|
||||||
</n-scrollbar>
|
<img
|
||||||
|
@click.stop="()=>{
|
||||||
|
getIconChange(item,'word')
|
||||||
|
}"
|
||||||
|
src="@/assets/image/icon/word.png"
|
||||||
|
class="ml-3 h-4 w-4"
|
||||||
|
alt="info icon"
|
||||||
|
/>
|
||||||
|
<img
|
||||||
|
@click.stop="()=>{
|
||||||
|
getIconChange(item,'excel')
|
||||||
|
}"
|
||||||
|
src="@/assets/image/icon/excel.png"
|
||||||
|
class="ml-3 h-4 w-4"
|
||||||
|
alt="info icon"
|
||||||
|
/>
|
||||||
|
<img
|
||||||
|
@click.stop="()=>{
|
||||||
|
getIconChange(item,'photo')
|
||||||
|
}"
|
||||||
|
src="@/assets/image/icon/photo.png"
|
||||||
|
class="ml-3 h-4 w-4"
|
||||||
|
alt="info icon"
|
||||||
|
/>
|
||||||
|
<img
|
||||||
|
@click.stop="()=>{
|
||||||
|
getIconChange(item,'zip')
|
||||||
|
}"
|
||||||
|
src="@/assets/image/icon/zip.png"
|
||||||
|
class="ml-3 h-4 w-4"
|
||||||
|
alt="info icon"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</n-scrollbar>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|