import * as Cesium from 'cesium'
|
|
import { analyzeKmzFile, removeTextKey, XMLToJSON } from '@/utils/cesium/kmz'
|
import { camelToSnake } from '@/utils/util'
|
import _, { cloneDeep, throttle } from 'lodash'
|
import * as turf from '@turf/turf'
|
|
/**
|
* 判断action里面是否有key
|
* @param action
|
* @param key
|
* @returns {{hasKey: boolean, val: *}|{hasKey: boolean, val: null}}
|
*/
|
export function actionHasKey (action, key) {
|
const curActionParams = action?.action_actuator_func_param
|
const val = curActionParams?.[key]
|
if (val !== undefined) {
|
return { hasKey: true, val }
|
} else {
|
return { hasKey: false, val: null }
|
}
|
}
|
|
// 解析kmz文件的时候处理pointList 写在这里
|
export function handlePointListForKmz ({ placemark, startPoint, execute_height_mode, auto_flight_speed }) {
|
if (!placemark?.length) return []
|
const isWGS84 = execute_height_mode === 'WGS84'
|
const list = placemark.map(item => {
|
const [longitude, latitude] = item.point.coordinates.trim().split(',')
|
let action_modes = item?.action_group?.action || []
|
action_modes = Array.isArray(action_modes) ? action_modes : [action_modes]
|
return {
|
longitude: _.round(longitude, 8),
|
latitude: _.round(latitude, 8),
|
height: isWGS84 ? item.execute_height : item.execute_height + startPoint.height,
|
waypoint_speed: item.waypoint_speed,
|
action_modes,
|
}
|
})
|
const pointStart = {
|
...startPoint,
|
flyRotateYaw: 0,
|
pointType: 'start',
|
waypoint_speed: auto_flight_speed,
|
heading: 0, // 椎体 heading
|
arrowHeading: 0, // 飞行器 heading
|
pitch: 0, //椎体俯仰角
|
fov: 19.5, // 这个是椎体的展示截面大小
|
}
|
list.forEach(item => {
|
item?.action_modes?.forEach(item1 => {
|
let { hasKey: has_focal_length, val: focal_length } = actionHasKey(item1, 'focal_length')
|
// 处理focalLength需要/24 focalLength可能是‘1,024’
|
if (has_focal_length && focal_length) {
|
focal_length = typeof focal_length === 'string' ? focal_length.replace(/,/g, '') : focal_length
|
item1.action_actuator_func_param.focal_length = Number(focal_length) / 24
|
}
|
})
|
item.arrowHeading = 0
|
})
|
return [pointStart, ...list]
|
}
|
|
export async function analysisPointLineKmz (kmzUrl) {
|
const res = await analyzeKmzFile(`${kmzUrl}?_t=${new Date().getTime()}`)
|
const templateXML = await res.fileInfoObj['wpmz/template.kml']
|
const waylinesXML = await res.fileInfoObj['wpmz/waylines.wpml']
|
const templateXMLJSON = XMLToJSON(templateXML)?.['Document']
|
const waylinesXMLJSON = XMLToJSON(waylinesXML)?.['Document']
|
const templateXMLObj = camelToSnake(removeTextKey(templateXMLJSON))
|
const waylinesXMLObj = camelToSnake(removeTextKey(waylinesXMLJSON))
|
const {
|
mission_config: {
|
take_off_ref_point,
|
drone_info: { drone_enum_value, drone_sub_enum_value } = {}
|
} = {},
|
folder: {
|
payload_param: { image_format } = {},
|
placemark: {
|
polygon
|
},
|
global_height, auto_flight_speed,
|
template_type: templateType
|
} = {},
|
} = templateXMLObj
|
|
const {
|
mission_config: { take_off_security_height } = {},
|
folder: polygonPointFolder
|
} = waylinesXMLObj
|
|
let execute_height_mode = '', pointPlacemark
|
|
if (templateType === "mapping3d") {
|
execute_height_mode = polygonPointFolder[0].execute_height_mode
|
pointPlacemark = polygonPointFolder.map(i => i.placemark)
|
} else {
|
execute_height_mode = polygonPointFolder.execute_height_mode
|
pointPlacemark = polygonPointFolder.placemark
|
}
|
|
const [latitude, longitude, height] = take_off_ref_point.split(',').map(item => _.round(item, 6))
|
let startPoint = { latitude, longitude, height }
|
|
// 取出点位
|
const coordinates = polygon?.outer_boundary_is.linear_ring
|
.coordinates?.split('\n') || []
|
|
// 数组转换
|
let polygonList = coordinates.map((coordinate) =>
|
coordinate
|
.replace(/\s+/g, '')
|
.split(',')
|
.map((v) => Number(v)),
|
)
|
|
polygonList.pop()
|
|
return {
|
image_format,
|
startPoint,
|
global_height,
|
auto_flight_speed,
|
take_off_ref_point,
|
drone_enum_value,
|
drone_sub_enum_value,
|
take_off_security_height,
|
execute_height_mode,
|
templateType,
|
pointPlacemark,
|
polygonList
|
}
|
}
|
|
// 获取连接地面线
|
export function getPolyLine (viewer, pointList, index) {
|
return {
|
positions: new Cesium.CallbackProperty(() => {
|
const point = pointList.value[index]
|
const pointPosition = Cesium.Cartesian3.fromDegrees(point.longitude, point.latitude, point.height)
|
if (!pointPosition) return []
|
// 获取点的位置
|
const cartographic = Cesium.Cartographic.fromCartesian(pointPosition)
|
// 获取地形高度
|
const terrainHeight = viewer.scene.globe.getHeight(cartographic) || 0
|
// 创建地面点位置
|
const groundPosition = Cesium.Cartesian3.fromRadians(cartographic.longitude, cartographic.latitude, terrainHeight)
|
|
return [pointPosition, groundPosition]
|
}, false),
|
width: 0.5,
|
material: Cesium.Color.WHITE,
|
}
|
}
|
|
export function getNewPolygonData (data) {
|
const polygonData = data.reduce((pre, cur) => {
|
let arr = cur.data.map(i => {
|
if ('point' in i) return i.point.coordinates.split(',')
|
if ('Point' in i) {
|
if (_.isObject(i.Point.coordinates) && '#text' in i.Point.coordinates) return i.Point.coordinates['#text'].split(',')
|
return i.Point.coordinates.split(',')
|
}
|
}).map(i => turf.point([Number(i[0]), Number(i[1])]))
|
|
return pre.push(...arr), pre
|
}, [])
|
|
const hull = turf.convex(turf.featureCollection(polygonData))
|
|
return hull.geometry.coordinates[0]
|
}
|