| | |
| | | import { Decimal } from 'decimal.js' |
| | | import _, { cloneDeep, throttle } from 'lodash' |
| | | import { v4 as uuidv4 } from 'uuid' |
| | | |
| | | import { render } from 'vue' |
| | | |
| | | import { analysisPointLineKmz, handlePointListForKmz } from '@/views/newRoutePlan/Waypoint/pointWayLineUtils' |
| | | import HistoryDronePopup from '@/components/DeviceJobDetails/HistoryDronePopup.vue' |
| | | |
| | | import { getNewPolygonData } from '@/views/RoutePlan/PlanarAirLine/planarRouteUtils' |
| | | import { |
| | | getNewPolygonData, |
| | | } from '@/views/newRoutePlan/routeUtils' |
| | | |
| | | import { analyzeKmzFile, removeTextKey, XMLToJSON } from '@/utils/cesium/kmz' |
| | | |
| | | import { ArrowLineMaterialProperty, LineTrailMaterial, PolylineGlowMaterial, } from '@/utils/cesium/Material' |
| | | |
| | | import { ArrowLineMaterialProperty, LineTrailMaterial, PolylineGlowMaterial } from '@/utils/cesium/Material' |
| | | import CreateFrustum from '@/utils/cesium/frustum/CreateFrustum' |
| | | import { ElMessage } from 'element-plus' |
| | | |
| | |
| | | import aircraftGltf from '@/assets/gltf/aircraft.gltf' |
| | | import newNumPoint from '@/assets/images/newStartPoint.png' |
| | | |
| | | import { |
| | | getPolyLine, |
| | | } from '@/views/RoutePlan/PointAirLine/pointWayLineUtils' |
| | | import { getPolyLine } from '@/views/newRoutePlan/Waypoint/pointWayLineUtils' |
| | | import store from '@/store/index' |
| | | import newStartPoint from '@/assets/images/newStartPoint.png' |
| | | import newStartPointMore from '@/assets/images/newStartPointMore.png' |
| | | import { |
| | | arrowLineMaterialProperty, arrowLineMaterialPropertyGray, arrowLineMaterialPropertyGrayT, |
| | | arrowLineMaterialPropertyGreen, |
| | | arrowLineMaterialPropertyOrange, |
| | | } from '@/hooks/useMorePointLine/useMorePointLine' |
| | | |
| | | let arrowLineMaterialProperty = new ArrowLineMaterialProperty({ |
| | | color: new Cesium.Color(128 / 255, 215 / 255, 255 / 255, 1), |
| | | directionColor: new Cesium.Color(1, 1, 1, 1), |
| | | outlineColor: new Cesium.Color(1, 1, 1, 1), |
| | | outlineWidth: 0, |
| | | speed: 5 |
| | | }) |
| | | |
| | | let arrowLineMaterialPropertyOrange = new ArrowLineMaterialProperty({ |
| | | color: new Cesium.Color(255 / 255, 185 / 255, 58 / 255, 1), |
| | | directionColor: new Cesium.Color(1, 1, 1, 1), |
| | | outlineColor: new Cesium.Color(1, 1, 1, 1), |
| | | outlineWidth: 0, |
| | | speed: 5, |
| | | }) |
| | | |
| | | let arrowLineMaterialPropertyGreen = new ArrowLineMaterialProperty({ |
| | | color: new Cesium.Color(6 / 255, 217 / 255, 87 / 255, 1), |
| | | directionColor: new Cesium.Color(1, 1, 1, 1), |
| | | outlineColor: new Cesium.Color(1, 1, 1, 1), |
| | | outlineWidth: 0, |
| | | speed: 5, |
| | | }) |
| | | |
| | | // 记录index |
| | | let indexLog = 0 |
| | | // 颜色 |
| | | function getLineColor(lineNumber) { |
| | | // 颜色顺序: 蓝(0), 黄(1), 绿(2) |
| | | const colors = [arrowLineMaterialProperty, arrowLineMaterialPropertyOrange, arrowLineMaterialPropertyGreen] |
| | | // 计算颜色索引 (从0开始) |
| | | const colorIndex = (lineNumber - 1) % 3 |
| | | // 返回对应颜色 |
| | | return colors[colorIndex] |
| | | } |
| | | |
| | | let runningLineMaterial = new LineTrailMaterial({ |
| | | color: Cesium.Color.fromCssColorString('#1FFF69'), |
| | | opacity: 1, |
| | | speed: 10, |
| | | }) |
| | | let runningTextColor = Cesium.Color.fromCssColorString('#1FFF69') |
| | | let runningTextOffset = new Cesium.Cartesian2(0, -32) |
| | | |
| | | let pendingLineMaterial = new PolylineGlowMaterial({ |
| | | color: Cesium.Color.fromCssColorString('#FFB81D'), |
| | | }) |
| | | let pendingTextColor = Cesium.Color.fromCssColorString('#FFB81D') |
| | | let pendingTextOffset = new Cesium.Cartesian2(0, 32) |
| | | |
| | | let MapPopUpBox = HistoryDronePopup |
| | | |
| | | function getZoomFactor (camerasInfo, type) { |
| | |
| | | |
| | | return zoom_factor |
| | | } |
| | | // 记录index |
| | | let indexLog = 0 |
| | | // 颜色 |
| | | function getPendingExecutionLineColor (lineNumber) { |
| | | // 颜色顺序: 蓝(灰), 更灰 |
| | | const colors = [arrowLineMaterialPropertyGray, arrowLineMaterialPropertyGrayT] |
| | | // 计算颜色索引 (从0开始) |
| | | const colorIndex = (lineNumber - 1) % 2 |
| | | // 返回对应颜色 |
| | | return colors[colorIndex] |
| | | } |
| | | |
| | | function getLineColor (lineNumber) { |
| | | // 颜色顺序: 蓝(0), 黄(1), 绿(2) |
| | | const colors = [arrowLineMaterialProperty, arrowLineMaterialPropertyOrange, arrowLineMaterialPropertyGreen] |
| | | // 计算颜色索引 (从0开始) |
| | | const colorIndex = (lineNumber - 1) % 3 |
| | | // 返回对应颜色 |
| | | return colors[colorIndex] |
| | | } |
| | | |
| | | function getBase64Image (imgUrl) { |
| | | const img = new Image() |
| | | const canvas = document.createElement('canvas') |
| | | const ctx = canvas.getContext('2d') |
| | | |
| | | return new Promise(resolve => { |
| | | img.onload = function () { |
| | | canvas.width = img.width |
| | | canvas.height = img.height |
| | | ctx.drawImage(img, 0, 0) |
| | | const base64 = canvas.toDataURL('image/png') |
| | | resolve(base64) |
| | | } |
| | | img.src = imgUrl |
| | | }) |
| | | } |
| | | async function createCombinedSVG (index, billboardImageUrl) { |
| | | const base64Image = await getBase64Image(billboardImageUrl) |
| | | const svg = ` |
| | | <svg width="100" height="100" xmlns="http://www.w3.org/2000/svg"> |
| | | <image href="${base64Image}" x="10" y="10" width="80" height="80"/> |
| | | <text x="50" y="54" font-size="26" fill="white" text-anchor="middle" dominant-baseline="middle"> |
| | | ${index + 1} |
| | | </text> |
| | | </svg> |
| | | ` |
| | | return `data:image/svg+xml;charset=utf-8,${encodeURIComponent(svg)}` |
| | | } |
| | | |
| | | function findHeightByCoordinates (data, targetLng, targetLat) { |
| | | // 展平二维数组,然后查找第一个匹配的点 |
| | | const allPoints = data.flat() |
| | | const point = allPoints.find(point => |
| | | point.longitude === targetLng && point.latitude === targetLat |
| | | ) |
| | | |
| | | return point ? point.height : null |
| | | } |
| | | |
| | | function renderingMachineNest (options) { |
| | | const { viewer, dockTransformPosition, dockPosition, data } = options |
| | | viewer.entities.add({ |
| | | name: 'work-drone-route-point-dock', |
| | | position: dockTransformPosition, |
| | | billboard: { |
| | | image: endingOnlineImg, |
| | | width: 50, |
| | | height: 50, |
| | | disableDepthTestDistance: Number.POSITIVE_INFINITY, |
| | | }, |
| | | customData: { |
| | | data, |
| | | }, |
| | | }) |
| | | viewer.entities.add({ |
| | | name: 'work-drone-route--point-polyline', |
| | | position: dockTransformPosition, |
| | | polyline: getPolyLine(viewer, { value: [dockPosition] }, 0), |
| | | }) |
| | | } |
| | | |
| | | function renderingStartingPoint (options) { |
| | | const { viewer, startPosition, data } = options |
| | | viewer.entities.add({ |
| | | name: 'work-drone-route-point-start', |
| | | position: startPosition, |
| | | billboard: { |
| | | image: rwqfdImg, |
| | | width: 50, |
| | | height: 50, |
| | | disableDepthTestDistance: Number.POSITIVE_INFINITY, |
| | | }, |
| | | customData: { |
| | | data, |
| | | }, |
| | | }) |
| | | } |
| | | |
| | | export default class CreateRouteLine { |
| | | /** |
| | | * |
| | | * |
| | | * @param {*} options 参数 |
| | | */ |
| | | constructor(options) { |
| | |
| | | |
| | | /** |
| | | * 初始化viewer |
| | | * @param {*} viewer |
| | | * @param {*} viewer |
| | | */ |
| | | initCreateRoute (viewer) { |
| | | indexLog = 0 |
| | | this.viewer = viewer |
| | | } |
| | | |
| | |
| | | const currentWaypointIndex = output?.ext['current_waypoint_index'] |
| | | |
| | | this.updataMultiNestData(sn, { |
| | | currentWaypointIndex |
| | | currentWaypointIndex, |
| | | }) |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 请求航线文件数据并解析处理 |
| | | * 请求航线文件数据并绘制解析处理 |
| | | * @param {*} data 包含文件url等信息 |
| | | * @param {*} dronePosition 无人机位置 |
| | | * @returns |
| | | * @param {*} dockPosition 无人机位置 |
| | | * @returns |
| | | */ |
| | | async parsingFiles (data, dronePosition = null, isShowDock = false, isShowPointBillboard = true) { |
| | | async parsingFiles (data, dockPosition = null, isShowDock = false, isShowPointBillboard = true) { |
| | | console.log(data,'888') |
| | | const { url, wayline_type, device_sn } = data |
| | | |
| | | if (!url) return dronePosition != null ? { |
| | | dronePosition: [{ lng: dronePosition.longitude, lat: dronePosition.latitude, alt: dronePosition.height }] |
| | | } : {} |
| | | |
| | | indexLog = 0 |
| | | if (!url) |
| | | return dockPosition != null |
| | | ? { |
| | | dronePosition: [{ lng: dockPosition.longitude, lat: dockPosition.latitude, alt: dockPosition.height }], |
| | | } |
| | | : {} |
| | | this.updataMultiNestData(device_sn) |
| | | |
| | | const res = await analyzeKmzFile(`${url}?_t=${new Date().getTime()}`) |
| | |
| | | const missionConfig = removeTextKey(waylinesXmlJson.missionConfig) |
| | | const waylinesXMLObj = removeTextKey(waylinesXmlJson.Folder) |
| | | |
| | | if (templateType === "mapping3d") { |
| | | if (templateType === 'mapping3d') { |
| | | if (!waylinesXMLObj[0].Placemark.length) return ElMessage.error('没有航线点位') |
| | | } else { |
| | | if (!waylinesXMLObj.Placemark.length) return ElMessage.error('没有航线点位') |
| | | } |
| | | |
| | | if ([2, 4, 5, 6, 7, 10].includes(Number(wayline_type))) { |
| | | if (templateType === "mapping3d") { |
| | | if ([2, 4, 5, 7, 10].includes(Number(wayline_type))) { |
| | | if (templateType === 'mapping3d') { |
| | | let morePolygonData = waylinesXMLObj.map(i => ({ |
| | | data: i.Placemark |
| | | data: i.Placemark, |
| | | })) |
| | | |
| | | let newPolygonData = getNewPolygonData(morePolygonData) |
| | |
| | | waylinesXMLObj[0], |
| | | missionConfig, |
| | | templateXmlJson, |
| | | dronePosition, |
| | | dockPosition, |
| | | data, |
| | | startPoint, |
| | | isShowDock, |
| | |
| | | waylinesXMLObj, |
| | | missionConfig, |
| | | templateXmlJson, |
| | | dronePosition, |
| | | dockPosition, |
| | | data, |
| | | startPoint, |
| | | isShowDock, |
| | |
| | | return this.drawPointRoute( |
| | | waylinesXMLObj, |
| | | missionConfig, |
| | | dronePosition, |
| | | dockPosition, |
| | | data, |
| | | startPoint, |
| | | isShowDock, |
| | |
| | | } |
| | | } |
| | | |
| | | // 拆分航线 |
| | | async splitWayLine (data, dronePosition = null, isShowDock = false, isShowPointBillboard = true) { |
| | | const { |
| | | pointPlacemark, |
| | | polygonList, |
| | | pointList, |
| | | templateType, |
| | | startPoint, |
| | | execute_height_mode, |
| | | auto_flight_speed, |
| | | take_off_security_height, |
| | | buffer_distance_meters, |
| | | missionConfig, |
| | | waylinesXMLObjR, |
| | | } = await analysisPointLineKmz(`${data.domain_url}${data.object_key}`) |
| | | const { positionArray, filePositions } = this.disposeData( |
| | | waylinesXMLObjR, |
| | | missionConfig, |
| | | null, |
| | | data, |
| | | startPoint, |
| | | 0 |
| | | ) |
| | | let bigPointList = handlePointListForKmz({ |
| | | placemark: pointPlacemark, |
| | | startPoint: startPoint, |
| | | execute_height_mode: execute_height_mode, |
| | | auto_flight_speed: auto_flight_speed, |
| | | }) |
| | | // 路径线 |
| | | let entityConfig |
| | | bigPointList.shift() |
| | | let flyPositions = bigPointList.map(i => [Number(i.longitude), Number(i.latitude), Number(i.height)]) |
| | | // 渲染多个点 |
| | | let firstTopPosition = null |
| | | let resultPosotions = [] |
| | | await Promise.all(data.wayline_file_list.map(async (item, index) => { |
| | | // 小航线渲染线 |
| | | const kmzUrl = import.meta.env.VITE_APP_AIRLINE_URL + item.object_key |
| | | const { pointList } = await analysisPointLineKmz(kmzUrl) |
| | | resultPosotions.push(pointList) |
| | | })).then(res => { |
| | | // 目的是区分大航线点属于哪条小航线 |
| | | bigPointList.forEach(bigObj => { |
| | | let foundIndex = -1 |
| | | // 遍历 resultPositions 查找匹配项 |
| | | resultPosotions.some((subArray, subIndex) => { |
| | | const found = subArray.some(obj => |
| | | obj.latitude === bigObj.latitude && |
| | | obj.longitude === bigObj.longitude |
| | | ) |
| | | if (found) { |
| | | foundIndex = subIndex |
| | | return true // 找到就停止搜索 |
| | | } |
| | | return false |
| | | }) |
| | | // 如果找到了,给 bigPointList 的对象添加标记 |
| | | if (foundIndex !== -1) { |
| | | bigObj.log = foundIndex // 或 bigObj.index = foundIndex |
| | | } |
| | | }) |
| | | console.log(bigPointList, '查看结果值') // 现在 bigPointList 会有 log 属性 |
| | | bigPointList.map(async (i, index) => { |
| | | firstTopPosition = i |
| | | const position = Cesium.Cartesian3.fromDegrees(Number(i.longitude), Number(i.latitude), Number(findHeightByCoordinates(resultPosotions, i.longitude, i.latitude))) |
| | | const combinedImage = await createCombinedSVG(index, i.log % 2 ? newStartPoint : newStartPointMore) |
| | | |
| | | entityConfig = { |
| | | name: 'work-drone-route-point-split', |
| | | position: position, |
| | | billboard: { |
| | | disableDepthTestDistance: Number.POSITIVE_INFINITY, |
| | | image: combinedImage, |
| | | width: 50, |
| | | height: 50, |
| | | verticalOrigin: Cesium.VerticalOrigin.CENTER, |
| | | horizontalOrigin: Cesium.HorizontalOrigin.CENTER, |
| | | } |
| | | } |
| | | |
| | | // 只在第一个点添加 label |
| | | if (index === 0) { |
| | | entityConfig.label = { |
| | | text: data.task_name || '', |
| | | font: 'bold 16px sans-serif', |
| | | fillColor: data.status === 2 ? runningTextColor : pendingTextColor, |
| | | pixelOffset: data.status === 2 ? runningTextOffset : pendingTextOffset, |
| | | style: Cesium.LabelStyle.FILL_AND_OUTLINE, |
| | | outlineWidth: 2, |
| | | outlineColor: Cesium.Color.BLACK, |
| | | disableDepthTestDistance: Number.POSITIVE_INFINITY, |
| | | } |
| | | } |
| | | |
| | | this.viewer.entities.add(entityConfig) |
| | | }) |
| | | }) |
| | | |
| | | // 渲染航线 |
| | | data.wayline_file_list.map(async (item, index) => { |
| | | // 小航线渲染线 |
| | | const kmzUrl = import.meta.env.VITE_APP_AIRLINE_URL + item.object_key |
| | | const { pointList } = await analysisPointLineKmz(kmzUrl) |
| | | // if (curRouteLineData.value.droneData && splitLines.length === 1) { |
| | | // // 把pointList的第一个点替换为无人机位置 |
| | | // pointList[0] = curRouteLineData.value.droneData[0] |
| | | // } |
| | | if (take_off_security_height + pointList[0].height > firstTopPosition.height) { |
| | | // 安全高度+机巢高度 > 第一个点高度 |
| | | const positionTest = { |
| | | longitude: pointList[0].longitude, |
| | | latitude: pointList[0].latitude, |
| | | height: take_off_security_height + pointList[0].height, |
| | | } |
| | | |
| | | const positionTest1 = { |
| | | longitude: pointList[1].longitude, |
| | | latitude: pointList[1].latitude, |
| | | height: take_off_security_height + pointList[0].height, |
| | | } |
| | | pointList.splice(1, 0, positionTest) |
| | | // 往数组中插入元素 |
| | | pointList.splice(2, 0, positionTest1) |
| | | // console.log(pointList, 'pointList') |
| | | } else if (take_off_security_height + pointList[0].height < firstTopPosition.height) { |
| | | const positionTest = { |
| | | longitude: pointList[0].longitude, |
| | | latitude: pointList[0].latitude, |
| | | height: firstTopPosition.height, |
| | | } |
| | | pointList.splice(1, 0, positionTest) |
| | | } |
| | | const routePositions = pointList.map(i => |
| | | Cesium.Cartesian3.fromDegrees(Number(i.longitude), Number(i.latitude), Number(i.height)) |
| | | ) |
| | | |
| | | this.viewer.entities.add({ |
| | | name: 'work-drone-route-line-split', |
| | | polyline: { |
| | | width: 4, |
| | | positions: routePositions, |
| | | material: data.status === 1 ? arrowLineMaterialPropertyGray : getLineColor(index + 1), |
| | | clampToGround: false, |
| | | }, |
| | | }) |
| | | }) |
| | | // 落点线 |
| | | ; (bigPointList || [])?.forEach((item, index) => { |
| | | const topPosition = Cesium.Cartesian3.fromDegrees( |
| | | Number(item.longitude), |
| | | Number(item.latitude), |
| | | Number(item.height) |
| | | ) |
| | | let setting = { |
| | | name: 'work-drone-route--planar-polyline-split', |
| | | position: topPosition, |
| | | polyline: getPolyLine(this.viewer, { value: bigPointList }, index), |
| | | } |
| | | this.viewer.entities.add(setting) |
| | | }) |
| | | return { |
| | | entity: entityConfig, |
| | | routeLinePositions: positionArray, |
| | | filePositions: |
| | | dronePosition != null |
| | | ? [{ lng: dronePosition.longitude, lat: dronePosition.latitude, alt: dronePosition.height }, ...filePositions] |
| | | : filePositions, |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 绘制面状航线 |
| | | * @param {*} lineObj 航线文件中的 |
| | | * @param {*} missionConfig 航线文件中的 |
| | | * @param {*} templateXmlJson 航线文件中的 |
| | | * @param {*} dronePosition 无人机位置 |
| | | * @param {*} data |
| | | * @param {*} startPoint |
| | | * @param {*} isShowPointBillboard 是否显示,航线起飞点,终点等标注 |
| | | * @returns |
| | | * @param {*} dockPosition 无人机位置 |
| | | * @param {*} data |
| | | * @param {*} startPoint |
| | | * @returns |
| | | */ |
| | | async drawPlanarRoute (lineObj, missionConfig, templateXmlJson, dronePosition, data, startPoint, isShowDock, isShowPointBillboard, wayline_type) { |
| | | const { positionArray, filePositions } = this.disposeData(lineObj, missionConfig, dronePosition, data, startPoint, wayline_type) |
| | | async drawPlanarRoute ( |
| | | lineObj, |
| | | missionConfig, |
| | | templateXmlJson, |
| | | dockPosition, |
| | | data, |
| | | startPoint, |
| | | isShowDock, |
| | | isShowPointBillboard, |
| | | wayline_type |
| | | ) { |
| | | const { positionArray, filePositions } = this.disposeData( |
| | | lineObj, |
| | | missionConfig, |
| | | dockPosition, |
| | | data, |
| | | startPoint, |
| | | wayline_type |
| | | ) |
| | | const { device_sn } = data |
| | | |
| | | const droneTransformPosition = Cesium.Cartesian3.fromDegrees( |
| | | Number(dronePosition.longitude), |
| | | Number(dronePosition.latitude), |
| | | Number(dronePosition.height), |
| | | const dockTransformPosition = Cesium.Cartesian3.fromDegrees( |
| | | Number(dockPosition.longitude), |
| | | Number(dockPosition.latitude), |
| | | Number(dockPosition.height) |
| | | ) |
| | | |
| | | let coordArr = null |
| | | |
| | | const placemark = templateXmlJson.Folder?.Placemark |
| | | // 取出点位 |
| | | const coordinates = |
| | | placemark.Polygon?.outerBoundaryIs.LinearRing.coordinates?.[ |
| | | '#text' |
| | | ]?.split('\n') || [] |
| | | |
| | | const coordinates = placemark.Polygon?.outerBoundaryIs.LinearRing.coordinates?.['#text']?.split('\n') || [] |
| | | // 数组转换 |
| | | coordArr = coordinates.map((coordinate) => |
| | | coordArr = coordinates.map(coordinate => |
| | | coordinate |
| | | .replace(/\s+/g, '') |
| | | .split(',') |
| | | .map((v) => Number(v)), |
| | | .map(v => Number(v)) |
| | | ) |
| | | |
| | | // 获取当前经纬度绝对高度 |
| | | let newCoordArr = coordArr.map(item => ([item[0], item[1], 0])) |
| | | |
| | | let newCoordArr = coordArr.map(item => [item[0], item[1], 0]) |
| | | let planarRouteEntity = this.viewer.entities.add({ |
| | | name: 'work-drone-route-planar-polyline', |
| | | |
| | | polyline: { |
| | | width: 3, |
| | | positions: positionArray, |
| | |
| | | }, |
| | | |
| | | customData: { |
| | | data |
| | | } |
| | | data, |
| | | }, |
| | | }) |
| | | |
| | | let droppointPositions = (filePositions || [])?.map(i => ({ |
| | | longitude: Number(i.lng), |
| | | latitude: Number(i.lat), |
| | | height: Number(i.alt), |
| | | })); |
| | | })) |
| | | |
| | | // 落点线 |
| | | (droppointPositions || [])?.forEach((item, index) => { |
| | | const topPosition = Cesium.Cartesian3.fromDegrees( |
| | | Number(item.longitude), |
| | | Number(item.latitude), |
| | | Number(item.height) |
| | | ) |
| | | let setting = { |
| | | name: 'work-drone-route-planar-polyline', |
| | | position: topPosition, |
| | | polyline: getPolyLine(this.viewer, { value: droppointPositions }, index), |
| | | } |
| | | this.viewer.entities.add(setting) |
| | | }) |
| | | // 落点线 |
| | | ; (droppointPositions || [])?.forEach((item, index) => { |
| | | const topPosition = Cesium.Cartesian3.fromDegrees( |
| | | Number(item.longitude), |
| | | Number(item.latitude), |
| | | Number(item.height) |
| | | ) |
| | | let setting = { |
| | | name: 'work-drone-route--planar-polyline', |
| | | position: topPosition, |
| | | polyline: getPolyLine(this.viewer, { value: droppointPositions }, index), |
| | | } |
| | | this.viewer.entities.add(setting) |
| | | }) |
| | | |
| | | // 面状航线第一个点突出展示 |
| | | isShowPointBillboard && this.startingIncreasePoint(positionArray) |
| | |
| | | name: 'work-drone-route-planar-border', |
| | | |
| | | polyline: { |
| | | positions: Cesium.Cartesian3.fromDegreesArrayHeights( |
| | | cloneCoordArr.flat(), |
| | | ), |
| | | positions: Cesium.Cartesian3.fromDegreesArrayHeights(cloneCoordArr.flat()), |
| | | width: 4, |
| | | material: new Cesium.PolylineOutlineMaterialProperty({ |
| | | color: new Cesium.Color.fromBytes(74, 138, 233), |
| | |
| | | // 绘制面状地块-------------------- |
| | | this.viewer.entities.add({ |
| | | name: 'work-drone-route-planar-polygon', |
| | | |
| | | polygon: { |
| | | hierarchy: Cesium.Cartesian3.fromDegreesArrayHeights( |
| | | newCoordArr.flat(), |
| | | ), |
| | | hierarchy: Cesium.Cartesian3.fromDegreesArrayHeights(newCoordArr.flat()), |
| | | material: new Cesium.Color.fromBytes(75, 159, 221, 100), |
| | | outline: true, |
| | | outlineColor: new Cesium.Color.fromBytes(35, 85, 216, 255), |
| | |
| | | |
| | | label: { |
| | | text: data.job_name || '', |
| | | font: 'bold 16px YouSheBiaoTiHei', |
| | | font: 'bold 16px sans-serif', |
| | | fillColor: Cesium.Color.WHITE, |
| | | pixelOffset: new Cesium.Cartesian2(0, -50), |
| | | style: Cesium.LabelStyle.FILL_AND_OUTLINE, |
| | |
| | | }) |
| | | } else { |
| | | // 显示机巢位置 |
| | | if (isShowDock) { |
| | | // 起点 |
| | | this.viewer.entities.add({ |
| | | name: 'work-drone-route-point-dock', |
| | | |
| | | position: droneTransformPosition, |
| | | |
| | | billboard: { |
| | | image: endingOnlineImg, |
| | | width: 50, |
| | | height: 50, |
| | | disableDepthTestDistance: Number.POSITIVE_INFINITY, |
| | | }, |
| | | |
| | | customData: { |
| | | data |
| | | } |
| | | }) |
| | | |
| | | this.viewer.entities.add({ |
| | | name: 'work-drone-route--point-polyline', |
| | | position: droneTransformPosition, |
| | | polyline: getPolyLine(this.viewer, { value: [dronePosition] }, 0), |
| | | }) |
| | | } |
| | | |
| | | const startPosition = Cesium.Cartesian3.fromDegrees( |
| | | Number(filePositions[0].lng), |
| | | Number(filePositions[0].lat), |
| | | Number(filePositions[0].alt) |
| | | ) |
| | | |
| | | isShowDock && renderingMachineNest({ |
| | | viewer: this.viewer, |
| | | dockTransformPosition, |
| | | dockPosition, |
| | | data |
| | | }) |
| | | // 起点 |
| | | isShowPointBillboard && this.viewer.entities.add({ |
| | | name: 'work-drone-route-point-start', |
| | | |
| | | position: startPosition, |
| | | |
| | | billboard: { |
| | | image: rwqfdImg, |
| | | width: 50, |
| | | height: 50, |
| | | disableDepthTestDistance: Number.POSITIVE_INFINITY, |
| | | }, |
| | | |
| | | customData: { |
| | | data |
| | | } |
| | | isShowPointBillboard && renderingStartingPoint({ |
| | | viewer: this.viewer, |
| | | startPosition: Cesium.Cartesian3.fromDegrees( |
| | | Number(filePositions[0].lng), |
| | | Number(filePositions[0].lat), |
| | | Number(filePositions[0].alt) |
| | | ), |
| | | data |
| | | }) |
| | | } |
| | | |
| | | return { |
| | | entity: planarRouteEntity, |
| | | routeLinePositions: positionArray, |
| | | filePositions: dronePosition != null ? [ |
| | | { lng: dronePosition.longitude, lat: dronePosition.latitude, alt: dronePosition.height }, |
| | | ...filePositions |
| | | ] : filePositions |
| | | filePositions: |
| | | dockPosition != null |
| | | ? [{ lng: dockPosition.longitude, lat: dockPosition.latitude, alt: dockPosition.height }, ...filePositions] |
| | | : filePositions, |
| | | } |
| | | } |
| | | |
| | |
| | | |
| | | let setting = { |
| | | name: 'work-drone-route-planar-start', |
| | | |
| | | position: positions, |
| | | |
| | | billboard: { |
| | | image: this.planarBillboard('#2D8CF0'), |
| | | pixelOffset: new Cesium.Cartesian2(146, 72), |
| | |
| | | * 绘制点航线 |
| | | * @param {*} lineObj 航线文件中的 |
| | | * @param {*} missionConfig 航线文件中的 |
| | | * @param {*} dronePosition 无人机位置 |
| | | * @param {*} dockPosition 无人机位置 |
| | | * @param {*} data 任务信息,航线地址等 |
| | | * @param {*} startPoint |
| | | * @param {*} startPoint |
| | | * @param {*} isShowDock 是否显示机巢位置 |
| | | * @param {*} isShowPointBillboard 是否显示,航线起飞点,终点等标注 |
| | | * @returns |
| | | * @returns |
| | | */ |
| | | async drawPointRoute (lineObj, missionConfig, dronePosition, data, startPoint, isShowDock, isShowPointBillboard, wayline_type) { |
| | | const { positionArray, filePositions } = this.disposeData(lineObj, missionConfig, dronePosition, data, startPoint, wayline_type) |
| | | |
| | | const droneTransformPosition = Cesium.Cartesian3.fromDegrees( |
| | | Number(dronePosition.longitude), |
| | | Number(dronePosition.latitude), |
| | | Number(dronePosition.height), |
| | | async drawPointRoute ( |
| | | lineObj, |
| | | missionConfig, |
| | | dockPosition, |
| | | data, |
| | | startPoint, |
| | | isShowDock, |
| | | isShowPointBillboard, |
| | | wayline_type |
| | | ) { |
| | | const { positionArray, filePositions } = this.disposeData( |
| | | lineObj, |
| | | missionConfig, |
| | | dockPosition, |
| | | data, |
| | | startPoint, |
| | | wayline_type |
| | | ) |
| | | |
| | | const dockTransformPosition = Cesium.Cartesian3.fromDegrees( |
| | | Number(dockPosition.longitude), |
| | | Number(dockPosition.latitude), |
| | | Number(dockPosition.height) |
| | | ) |
| | | // 路径线 |
| | | let polyline |
| | | |
| | | |
| | | indexLog = indexLog + 1 |
| | | |
| | | if (this.type === 'clusterScheduling') { |
| | | filePositions.forEach((item, index) => { |
| | | let position = Cesium.Cartesian3.fromDegrees(item.lng, item.lat, item.alt) |
| | | |
| | | if (index === 0) { |
| | | this.viewer.entities.add({ |
| | | name: 'work-drone-route-point-start', |
| | | position, |
| | | |
| | | billboard: { |
| | | image: rwqfdImg, |
| | | outlineWidth: 0, |
| | |
| | | height: 50, |
| | | disableDepthTestDistance: Number.POSITIVE_INFINITY, |
| | | }, |
| | | |
| | | label: { |
| | | text: data.job_name || '', |
| | | font: 'bold 16px YouSheBiaoTiHei', |
| | | font: 'bold 16px sans-serif', |
| | | fillColor: data.type === 2 ? runningTextColor : pendingTextColor, |
| | | pixelOffset: data.type === 2 ? runningTextOffset : pendingTextOffset, |
| | | style: Cesium.LabelStyle.FILL_AND_OUTLINE, |
| | |
| | | } else if (index === filePositions.length - 1) { |
| | | this.viewer.entities.add({ |
| | | name: 'work-drone-route-point-end', |
| | | |
| | | position, |
| | | |
| | | billboard: { |
| | | image: newEndPointImg, |
| | | outlineWidth: 0, |
| | |
| | | } else { |
| | | this.viewer.entities.add({ |
| | | name: 'work-drone-route-point-approach', |
| | | |
| | | position, |
| | | |
| | | billboard: { |
| | | image: newNumPoint, |
| | | width: 50, |
| | |
| | | }) |
| | | } |
| | | }) |
| | | |
| | | polyline = this.viewer.entities.add({ |
| | | name: 'work-drone-route-point-polyline', |
| | | |
| | | polyline: { |
| | | width: 4, |
| | | positions: positionArray, |
| | | material: data.type === 2 ? runningLineMaterial : pendingLineMaterial, |
| | | material: data.type === 2 ? getLineColor(indexLog) : arrowLineMaterialPropertyGray, |
| | | clampToGround: false, |
| | | } |
| | | }, |
| | | }) |
| | | } else { |
| | | // 显示机巢位置 |
| | | if (isShowDock) { |
| | | // 起点 |
| | | this.viewer.entities.add({ |
| | | name: 'work-drone-route-point-dock', |
| | | |
| | | position: droneTransformPosition, |
| | | |
| | | billboard: { |
| | | image: endingOnlineImg, |
| | | width: 50, |
| | | height: 50, |
| | | disableDepthTestDistance: Number.POSITIVE_INFINITY, |
| | | }, |
| | | |
| | | customData: { |
| | | data |
| | | } |
| | | }) |
| | | |
| | | this.viewer.entities.add({ |
| | | name: 'work-drone-route--point-polyline', |
| | | position: droneTransformPosition, |
| | | polyline: getPolyLine(this.viewer, { value: [dronePosition] }, 0), |
| | | }) |
| | | } |
| | | |
| | | const startPosition = Cesium.Cartesian3.fromDegrees( |
| | | Number(filePositions[0].lng), |
| | | Number(filePositions[0].lat), |
| | | Number(filePositions[0].alt) |
| | | ) |
| | | |
| | | isShowDock && renderingMachineNest({ |
| | | viewer: this.viewer, |
| | | dockTransformPosition, |
| | | dockPosition |
| | | }) |
| | | // 起点 |
| | | isShowPointBillboard && this.viewer.entities.add({ |
| | | name: 'work-drone-route-point-start', |
| | | |
| | | position: startPosition, |
| | | |
| | | billboard: { |
| | | image: rwqfdImg, |
| | | width: 50, |
| | | height: 50, |
| | | disableDepthTestDistance: Number.POSITIVE_INFINITY, |
| | | }, |
| | | |
| | | customData: { |
| | | data |
| | | } |
| | | isShowPointBillboard && renderingStartingPoint({ |
| | | viewer: this.viewer, |
| | | startPosition: Cesium.Cartesian3.fromDegrees( |
| | | Number(filePositions[0].lng), |
| | | Number(filePositions[0].lat), |
| | | Number(filePositions[0].alt) |
| | | ), |
| | | data |
| | | }) |
| | | |
| | | // 终点 |
| | | isShowPointBillboard && this.viewer.entities.add({ |
| | | name: 'work-drone-route-point-end', |
| | | |
| | | position: positionArray[positionArray.length - 1], |
| | | |
| | | billboard: { |
| | | image: new Cesium.ConstantProperty(endPointImg), |
| | | width: 30, |
| | | height: 30, |
| | | verticalOrigin: Cesium.VerticalOrigin.BOTTOM, // 底部对齐 |
| | | }, |
| | | }) |
| | | |
| | | isShowPointBillboard && |
| | | this.viewer.entities.add({ |
| | | name: 'work-drone-route-point-end', |
| | | position: positionArray[positionArray.length - 1], |
| | | billboard: { |
| | | image: new Cesium.ConstantProperty(endPointImg), |
| | | width: 30, |
| | | height: 30, |
| | | verticalOrigin: Cesium.VerticalOrigin.BOTTOM, // 底部对齐 |
| | | }, |
| | | }) |
| | | console.log(data.status, '失败') |
| | | polyline = this.viewer.entities.add({ |
| | | name: 'work-drone-route-point-polyline', |
| | | |
| | | polyline: { |
| | | width: 4, |
| | | positions: positionArray, |
| | | material: getLineColor(indexLog), |
| | | material: data.status === 5 ? arrowLineMaterialPropertyGray : getLineColor(indexLog), |
| | | clampToGround: false, |
| | | }, |
| | | |
| | | customData: { |
| | | data |
| | | } |
| | | data, |
| | | }, |
| | | }) |
| | | } |
| | | |
| | |
| | | longitude: Number(i.lng), |
| | | latitude: Number(i.lat), |
| | | height: Number(i.alt), |
| | | })); |
| | | })) |
| | | |
| | | // 落点线 |
| | | (droppointPositions || [])?.forEach((item, index) => { |
| | | const topPosition = Cesium.Cartesian3.fromDegrees( |
| | | Number(item.longitude), |
| | | Number(item.latitude), |
| | | Number(item.height) |
| | | ) |
| | | // 落点线 |
| | | ; (droppointPositions || [])?.forEach((item, index) => { |
| | | const topPosition = Cesium.Cartesian3.fromDegrees( |
| | | Number(item.longitude), |
| | | Number(item.latitude), |
| | | Number(item.height) |
| | | ) |
| | | |
| | | let setting = { |
| | | name: 'work-drone-route-point-polyline', |
| | | position: topPosition, |
| | | polyline: getPolyLine(this.viewer, { value: droppointPositions }, index), |
| | | } |
| | | this.viewer.entities.add(setting) |
| | | }) |
| | | let setting = { |
| | | name: 'work-drone-route--point-polyline', |
| | | position: topPosition, |
| | | polyline: getPolyLine(this.viewer, { value: droppointPositions }, index), |
| | | } |
| | | this.viewer.entities.add(setting) |
| | | }) |
| | | |
| | | return { |
| | | entity: polyline, |
| | | routeLinePositions: positionArray, |
| | | filePositions: dronePosition != null ? [ |
| | | { lng: dronePosition.longitude, lat: dronePosition.latitude, alt: dronePosition.height }, |
| | | ...filePositions |
| | | ] : filePositions, |
| | | filePositions: |
| | | dockPosition !== null |
| | | ? [{ lng: dockPosition.longitude, lat: dockPosition.latitude, alt: dockPosition.height }, ...filePositions] |
| | | : filePositions, |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 通用处理数据 |
| | | * @param {*} lineObj |
| | | * @param {*} missionConfig |
| | | * @param {*} dronePosition |
| | | * @param {*} startPoint |
| | | * @param {*} lineObj |
| | | * @param {*} missionConfig |
| | | * @param {*} dronePosition |
| | | * @param {*} startPoint |
| | | * @returns {} {positionArray: 带拼接点位置, filePositions:光航线点位置} |
| | | */ |
| | | disposeData (lineObj, missionConfig, dronePosition, data, startPoint, wayline_type) { |
| | | indexLog = indexLog + 1 |
| | | const { device_sn } = data |
| | | |
| | | const executeHeightMode = lineObj.executeHeightMode === "WGS84" |
| | | const executeHeightMode = lineObj.executeHeightMode === 'WGS84' |
| | | |
| | | let filePositions = lineObj.Placemark.map(item => { |
| | | const [lng, lat] = item.Point.coordinates.split(',') |
| | |
| | | let safetyHeight |
| | | |
| | | if (executeHeightMode) { |
| | | let startHeight = new Decimal(missionConfig.takeOffSecurityHeight) |
| | | .plus(dronePosition.height).toNumber() |
| | | let startHeight = new Decimal(missionConfig.takeOffSecurityHeight).plus(dronePosition?.height || 0).toNumber() |
| | | |
| | | safetyHeight = startHeight < filePositions[0].alt ? filePositions[0].alt : startHeight |
| | | } else { |
| | | safetyHeight = missionConfig.takeOffSecurityHeight < filePositions[0].alt ? filePositions[0].alt : missionConfig.takeOffSecurityHeight |
| | | safetyHeight = |
| | | missionConfig.takeOffSecurityHeight < filePositions[0].alt |
| | | ? filePositions[0].alt |
| | | : missionConfig.takeOffSecurityHeight |
| | | } |
| | | |
| | | let safetyPositions = [] |
| | |
| | | }) |
| | | |
| | | this.updataMultiNestData(device_sn, { |
| | | currentRoutePositions |
| | | currentRoutePositions, |
| | | }) |
| | | |
| | | if ([0].includes(wayline_type)) { |
| | | let startHeight = executeHeightMode ? filePositions[0].alt : filePositions[0].alt + (dronePosition != null ? dronePosition.height : 0) |
| | | let endHeight = executeHeightMode ? filePositions[1].alt : filePositions[1].alt + (dronePosition != null ? dronePosition.height : 0) |
| | | let startHeight = executeHeightMode |
| | | ? filePositions[0].alt |
| | | : filePositions[0].alt + (dronePosition != null ? dronePosition.height : 0) |
| | | let endHeight = executeHeightMode |
| | | ? filePositions[1].alt |
| | | : filePositions[1].alt + (dronePosition != null ? dronePosition.height : 0) |
| | | |
| | | this.updataMultiNestData(device_sn, { |
| | | showPopupPosition: Cesium.Cartesian3.midpoint( |
| | | Cesium.Cartesian3.fromDegrees(filePositions[0].lng, filePositions[0].lat, startHeight), |
| | | Cesium.Cartesian3.fromDegrees(filePositions[1].lng, filePositions[1].lat, endHeight), |
| | | new Cesium.Cartesian3()) |
| | | new Cesium.Cartesian3() |
| | | ), |
| | | }) |
| | | } else { |
| | | let startHeight = executeHeightMode ? safetyPositions[1].alt : safetyPositions[1].alt + (dronePosition != null ? dronePosition.height : 0) |
| | | let endHeight = executeHeightMode ? safetyPositions[2].alt : safetyPositions[2].alt + (dronePosition != null ? dronePosition.height : 0) |
| | | let startHeight = executeHeightMode |
| | | ? safetyPositions[1].alt |
| | | : safetyPositions[1].alt + (dronePosition != null ? dronePosition.height : 0) |
| | | let endHeight = executeHeightMode |
| | | ? safetyPositions[2].alt |
| | | : safetyPositions[2].alt + (dronePosition != null ? dronePosition.height : 0) |
| | | |
| | | this.updataMultiNestData(device_sn, { |
| | | showPopupPosition: Cesium.Cartesian3.midpoint( |
| | | Cesium.Cartesian3.fromDegrees(safetyPositions[1].lng, safetyPositions[1].lat, startHeight), |
| | | Cesium.Cartesian3.fromDegrees(safetyPositions[2].lng, safetyPositions[2].lat, endHeight), |
| | | new Cesium.Cartesian3()) |
| | | new Cesium.Cartesian3() |
| | | ), |
| | | }) |
| | | } |
| | | |
| | |
| | | |
| | | return { |
| | | ...item, |
| | | alt: Number(height) |
| | | alt: Number(height), |
| | | } |
| | | }) |
| | | }), |
| | | } |
| | | } |
| | | |
| | |
| | | return i?.name && i?.name.includes('work-drone-route-') |
| | | }) |
| | | |
| | | Array.isArray(entities) && entities.forEach(item => { |
| | | this.viewer?.entities.remove(item) |
| | | }) |
| | | Array.isArray(entities) && |
| | | entities.forEach(item => { |
| | | this.viewer?.entities.remove(item) |
| | | }) |
| | | } |
| | | |
| | | // 当前无人机视椎体相关 |
| | |
| | | ['wide', 'ir', 'zoom'].includes(curDroneData?.camera_type) |
| | | ) { |
| | | if (curDroneData.camera_type === 'wide') { |
| | | fov = 60 |
| | | fov = 65 |
| | | } else { |
| | | const diffFocal = zoomFactor.value[curDroneData.camera_type].max - getZoomFactor(host?.cameras?.[0], curDroneData.camera_type) |
| | | |
| | | fov = (60 / zoomFactor.value[curDroneData.camera_type].max) * (diffFocal === 0 ? 1 : diffFocal) |
| | | const cameraMultiplier = getZoomFactor(host?.cameras?.[0], curDroneData.camera_type) |
| | | switch (cameraMultiplier) { |
| | | case 2: fov = 30; break |
| | | case 3: fov = 19; break |
| | | case 4: fov = 15; break |
| | | case 5: fov = 13; break |
| | | case 6: fov = 11; break |
| | | case 7: fov = 9; break |
| | | case 8: fov = 8.34; break |
| | | case 9: fov = 7.68; break |
| | | case 10: fov = 6.9; break |
| | | case 14: fov = 5; break |
| | | default: fov = 55.946 * Math.exp(-0.4504 * cameraMultiplier) + 6.323 |
| | | } |
| | | } |
| | | } |
| | | |
| | |
| | | pitch: 0, |
| | | heading: attitude_head, |
| | | |
| | | isShowVideoPlan: this.isShowVideoPlan |
| | | }) |
| | | isShowVideoPlan: this.isShowVideoPlan, |
| | | }), |
| | | }) |
| | | } |
| | | } |
| | |
| | | |
| | | if (device_sn && live_status) { |
| | | this.updataMultiNestData(device_sn, { |
| | | camera_type: live_status?.[0].video_type || 'wide' |
| | | camera_type: live_status?.[0].video_type || 'wide', |
| | | }) |
| | | } |
| | | } |
| | |
| | | } |
| | | } |
| | | |
| | | // 设置当前无人机视椎体信息面板 |
| | | setFrustumInfoDetails (data) { |
| | | const { |
| | | dock_sn, |
| | | distance_to_airport, |
| | | distance_to_next_point, |
| | | estimated_time_to_next_point, |
| | | plane_mileage |
| | | } = data |
| | | const { dock_sn, distance_to_airport, distance_to_next_point, estimated_time_to_next_point, plane_mileage } = data |
| | | |
| | | if (dock_sn) { |
| | | const aircraftEntity = this.viewer?.entities.values.find(i => { |
| | |
| | | } |
| | | |
| | | aircraftEntity.label = new Cesium.LabelGraphics({ |
| | | text: `离机场平面距离:${distance_to_airport}m\n离下个航点平面距离:${Math.round(distance_to_next_point)}m\n到达下个航点剩余时间:${arrivalTime}\n航线总平面里程:${Math.round(plane_mileage)}m`, |
| | | text: `离机场平面距离:${distance_to_airport}m\n离下个航点平面距离:${Math.round( |
| | | distance_to_next_point |
| | | )}m\n到达下个航点剩余时间:${arrivalTime}\n航线总平面里程:${Math.round(plane_mileage)}m`, |
| | | font: '13px monospace', |
| | | showBackground: true, |
| | | horizontalOrigin: Cesium.HorizontalOrigin.CENTER, |
| | |
| | | |
| | | return |
| | | } |
| | | |
| | | } |
| | | } |
| | | |
| | |
| | | } |
| | | } |
| | | |
| | | // 设置无人机模型 |
| | | setAircraftGltf (host) { |
| | | const parent_sn = host?.parent_sn |
| | | const attitude_head = Number(host?.payloads?.[0]?.gimbal_yaw) - 90 || 0 |
| | | |
| | | if (parent_sn) { |
| | | const aircraftEntity = this.viewer?.entities.values.find(i => { |
| | |
| | | }) |
| | | |
| | | const position = Cesium.Cartesian3.fromDegrees(host?.longitude, host?.latitude, host?.height) |
| | | // ✅ 新增:Heading / Pitch / Roll(单位:度 -> 弧度) |
| | | const heading = Cesium.Math.toRadians(attitude_head) // 航向角 |
| | | const pitch = Cesium.Math.toRadians(0) // 俯仰角 |
| | | const roll = Cesium.Math.toRadians(0) // 横滚角 |
| | | |
| | | // ✅ 新增:构造 HeadingPitchRoll 和 四元数 |
| | | const hpr = new Cesium.HeadingPitchRoll(heading, pitch, roll) |
| | | const orientation = Cesium.Transforms.headingPitchRollQuaternion(position, hpr) |
| | | |
| | | if (aircraftEntity) { |
| | | aircraftEntity.position = new Cesium.ConstantPositionProperty(position) |
| | | aircraftEntity.orientation = new Cesium.ConstantProperty(orientation) |
| | | |
| | | return |
| | | } |
| | |
| | | this.viewer?.entities.add({ |
| | | name: `aircraft-glf-${parent_sn}`, |
| | | position, |
| | | orientation, |
| | | label: {}, |
| | | model: { |
| | | uri: aircraftGltf, // 或 .glb |
| | | scale: 1.0, // 缩放比例 |
| | | scale: 64, // 缩放比例 |
| | | minimumPixelSize: 64, // 最小像素尺寸(保证模型远处可见) |
| | | maximumScale: 128, // 最大缩放(可选) |
| | | maximumScale: 64, // 最大缩放(可选) |
| | | }, |
| | | }) |
| | | } |
| | | } |
| | | } |
| | | |
| | | // 移除无人机模型 |
| | | removeAircraftGltf (host) { |
| | | const parent_sn = host?.parent_sn |
| | | |
| | | if (parent_sn) { |
| | | const aircraftEntity = this.viewer?.entities.values.find(i => { |
| | | return i?.name && i?.name.includes(`aircraft-glf-${parent_sn}`) |
| | | }) |
| | | |
| | | if (aircraftEntity) { |
| | | this.viewer?.entities.remove(aircraftEntity) |
| | | } |
| | | } |
| | | } |
| | | |
| | | // 移除所有无人机视椎体 |
| | | removeViewInfoFrustum () { |
| | | this.multiNestData.forEach(item => { |
| | | if ('viewInfoFrustum' in item && item.viewInfoFrustum) { |
| | |
| | | return i?.name && i?.name.includes(`aircraft-glf-${parent_sn}`) |
| | | }) |
| | | |
| | | Array.isArray(entities) && entities.forEach(item => { |
| | | this.viewer?.entities.remove(item) |
| | | }) |
| | | Array.isArray(entities) && |
| | | entities.forEach(item => { |
| | | this.viewer?.entities.remove(item) |
| | | }) |
| | | } |
| | | } |
| | | |
| | |
| | | return i?.name && i?.name.includes(`aircraft-glf-`) |
| | | }) |
| | | |
| | | Array.isArray(entities) && entities.forEach(item => { |
| | | this.viewer?.entities.remove(item) |
| | | }) |
| | | Array.isArray(entities) && |
| | | entities.forEach(item => { |
| | | this.viewer?.entities.remove(item) |
| | | }) |
| | | |
| | | this.multiNestData.length > 0 && (this.multiNestData.forEach(item => { |
| | | item.viewInfoFrustum?.clear() |
| | | })) |
| | | this.multiNestData.length > 0 && |
| | | this.multiNestData.forEach(item => { |
| | | item.viewInfoFrustum?.clear() |
| | | }) |
| | | } |
| | | |
| | | /** |
| | |
| | | this.multiNestData[isHaveInd] = { |
| | | ...this.multiNestData[isHaveInd], |
| | | |
| | | ...data |
| | | ...data, |
| | | } |
| | | } else { |
| | | this.multiNestData.push({ |
| | | device_sn, |
| | | ...data |
| | | ...data, |
| | | }) |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 根据机巢sn获取当前机巢对应的相关信息 |
| | | * @param {*} device_sn |
| | | * @param {*} device_sn |
| | | */ |
| | | getCurDroneData (device_sn) { |
| | | const isHave = this.multiNestData.find(item => item.device_sn === device_sn) |
| | |
| | | return { |
| | | ...item, |
| | | show: true, |
| | | uuid: uuidv4() |
| | | uuid: uuidv4(), |
| | | } |
| | | }) |
| | | this.viewer.scene.postRender.addEventListener(that.labelBoxRenderHandler) |
| | | } |
| | | |
| | | showSingleDetailMapPopup (data) { |
| | | this.detailsMapPopupData.forEach(i => i.job_id === data.job_id && i.device_sn === data.device_sn && (i.show = true)) |
| | | this.detailsMapPopupData.forEach( |
| | | i => i?.job_id === data?.job_id && i?.device_sn === data?.device_sn && (i.show = true) |
| | | ) |
| | | } |
| | | |
| | | getLabelDom (data) { |
| | |
| | | tooltipContainer.style.position = 'absolute' |
| | | tooltipContainer.style.transform = 'translate(-50%,10%)' |
| | | tooltipContainer.style.pointerEvents = 'none' |
| | | document.querySelector('.content-map-popups')?.append(tooltipContainer) |
| | | document.querySelector('.content-map-popups').append(tooltipContainer) |
| | | render(vNode, tooltipContainer) |
| | | return tooltipContainer |
| | | } |
| | | |
| | | labelBoxRender () { |
| | | this.detailsMapPopupData.filter(i => i.show === true).forEach(item => { |
| | | const { showPopupPosition } = this.getCurDroneData(item.device_sn) |
| | | this.detailsMapPopupData |
| | | .filter(i => i.show === true) |
| | | .forEach(item => { |
| | | const { showPopupPosition } = this.getCurDroneData(item.device_sn) |
| | | |
| | | let dom = document.querySelector(`[id="${item.uuid}"]`) |
| | | let dom = document.querySelector(`[id="${item.uuid}"]`) |
| | | |
| | | if (!dom) { |
| | | dom = this.getLabelDom(item) |
| | | } |
| | | if (!dom) { |
| | | dom = this.getLabelDom(item) |
| | | } |
| | | |
| | | const screenPosition = this.viewer?.scene.cartesianToCanvasCoordinates(showPopupPosition) |
| | | if (screenPosition) { |
| | | dom.style.left = `${screenPosition.x}px` |
| | | dom.style.top = `${screenPosition.y}px` |
| | | dom.style.display = 'block' |
| | | } |
| | | }) |
| | | const screenPosition = this.viewer?.scene.cartesianToCanvasCoordinates(showPopupPosition) |
| | | if (screenPosition) { |
| | | dom.style.left = `${screenPosition.x}px` |
| | | dom.style.top = `${screenPosition.y}px` |
| | | dom.style.display = 'block' |
| | | } |
| | | }) |
| | | } |
| | | |
| | | // 移除弹框标签 |
| | |
| | | const that = this |
| | | that.viewer?.scene.postRender.removeEventListener(that.labelBoxRenderHandler) |
| | | } |
| | | } |
| | | } |