| | |
| | | import _ from 'lodash'; |
| | | import JSZIP from 'jszip'; |
| | | import { JSONToXML } from './kmz'; |
| | | import { getDateFromTimestamp } from '@/utils/date'; |
| | | import _ from 'lodash' |
| | | import JSZIP from 'jszip' |
| | | import { JSONToXML } from './kmz' |
| | | import { getDateFromTimestamp } from '@/utils/date' |
| | | |
| | | export default function kmzFile() { |
| | | // 云台信息 |
| | | const droneModel = { |
| | | 52: '0', |
| | | 53: '1', |
| | | 66: '0', |
| | | 67: '1', |
| | | 80: '0', |
| | | 81: '1', |
| | | }; |
| | | // 创建图斑航线 |
| | | const create = async (waylineBasicInfo, lnglats, spotList) => { |
| | | try { |
| | | const date = new Date(); |
| | | const username = window.localStorage.getItem('bs_username'); |
| | | const updateTime = date.getTime(); |
| | | const fileName = '图斑航线规划_' + date.getTime(); |
| | | // 无人机机型、云台型号、航线高度 |
| | | const { droneEnumValue, payloadEnumValue, height } = waylineBasicInfo; |
| | | const defaultHeight = height || 100; |
| | | // 起始点位 (参考点位-具体以机场为准) |
| | | const startPoint = lnglats[0]; |
| | | const takeOffPoint = [startPoint[1], startPoint[0], 0].join(','); |
| | | // template.xml对象模版 |
| | | const fileTemplate = { |
| | | author: { '#text': username }, |
| | | createTime: { '#text': updateTime }, |
| | | updateTime: { '#text': updateTime }, |
| | | missionConfig: { |
| | | // 飞向首航点模式 |
| | | flyToWaylineMode: { '#text': 'safely' }, |
| | | // 航线结束动作 |
| | | finishAction: { '#text': 'goHome' }, |
| | | // 失控是否继续执行航线 |
| | | exitOnRCLost: { '#text': 'goContinue' }, |
| | | // 失控动作类型 |
| | | executeRCLostAction: { '#text': 'goBack' }, |
| | | // 安全起飞高度 |
| | | takeOffSecurityHeight: { '#text': 20 }, |
| | | // 参考起飞点 |
| | | takeOffRefPoint: { '#text': takeOffPoint }, |
| | | // 参考起飞点海拔高度 |
| | | takeOffRefPointAGLHeight: { '#text': 0 }, |
| | | // 全局航线过渡速度 |
| | | globalTransitionalSpeed: { '#text': 10 }, |
| | | // 全局返航高度 |
| | | globalRTHHeight: { '#text': defaultHeight }, |
| | | // 无人机参数 |
| | | droneInfo: { |
| | | droneEnumValue: { '#text': droneEnumValue }, |
| | | droneSubEnumValue: { |
| | | '#text': droneModel[payloadEnumValue], |
| | | }, |
| | | }, |
| | | // 云台参数 |
| | | payloadInfo: { |
| | | payloadEnumValue: { '#text': payloadEnumValue }, |
| | | payloadSubEnumValue: { |
| | | '#text': droneModel[payloadEnumValue], |
| | | }, |
| | | payloadPositionIndex: { '#text': 0 }, |
| | | }, |
| | | }, |
| | | Folder: { |
| | | // 预定义模板类型 - 航点飞行 |
| | | templateType: { '#text': 'waypoint' }, |
| | | // 是否使用全局航线过渡速度 |
| | | useGlobalTransitionalSpeed: { '#text': 0 }, |
| | | templateId: { '#text': 0 }, |
| | | // 坐标系参数信息 |
| | | waylineCoordinateSysParam: { |
| | | // 经纬度坐标系 - 固定值 |
| | | coordinateMode: { '#text': 'WGS84' }, |
| | | // 航点高程参考平面 - 相对高度 |
| | | heightMode: { '#text': 'relativeToStartPoint' }, |
| | | }, |
| | | // 全局航线飞行速度 |
| | | autoFlightSpeed: { '#text': 10 }, |
| | | // 云台俯仰角控制模式 |
| | | gimbalPitchMode: { '#text': 'usePointSetting' }, |
| | | // 全局高度 |
| | | globalHeight: { '#text': '100' }, |
| | | // 全局偏航角模式参数 - 可使用当前默认值 |
| | | globalWaypointHeadingParam: { |
| | | waypointHeadingMode: { '#text': 'followWayline' }, |
| | | waypointHeadingAngle: { '#text': 0 }, |
| | | waypointPoiPoint: { |
| | | '#text': '0.000000,0.000000,0.000000', |
| | | }, |
| | | waypointHeadingPathMode: { '#text': 'followBadArc' }, |
| | | waypointHeadingPoiIndex: { '#text': 0 }, |
| | | }, |
| | | // 全局航点类型 - 直线飞行,飞行器到点停 |
| | | globalWaypointTurnMode: { |
| | | '#text': 'toPointAndStopWithDiscontinuityCurvature', |
| | | }, |
| | | // 全局航段轨迹是否尽量贴合直线 |
| | | globalUseStraightLine: { '#text': 1 }, |
| | | // 航点点位信息 - 位置、事件等 |
| | | Placemark: [], |
| | | // payloadParam: { |
| | | // payloadPositionIndex: { '#text': 0 }, |
| | | // focusMode: { '#text': 'firstPoint' }, |
| | | // meteringMode: { '#text': 'average' }, |
| | | // returnMode: { '#text': 'singleReturnFirst' }, |
| | | // samplingRate: { '#text': '240000' }, |
| | | // scanningMode: { '#text': 'repetitive' }, |
| | | // imageFormat: { '#text': 'wide,zoom' }, |
| | | // }, |
| | | }, |
| | | }; |
| | | // 航点创建 |
| | | const polygonNo = { |
| | | no: '', |
| | | index: 0, |
| | | }; |
| | | lnglats.forEach((lnglat, index) => { |
| | | const obj = spotList.find((spot) => |
| | | spot.dkfw.find((item) => _.isEqual(item, lnglat)), |
| | | ); |
| | | let fileSuffix = ''; |
| | | if (obj) { |
| | | if (polygonNo.no === obj.dkbh) { |
| | | polygonNo.index++; |
| | | } else { |
| | | polygonNo.no = obj.dkbh; |
| | | polygonNo.index = 1; |
| | | } |
| | | fileSuffix = `图斑航线拍摄(${obj.dkbh}-${polygonNo.index})`; |
| | | } else { |
| | | fileSuffix = '图斑航线拍摄(起点)'; |
| | | } |
| | | const placemark = { |
| | | Point: { |
| | | // 航点经纬度 |
| | | coordinates: { '#text': `${lnglat[0]},${lnglat[1]}` }, |
| | | }, |
| | | // 航点index |
| | | index: { '#text': index }, |
| | | // 全局航线高度(椭球高) |
| | | ellipsoidHeight: { '#text': defaultHeight }, |
| | | // 全局航线高度 (EGM96海拔高/相对起飞点高度/AGL相对地面高度) |
| | | height: { '#text': defaultHeight }, |
| | | // 航点飞行速度 |
| | | waypointSpeed: { '#text': 10 }, |
| | | // 沿航线方向 - 可使用当前默认值 |
| | | waypointHeadingParam: { |
| | | waypointHeadingMode: { '#text': 'followWayline' }, |
| | | waypointHeadingAngle: { '#text': 0 }, |
| | | waypointPoiPoint: { |
| | | '#text': '0.000000,0.000000,0.000000', |
| | | }, |
| | | waypointHeadingPathMode: { '#text': 'followBadArc' }, |
| | | waypointHeadingPoiIndex: { '#text': 0 }, |
| | | }, |
| | | // 航点类型 |
| | | waypointTurnParam: { |
| | | waypointTurnMode: { |
| | | '#text': 'toPointAndStopWithDiscontinuityCurvature', |
| | | }, |
| | | waypointTurnDampingDist: { '#text': 0.2 }, |
| | | }, |
| | | // 是否全局参数 |
| | | useGlobalHeight: { '#text': 1 }, |
| | | useGlobalSpeed: { '#text': 1 }, |
| | | useGlobalHeadingParam: { '#text': 1 }, |
| | | useGlobalTurnParam: { '#text': 1 }, |
| | | useStraightLine: { '#text': 1 }, |
| | | // 事件组 |
| | | actionGroup: { |
| | | actionGroupId: { '#text': index }, |
| | | actionGroupStartIndex: { '#text': index }, |
| | | actionGroupEndIndex: { '#text': index }, |
| | | actionGroupMode: { '#text': 'sequence' }, |
| | | actionTrigger: { |
| | | actionTriggerType: { '#text': 'reachPoint' }, |
| | | }, |
| | | // 单个事件 - 如果是多个事件action可改成数组 action: [{}] |
| | | action: { |
| | | actionId: { '#text': 0 }, |
| | | actionActuatorFunc: { '#text': 'takePhoto' }, |
| | | actionActuatorFuncParam: { |
| | | fileSuffix: { '#text': fileSuffix }, |
| | | payloadPositionIndex: { '#text': '0' }, |
| | | useGlobalPayloadLensIndex: { '#text': '1' }, |
| | | }, |
| | | }, |
| | | }, |
| | | }; |
| | | fileTemplate.Folder.Placemark.push(placemark); |
| | | }); |
| | | const fileWaylines = waylinesContext(fileTemplate); |
| | | // 云台信息 |
| | | const droneModel = { |
| | | 52: '0', |
| | | 53: '1', |
| | | 66: '0', |
| | | 67: '1', |
| | | 80: '0', |
| | | 81: '1', |
| | | } |
| | | // 创建图斑航线 |
| | | const create = async (waylineBasicInfo, lnglats, spotList) => { |
| | | try { |
| | | const date = new Date() |
| | | const username = window.localStorage.getItem('bs_username') |
| | | const updateTime = date.getTime() |
| | | const fileName = '图斑航线规划_' + date.getTime() |
| | | // 无人机机型、云台型号、航线高度 |
| | | const { droneEnumValue, payloadEnumValue, height } = waylineBasicInfo |
| | | const defaultHeight = height || 100 |
| | | // 起始点位 (参考点位-具体以机场为准) |
| | | const startPoint = lnglats[0] |
| | | const takeOffPoint = [startPoint[1], startPoint[0], 0].join(',') |
| | | // template.xml对象模版 |
| | | const fileTemplate = { |
| | | author: { '#text': username }, |
| | | createTime: { '#text': updateTime }, |
| | | updateTime: { '#text': updateTime }, |
| | | missionConfig: { |
| | | // 飞向首航点模式 |
| | | flyToWaylineMode: { '#text': 'safely' }, |
| | | // 航线结束动作 |
| | | finishAction: { '#text': 'goHome' }, |
| | | // 失控是否继续执行航线 |
| | | exitOnRCLost: { '#text': 'goContinue' }, |
| | | // 失控动作类型 |
| | | executeRCLostAction: { '#text': 'goBack' }, |
| | | // 安全起飞高度 |
| | | takeOffSecurityHeight: { '#text': 20 }, |
| | | // 参考起飞点 |
| | | takeOffRefPoint: { '#text': takeOffPoint }, |
| | | // 参考起飞点海拔高度 |
| | | takeOffRefPointAGLHeight: { '#text': 0 }, |
| | | // 全局航线过渡速度 |
| | | globalTransitionalSpeed: { '#text': 10 }, |
| | | // 全局返航高度 |
| | | globalRTHHeight: { '#text': defaultHeight }, |
| | | // 无人机参数 |
| | | droneInfo: { |
| | | droneEnumValue: { '#text': droneEnumValue }, |
| | | droneSubEnumValue: { |
| | | '#text': droneModel[payloadEnumValue], |
| | | }, |
| | | }, |
| | | // 云台参数 |
| | | payloadInfo: { |
| | | payloadEnumValue: { '#text': payloadEnumValue }, |
| | | payloadSubEnumValue: { |
| | | '#text': droneModel[payloadEnumValue], |
| | | }, |
| | | payloadPositionIndex: { '#text': 0 }, |
| | | }, |
| | | }, |
| | | Folder: { |
| | | // 预定义模板类型 - 航点飞行 |
| | | templateType: { '#text': 'waypoint' }, |
| | | // 是否使用全局航线过渡速度 |
| | | useGlobalTransitionalSpeed: { '#text': 0 }, |
| | | templateId: { '#text': 0 }, |
| | | // 坐标系参数信息 |
| | | waylineCoordinateSysParam: { |
| | | // 经纬度坐标系 - 固定值 |
| | | coordinateMode: { '#text': 'WGS84' }, |
| | | // 航点高程参考平面 - 相对高度 |
| | | heightMode: { '#text': 'relativeToStartPoint' }, |
| | | }, |
| | | // 全局航线飞行速度 |
| | | autoFlightSpeed: { '#text': 10 }, |
| | | // 云台俯仰角控制模式 |
| | | gimbalPitchMode: { '#text': 'usePointSetting' }, |
| | | // 全局高度 |
| | | globalHeight: { '#text': '100' }, |
| | | // 全局偏航角模式参数 - 可使用当前默认值 |
| | | globalWaypointHeadingParam: { |
| | | waypointHeadingMode: { '#text': 'followWayline' }, |
| | | waypointHeadingAngle: { '#text': 0 }, |
| | | waypointPoiPoint: { |
| | | '#text': '0.000000,0.000000,0.000000', |
| | | }, |
| | | waypointHeadingPathMode: { '#text': 'followBadArc' }, |
| | | waypointHeadingPoiIndex: { '#text': 0 }, |
| | | }, |
| | | // 全局航点类型 - 直线飞行,飞行器到点停 |
| | | globalWaypointTurnMode: { |
| | | '#text': 'toPointAndStopWithDiscontinuityCurvature', |
| | | }, |
| | | // 全局航段轨迹是否尽量贴合直线 |
| | | globalUseStraightLine: { '#text': 1 }, |
| | | // 航点点位信息 - 位置、事件等 |
| | | Placemark: [], |
| | | // payloadParam: { |
| | | // payloadPositionIndex: { '#text': 0 }, |
| | | // focusMode: { '#text': 'firstPoint' }, |
| | | // meteringMode: { '#text': 'average' }, |
| | | // returnMode: { '#text': 'singleReturnFirst' }, |
| | | // samplingRate: { '#text': '240000' }, |
| | | // scanningMode: { '#text': 'repetitive' }, |
| | | // imageFormat: { '#text': 'wide,zoom' }, |
| | | // }, |
| | | }, |
| | | } |
| | | // 航点创建 |
| | | const polygonNo = { |
| | | no: '', |
| | | index: 0, |
| | | } |
| | | lnglats.forEach((lnglat, index) => { |
| | | const obj = spotList.find(spot => spot.dkfw.find(item => _.isEqual(item, lnglat))) |
| | | let fileSuffix = '' |
| | | if (obj) { |
| | | if (polygonNo.no === obj.dkbh) { |
| | | polygonNo.index++ |
| | | } else { |
| | | polygonNo.no = obj.dkbh |
| | | polygonNo.index = 1 |
| | | } |
| | | fileSuffix = `图斑航线拍摄(${obj.dkbh}-${polygonNo.index})` |
| | | } else { |
| | | fileSuffix = '图斑航线拍摄(起点)' |
| | | } |
| | | const placemark = { |
| | | Point: { |
| | | // 航点经纬度 |
| | | coordinates: { '#text': `${lnglat[0]},${lnglat[1]}` }, |
| | | }, |
| | | // 航点index |
| | | index: { '#text': index }, |
| | | // 全局航线高度(椭球高) |
| | | ellipsoidHeight: { '#text': defaultHeight }, |
| | | // 全局航线高度 (EGM96海拔高/相对起飞点高度/AGL相对地面高度) |
| | | height: { '#text': defaultHeight }, |
| | | // 航点飞行速度 |
| | | waypointSpeed: { '#text': 10 }, |
| | | // 沿航线方向 - 可使用当前默认值 |
| | | waypointHeadingParam: { |
| | | waypointHeadingMode: { '#text': 'followWayline' }, |
| | | waypointHeadingAngle: { '#text': 0 }, |
| | | waypointPoiPoint: { |
| | | '#text': '0.000000,0.000000,0.000000', |
| | | }, |
| | | waypointHeadingPathMode: { '#text': 'followBadArc' }, |
| | | waypointHeadingPoiIndex: { '#text': 0 }, |
| | | }, |
| | | // 航点类型 |
| | | waypointTurnParam: { |
| | | waypointTurnMode: { |
| | | '#text': 'toPointAndStopWithDiscontinuityCurvature', |
| | | }, |
| | | waypointTurnDampingDist: { '#text': 0.2 }, |
| | | }, |
| | | // 是否全局参数 |
| | | useGlobalHeight: { '#text': 1 }, |
| | | useGlobalSpeed: { '#text': 1 }, |
| | | useGlobalHeadingParam: { '#text': 1 }, |
| | | useGlobalTurnParam: { '#text': 1 }, |
| | | useStraightLine: { '#text': 1 }, |
| | | // 事件组 |
| | | actionGroup: { |
| | | actionGroupId: { '#text': index }, |
| | | actionGroupStartIndex: { '#text': index }, |
| | | actionGroupEndIndex: { '#text': index }, |
| | | actionGroupMode: { '#text': 'sequence' }, |
| | | actionTrigger: { |
| | | actionTriggerType: { '#text': 'reachPoint' }, |
| | | }, |
| | | // 单个事件 - 如果是多个事件action可改成数组 action: [{}] |
| | | action: { |
| | | actionId: { '#text': 0 }, |
| | | actionActuatorFunc: { '#text': 'takePhoto' }, |
| | | actionActuatorFuncParam: { |
| | | fileSuffix: { '#text': fileSuffix }, |
| | | payloadPositionIndex: { '#text': '0' }, |
| | | useGlobalPayloadLensIndex: { '#text': '1' }, |
| | | }, |
| | | }, |
| | | }, |
| | | } |
| | | fileTemplate.Folder.Placemark.push(placemark) |
| | | }) |
| | | const fileWaylines = waylinesContext(fileTemplate) |
| | | |
| | | return { |
| | | fileName, |
| | | template: fileTemplate, |
| | | waylines: fileWaylines, |
| | | }; |
| | | } catch (error) { |
| | | console.log(error); |
| | | return false; |
| | | } |
| | | }; |
| | | return { |
| | | fileName, |
| | | template: fileTemplate, |
| | | waylines: fileWaylines, |
| | | } |
| | | } catch (error) { |
| | | console.log(error) |
| | | return false |
| | | } |
| | | } |
| | | |
| | | // 创建正常航线 |
| | | const createNoramlWaylines = (waylineBasicInfo, lnglats) => { |
| | | try { |
| | | const date = new Date(); |
| | | const username = window.localStorage.getItem('bs_username'); |
| | | const updateTime = date.getTime(); |
| | | const { year, month, day, hours, minutes } = |
| | | getDateFromTimestamp(updateTime); |
| | | const fileName = '新建航线_' + year + month + day + hours + minutes; |
| | | // 无人机机型、云台型号、航线高度 |
| | | const { droneEnumValue, payloadEnumValue, height, waylineName } = |
| | | waylineBasicInfo; |
| | | const defaultHeight = height || 100; |
| | | // 起始点位 (参考点位-具体以机场为准) |
| | | const startPoint = lnglats[0]; |
| | | const takeOffPoint = [startPoint.latitude, startPoint.longitude, 0].join( |
| | | ',', |
| | | ); |
| | | // template.xml对象模版 |
| | | const fileTemplate = { |
| | | author: { '#text': username }, |
| | | createTime: { '#text': updateTime }, |
| | | updateTime: { '#text': updateTime }, |
| | | missionConfig: { |
| | | // 飞向首航点模式 |
| | | flyToWaylineMode: { '#text': 'safely' }, |
| | | // 航线结束动作 |
| | | finishAction: { '#text': 'goHome' }, |
| | | // 失控是否继续执行航线 |
| | | exitOnRCLost: { '#text': 'goContinue' }, |
| | | // 失控动作类型 |
| | | executeRCLostAction: { '#text': 'goBack' }, |
| | | // 安全起飞高度 |
| | | takeOffSecurityHeight: { '#text': 20 }, |
| | | // 参考起飞点 |
| | | takeOffRefPoint: { '#text': takeOffPoint }, |
| | | // 参考起飞点海拔高度 |
| | | takeOffRefPointAGLHeight: { '#text': 0 }, |
| | | // 全局航线过渡速度 |
| | | globalTransitionalSpeed: { '#text': 10 }, |
| | | // 全局返航高度 |
| | | globalRTHHeight: { '#text': defaultHeight }, |
| | | // 无人机参数 |
| | | droneInfo: { |
| | | droneEnumValue: { '#text': droneEnumValue }, |
| | | droneSubEnumValue: { |
| | | '#text': droneModel[payloadEnumValue], |
| | | }, |
| | | }, |
| | | // 是否自动绕行(暂未验证M30T机型使用此参数后会不会无法起飞) |
| | | autoRerouteInfo: { |
| | | missionAutoRerouteMode: { '#text': 1 }, |
| | | transitionalAutoRerouteMode: { '#text': 1 }, |
| | | }, |
| | | // 云台参数 |
| | | payloadInfo: { |
| | | payloadEnumValue: { '#text': payloadEnumValue }, |
| | | payloadSubEnumValue: { |
| | | '#text': droneModel[payloadEnumValue], |
| | | }, |
| | | payloadPositionIndex: { '#text': 0 }, |
| | | }, |
| | | }, |
| | | Folder: { |
| | | // 预定义模板类型 - 航点飞行 |
| | | templateType: { '#text': 'waypoint' }, |
| | | // 是否使用全局航线过渡速度 |
| | | useGlobalTransitionalSpeed: { '#text': 0 }, |
| | | templateId: { '#text': 0 }, |
| | | // 坐标系参数信息 |
| | | waylineCoordinateSysParam: { |
| | | // 经纬度坐标系 - 固定值 |
| | | coordinateMode: { '#text': 'WGS84' }, |
| | | // 航点高程参考平面 - 相对高度 |
| | | heightMode: { '#text': 'relativeToStartPoint' }, |
| | | }, |
| | | // 全局航线飞行速度 |
| | | autoFlightSpeed: { '#text': 10 }, |
| | | // 云台俯仰角控制模式 |
| | | gimbalPitchMode: { '#text': 'usePointSetting' }, |
| | | // 全局高度 |
| | | globalHeight: { '#text': '100' }, |
| | | // 全局偏航角模式参数 - 可使用当前默认值 |
| | | globalWaypointHeadingParam: { |
| | | waypointHeadingMode: { '#text': 'followWayline' }, |
| | | waypointHeadingAngle: { '#text': 0 }, |
| | | waypointPoiPoint: { |
| | | '#text': '0.000000,0.000000,0.000000', |
| | | }, |
| | | waypointHeadingPathMode: { '#text': 'followBadArc' }, |
| | | waypointHeadingPoiIndex: { '#text': 0 }, |
| | | }, |
| | | // 全局航点类型 - 直线飞行,飞行器到点停 |
| | | globalWaypointTurnMode: { |
| | | '#text': 'toPointAndStopWithDiscontinuityCurvature', |
| | | }, |
| | | // 全局航段轨迹是否尽量贴合直线 |
| | | globalUseStraightLine: { '#text': 1 }, |
| | | // 航点点位信息 - 位置、事件等 |
| | | Placemark: [], |
| | | payloadParam: { |
| | | payloadPositionIndex: { '#text': 0 }, |
| | | focusMode: { '#text': 'firstPoint' }, |
| | | meteringMode: { '#text': 'average' }, |
| | | returnMode: { '#text': 'singleReturnFirst' }, |
| | | samplingRate: { '#text': '240000' }, |
| | | scanningMode: { '#text': 'repetitive' }, |
| | | imageFormat: { '#text': 'wide,zoom' }, |
| | | }, |
| | | }, |
| | | }; |
| | | lnglats.forEach((lnglat, index) => { |
| | | const placemark = { |
| | | Point: { |
| | | // 航点经纬度 |
| | | coordinates: { |
| | | '#text': `${lnglat.longitude},${lnglat.latitude}`, |
| | | }, |
| | | }, |
| | | // 航点index |
| | | index: { '#text': index }, |
| | | // 全局航线高度(椭球高) |
| | | ellipsoidHeight: { '#text': lnglat.height }, |
| | | // 全局航线高度 (EGM96海拔高/相对起飞点高度/AGL相对地面高度) |
| | | height: { '#text': lnglat.height }, |
| | | // 航点飞行速度 |
| | | waypointSpeed: { '#text': lnglat?.speed || 10 }, |
| | | // 沿航线方向 - 可使用当前默认值 |
| | | waypointHeadingParam: { |
| | | waypointHeadingMode: { '#text': 'followWayline' }, |
| | | waypointHeadingAngle: { '#text': 0 }, |
| | | waypointPoiPoint: { |
| | | '#text': '0.000000,0.000000,0.000000', |
| | | }, |
| | | waypointHeadingPathMode: { '#text': 'followBadArc' }, |
| | | waypointHeadingPoiIndex: { '#text': 0 }, |
| | | }, |
| | | // 航点类型 |
| | | waypointTurnParam: { |
| | | waypointTurnMode: { |
| | | '#text': 'toPointAndStopWithDiscontinuityCurvature', |
| | | }, |
| | | waypointTurnDampingDist: { '#text': 0.2 }, |
| | | }, |
| | | // 是否全局参数 |
| | | useGlobalHeight: { '#text': 1 }, |
| | | useGlobalSpeed: { '#text': 0 }, |
| | | useGlobalHeadingParam: { '#text': 1 }, |
| | | useGlobalTurnParam: { '#text': 1 }, |
| | | useStraightLine: { '#text': 1 }, |
| | | }; |
| | | if (lnglat?.actions) { |
| | | const actionGroup = { |
| | | actionGroupId: { '#text': index }, |
| | | actionGroupStartIndex: { '#text': index }, |
| | | actionGroupEndIndex: { '#text': index }, |
| | | actionGroupMode: { '#text': 'sequence' }, |
| | | actionTrigger: { |
| | | actionTriggerType: { '#text': 'reachPoint' }, |
| | | }, |
| | | // 单个事件 - 如果是多个事件action可改成数组 action: [{}] |
| | | // action: [{ |
| | | // actionId: { '#text': 0 }, |
| | | // actionActuatorFunc: { '#text': '' }, |
| | | // actionActuatorFuncParam: {}, |
| | | // }], |
| | | action: [], |
| | | }; |
| | | lnglat?.actions.forEach((action, index) => { |
| | | const singleAction = { |
| | | actionId: { '#text': index }, |
| | | actionActuatorFunc: { '#text': '' }, |
| | | actionActuatorFuncParam: {}, |
| | | }; |
| | | // actionGroup.action['actionActuatorFunc'] = { '#text': action.key } |
| | | // action.params.forEach(p => { |
| | | // if (p.value || p.value !== '') { |
| | | // actionGroup.action['actionActuatorFuncParam'][p.key] = { '#text': p.value } |
| | | // } |
| | | // }) |
| | | singleAction['actionActuatorFunc'] = { |
| | | '#text': action.key, |
| | | }; |
| | | action.params.forEach((p) => { |
| | | if (p.value || p.value !== '') { |
| | | singleAction['actionActuatorFuncParam'][p.key] = { |
| | | '#text': p.value, |
| | | }; |
| | | } |
| | | }); |
| | | if (lnglat?.actions.length > 1) { |
| | | actionGroup.action.push(singleAction); |
| | | } else { |
| | | actionGroup.action = singleAction; |
| | | } |
| | | }); |
| | | placemark.actionGroup = actionGroup; |
| | | } |
| | | fileTemplate.Folder.Placemark.push(placemark); |
| | | }); |
| | | const fileWaylines = waylinesContext(fileTemplate); |
| | | return { |
| | | fileName: waylineName || fileName, |
| | | template: fileTemplate, |
| | | waylines: fileWaylines, |
| | | }; |
| | | } catch (error) { |
| | | console.log(error); |
| | | return error; |
| | | } |
| | | }; |
| | | // 创建正常航线 |
| | | const createNoramlWaylines = (waylineBasicInfo, lnglats) => { |
| | | try { |
| | | const date = new Date() |
| | | const username = window.localStorage.getItem('bs_username') |
| | | const updateTime = date.getTime() |
| | | const { year, month, day, hours, minutes } = getDateFromTimestamp(updateTime) |
| | | const fileName = '新建航线_' + year + month + day + hours + minutes |
| | | // 无人机机型、云台型号、航线高度 |
| | | const { droneEnumValue, payloadEnumValue, height, waylineName } = waylineBasicInfo |
| | | const defaultHeight = height || 100 |
| | | // 起始点位 (参考点位-具体以机场为准) |
| | | const startPoint = lnglats[0] |
| | | const takeOffPoint = [startPoint.latitude, startPoint.longitude, 0].join(',') |
| | | // template.xml对象模版 |
| | | const fileTemplate = { |
| | | author: { '#text': username }, |
| | | createTime: { '#text': updateTime }, |
| | | updateTime: { '#text': updateTime }, |
| | | missionConfig: { |
| | | // 飞向首航点模式 |
| | | flyToWaylineMode: { '#text': 'safely' }, |
| | | // 航线结束动作 |
| | | finishAction: { '#text': 'goHome' }, |
| | | // 失控是否继续执行航线 |
| | | exitOnRCLost: { '#text': 'goContinue' }, |
| | | // 失控动作类型 |
| | | executeRCLostAction: { '#text': 'goBack' }, |
| | | // 安全起飞高度 |
| | | takeOffSecurityHeight: { '#text': 20 }, |
| | | // 参考起飞点 |
| | | takeOffRefPoint: { '#text': takeOffPoint }, |
| | | // 参考起飞点海拔高度 |
| | | takeOffRefPointAGLHeight: { '#text': 0 }, |
| | | // 全局航线过渡速度 |
| | | globalTransitionalSpeed: { '#text': 10 }, |
| | | // 全局返航高度 |
| | | globalRTHHeight: { '#text': defaultHeight }, |
| | | // 无人机参数 |
| | | droneInfo: { |
| | | droneEnumValue: { '#text': droneEnumValue }, |
| | | droneSubEnumValue: { |
| | | '#text': droneModel[payloadEnumValue], |
| | | }, |
| | | }, |
| | | // 是否自动绕行(暂未验证M30T机型使用此参数后会不会无法起飞) |
| | | autoRerouteInfo: { |
| | | missionAutoRerouteMode: { '#text': 1 }, |
| | | transitionalAutoRerouteMode: { '#text': 1 }, |
| | | }, |
| | | // 云台参数 |
| | | payloadInfo: { |
| | | payloadEnumValue: { '#text': payloadEnumValue }, |
| | | payloadSubEnumValue: { |
| | | '#text': droneModel[payloadEnumValue], |
| | | }, |
| | | payloadPositionIndex: { '#text': 0 }, |
| | | }, |
| | | }, |
| | | Folder: { |
| | | // 预定义模板类型 - 航点飞行 |
| | | templateType: { '#text': 'waypoint' }, |
| | | // 是否使用全局航线过渡速度 |
| | | useGlobalTransitionalSpeed: { '#text': 0 }, |
| | | templateId: { '#text': 0 }, |
| | | // 坐标系参数信息 |
| | | waylineCoordinateSysParam: { |
| | | // 经纬度坐标系 - 固定值 |
| | | coordinateMode: { '#text': 'WGS84' }, |
| | | // 航点高程参考平面 - 相对高度 |
| | | heightMode: { '#text': 'relativeToStartPoint' }, |
| | | }, |
| | | // 全局航线飞行速度 |
| | | autoFlightSpeed: { '#text': 10 }, |
| | | // 云台俯仰角控制模式 |
| | | gimbalPitchMode: { '#text': 'usePointSetting' }, |
| | | // 全局高度 |
| | | globalHeight: { '#text': '100' }, |
| | | // 全局偏航角模式参数 - 可使用当前默认值 |
| | | globalWaypointHeadingParam: { |
| | | waypointHeadingMode: { '#text': 'followWayline' }, |
| | | waypointHeadingAngle: { '#text': 0 }, |
| | | waypointPoiPoint: { |
| | | '#text': '0.000000,0.000000,0.000000', |
| | | }, |
| | | waypointHeadingPathMode: { '#text': 'followBadArc' }, |
| | | waypointHeadingPoiIndex: { '#text': 0 }, |
| | | }, |
| | | // 全局航点类型 - 直线飞行,飞行器到点停 |
| | | globalWaypointTurnMode: { |
| | | '#text': 'toPointAndStopWithDiscontinuityCurvature', |
| | | }, |
| | | // 全局航段轨迹是否尽量贴合直线 |
| | | globalUseStraightLine: { '#text': 1 }, |
| | | // 航点点位信息 - 位置、事件等 |
| | | Placemark: [], |
| | | payloadParam: { |
| | | payloadPositionIndex: { '#text': 0 }, |
| | | focusMode: { '#text': 'firstPoint' }, |
| | | meteringMode: { '#text': 'average' }, |
| | | returnMode: { '#text': 'singleReturnFirst' }, |
| | | samplingRate: { '#text': '240000' }, |
| | | scanningMode: { '#text': 'repetitive' }, |
| | | imageFormat: { '#text': 'wide,zoom' }, |
| | | }, |
| | | }, |
| | | } |
| | | lnglats.forEach((lnglat, index) => { |
| | | const placemark = { |
| | | Point: { |
| | | // 航点经纬度 |
| | | coordinates: { |
| | | '#text': `${lnglat.longitude},${lnglat.latitude}`, |
| | | }, |
| | | }, |
| | | // 航点index |
| | | index: { '#text': index }, |
| | | // 全局航线高度(椭球高) |
| | | ellipsoidHeight: { '#text': lnglat.height }, |
| | | // 全局航线高度 (EGM96海拔高/相对起飞点高度/AGL相对地面高度) |
| | | height: { '#text': lnglat.height }, |
| | | // 航点飞行速度 |
| | | waypointSpeed: { '#text': lnglat?.speed || 10 }, |
| | | // 沿航线方向 - 可使用当前默认值 |
| | | waypointHeadingParam: { |
| | | waypointHeadingMode: { '#text': 'followWayline' }, |
| | | waypointHeadingAngle: { '#text': 0 }, |
| | | waypointPoiPoint: { |
| | | '#text': '0.000000,0.000000,0.000000', |
| | | }, |
| | | waypointHeadingPathMode: { '#text': 'followBadArc' }, |
| | | waypointHeadingPoiIndex: { '#text': 0 }, |
| | | }, |
| | | // 航点类型 |
| | | waypointTurnParam: { |
| | | waypointTurnMode: { |
| | | '#text': 'toPointAndStopWithDiscontinuityCurvature', |
| | | }, |
| | | waypointTurnDampingDist: { '#text': 0.2 }, |
| | | }, |
| | | // 是否全局参数 |
| | | useGlobalHeight: { '#text': 1 }, |
| | | useGlobalSpeed: { '#text': 0 }, |
| | | useGlobalHeadingParam: { '#text': 1 }, |
| | | useGlobalTurnParam: { '#text': 1 }, |
| | | useStraightLine: { '#text': 1 }, |
| | | } |
| | | if (lnglat?.actions) { |
| | | const actionGroup = { |
| | | actionGroupId: { '#text': index }, |
| | | actionGroupStartIndex: { '#text': index }, |
| | | actionGroupEndIndex: { '#text': index }, |
| | | actionGroupMode: { '#text': 'sequence' }, |
| | | actionTrigger: { |
| | | actionTriggerType: { '#text': 'reachPoint' }, |
| | | }, |
| | | // 单个事件 - 如果是多个事件action可改成数组 action: [{}] |
| | | // action: [{ |
| | | // actionId: { '#text': 0 }, |
| | | // actionActuatorFunc: { '#text': '' }, |
| | | // actionActuatorFuncParam: {}, |
| | | // }], |
| | | action: [], |
| | | } |
| | | lnglat?.actions.forEach((action, index) => { |
| | | const singleAction = { |
| | | actionId: { '#text': index }, |
| | | actionActuatorFunc: { '#text': '' }, |
| | | actionActuatorFuncParam: {}, |
| | | } |
| | | // actionGroup.action['actionActuatorFunc'] = { '#text': action.key } |
| | | // action.params.forEach(p => { |
| | | // if (p.value || p.value !== '') { |
| | | // actionGroup.action['actionActuatorFuncParam'][p.key] = { '#text': p.value } |
| | | // } |
| | | // }) |
| | | singleAction['actionActuatorFunc'] = { |
| | | '#text': action.key, |
| | | } |
| | | action.params.forEach(p => { |
| | | if (p.value || p.value !== '') { |
| | | singleAction['actionActuatorFuncParam'][p.key] = { |
| | | '#text': p.value, |
| | | } |
| | | } |
| | | }) |
| | | if (lnglat?.actions.length > 1) { |
| | | actionGroup.action.push(singleAction) |
| | | } else { |
| | | actionGroup.action = singleAction |
| | | } |
| | | }) |
| | | placemark.actionGroup = actionGroup |
| | | } |
| | | fileTemplate.Folder.Placemark.push(placemark) |
| | | }) |
| | | const fileWaylines = waylinesContext(fileTemplate) |
| | | return { |
| | | fileName: waylineName || fileName, |
| | | template: fileTemplate, |
| | | waylines: fileWaylines, |
| | | } |
| | | } catch (error) { |
| | | console.log(error) |
| | | return error |
| | | } |
| | | } |
| | | |
| | | // 创建面状航线 |
| | | const createPlanarWayline = (waylineBasicInfo, lnglats) => {}; |
| | | // 创建面状航线 |
| | | const createPlanarWayline = (waylineBasicInfo, lnglats) => {} |
| | | |
| | | // 创建点状航线 |
| | | const createPointWayLines = ( |
| | | waylineBasicInfo, |
| | | points, |
| | | settingInfo, |
| | | dockPosition, |
| | | ) => { |
| | | try { |
| | | const { droneEnumValue, payloadEnumValue, waylineName } = |
| | | waylineBasicInfo; |
| | | // 创建点状航线 |
| | | const createPointWayLines = (waylineBasicInfo, points, settingInfo, dockPosition) => { |
| | | try { |
| | | const { droneEnumValue, payloadEnumValue, waylineName } = waylineBasicInfo |
| | | |
| | | const { imageFormat, heightMode, globalHeight, autoFlightSpeed,gimbalPitchMode, |
| | | waypointTurnMode,waypointHeadingMode,finishAction,globalTransitionalSpeed } = |
| | | settingInfo; |
| | | const { |
| | | imageFormat, |
| | | heightMode, |
| | | globalHeight, |
| | | autoFlightSpeed, |
| | | gimbalPitchMode, |
| | | waypointTurnMode, |
| | | waypointHeadingMode, |
| | | finishAction, |
| | | globalTransitionalSpeed, |
| | | } = settingInfo |
| | | |
| | | const date = new Date(); |
| | | const username = window.localStorage.getItem('bs_username'); |
| | | const updateTime = date.getTime(); |
| | | const { year, month, day, hours, minutes } = |
| | | getDateFromTimestamp(updateTime); |
| | | const fileName = '新建航线_' + year + month + day + hours + minutes; |
| | | // 无人机机型、云台型号、航线高度 |
| | | const date = new Date() |
| | | const username = window.localStorage.getItem('bs_username') |
| | | const updateTime = date.getTime() |
| | | const { year, month, day, hours, minutes } = getDateFromTimestamp(updateTime) |
| | | const fileName = '新建航线_' + year + month + day + hours + minutes |
| | | // 无人机机型、云台型号、航线高度 |
| | | |
| | | const defaultHeight = 100; |
| | | // 起始点位 (参考点位-具体以机场为准) |
| | | const takeOffPoint = [ |
| | | dockPosition.latitude, |
| | | dockPosition.longitude, |
| | | 0, |
| | | ].join(','); |
| | | const defaultHeight = 100 |
| | | // 起始点位 (参考点位-具体以机场为准) |
| | | const takeOffPoint = [dockPosition.latitude, dockPosition.longitude, 0].join(',') |
| | | |
| | | // template.xml对象模版 |
| | | const fileTemplate = { |
| | | author: { '#text': username }, |
| | | createTime: { '#text': updateTime }, |
| | | updateTime: { '#text': updateTime }, |
| | | missionConfig: { |
| | | // 飞向首航点模式 |
| | | flyToWaylineMode: { '#text': 'safely' }, |
| | | // 航线结束动作 |
| | | finishAction: { '#text': finishAction || 'goHome' }, |
| | | // 失控是否继续执行航线 |
| | | exitOnRCLost: { '#text': 'executeLostAction' }, |
| | | // 失控动作类型 |
| | | executeRCLostAction: { '#text': 'goBack' }, |
| | | // 安全起飞高度 |
| | | takeOffSecurityHeight: { '#text': 120 }, |
| | | // 参考起飞点 |
| | | takeOffRefPoint: { '#text': takeOffPoint }, |
| | | // 参考起飞点海拔高度 |
| | | takeOffRefPointAGLHeight: { '#text': 0 }, |
| | | // 全局航线过渡速度 |
| | | globalTransitionalSpeed: { '#text': globalTransitionalSpeed || 10 }, |
| | | // 全局返航高度 |
| | | globalRTHHeight: { '#text': defaultHeight }, |
| | | // 无人机参数 |
| | | droneInfo: { |
| | | droneEnumValue: { '#text': droneEnumValue }, |
| | | droneSubEnumValue: { |
| | | '#text': droneModel[payloadEnumValue], |
| | | }, |
| | | }, |
| | | // 是否自动绕行(暂未验证M30T机型使用此参数后会不会无法起飞) |
| | | autoRerouteInfo: { |
| | | missionAutoRerouteMode: { '#text': 1 }, |
| | | transitionalAutoRerouteMode: { '#text': 1 }, |
| | | }, |
| | | // 云台参数 |
| | | payloadInfo: { |
| | | payloadEnumValue: { '#text': payloadEnumValue }, |
| | | payloadSubEnumValue: { |
| | | '#text': droneModel[payloadEnumValue], |
| | | }, |
| | | payloadPositionIndex: { '#text': 0 }, |
| | | }, |
| | | }, |
| | | Folder: { |
| | | // 预定义模板类型 - 航点飞行 |
| | | templateType: { '#text': 'waypoint' }, |
| | | // 是否使用全局航线过渡速度 |
| | | useGlobalTransitionalSpeed: { '#text': 0 }, |
| | | templateId: { '#text': 0 }, |
| | | // 坐标系参数信息 |
| | | waylineCoordinateSysParam: { |
| | | // 经纬度坐标系 - 固定值 |
| | | coordinateMode: { '#text': 'WGS84' }, |
| | | // 航点高程参考平面 - 相对高度 |
| | | heightMode: heightMode, |
| | | }, |
| | | // 全局航线飞行速度 |
| | | autoFlightSpeed: { '#text': autoFlightSpeed || 10 }, |
| | | // 云台俯仰角控制模式 |
| | | gimbalPitchMode: { '#text': gimbalPitchMode || 'manual' }, |
| | | // 全局高度 |
| | | globalHeight: { '#text': globalHeight || '100' }, |
| | | // 全局偏航角模式参数 - 可使用当前默认值 |
| | | globalWaypointHeadingParam: { |
| | | waypointHeadingMode: { '#text': waypointHeadingMode || 'followWayline' }, |
| | | waypointHeadingAngle: { '#text': 0 }, |
| | | waypointPoiPoint: { |
| | | '#text': '0.000000,0.000000,0.000000', |
| | | }, |
| | | waypointHeadingPathMode: { '#text': 'followBadArc' }, |
| | | waypointHeadingPoiIndex: { '#text': 0 }, |
| | | }, |
| | | // 全局航点类型 - 直线飞行,飞行器到点停 |
| | | globalWaypointTurnMode: { |
| | | '#text': waypointTurnMode || 'toPointAndStopWithDiscontinuityCurvature', |
| | | }, |
| | | // 全局航段轨迹是否尽量贴合直线 |
| | | globalUseStraightLine: { '#text': 1 }, |
| | | // 航点点位信息 - 位置、事件等 |
| | | Placemark: [], |
| | | payloadParam: { |
| | | payloadPositionIndex: { '#text': 0 }, |
| | | focusMode: { '#text': 'firstPoint' }, |
| | | meteringMode: { '#text': 'average' }, |
| | | returnMode: { '#text': 'singleReturnFirst' }, |
| | | samplingRate: { '#text': '240000' }, |
| | | scanningMode: { '#text': 'repetitive' }, |
| | | imageFormat: imageFormat, |
| | | }, |
| | | }, |
| | | }; |
| | | points.length && |
| | | points.forEach((detail, ind) => { |
| | | const { Point, index, height, ellipsoidHeight, actionGroup,waypointSpeed } = detail; |
| | | // template.xml对象模版 |
| | | const fileTemplate = { |
| | | author: { '#text': username }, |
| | | createTime: { '#text': updateTime }, |
| | | updateTime: { '#text': updateTime }, |
| | | missionConfig: { |
| | | // 飞向首航点模式 |
| | | flyToWaylineMode: { '#text': 'safely' }, |
| | | // 航线结束动作 |
| | | finishAction: { '#text': finishAction || 'goHome' }, |
| | | // 失控是否继续执行航线 |
| | | exitOnRCLost: { '#text': 'executeLostAction' }, |
| | | // 失控动作类型 |
| | | executeRCLostAction: { '#text': 'goBack' }, |
| | | // 安全起飞高度 |
| | | takeOffSecurityHeight: { '#text': 120 }, |
| | | // 参考起飞点 |
| | | takeOffRefPoint: { '#text': takeOffPoint }, |
| | | // 参考起飞点海拔高度 |
| | | takeOffRefPointAGLHeight: { '#text': 0 }, |
| | | // 全局航线过渡速度 |
| | | globalTransitionalSpeed: { '#text': globalTransitionalSpeed || 10 }, |
| | | // 全局返航高度 |
| | | globalRTHHeight: { '#text': defaultHeight }, |
| | | // 无人机参数 |
| | | droneInfo: { |
| | | droneEnumValue: { '#text': droneEnumValue }, |
| | | droneSubEnumValue: { |
| | | '#text': droneModel[payloadEnumValue], |
| | | }, |
| | | }, |
| | | // 是否自动绕行(暂未验证M30T机型使用此参数后会不会无法起飞) |
| | | autoRerouteInfo: { |
| | | missionAutoRerouteMode: { '#text': 1 }, |
| | | transitionalAutoRerouteMode: { '#text': 1 }, |
| | | }, |
| | | // 云台参数 |
| | | payloadInfo: { |
| | | payloadEnumValue: { '#text': payloadEnumValue }, |
| | | payloadSubEnumValue: { |
| | | '#text': droneModel[payloadEnumValue], |
| | | }, |
| | | payloadPositionIndex: { '#text': 0 }, |
| | | }, |
| | | }, |
| | | Folder: { |
| | | // 预定义模板类型 - 航点飞行 |
| | | templateType: { '#text': 'waypoint' }, |
| | | // 是否使用全局航线过渡速度 |
| | | useGlobalTransitionalSpeed: { '#text': 0 }, |
| | | templateId: { '#text': 0 }, |
| | | // 坐标系参数信息 |
| | | waylineCoordinateSysParam: { |
| | | // 经纬度坐标系 - 固定值 |
| | | coordinateMode: { '#text': 'WGS84' }, |
| | | // 航点高程参考平面 - 相对高度 |
| | | heightMode: heightMode, |
| | | }, |
| | | // 全局航线飞行速度 |
| | | autoFlightSpeed: { '#text': autoFlightSpeed || 10 }, |
| | | // 云台俯仰角控制模式 |
| | | gimbalPitchMode: { '#text': gimbalPitchMode || 'manual' }, |
| | | // 全局高度 |
| | | globalHeight: { '#text': globalHeight || '100' }, |
| | | // 全局偏航角模式参数 - 可使用当前默认值 |
| | | globalWaypointHeadingParam: { |
| | | waypointHeadingMode: { '#text': waypointHeadingMode || 'followWayline' }, |
| | | waypointHeadingAngle: { '#text': 0 }, |
| | | waypointPoiPoint: { |
| | | '#text': '0.000000,0.000000,0.000000', |
| | | }, |
| | | waypointHeadingPathMode: { '#text': 'followBadArc' }, |
| | | waypointHeadingPoiIndex: { '#text': 0 }, |
| | | }, |
| | | // 全局航点类型 - 直线飞行,飞行器到点停 |
| | | globalWaypointTurnMode: { |
| | | '#text': waypointTurnMode || 'toPointAndStopWithDiscontinuityCurvature', |
| | | }, |
| | | // 全局航段轨迹是否尽量贴合直线 |
| | | globalUseStraightLine: { '#text': 1 }, |
| | | // 航点点位信息 - 位置、事件等 |
| | | Placemark: [], |
| | | payloadParam: { |
| | | payloadPositionIndex: { '#text': 0 }, |
| | | focusMode: { '#text': 'firstPoint' }, |
| | | meteringMode: { '#text': 'average' }, |
| | | returnMode: { '#text': 'singleReturnFirst' }, |
| | | samplingRate: { '#text': '240000' }, |
| | | scanningMode: { '#text': 'repetitive' }, |
| | | imageFormat: imageFormat, |
| | | }, |
| | | }, |
| | | } |
| | | points.length && |
| | | points.forEach((detail, ind) => { |
| | | const { Point, index, height, ellipsoidHeight, actionGroup, waypointSpeed } = detail |
| | | |
| | | const placemark = { |
| | | Point, |
| | | // 航点index |
| | | index, |
| | | // 全局航线高度(椭球高) |
| | | ellipsoidHeight, |
| | | // 全局航线高度 (EGM96海拔高/相对起飞点高度/AGL相对地面高度) |
| | | height, |
| | | // 航点飞行速度 |
| | | waypointSpeed: { '#text': waypointSpeed || 10 }, |
| | | // 沿航线方向 - 可使用当前默认值 |
| | | waypointHeadingParam: { |
| | | waypointHeadingMode: { '#text': waypointHeadingMode || 'followWayline' }, |
| | | waypointHeadingAngle: { '#text': 0 }, |
| | | waypointPoiPoint: { |
| | | '#text': '0.000000,0.000000,0.000000', |
| | | }, |
| | | waypointHeadingPathMode: { '#text': 'followBadArc' }, |
| | | waypointHeadingPoiIndex: { '#text': 0 }, |
| | | }, |
| | | // 航点类型 |
| | | waypointTurnParam: { |
| | | waypointTurnMode: { |
| | | '#text': waypointTurnMode || 'toPointAndStopWithDiscontinuityCurvature', |
| | | }, |
| | | waypointTurnDampingDist: { '#text': 0.2 }, |
| | | }, |
| | | // 是否全局参数 |
| | | useGlobalHeight: { '#text': 1 }, |
| | | useGlobalSpeed: { '#text': 0 }, |
| | | useGlobalHeadingParam: { '#text': 1 }, |
| | | useGlobalTurnParam: { '#text': 1 }, |
| | | useStraightLine: { '#text': 1 }, |
| | | }; |
| | | if (actionGroup) { |
| | | placemark.actionGroup = actionGroup; |
| | | } |
| | | const placemark = { |
| | | Point, |
| | | // 航点index |
| | | index, |
| | | // 全局航线高度(椭球高) |
| | | ellipsoidHeight, |
| | | // 全局航线高度 (EGM96海拔高/相对起飞点高度/AGL相对地面高度) |
| | | height, |
| | | // 航点飞行速度 |
| | | waypointSpeed: { '#text': waypointSpeed || 10 }, |
| | | // 沿航线方向 - 可使用当前默认值 |
| | | waypointHeadingParam: { |
| | | waypointHeadingMode: { |
| | | '#text': waypointHeadingMode || 'followWayline', |
| | | }, |
| | | waypointHeadingAngle: { '#text': 0 }, |
| | | waypointPoiPoint: { |
| | | '#text': '0.000000,0.000000,0.000000', |
| | | }, |
| | | waypointHeadingPathMode: { '#text': 'followBadArc' }, |
| | | waypointHeadingPoiIndex: { '#text': 0 }, |
| | | }, |
| | | // 航点类型 |
| | | waypointTurnParam: { |
| | | waypointTurnMode: { |
| | | '#text': waypointTurnMode || 'toPointAndStopWithDiscontinuityCurvature', |
| | | }, |
| | | waypointTurnDampingDist: { '#text': 0.2 }, |
| | | }, |
| | | // 是否全局参数 |
| | | useGlobalHeight: { '#text': 1 }, |
| | | useGlobalSpeed: { '#text': 0 }, |
| | | useGlobalHeadingParam: { '#text': 1 }, |
| | | useGlobalTurnParam: { '#text': 1 }, |
| | | useStraightLine: { '#text': 1 }, |
| | | } |
| | | if (actionGroup) { |
| | | placemark.actionGroup = actionGroup |
| | | } |
| | | |
| | | fileTemplate.Folder.Placemark.push(placemark); |
| | | }); |
| | | fileTemplate.Folder.Placemark.push(placemark) |
| | | }) |
| | | |
| | | const fileWaylines = waylinesContext(fileTemplate); |
| | | return { |
| | | fileName: waylineName || fileName, |
| | | template: fileTemplate, |
| | | waylines: fileWaylines, |
| | | }; |
| | | } catch (error) { |
| | | console.log(error); |
| | | return error; |
| | | } |
| | | }; |
| | | const fileWaylines = waylinesContext(fileTemplate) |
| | | return { |
| | | fileName: waylineName || fileName, |
| | | template: fileTemplate, |
| | | waylines: fileWaylines, |
| | | } |
| | | } catch (error) { |
| | | console.log(error) |
| | | return error |
| | | } |
| | | } |
| | | |
| | | const save = async (fileInfo) => { |
| | | const JsZip = new JSZIP(); |
| | | const { fileName, template, waylines } = fileInfo; |
| | | const templateXml = JSONToXML(template, '', true); |
| | | const waylinesWpml = JSONToXML(waylines, '', true); |
| | | JsZip.file('wpmz/template.kml', templateXml); |
| | | JsZip.file('wpmz/waylines.wpml', waylinesWpml); |
| | | const fileBlob = await JsZip.generateAsync({ type: 'blob' }); |
| | | // saveAs(kmzFile, `${fileName}.kmz`) |
| | | return fileBlob; |
| | | }; |
| | | const save = async fileInfo => { |
| | | const JsZip = new JSZIP() |
| | | const { fileName, template, waylines } = fileInfo |
| | | const templateXml = JSONToXML(template, '', true) |
| | | const waylinesWpml = JSONToXML(waylines, '', true) |
| | | JsZip.file('wpmz/template.kml', templateXml) |
| | | JsZip.file('wpmz/waylines.wpml', waylinesWpml) |
| | | const fileBlob = await JsZip.generateAsync({ type: 'blob' }) |
| | | // saveAs(kmzFile, `${fileName}.kmz`) |
| | | return fileBlob |
| | | } |
| | | |
| | | const waylinesContext = (templateJson) => { |
| | | const waylinesObj = { |
| | | // 标准模版 |
| | | missionConfig: { |
| | | flyToWaylineMode: null, |
| | | finishAction: null, |
| | | exitOnRCLost: null, |
| | | executeRCLostAction: null, |
| | | takeOffSecurityHeight: null, |
| | | globalTransitionalSpeed: null, |
| | | globalRTHHeight: null, |
| | | droneInfo: null, |
| | | payloadInfo: null, |
| | | }, |
| | | Folder: { |
| | | templateId: null, |
| | | executeHeightMode: null, |
| | | waylineId: null, |
| | | autoFlightSpeed: null, |
| | | /* |
| | | const waylinesContext = templateJson => { |
| | | const waylinesObj = { |
| | | // 标准模版 |
| | | missionConfig: { |
| | | flyToWaylineMode: null, |
| | | finishAction: null, |
| | | exitOnRCLost: null, |
| | | executeRCLostAction: null, |
| | | takeOffSecurityHeight: null, |
| | | globalTransitionalSpeed: null, |
| | | globalRTHHeight: null, |
| | | droneInfo: null, |
| | | payloadInfo: null, |
| | | }, |
| | | Folder: { |
| | | templateId: null, |
| | | executeHeightMode: null, |
| | | waylineId: null, |
| | | autoFlightSpeed: null, |
| | | /* |
| | | waylines.wpml和template.xml的Placemark通用 |
| | | 不同点: |
| | | waylineId = templateId |
| | | ellipsoidHeight、 height 替换成 executeHeight |
| | | */ |
| | | Placemark: null, |
| | | }, |
| | | }; |
| | | Object.keys(waylinesObj).forEach((key) => { |
| | | if ( |
| | | Object.prototype.toString.call(waylinesObj[key]) === '[object Object]' |
| | | ) { |
| | | Object.keys(waylinesObj[key]).forEach((item) => { |
| | | waylinesObj[key][item] = templateJson[key][item]; |
| | | if (item === 'executeHeightMode') { |
| | | waylinesObj[key][item] = |
| | | templateJson[key].waylineCoordinateSysParam.heightMode; |
| | | } |
| | | if (item === 'waylineId') { |
| | | waylinesObj[key][item] = templateJson[key].templateId; |
| | | } |
| | | if (item === 'Placemark') { |
| | | const placemarks = _.cloneDeep(templateJson[key][item]); |
| | | placemarks.forEach((placemark) => { |
| | | placemark.executeHeight = { |
| | | '#text': placemark.ellipsoidHeight?.['#text'] || '', |
| | | }; |
| | | delete placemark.ellipsoidHeight; |
| | | delete placemark.height; |
| | | }); |
| | | waylinesObj[key][item] = placemarks; |
| | | } |
| | | }); |
| | | } else { |
| | | waylinesObj[key] = templateJson[key]; |
| | | } |
| | | }); |
| | | return waylinesObj; |
| | | }; |
| | | Placemark: null, |
| | | }, |
| | | } |
| | | Object.keys(waylinesObj).forEach(key => { |
| | | if (Object.prototype.toString.call(waylinesObj[key]) === '[object Object]') { |
| | | Object.keys(waylinesObj[key]).forEach(item => { |
| | | waylinesObj[key][item] = templateJson[key][item] |
| | | if (item === 'executeHeightMode') { |
| | | waylinesObj[key][item] = templateJson[key].waylineCoordinateSysParam.heightMode |
| | | } |
| | | if (item === 'waylineId') { |
| | | waylinesObj[key][item] = templateJson[key].templateId |
| | | } |
| | | if (item === 'Placemark') { |
| | | const placemarks = _.cloneDeep(templateJson[key][item]) |
| | | placemarks.forEach(placemark => { |
| | | placemark.executeHeight = { |
| | | '#text': placemark.ellipsoidHeight?.['#text'] || '', |
| | | } |
| | | delete placemark.ellipsoidHeight |
| | | delete placemark.height |
| | | }) |
| | | waylinesObj[key][item] = placemarks |
| | | } |
| | | }) |
| | | } else { |
| | | waylinesObj[key] = templateJson[key] |
| | | } |
| | | }) |
| | | return waylinesObj |
| | | } |
| | | |
| | | return { |
| | | create, |
| | | createNoramlWaylines, |
| | | createPlanarWayline, |
| | | createPointWayLines, |
| | | save, |
| | | }; |
| | | return { |
| | | create, |
| | | createNoramlWaylines, |
| | | createPlanarWayline, |
| | | createPointWayLines, |
| | | save, |
| | | } |
| | | } |