import * as Cesium from 'cesium' import { appointroutePlanning } from '@/api/RoutePlanning' import { analyzeKmzFile, XMLToJSON } from '@/utils/cesium/kmz.js' import cesiumOperation from '@/utils/cesium-tsa' import { getLnglatDist, cartesian3Convert } from '@/utils/cesium/mapUtil.js' import ImageTrailMaterial from '@/utils/cesium/ImageTrailMaterial' import { getLnglatAltitude, getPositionsHeight } from '@/utils/cesium/mapUtil' import { PatchesgetInfoById } from '@/api/patternSpot' const { getEntityById, removeById, addLeftClickEvent, removeLeftClickEvent } = cesiumOperation() export default { inject: ["panelSwitchingElement"], data () { return { waylineDetails: [ { label: '航线长度', value: 0, }, { label: '预计执行时间', value: 0, }, { label: '航点', value: 0, }, { label: '照片', value: 0, }, ], workspaceId: '', pointList: [], obtainWaypointData: [], nowObtainWaypointData: [], taskBoxis: false, pointEventList: [ { label: '单拍', key: 'takePhoto', icon: require('@/assets/icons/waylinetool/camera.png'), }, { label: '开始录像', key: 'startRecord', icon: require('@/assets/icons/waylinetool/camera-on.png'), }, { label: '结束录像', key: 'stopRecord', icon: require('@/assets/icons/waylinetool/camera-off.png'), }, { label: '变焦', key: 'zoom', icon: require('@/assets/icons/waylinetool/holdertilt.png'), }, { label: '创建新文件夹', key: 'customDirName', icon: require('@/assets/icons/waylinetool/create-file.png'), }, { label: '旋转云台', key: 'gimbalRotate', icon: require('@/assets/icons/waylinetool/holderyaw.png'), }, { label: '飞行器偏航', key: 'rotateYaw', icon: require('@/assets/icons/waylinetool/droneyaw.png'), }, { label: '悬停等待', key: 'hover', icon: require('@/assets/icons/waylinetool/xt.png'), }, { label: '航段间均匀转动云台pitch角', key: 'gimbalEvenlyRotate', }, { label: '精准复拍动作', key: 'accurateShoot', }, { label: '精准复拍动作', key: 'orientedShoot', }, { label: '全景拍照动作', key: 'panoShot', icon: require('@/assets/icons/waylinetool/panoramicview.png'), }, { label: '点云录制操作', key: 'recordPointCloud', }, ], dockPosition: [], //机场坐标信息 droneCoordinates: null, lastlongitude: null, spotData: [], } }, methods: { // 读取kmz文件 async initPointWayline (route) { if (!route) return this.workspaceId = localStorage.getItem('bs_workspace_id') || this.$store.state.drone.selectedWorkSpaceId const { data: waylineUrl } = await appointroutePlanning( this.workspaceId, this.wayline?.id || route.id, ) if (waylineUrl.code !== 0) return this._showMessage.error(waylineUrl.message) const { fileInfoObj } = await analyzeKmzFile( `${waylineUrl.data}?_t=${new Date().getTime()}`, ) const xmlStr = await fileInfoObj['wpmz/template.kml'] const xmlJson = XMLToJSON(xmlStr)?.['Document'] this.pointList = xmlJson.Folder.Placemark if (!getEntityById(route.id)) { this.drawWayline(xmlJson, route) } if ( !route.patches_id || route.patches_id == 'null' || route.patches_id == '' ) return this.obtainSpotInfo(xmlJson) this.spottedSurfaceGet(route) }, // 绘制航线到地图上 async drawWayline (xmlJson, route) { const points = xmlJson?.['Folder']?.['Placemark'] //每个点数据 let waylinePosition = [] this.obtainWaypointData = [] let SpecialPointsd = false getPositionsHeight(points, global.$viewer).then((res) => { waylinePosition = res.map((item) => { return Cesium.Cartesian3.fromDegrees( Number(item.longitude), Number(item.latitude), item.FinalHeight, ) }) res.forEach((item, index) => { let setting = {} if (index === 0) { let firstPoint = cartesian3Convert( waylinePosition[index], global.$viewer, ) let dornePoint = cartesian3Convert( this.droneCoordinates, global.$viewer, ) let getLongOk = getLnglatDist( firstPoint.longitude, firstPoint.latitude, dornePoint.longitude, dornePoint.latitude, ) if (getLongOk < 20) { setting = { id: 'route_point_' + index, position: waylinePosition[index], billboard: { image: require('@/assets/images/Startingpointicon.png'), pixelOffset: new Cesium.Cartesian2(0, -13), outlineWidth: 0, width: 30, height: 30, scale: 1.0, }, } } else { setting = { id: 'route_point_' + index, position: waylinePosition[index], billboard: { image: this.createBillboard(`${index + 1}`, '#FFBA00FF'), pixelOffset: new Cesium.Cartesian2(0, -13), outlineWidth: 0, }, } SpecialPointsd = true } } else if (index === points.length - 1) { setting = { id: 'route_point_' + index, position: waylinePosition[index], billboard: { image: require('@/assets/images/EndPointicon.png'), pixelOffset: new Cesium.Cartesian2(0, -13), outlineWidth: 0, width: 30, height: 30, scale: 1.0, }, } } else { setting = { id: 'route_point_' + index, position: waylinePosition[index], billboard: { image: this.createBillboard( `${SpecialPointsd ? index + 1 : index}`, '#FFBA00FF', ), pixelOffset: new Cesium.Cartesian2(0, -13), outlineWidth: 0, }, } } global.$viewer.entities.add(setting) this.addClickevents('route_point_' + index, waylinePosition[index]) if (item?.['actionGroup']) { this.obtainWaypointInfo(item?.['actionGroup']?.['action'], index) } }) waylinePosition.unshift(this.droneCoordinates) //没有起点坐标时,在机场和第一个点增加一个中间转折点作为起点 if (SpecialPointsd) { let cartesian = this.addTurnPoint( waylinePosition[0], waylinePosition[1], ) waylinePosition.splice(1, 0, cartesian) if (getEntityById('route_detailSpecialPointsd')) { removeById('route_detailSpecialPointsd') } global.$viewer.entities.add({ position: cartesian, id: 'route_detailSpecialPointsd', billboard: { image: require('@/assets/images/Startingpointicon.png'), width: 30, height: 30, pixelOffset: new Cesium.Cartesian2(0, -20), }, }) } global.$viewer.entities.add({ id: 'route_wayline_line', polyline: { positions: waylinePosition, width: 5, material: new ImageTrailMaterial({ color: Cesium.Color.WHITE, speed: 10, image: require('@/assets/images/arrow-right-blue.png'), repeat: { x: waylinePosition.length, y: 0 }, }), zIndex: 1, clampToGround: this.clampToGroundshow, }, }) this.$store.commit('SET_WAYLINE_POINTS', { type: 'point', data: waylinePosition, }) this.flyToRouterShow(waylinePosition) }) }, // 在机场和第一个点直接增加一个中间转折点 addTurnPoint (firstPoint, SecondPoint) { const dronePosition = cartesian3Convert(firstPoint, global.$viewer) const firstPosition = cartesian3Convert(SecondPoint, global.$viewer) return new Cesium.Cartesian3.fromDegrees( dronePosition?.longitude, dronePosition?.latitude, firstPosition?.height, ) }, // 增加鼠标监听事件,点击展示事件 addClickevents (tragetPointint_id, currentPositionxyz) { addLeftClickEvent(tragetPointint_id, startPointEvent) const _this = this //鼠标点击展示详情 function startPointEvent (click, pick, viewer) { // 当前点击项获取数据 let id = pick?.id?._id.split('_')[2] let getNowData = _this.obtainWaypointData.find( (obj) => obj.subIndex == id, ) if (getNowData) { _this.nowObtainWaypointData = getNowData.label } // 展示详情 _this.taskBoxis = true viewer.container.appendChild(_this.$refs.taskBox) viewer.scene.postRender.addEventListener(() => { let windowCoord = Cesium.SceneTransforms.wgs84ToWindowCoordinates( global.$viewer.scene, currentPositionxyz, ) if (!_this.$refs.taskBox) return const x = windowCoord.x + 25 const y = windowCoord.y - _this.$refs.taskBox.offsetHeight / 2 - 15 _this.$refs.taskBox.style.transform = `translate3d(${Math.round( x, )}px,${Math.round(y)}px,${Math.round(40)}px )` }) } }, // 创建广告牌 createBillboard (title, color) { const billboard = document.createElement('canvas') const ctx = billboard.getContext('2d') ctx.beginPath() ctx.ellipse(150, 90, 11, 11, 0, 0, Math.PI * 2) ctx.fillStyle = color ctx.fill() ctx.font = 'bold 15px serif' ctx.textAlign = 'center' ctx.fillStyle = '#ffffff' ctx.fillText(title, 150, 95) ctx.closePath() return billboard }, // 添加图斑面 spottedSurfaceGet (wayline) { this.spotData = wayline.patches_id.split(',') this.spotData.forEach((item, index) => { PatchesgetInfoById({ patchesId: item }).then((polygonRes) => { if (polygonRes.data.data === '') return const dkfw = polygonRes.data.data.dkfw const numbersWithCommas = dkfw.match(/\d+(\.\d+)?/g) const grouped = numbersWithCommas.map((item) => Number(item)) if (getEntityById('task_polygon_dk_wayline' + index)) { removeById('task_polygon_dk_wayline' + index) } global.$viewer.entities.add({ id: 'task_polygon_dk_wayline' + index, polyline: { positions: Cesium.Cartesian3.fromDegreesArray(grouped), width: 1, material: Cesium.Color.RED, zIndex: 0, clampToGround: true, }, }) }) }) }, // 所有点事件 obtainWaypointInfo (obtainlist, index) { if (Array.isArray(obtainlist)) { let eventData = [] obtainlist.forEach((item) => { let eventName = item?.['actionActuatorFunc']?.['#text'] eventData.push(this.findValueByLabel(eventName)) }) this.obtainWaypointData.push({ label: eventData, subIndex: index, }) } else { let eventName = obtainlist?.['actionActuatorFunc']?.['#text'] this.obtainWaypointData.push({ label: [this.findValueByLabel(eventName)], subIndex: index, }) } }, // 获取图斑块与拍摄的图片信息 obtainSpotInfo (xmlJson) { let mergedArray = [] this.panelSwitchingElement.updateObtainSpotData([]) const points = xmlJson?.['Folder']?.['Placemark'].slice(1) for (let [i, entity] of points.entries()) { if (entity?.['actionGroup']) { // 点位信息 let PointPosition = entity?.['Point']?.['coordinates']?.['#text'].split(',') // 当前所在图斑 let takePhotoName = '' // 只有一个事件 if (!entity?.['actionGroup']?.['action'].length) { let takePhotoHas = entity?.['actionGroup']?.['action']?.['actionActuatorFunc']?.[ '#text' ] if (takePhotoHas === 'takePhoto') { takePhotoName = this.getSpotName( entity?.['actionGroup']?.['action'], ) const takePhotoData = { PointPosition: [ Number(PointPosition[0]), Number(PointPosition[1]), ], takePhotoName: takePhotoName, } mergedArray.push(takePhotoData) } } // 存在多个事件 else { entity?.['actionGroup']?.['action'].forEach((item, index) => { if (item?.['actionActuatorFunc']?.['#text'] === 'takePhoto') { takePhotoName = this.getSpotName(item) const takePhotoData = { PointPosition: [ Number(PointPosition[0]), Number(PointPosition[1]), ], takePhotoName: takePhotoName, } mergedArray.push(takePhotoData) } }) } } } this.panelSwitchingElement.updateObtainSpotData(Array.from( mergedArray .reduce((map, obj) => { let takePhotoName = obj.takePhotoName if (!map.has(takePhotoName)) { map.set(takePhotoName, []) } map.get(takePhotoName).push(obj) return map }, new Map()) .values(), )) }, // 获取图斑名称 getSpotName (str) { let strIn = str?.['actionActuatorFuncParam']?.['fileSuffix']?.['#text'] let startIndex = strIn.indexOf('航点') + '航点'.length let endIndex = strIn.indexOf('~') return strIn.substring(startIndex, endIndex) }, // 根据key获取label findValueByLabel (keyToFind) { return this.pointEventList.find((obj) => obj.key === keyToFind) }, // 取消详细信息展示 cancleTaskBoxis () { this.taskBoxis = false this.nowObtainWaypointData = [] }, }, mounted () { }, destroyed () { removeLeftClickEvent() let taskBox = document.getElementById('taskBox') if (!taskBox) return taskBox.remove() }, }