|
import { EDeviceTypeName, EHmsLevel } from '@/types/enums'
|
import cesiumOperation from '@/utils/cesium-tsa'
|
import { analyzeKmzFile, XMLToJSON } from '@/utils/cesium/kmz.js'
|
import IndexedDBService from '@/utils/indexDB'
|
import CreateFrustum from '@/utils/cesium/frustum/CreateFrustum'
|
import { useMyStore } from '@/store'
|
import { getTwoPointInfo } from '@/api/manage'
|
|
const { getEntityById, removeById, globalCesium, removeAllPoint, addLeftClickEvent, removeLeftClickEvent, flyTo } = cesiumOperation()
|
// 无人机实体
|
let droneEntity = null
|
|
// 激光实体
|
let laserEntity = null
|
|
// 两点之间线实体
|
let twoLineEntity = null
|
let myAppEntity = null;
|
export function droneFly () {
|
const store = useMyStore()
|
let deviceInfo = {} // 无人机信息
|
let dockInfo = {} // 机场信息
|
let previousPositions = []
|
let wId = ''
|
let snCode = []
|
let viewDroneInfo = {} // 获取实时经纬度
|
let waylinePoints = [] // 当前航线点
|
let currentTaskCreateTime = null // 当前飞行任务创建时间
|
let switchSaving = true // 有selectedWorkSpaceId 就为true
|
// 航线飞行处于第几个点位
|
let currentWaypointIndex = 0
|
// 速度集合
|
let droneSpeedArr = []
|
let lastTime = null
|
let viewInfoFrustum = null
|
|
// 手机设备定位
|
let me_latitude = 0;// 28.624647955787974;
|
let me_longitude = 0;//115.85635808986208;
|
let me_altitude = 0;
|
// 扫射定位
|
let measure_target_longitude = 0;//115.85635872364763;
|
let measure_target_latitude = 0;//28.624648387113627;
|
let measure_target_altitude = 0;
|
|
|
async function initDock(data:any, sn:String, dockSn:String, workspaceId:String, ssLinePath:String, viewDroneInfo:any) {
|
// 获取workspaceId
|
wId = workspaceId
|
// 给无人机参数赋值
|
deviceInfo = data.deviceInfo[`${sn}`]
|
// 机场信息
|
dockInfo = data.dockInfo[`${dockSn}`]
|
viewDroneInfo = viewDroneInfo
|
// 当前飞行任务创建时间
|
if (data.currentType === EDeviceTypeName.Aircraft && deviceInfo) {
|
const droneLngLat = {
|
latitude: deviceInfo.latitude || 0,
|
longitude: deviceInfo.longitude || 0,
|
}
|
// 当飞机模型存在
|
if (droneEntity) {
|
// 且在空中飞行时,实时更新飞机模型的位置
|
if (deviceInfo.mode_code && [3, 4, 5, 9, 10, 16, 17].includes(deviceInfo.mode_code)) {
|
if (store.currentAngle == 3) {
|
viewInfoFrustum?.clear()
|
} else {
|
// 暂时把视锥代码注释掉
|
initCreateFrustum(deviceInfo, viewDroneInfo)
|
}
|
addFlyGltf(
|
viewDroneInfo.longitude,
|
viewDroneInfo.latitude,
|
deviceInfo.height,
|
deviceInfo.payloads[0],
|
deviceInfo.attitude_head,
|
deviceInfo,
|
dockInfo,
|
ssLinePath
|
)
|
let domain = sessionStorage.getItem('domain')
|
// if (domain !== '0') {
|
// addFlyLaser(
|
// deviceInfo.payloads[0]
|
// )
|
// }
|
setelCamera(
|
viewDroneInfo.longitude,
|
viewDroneInfo.latitude,
|
deviceInfo.height,
|
deviceInfo.payloads[0],
|
deviceInfo.attitude_head,
|
)
|
} else {
|
removeById('drone_fly')
|
droneEntity = null
|
|
removeById('me_dw')
|
myAppEntity = null
|
|
lastTime = null
|
viewInfoFrustum?.clear()
|
viewInfoFrustum = null
|
|
window.cesiumViewer.camera.lookAtTransform(globalCesium.Matrix4.IDENTITY)
|
store.commit('SET_CURRENTANGLE', 1)
|
removeAllPoint()
|
}
|
} else {
|
if (deviceInfo.mode_code && [3, 4, 5, 9, 10, 17].includes(deviceInfo.mode_code)) {
|
initCreateFrustum(deviceInfo, viewDroneInfo)
|
addFlyGltf(
|
viewDroneInfo.longitude,
|
viewDroneInfo.latitude,
|
deviceInfo.height,
|
deviceInfo.payloads[0],
|
deviceInfo.attitude_head,
|
deviceInfo,
|
dockInfo,
|
ssLinePath
|
)
|
let domain = sessionStorage.getItem('domain')
|
// if (domain !== '0') {
|
// addFlyLaser(
|
// deviceInfo.payloads[0]
|
// )
|
// }
|
}
|
}
|
const imgRightBlue = new URL('@/assets/images/arrow-right-pink.png', import.meta.url).href
|
// 无人机路线轨迹,判断是否存在drone_route_remove
|
if (getEntityById('drone_route_remove')) {
|
window.cesiumViewer.entities.add({
|
name: 'drone_route_remove',
|
id: 'drone_route_remove',
|
polyline: {
|
width: 7,
|
positions: previousPositions,
|
material: new ImageTrailMaterial({
|
color: globalCesium.Color.ORANGE,
|
speed: 10,
|
image: imgRightBlue,
|
repeat: { x: 1, y: 0 },
|
}),
|
clampToGround: false,
|
},
|
})
|
}
|
|
if (data.deviceInfo[data.currentSn].mode_code && [3, 4, 5, 9, 10].includes(deviceInfo.mode_code)) {
|
if (switchSaving) return (switchSaving = false)
|
const newPositions = globalCesium.Cartesian3.fromDegrees(
|
data.deviceInfo[data.currentSn].longitude,
|
data.deviceInfo[data.currentSn].latitude,
|
Math.floor(viewDroneInfo.elevation),
|
)
|
//若刷新,恢复无人机之前的路线轨迹
|
const dataIndexedDB = await IndexedDBService.getDataById(wId)
|
if (previousPositions.length == 0 && dataIndexedDB) {
|
previousPositions = previousPositions.concat(dataIndexedDB?.temporaryflightData)
|
} else {
|
previousPositions = previousPositions.concat(newPositions)
|
}
|
// 保存无人机当前执行的路线,防止刷新数据丢失
|
if (!dataIndexedDB) {
|
await IndexedDBService.addData({
|
id: wId,
|
temporaryflightData: previousPositions,
|
})
|
} else {
|
await IndexedDBService.updateData(wId, {temporaryflightData: previousPositions})
|
}
|
// 更新线段的位置
|
const drone_route_remove = getEntityById('drone_route_remove')
|
if (!drone_route_remove) return
|
drone_route_remove.polyline.positions = previousPositions
|
drone_route_remove.polyline._material._repeat._value.x = Math.floor(previousPositions.length / 7)
|
} else if ([0, 14].includes(deviceInfo.mode_code)) {
|
previousPositions = []
|
await IndexedDBService.deleteData(wId)
|
const drone_route_remove = getEntityById('drone_route_remove')
|
if (!drone_route_remove) return
|
drone_route_remove.polyline.positions = previousPositions
|
removeById('drone_route_remove')
|
viewInfoFrustum?.clear()
|
viewInfoFrustum = null
|
}
|
}
|
if (data.currentType === EDeviceTypeName.Dock && data.dockInfo[data.currentSn]) {
|
if (!deviceInfo?.basic_osd?.longitude || !deviceInfo?.basic_osd?.latitude) return
|
if (snCode.includes(data.currentSn)) return
|
snCode.push(data.currentSn)
|
}
|
}
|
|
const imgLaser = new URL('@/assets/images/laser.png', import.meta.url).href
|
// 增加激光扫射点
|
function addFlyLaser(payloads:any) {
|
console.log('激光扫射经度',payloads.measure_target_longitude)
|
console.log('激光扫射纬度',payloads.measure_target_latitude)
|
const startPosition = globalCesium.Cartesian3.fromDegrees(
|
me_longitude, me_latitude, 0
|
)
|
const position = globalCesium.Cartesian3.fromDegrees(
|
payloads.measure_target_longitude, payloads.measure_target_latitude, payloads.measure_target_altitude
|
)
|
measure_target_longitude = payloads.measure_target_longitude;
|
measure_target_latitude = payloads.measure_target_latitude;
|
measure_target_altitude = payloads.measure_target_altitude;
|
|
if (laserEntity && laserEntity != null) {
|
laserEntity.position = new globalCesium.CallbackProperty(function () {
|
return position
|
}, false)
|
|
laserEntity.show = true
|
window.cesiumViewer.scene.requestRender()
|
} else {
|
removeById('laser_coordinate')
|
laserEntity = window.cesiumViewer.entities.add({
|
position: new globalCesium.CallbackProperty(() => {
|
return globalCesium.Cartesian3.fromDegrees(
|
payloads.measure_target_longitude,
|
payloads.measure_target_latitude,
|
payloads.measure_target_altitude
|
)
|
}, false),
|
id: 'laser_coordinate',
|
billboard: {
|
image: imgLaser,
|
width: 30,
|
height: 30,
|
scale: 1.0,
|
outlineWidth: 0,
|
}
|
})
|
}
|
// 增加激光扫射信息
|
laserEntity.label = new globalCesium.LabelGraphics({
|
text: `H:${Math.ceil(payloads.measure_target_altitude)}m-L:${Math.round(Math.ceil(payloads.measure_target_distance),)}m`,
|
font: '13px monospace',
|
fillColor: globalCesium.Color.fromCssColorString('red'), // 文字颜色
|
backgroundColor: globalCesium.Color.WHITE, // 背景颜色
|
showBackground: true,
|
horizontalOrigin: globalCesium.HorizontalOrigin.CENTER,
|
verticalOrigin: globalCesium.VerticalOrigin.BOTTOM,
|
disableDepthTestDistance: Number.POSITIVE_INFINITY,
|
pixelOffset: new globalCesium.Cartesian2(0, -20),
|
show: true,
|
})
|
console.log('起点',startPosition)
|
console.log('终点',position)
|
if (startPosition && position) {
|
if (twoLineEntity && twoLineEntity != null) {
|
// 如果线实体已存在,只更新位置
|
twoLineEntity.polyline.positions = new globalCesium.CallbackProperty(() => {
|
return [
|
globalCesium.Cartesian3.fromDegrees(me_longitude, me_latitude, 0),
|
globalCesium.Cartesian3.fromDegrees(
|
payloads.measure_target_longitude,
|
payloads.measure_target_latitude,
|
payloads.measure_target_altitude
|
)
|
]
|
}, false)
|
} else {
|
// 如果线实体不存在,创建新的线实体
|
twoLineEntity = window.cesiumViewer.entities.add({
|
polyline: {
|
positions: new globalCesium.CallbackProperty(() => {
|
return [
|
globalCesium.Cartesian3.fromDegrees(me_longitude, me_latitude, 0),
|
globalCesium.Cartesian3.fromDegrees(
|
payloads.measure_target_longitude,
|
payloads.measure_target_latitude,
|
payloads.measure_target_altitude
|
)
|
]
|
}, false),
|
width: 2,
|
material: globalCesium.Color.fromCssColorString('red'),
|
clampToGround: false,
|
},
|
})
|
}
|
}
|
}
|
|
function addFlyGltf (lng:any, lat:any, alt:any, payloads:any, attitude_head:any, deviceInfo:any, dockInfo:any, ssLinePath:any) {
|
const { gimbal_pitch, gimbal_yaw } = payloads
|
const position = globalCesium.Cartesian3.fromDegrees(
|
lng, lat, alt
|
)
|
|
const heading = globalCesium.Math.toRadians(Number(attitude_head)) //135度转弧度
|
const pitch = globalCesium.Math.toRadians(0)
|
const roll = 0
|
const hpr = new globalCesium.HeadingPitchRoll(heading, pitch, roll)
|
const orientation = globalCesium.Transforms.headingPitchRollQuaternion(
|
position,
|
hpr,
|
)
|
|
if (droneEntity && droneEntity != null) {
|
droneEntity.position = new globalCesium.CallbackProperty(function () {
|
return position
|
}, false)
|
|
droneEntity.orientation = new globalCesium.CallbackProperty(function () {
|
return orientation
|
}, false)
|
|
droneEntity.show = true
|
|
window.cesiumViewer.scene.requestRender()
|
} else {
|
droneEntity = window.cesiumViewer.entities.add({
|
show: true,
|
position,
|
id: 'drone_fly',
|
orientation: orientation,
|
model: {
|
uri: '/pilot-h5/gltf/dajiang-processed.gltf', //注意entitits.add方式加载gltf文件时,这里是uri,不是url,并且这种方式只能加载.glb格式的文件
|
scale: 1, //缩放比例
|
minimumPixelSize: 64, //最小像素大小,可以避免太小看不见
|
maximumScale: 128, //模型的最大比例尺大小。minimumPixelSize的上限
|
incrementallyLoadTextures: true, //加载模型后纹理是否可以继续流入
|
runAnimations: true, //是否启动模型中制定的gltf动画
|
clampAnimations: true, //制定gltf动画是否在没有关键帧的持续时间内保持最后一个姿势
|
shadows: globalCesium.ShadowMode.ENABLED,
|
heightReference: globalCesium.HeightReference.NONE,
|
},
|
})
|
}
|
|
// 创建无人机信息
|
// createDroneEntityLabel(droneEntity, deviceInfo, dockInfo, ssLinePath)
|
}
|
|
function setelCamera (lng, lat, alt, payloads, attitude_head) {
|
const { gimbal_pitch, gimbal_yaw } = payloads
|
let time = 0
|
|
let current = store.currentAngle
|
var heading = globalCesium.Math.toRadians(Number(gimbal_yaw || attitude_head)) // 相机左右方向
|
|
if (current == 1) {
|
lastTime = null
|
droneEntity.show = true
|
window.cesiumViewer.camera.lookAtTransform(globalCesium.Matrix4.IDENTITY)
|
} else if (current == 2) {
|
lastTime = null
|
droneEntity.show = true
|
window.cesiumViewer.camera.lookAtTransform(globalCesium.Matrix4.IDENTITY)
|
|
let center = globalCesium.Cartesian3.fromDegrees(lng, lat)
|
|
window.cesiumViewer.camera.lookAt(center, new globalCesium.Cartesian3(0.0, 0, 1500))
|
} else if (current == 3) {
|
droneEntity.show = false
|
|
let curTime = Date.now()
|
if (lastTime && lastTime != null) {
|
time = (curTime - lastTime) / 1000
|
}
|
|
window.cesiumViewer.camera.lookAtTransform(globalCesium.Matrix4.IDENTITY)
|
let center = globalCesium.Cartesian3.fromDegrees(lng, lat, alt)
|
var pitch = globalCesium.Math.toRadians(pitchAngle({ gimbal_pitch })) // 相机上下方向,负值表示向下看
|
|
window.cesiumViewer.camera.flyTo({
|
destination: center,
|
orientation: {
|
heading,
|
pitch,
|
roll: 0
|
},
|
duration: time,
|
complete () {
|
window.cesiumViewer.camera.lookAt(center, new globalCesium.HeadingPitchRange(
|
heading,
|
pitch,
|
0.01
|
))
|
}
|
})
|
|
lastTime = Date.now()
|
}
|
}
|
// pitch
|
function pitchAngle (options) {
|
const gimbal_pitch = Number(options?.gimbal_pitch) || 0
|
return gimbal_pitch
|
}
|
// 创建视锥
|
function initCreateFrustum (deviceInfo:any, test:any) {
|
// console.log('视锥传参1',deviceInfo)
|
// console.log('视锥传参2',test)
|
if (!deviceInfo || !deviceInfo.longitude || !deviceInfo.latitude || !test.longitude || !test.latitude) return
|
|
const attitude_head = 180 + deviceInfo.attitude_head
|
|
const gimbal_pitch = 90 - pitchAngle({ gimbal_pitch: deviceInfo.payloads[0].gimbal_pitch })
|
|
viewInfoFrustum?.clear()
|
viewInfoFrustum = new CreateFrustum(window.cesiumViewer, {
|
position: {
|
longitude: test.longitude,
|
latitude: test.latitude,
|
altitude: deviceInfo.height,
|
},
|
width: 30,
|
height: 30,
|
fov: 20.0,
|
near: 3.0,
|
far: 250.0,
|
roll: gimbal_pitch,
|
pitch: 0,
|
heading: attitude_head,
|
})
|
}
|
|
// 获取手机定位和激光发射定位的高度和距离
|
function getTwoHeightWidth(workspaceId:String) {
|
if (me_latitude <= 0 || me_longitude <= 0 || measure_target_latitude <= 0 || measure_target_longitude <= 0) return
|
getTwoPointInfo(workspaceId,me_latitude,me_longitude,measure_target_latitude,measure_target_longitude).then((res:any) => {
|
const heightDifference = res.data.heightDifference
|
const distance = res.data.distance
|
// 增加激光扫射信息
|
myAppEntity.label = new globalCesium.LabelGraphics({
|
text: `H:${Math.ceil(heightDifference)}m-L:${Math.round(Math.ceil(distance),)}m`,
|
font: '13px monospace',
|
fillColor: globalCesium.Color.fromCssColorString('red'), // 文字颜色
|
backgroundColor: globalCesium.Color.WHITE, // 背景颜色
|
showBackground: true,
|
horizontalOrigin: globalCesium.HorizontalOrigin.CENTER,
|
verticalOrigin: globalCesium.VerticalOrigin.BOTTOM,
|
disableDepthTestDistance: Number.POSITIVE_INFINITY,
|
pixelOffset: new globalCesium.Cartesian2(0, -24),
|
show: true,
|
})
|
})
|
}
|
|
const meMapSrc = new URL('@/assets/images/me.png', import.meta.url).href
|
// 获取手机设备定位
|
function getPhoneLocation(workspaceId:String) {
|
if (window.cesiumViewer == null) return
|
if (navigator.geolocation) {
|
// 如果实体不存在,先创建实体
|
if (!myAppEntity) {
|
myAppEntity = window.cesiumViewer.entities.add({
|
id: 'me_dw',
|
position: new globalCesium.CallbackProperty(() => {
|
return globalCesium.Cartesian3.fromDegrees(me_longitude, me_latitude, me_altitude)
|
}, false),
|
billboard: {
|
image: meMapSrc,
|
width: 30,
|
height: 30,
|
scale: 1.0,
|
outlineWidth: 0,
|
}
|
});
|
} else {
|
myAppEntity.position = new globalCesium.CallbackProperty(() => {
|
return globalCesium.Cartesian3.fromDegrees(me_longitude, me_latitude, me_altitude)
|
}, false);
|
}
|
navigator.geolocation.watchPosition((position) => {
|
if (me_longitude > 0 && me_longitude == position.coords.longitude &&
|
me_latitude > 0 && me_latitude == position.coords.latitude) return
|
|
me_longitude = position.coords.longitude;
|
me_latitude = position.coords.latitude;
|
me_altitude = position.coords.altitude || 0;
|
|
// 查看两条线直接距离和高度
|
getTwoHeightWidth(workspaceId)
|
}, (error) => {
|
console.error('定位有误:', error);
|
});
|
} else {
|
console.log('手机不支持.');
|
}
|
}
|
|
// 点击右边定自身定位
|
function clickPhoneLocation() {
|
if (myAppEntity && myAppEntity != null) {
|
// 将相机定位到设备位置 只有点击图标才可以执行这里
|
window.cesiumViewer.camera.setView({
|
destination: globalCesium.Cartesian3.fromDegrees(
|
Number(me_longitude),
|
Number(me_latitude),
|
10000.0,
|
), // 相机高度
|
});
|
}
|
}
|
|
|
return {
|
initDock,
|
getPhoneLocation,
|
clickPhoneLocation
|
}
|
}
|