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] }