diff --git a/src/api/sys/workplan.ts b/src/api/sys/workplan.ts index fe75b1e..f219525 100644 --- a/src/api/sys/workplan.ts +++ b/src/api/sys/workplan.ts @@ -22,7 +22,13 @@ enum Api{ EditAirLine = '/api/Manage/EditAirLine', GetAirLine = '/api/Manage/GetAirLine', DeleteAirLine = '/api/Manage/DeleteAirLine', - UploadXmlFile = '/api/Manage/UploadXmlFile/upload' + UploadXmlFile = '/api/Manage/UploadXmlFile/upload', + + + // 文件目录 + ListAirLineFolder = '/api/Manage/ListAirLineFolder', + DeleteAirLineFolder = '/api/Manage/DeleteAirLineFolder', + CreateAirLineFolder = '/api/Manage/CreateAirLineFolder' } @@ -89,3 +95,21 @@ export function deleteAirLine(params){ } +// 文件目录 +export function getListAirLineFolder(params) { + return defHttp.get({ url: Api.ListAirLineFolder, params }); +} + +export function deleteAirLineFolder(params){ + return defHttp.post({ url: Api.DeleteAirLineFolder+"?folderId="+params.folderId }); +} + +export function createAirLineFolder(params){ + return defHttp.post({ url: Api.CreateAirLineFolder, params }); +} + + + + + + diff --git a/src/views/demo/workmanagement/workplan/components/airLineList.vue b/src/views/demo/workmanagement/workplan/components/airLineList.vue index aff7e7e..f9f3bd3 100644 --- a/src/views/demo/workmanagement/workplan/components/airLineList.vue +++ b/src/views/demo/workmanagement/workplan/components/airLineList.vue @@ -61,7 +61,7 @@
文件夹
-
+
@@ -70,7 +70,17 @@ multiple :tree-data="treeData" :defaultExpandAll="true" - > + :autoExpandParent="true" + :field-names="fieldNames" + + > + +
@@ -101,9 +111,9 @@ 预览 - + 删除 @@ -185,13 +195,30 @@
+ + + + +
+
文件名称:
+ +
+
\ No newline at end of file diff --git a/src/views/demo/workmanagement/workplan/components/airPoint.vue b/src/views/demo/workmanagement/workplan/components/airPoint.vue index 2cf5760..91059b7 100644 --- a/src/views/demo/workmanagement/workplan/components/airPoint.vue +++ b/src/views/demo/workmanagement/workplan/components/airPoint.vue @@ -463,6 +463,8 @@ const saveAirLine = ()=>{ let xmlString3 = xmlString2.replace("",``) + console.log("xmlString3",xmlString3); + return null; handlerCreateFile(xmlString3); } diff --git a/src/views/demo/workmanagement/workplan/components/airPolygon.vue b/src/views/demo/workmanagement/workplan/components/airPolygon.vue index 43a2f9a..7eade6b 100644 --- a/src/views/demo/workmanagement/workplan/components/airPolygon.vue +++ b/src/views/demo/workmanagement/workplan/components/airPolygon.vue @@ -4,10 +4,10 @@
面状航线
- +
- +
@@ -79,6 +79,15 @@
%
+ +
+
航线间距
+
+ +
+
m
+
+
主航线角度
@@ -237,6 +246,7 @@ const calculatParam = ref({ overlapAngle:0, height:0, spacing:0, + safeyFlyHeight:20, }) watch( @@ -247,6 +257,8 @@ watch( {deep:true} ) + + calculatParam.value.height = calculateHeight(calculatParam.value.gsd,uavModel['m4td']); calculatParam.value.spacing = calculateSpacing(calculatParam.value.gsd,calculatParam.value.overlapY/100,uavModel['m4td']) @@ -296,15 +308,81 @@ const missionConfig = ref( ) + +watch( + () => missionConfig.value, + (newVal,oldVal) => { + calculatParam.value.safeyFlyHeight = missionConfig.value.takeOffSecurityHeight; + }, + {deep:true} +) + // 航点基本信息 const folder = ref({ "templateId": 0, "executeHeightMode": "WGS84", "waylineId": 0, - "distance": 410.047576904297, - "duration": 80.3239784240723, - "autoFlightSpeed": 10, - "Placemark":[] + "distance": 1391.755859375, + "duration": 200.941531419754, + "autoFlightSpeed": 8.2, + "startActionGroup": { + "action": [ + { + "actionId": 0, + "actionActuatorFunc": "gimbalRotate", + "actionActuatorFuncParam": { + "gimbalHeadingYawBase": "aircraft", + "gimbalRotateMode": "absoluteAngle", + "gimbalPitchRotateEnable": 1, + "gimbalPitchRotateAngle": -90, + "gimbalRollRotateEnable": 0, + "gimbalRollRotateAngle": 0, + "gimbalYawRotateEnable": 1, + "gimbalYawRotateAngle": 0, + "gimbalRotateTimeEnable": 0, + "gimbalRotateTime": 10, + "payloadPositionIndex": 0 + } + }, + { + "actionId": 1, + "actionActuatorFunc": "hover", + "actionActuatorFuncParam": { + "hoverTime": 0.5 + } + }, + { + "actionId": 2, + "actionActuatorFunc": "setFocusType", + "actionActuatorFuncParam": { + "cameraFocusType": "manual", + "payloadPositionIndex": 0 + } + }, + { + "actionId": 3, + "actionActuatorFunc": "focus", + "actionActuatorFuncParam": { + "focusX": 0, + "focusY": 0, + "focusRegionWidth": 0, + "focusRegionHeight": 0, + "isPointFocus": 0, + "isInfiniteFocus": 1, + "payloadPositionIndex": 0, + "isCalibrationFocus": 0 + } + }, + { + "actionId": 4, + "actionActuatorFunc": "hover", + "actionActuatorFuncParam": { + "hoverTime": 1 + } + } + ] + }, + Placemark:[] }) // 航点详细信息 @@ -413,16 +491,18 @@ const pointInfo = { const handlerPointInfo = ()=>{ if(props.airPoints?.length<=0){ - message.warning("请添加航点!"); + message.warning("请绘制航测区域!"); return null; } + + let placemarkArray = []; props.airPoints?.forEach((item,index)=>{ let point = { "Point": { "coordinates": item.lng+","+item.lat // 坐标 }, "index": index, // 序号 - "executeHeight": 167, // 高度 + "executeHeight": item.alt, // 高度 "waypointSpeed": 12.7125370218057, // 飞行速度 "waypointHeadingParam": { // 飞行器参数 "waypointHeadingMode": "followWayline", // 偏航角模式 和航线角度一致 @@ -516,9 +596,11 @@ const handlerPointInfo = ()=>{ "isRisky": 0, "waypointWorkType": 0 } - - folder.value.Placemark?.push(point); - }) + placemarkArray.push(point); + + }); + + folder.value.Placemark = placemarkArray; return true; @@ -544,11 +626,14 @@ const saveAirLine = ()=>{ let handlerResult = handlerPointInfo(); if(handlerResult){ + const builder = new XMLBuilder(); let lineData = {...waylinesJson.value} let obj = handlerPrefixWpml(lineData); + + console.log("obj1234",obj); let xmlString = builder.build(obj); @@ -556,6 +641,12 @@ const saveAirLine = ()=>{ let xmlString3 = xmlString2.replace("",``) + convertXmlToWmpl(xmlString3); + + console.log("xmlString3",xmlString3); + + return null; + handlerCreateFile(xmlString3); } @@ -564,8 +655,9 @@ const saveAirLine = ()=>{ // 处理wmpl:前缀 const handlerPrefixWpml = (obj) => { - for (const key in obj) { + console.log("obj123",obj); + for (const key in obj) { // 如果是对象 if (typeof obj[key] === 'object' && obj[key] !== null) { @@ -573,7 +665,6 @@ const handlerPrefixWpml = (obj) => { const newAttrs = {}; for (const attrName in obj[key]) { - // 检查属性名是否首字母小写 if (/^[a-z]/.test(attrName)) { newAttrs[`wmpl:${attrName}`] = obj[key][attrName]; @@ -611,10 +702,13 @@ const submitForm = ref({ // 生成xml文件,创建航线 const handlerCreateFile =async (content)=>{ + const blob = new Blob([content], { type: 'wmpl/plain' }); + // 创建FormData对象用于上传 const formData = new FormData(); formData.append('xmlFile', blob); + let res = await uploadXmlFile(formData); if(res){ submitForm.value.wpml = res.path; @@ -630,6 +724,17 @@ const handlerCreateFile =async (content)=>{ } } +// xml文本转换为wmpl和kml文件 +const convertXmlToWmpl = (xmlString)=>{ + + const parser = new DOMParser(); + + const xmlDoc = parser.parseFromString(xmlString, "text/xml"); + + console.log(); + + console.log(xmlDoc); +} // 退出绘制 const backPage = ()=>{ emits("exitDraw") diff --git a/src/views/demo/workmanagement/workplan/components/createAirLine.vue b/src/views/demo/workmanagement/workplan/components/createAirLine.vue index 0b66aad..fbabbe4 100644 --- a/src/views/demo/workmanagement/workplan/components/createAirLine.vue +++ b/src/views/demo/workmanagement/workplan/components/createAirLine.vue @@ -95,27 +95,31 @@ name:"面状航线", checked:false, icon:'', - },{ - name:"带状航线", - checked:false, - icon:'', - } + }, + // { + // name:"带状航线", + // checked:false, + // icon:'', + // } ]) const airType = ref([ + // { + // name:"经纬 M30 系列", + // checked:false, + // },{ + // name:"Mavic 3 行业系列", + // checked:false, + // }, + // { + // name:"Matrice 3D 系列", + // checked:false, + // }, + // { + // name:"Matrice 4 行业系列", + // checked:false, + // }, { - name:"经纬 M30 系列", - checked:false, - },{ - name:"Mavic 3 行业系列", - checked:false, - },{ - name:"Matrice 3D 系列", - checked:false, - },{ - name:"Matrice 4 行业系列", - checked:false, - },{ name:"Matrice 4D 系列", checked:false, } @@ -125,7 +129,8 @@ { name:"Matrice 4D", checked:false, - },{ + }, + { name:"Matrice 4TD", checked:false, } diff --git a/src/views/demo/workmanagement/workplan/components/createWorkPlan.vue b/src/views/demo/workmanagement/workplan/components/createWorkPlan.vue index 14bb927..203f49b 100644 --- a/src/views/demo/workmanagement/workplan/components/createWorkPlan.vue +++ b/src/views/demo/workmanagement/workplan/components/createWorkPlan.vue @@ -20,7 +20,7 @@
- + @@ -80,8 +80,8 @@
{{item.label}}
@@ -95,12 +95,12 @@ - + -
+
@@ -492,17 +492,19 @@ const onOnceTimeChange = (e) => { let yearTime = time.getFullYear(); let cronTime = secondTime+" "+minutisTime+" "+ hourTime+" "+ dayTime+" "+monthTime+" ? "+yearTime + + submitForm.value.periodicFormula = cronTime; } // 选择日期 const onRepeatDateChange = (e) =>{ - console.log(e); + } // 选择时间 const onRepeatTimeChange = (e) => { - console.log("123",e); + } // 重复定时 @@ -541,7 +543,7 @@ const handleRepeatTypeChange = (e)=>{ break; } - submitForm.value.executeTime = cronTime; + submitForm.value.periodicFormula = cronTime; } diff --git a/src/views/demo/workmanagement/workplan/components/map.vue b/src/views/demo/workmanagement/workplan/components/map.vue index 4d8c1fc..6af5fd7 100644 --- a/src/views/demo/workmanagement/workplan/components/map.vue +++ b/src/views/demo/workmanagement/workplan/components/map.vue @@ -21,11 +21,13 @@ :airInfo="airInfo" :polygonAirForm="polygonAirForm" :airRoute="props.airRoute" + :airPoints="airPoints" @calculatParamChange="calculatParamChange" @exitDraw="exitDraw" >
+
@@ -147,11 +149,7 @@ const generatePreviewPoint = (placemark)=>{ airPoints.value?.forEach((item, index) => { coordinates.push([item.lng, item.lat]); }); - - console.log('coordinates', coordinates); - let line = turf.lineString(coordinates); - preViewPolygonWayLine(line); } }; @@ -220,7 +218,8 @@ const generatePreviewPoint = (placemark)=>{ drawGraphicLayer ? drawGraphicLayer.clear() : null; stickGroundPointLayer ? stickGroundPointLayer.clear() : null; lineGroundPointLayer ? lineGroundPointLayer.clear() : null; - + labelGraphicLayer ? labelGraphicLayer.clear() : null; + polygonGraphicLayer ? polygonGraphicLayer.clear() : null; polygonLineGraphicLayer ? polygonLineGraphicLayer.clear() : null; airPoints.value = []; @@ -268,223 +267,271 @@ const generatePreviewPoint = (placemark)=>{ }); }); - const initMap = () => { - map = new mars3d.Map(vChartRef.value, { - scene: { - center: { lat: 35.132103, lng: 118.296315, alt: 260.9, heading: 357.9, pitch: -32 }, - scene3DOnly: false, - shadows: false, - removeDblClick: true, - sceneMode: 3, - showSun: true, - showMoon: true, - showSkyBox: true, - showSkyAtmosphere: true, - fog: true, - fxaa: true, - requestRenderMode: true, - contextOptions: { - requestWebgl1: false, - webgl: { - preserveDrawingBuffer: true, - alpha: false, - stencil: true, - powerPreference: 'high-performance', - }, +// 初始化地图 +const initMap = () => { + map = new mars3d.Map(vChartRef.value, { + scene: { + center: { lat: 35.132103, lng: 118.296315, alt: 260.9, heading: 357.9, pitch: -32 }, + scene3DOnly: false, + shadows: false, + removeDblClick: true, + sceneMode: 3, + showSun: true, + showMoon: true, + showSkyBox: true, + showSkyAtmosphere: true, + fog: true, + fxaa: true, + requestRenderMode: true, + contextOptions: { + requestWebgl1: false, + webgl: { + preserveDrawingBuffer: true, + alpha: false, + stencil: true, + powerPreference: 'high-performance', }, + }, - globe: { - depthTestAgainstTerrain: true, - baseColor: '#546a53', - showGroundAtmosphere: true, - enableLighting: false, - }, - cameraController: { - zoomFactor: 3, - minimumZoomDistance: 1, - maximumZoomDistance: 50000000, - enableRotate: true, - enableTranslate: true, - enableTilt: true, - enableZoom: true, - enableCollisionDetection: true, - minimumCollisionTerrainHeight: 15000, - }, + globe: { + depthTestAgainstTerrain: true, + baseColor: '#546a53', + showGroundAtmosphere: true, + enableLighting: false, }, - control: { - homeButton: true, - baseLayerPicker: false, - sceneModePicker: true, - vrButton: false, - fullscreenButton: true, - navigationHelpButton: true, - animation: false, - timeline: false, - infoBox: false, - geocoder: false, - selectionIndicator: false, - showRenderLoopErrors: true, - contextmenu: { - hasDefault: true, - }, - mouseDownView: true, - zoom: { - insertIndex: 1, - }, - compass: { - bottom: 'toolbar', - left: '5px', - rotation: true, - }, - distanceLegend: { - left: '10px', - bottom: '2px', - }, - locationBar: { - crs: 'CGCS2000_GK_Zone_3', - crsDecimal: 0, - template: - "
经度:{lng}
纬度:{lat}
横{crsx} 纵{crsy}
海拔:{alt}米
层级:{level}
方向:{heading}°
俯仰角:{pitch}°
视高:{cameraHeight}米
", - cacheTime: 50, - }, + cameraController: { + zoomFactor: 3, + minimumZoomDistance: 1, + maximumZoomDistance: 50000000, + enableRotate: true, + enableTranslate: true, + enableTilt: true, + enableZoom: true, + enableCollisionDetection: true, + minimumCollisionTerrainHeight: 15000, }, - method: { - templateValues: { - dataServer: '//data.mars3d.cn', - gltfServerUrl: '//data.mars3d.cn/gltf', - }, + }, + control: { + homeButton: true, + baseLayerPicker: false, + sceneModePicker: true, + vrButton: false, + fullscreenButton: true, + navigationHelpButton: true, + animation: false, + timeline: false, + infoBox: false, + geocoder: false, + selectionIndicator: false, + showRenderLoopErrors: true, + contextmenu: { + hasDefault: true, }, - terrain: { - url: '//data.mars3d.cn/terrain', - show: true, - clip: true, + mouseDownView: true, + zoom: { + insertIndex: 1, }, - basemaps: [ - { - "id": 10, - "name": "地图底图", - "type": "group" - }, - { - "id": 2021, - "pid": 10, - "name": "天地图影像", - "icon": "https://data.mars3d.cn/img/thumbnail/basemap/tdt_img.png", - "type": "group", - "layers": [ - { - "name": "底图", - "type": "tdt", - "layer": "img_d" - }, - { - "name": "注记", - "type": "tdt", - "layer": "img_z", - "zIndex":20, - } - ], - "zIndex":20, - "show": true - }, - ], - layers: [ + compass: { + bottom: 'toolbar', + left: '5px', + rotation: true, + }, + distanceLegend: { + left: '10px', + bottom: '2px', + }, + locationBar: { + crs: 'CGCS2000_GK_Zone_3', + crsDecimal: 0, + template: + "
经度:{lng}
纬度:{lat}
横{crsx} 纵{crsy}
海拔:{alt}米
层级:{level}
方向:{heading}°
俯仰角:{pitch}°
视高:{cameraHeight}米
", + cacheTime: 50, + }, + }, + method: { + templateValues: { + dataServer: '//data.mars3d.cn', + gltfServerUrl: '//data.mars3d.cn/gltf', + }, + }, + terrain: { + url: '//data.mars3d.cn/terrain', + show: true, + clip: true, + }, + basemaps: [ + { + "id": 10, + "name": "地图底图", + "type": "group" + }, + { + "id": 2021, + "pid": 10, + "name": "天地图影像", + "icon": "https://data.mars3d.cn/img/thumbnail/basemap/tdt_img.png", + "type": "group", + "layers": [ + { + "name": "底图", + "type": "tdt", + "layer": "img_d" + }, + { + "name": "注记", + "type": "tdt", + "layer": "img_z", + "zIndex":20, + } + ], + "zIndex":20, + "show": true + }, + ], + layers: [ - ], + ], + }); + + map.on(mars3d.EventType.load, function (event) { + // 地图右键菜单 + handlerBindMapMenus(); + + graphicLayer = new mars3d.layer.GraphicLayer({ + isAutoEditing: false, // 是否自动激活编辑 }); - map.on(mars3d.EventType.load, function (event) { - // 地图右键菜单 - handlerBindMapMenus(); + graphicLayer.bindContextMenu([ + { + text: '按轴平移', + icon: 'fa fa-pencil', + callback: (event) => { + const graphic = event.graphic; + let id = event.graphic.options.id; - graphicLayer = new mars3d.layer.GraphicLayer({ - isAutoEditing: false, // 是否自动激活编辑 - }); - - drawGraphicLayer = new mars3d.layer.GraphicLayer({ - isAutoEditing:false, - }) - - graphicLayer.bindContextMenu([ - { - text: '按轴平移', - icon: 'fa fa-pencil', - callback: (event) => { - const graphic = event.graphic; - let id = event.graphic.options.id; - - if (moveTool) { - return null; - } - // 按轴移动 - moveTool = new mars3d.thing.MatrixMove2({ - position: graphic.position, - }); - map.addThing(moveTool); - moveTool.on(mars3d.EventType.change, (event) => { - graphic.position = event.position; - pointMove(event, id); - }); - }, + if (moveTool) { + return null; + } + // 按轴移动 + moveTool = new mars3d.thing.MatrixMove2({ + position: graphic.position, + }); + map.addThing(moveTool); + moveTool.on(mars3d.EventType.change, (event) => { + graphic.position = event.position; + pointMove(event, id); + }); }, - { - text: '停止平移', - icon: 'fa fa-pencil', - callback: (event) => { - const graphic = event.graphic; - if (moveTool) { - map.removeThing(moveTool); - moveTool.destroy(); - moveTool = null; - console.log('moveTool', moveTool); - } - }, + }, + { + text: '停止平移', + icon: 'fa fa-pencil', + callback: (event) => { + const graphic = event.graphic; + if (moveTool) { + map.removeThing(moveTool); + moveTool.destroy(); + moveTool = null; + } }, - { - text: '删除', - icon: 'fa fa-camera-retro', // 支持 font-class 的字体方式图标 - callback: (e) => { - deleteAirPoint(e); - }, + }, + { + text: '删除', + icon: 'fa fa-camera-retro', // 支持 font-class 的字体方式图标 + callback: (e) => { + deleteAirPoint(e); }, - ]); + }, + ]); - map.addLayer(graphicLayer); - map.addLayer(drawGraphicLayer); + map.addLayer(graphicLayer); - // 航点地面投影点 - stickGroundPointLayer = new mars3d.layer.GraphicLayer({ - isAutoEditing: false, // 是否自动激活编辑 - }); - map.addLayer(stickGroundPointLayer); - // 航点连接线 - lineGroundPointLayer = new mars3d.layer.GraphicLayer({ - isAutoEditing: false, // 是否自动激活编辑 - }); - map.addLayer(lineGroundPointLayer); + // 参考起飞点图层 + drawGraphicLayer = new mars3d.layer.GraphicLayer({ + isAutoEditing:true, + }) - // 绘制航线 - graphicLayer.on(mars3d.EventType.click, (e) => { - // 设置当前选中点 - - clickPoint(e.graphic.options.id); - }); - - // 绘制起点 - // handlerDrawStartPoint(); - - if (props.airPort) { - setAirportPosition(); - } - if (props.uavTrack) { - setUAVPosition(); - } - // 加载长光高清影像 - // loadChangGuangLayer(); - emits('mapOnLoad',map) + drawGraphicLayer.on(mars3d.EventType.editMovePoint, function (event) { + flyPointMove(event); }); - }; + + map.addLayer(drawGraphicLayer); + + // 航点地面投影点 + stickGroundPointLayer = new mars3d.layer.GraphicLayer({ + isAutoEditing: false, // 是否自动激活编辑 + }); + map.addLayer(stickGroundPointLayer); + + // 航点连接线 + lineGroundPointLayer = new mars3d.layer.GraphicLayer({ + isAutoEditing: false, // 是否自动激活编辑 + }); + map.addLayer(lineGroundPointLayer); + + // 绘制航线 + graphicLayer.on(mars3d.EventType.click, (e) => { + // 设置当前选中点 + + clickPoint(e.graphic.options.id); + }); + + // 绘制起点 + // handlerDrawStartPoint(); + + if (props.airPort) { + setAirportPosition(); + } + if (props.uavTrack) { + setUAVPosition(); + } + // 加载长光高清影像 + // loadChangGuangLayer(); + + emits('mapOnLoad',map) + + }); +}; + +// 绑定地图右键菜单 +const handlerBindMapMenus = () => { + const mapContextmenuItems = [ + { + text: '飞行到此处', + icon: 'fa fa-camera-retro', // 支持 font-class 的字体方式图标 + callback: (e) => { + flyToThere(e); + }, + }, + { + text: '添加航点', + icon: 'fa fa-camera-retro', // 支持 font-class 的字体方式图标 + callback: (e) => { + if (!startPosition.value) { + message.warning('请先设置起飞点'); + return null; + } + handlerDrawPoint(e); + }, + }, + { + text: '添加面区域', + icon: 'fa fa-camera-retro', // 支持 font-class 的字体方式图标 + callback: (e) => { + if (!polygonAirForm.value.startingPoint) { + message.warning('请先设置起飞点'); + return null; + } + handlerDrawPolygon(); + }, + }, + ]; + map.bindContextMenu(mapContextmenuItems); +}; + +///////////////////////////////图层和影像加载//////////////////////////////////////////// + // 加载长光卫星高分影像 const loadChangGuangLayer = ()=>{ @@ -503,171 +550,85 @@ const loadChangGuangLayer = ()=>{ map.addLayer(layer); } - // 绑定地图右键菜单 - const handlerBindMapMenus = () => { - const mapContextmenuItems = [ - { - text: '飞行到此处', - icon: 'fa fa-camera-retro', // 支持 font-class 的字体方式图标 - callback: (e) => { - flyToThere(e); - }, + +///////////////////////////////参考起飞点//////////////////////////////////////////// + +// 全局参考起飞点 +const startPosition = ref(null); + +// 设置起飞点 +const setFlyPoint = async () => { + drawGraphicLayer ? drawGraphicLayer.clear() : null; + const graphic = await drawGraphicLayer.startDraw({ + type: 'billboardP', + style: { + image: '/map/start.png', + horizontalOrigin: Cesium.HorizontalOrigin.CENTER, + verticalOrigin: Cesium.VerticalOrigin.BOTTOM, + label: { + text: '参考起飞点', + font_size: 16, + color: '#ffffff', + outline: true, + outlineColor: '#000000', + pixelOffsetY: -50, }, - { - text: '添加航点', - icon: 'fa fa-camera-retro', // 支持 font-class 的字体方式图标 - callback: (e) => { - if (!startPosition.value) { - message.warning('请先设置起飞点'); - return null; - } - handlerDrawPoint(e); - }, - }, - { - text: '添加面区域', - icon: 'fa fa-camera-retro', // 支持 font-class 的字体方式图标 - callback: (e) => { - if (!polygonAirForm.value.startingPoint) { - message.warning('请先设置起飞点'); - return null; - } - handlerDrawPolygon(); - }, - }, - ]; - map.bindContextMenu(mapContextmenuItems); - }; + }, + }); + startPosition.value = graphic.toJSON().position; + polygonAirForm.value.startingPoint = graphic.toJSON().position; + // 更新航线 + updatePolygonLineByParams(); +}; +// 参考起飞点移动 +const flyPointMove = (e) => { + let res = handlerGetLngLatHeight(e); + startPosition.value = [res.lng,res.lat,res.alt]; + polygonAirForm.value.startingPoint = [res.lng,res.lat,res.alt]; + // 更新航线 + updatePolygonLineByParams(); - // 航点移动 - const pointMove = (e, id) => { - const cartographic = mars3d.Cesium.Cartographic.fromCartesian(e.position); - const longitude = mars3d.Cesium.Math.toDegrees(cartographic.longitude); - const latitude = mars3d.Cesium.Math.toDegrees(cartographic.latitude); - const height = cartographic.height; // 高度(米) - let stickGraphic = stickGroundPointLayer.getGraphicById('stick' + id); - if (stickGraphic) { - stickGraphic.setOptions({ - position: [longitude, latitude], - style: { - color: '#f5f5f5', - pixelSize: 8, - outline: true, - outlineColor: '#f5f5f5', - outlineWidth: 1, - clampToGround: true, - }, - }); - } - let lineGraphic = lineGroundPointLayer.getGraphicById('line' + id); - if (lineGraphic) { - lineGraphic.setOptions({ - positions: [ - [longitude, latitude, height], - [longitude, latitude, 0], - ], - style: { - color: '#f5f5f5', - width: 1, - }, - }); - } +} - // 更新坐标数据 - airPoints.value?.forEach((item, index) => { - if (item.id == id) { - airPoints.value[index].lng = longitude; - airPoints.value[index].lat = latitude; - airPoints.value[index].alt = height; - } - }); +// 处理Graphic鼠标事件返回信息 +const handlerGetLngLatHeight = (e)=>{ - // 更新航线 - handlerDrawLine(); - }; + let cartographic = mars3d.Cesium.Cartographic.fromCartesian(e.cartesian); + let longitude = mars3d.Cesium.Math.toDegrees(cartographic.longitude); + let latitude = mars3d.Cesium.Math.toDegrees(cartographic.latitude); + let height = cartographic.height; - // 绘制航线 - const handlerDrawLine = () => { - let positions = []; + let res = { + lng:longitude, + lat:latitude, + alt:height + } + return res; +} - airPoints.value?.forEach((item, index) => { - positions.push([item.lng, item.lat, item.alt]); - }); +///////////////////////////////面状航线计算//////////////////////////////////////////// - positions.unshift([startPosition.value[0], startPosition.value[1], airPoints.value[0].alt]); +// 全局面状测区 - positions.unshift([startPosition.value[0], startPosition.value[1], startPosition.value[2]]); +const polygonGeoJson = ref(); - // 判断是否已经绘制 - if (positions.length > 1) { - let lineGraphic = graphicLayer.getGraphicById('pointsLine'); +const polygonCalculateParams = ref({ + "gsd": 0, + "overlapY": 70, + "overlapX": 80, + "overlapAngle": 0, + "height": 0, + "spacing": 0, + "safeyFlyHeight":20, +}) - if (lineGraphic) { - lineGraphic.setOptions({ - id: 'pointsLine', - positions: positions, - style: { - width: 2, - color: '#3388ff', - }, - }); - } else { - const graphic = new mars3d.graphic.PolylineEntity({ - id: 'pointsLine', - positions: positions, - style: { - width: 2, - color: '#3388ff', - }, - }); - graphicLayer.addGraphic(graphic); - } - } - - // 计算航线长度 - // let lineString = turf.lineString(positions); - // lineInfo.value.length = turf.length(lineString).toFixed(2); - }; - - const startPosition = ref(null); - - // 设置起飞点 - const setFlyPoint = async () => { - - drawGraphicLayer ? drawGraphicLayer.clear : null; - - const graphic = await drawGraphicLayer.startDraw({ - type: 'billboardP', - style: { - image: '/map/start.png', - horizontalOrigin: Cesium.HorizontalOrigin.CENTER, - verticalOrigin: Cesium.VerticalOrigin.BOTTOM, - label: { - text: '参考起飞点', - font_size: 16, - color: '#ffffff', - outline: true, - outlineColor: '#000000', - pixelOffsetY: -50, - }, - }, - }); - - startPosition.value = graphic.toJSON().position; - - polygonAirForm.value.startingPoint = graphic.toJSON().position; - }; - - // 全局区域 - const polygonGeoJson = ref(); - - // 绘制面状 - const handlerDrawPolygon = async () => { - if (polygonGraphicLayer == null) { +// 绘制面状测区 +const handlerDrawPolygon = async () => { + if (polygonGraphicLayer == null) { polygonGraphicLayer = new mars3d.layer.GraphicLayer({ - isAutoEditing: false, // 是否自动激活编辑 + isAutoEditing: true, // 是否自动激活编辑 }); polygonGraphicLayer.bindContextMenu([ @@ -679,1101 +640,1331 @@ const loadChangGuangLayer = ()=>{ }, }, ]); - map.addLayer(polygonGraphicLayer); - } - const graphic = await polygonGraphicLayer.startDraw({ - type: 'polygon', - style: { - color: '#408eff', - opacity: 0.3, - outline: true, - outlineColor: '#408eff', - outlineWidth: 3.0, - clampToGround: true, - }, - }); - - let coordinates = graphic.toJSON().positions; - - coordinates.push(coordinates[0]); - - polygonGeoJson.value = coordinates; - - let polygon = turf.polygon([coordinates]); - let lines = generateScanLines(polygon, 0.005, 0); - - // 绘制区域转存wkt - // let wkt = GeojsonToWkt(polygon.geometry); - - CalculateAreaInfo(polygon, lines); - - // 绘制面航线 - handlerDrawPolygonLine(lines); - }; - - // 绘制面航线 - const handlerDrawPolygonLine = (lines) => { - - let nodeGraphic = polygonGraphicLayer.getGraphicById("polygon-node-1"); - - if(nodeGraphic){ - nodeGraphic.setOptions({ - id: 'polygon-node-1', - name: '航点', - position: lines.geometry.coordinates[0], - style: { - image: '/map/node.png', - scale: 1, - horizontalOrigin: Cesium.HorizontalOrigin.CENTER, - verticalOrigin: Cesium.VerticalOrigin.BOTTOM, - label: { - text: '', - font_size: 14, - color: '#ffffff', - outline: true, - outlineColor: '#000000', - pixelOffsetY: -35, - }, - }, + polygonGraphicLayer.on(mars3d.EventType.editMovePoint,(event)=>{ + handlerPolygonEdit(event); }) - }else{ - const graphic = new mars3d.graphic.BillboardEntity({ - id: 'polygon-node-1', - name: '航点', - position: lines.geometry.coordinates[0], - style: { - image: '/map/node.png', - scale: 1, - horizontalOrigin: Cesium.HorizontalOrigin.CENTER, - verticalOrigin: Cesium.VerticalOrigin.BOTTOM, - label: { - text: '', - font_size: 14, - color: '#ffffff', - outline: true, - outlineColor: '#000000', - pixelOffsetY: -35, - }, - }, - }); - - polygonGraphicLayer.addGraphic(graphic); - } - - - // 添加起飞点 - lines.geometry.coordinates.unshift([ - polygonAirForm.value.startingPoint[0], - polygonAirForm.value.startingPoint[1], - polygonAirForm.value.startingPoint[2] + 20, - ]); - - lines.geometry.coordinates.unshift(polygonAirForm.value.startingPoint); - - if (polygonLineGraphicLayer) { - polygonLineGraphicLayer.clear(); - polygonLineGraphicLayer.loadGeoJSON(lines); - } else { - polygonLineGraphicLayer = new mars3d.layer.GeoJsonLayer({ - name: '面航线', - data: lines, - symbol: { - type: 'polyline', - styleOptions: { - arcType: Cesium.ArcType.GEODESIC, // 使用大地线 - width: 2.0, - color: '#0aed8b', - // clampToGround: true, - }, - }, - flyTo: true, - }); - map.addLayer(polygonLineGraphicLayer); - } - }; - - // 删除面 和 面航线 - const handlerRemovePolygonArea = () => { - if (polygonGraphicLayer) { - polygonGraphicLayer.clear(); - } - if (polygonLineGraphicLayer) { - polygonLineGraphicLayer.clear(); - } - - airInfo.value = { - area: 0, - length: 0, - time: 0, - picture: '- -', - }; - }; - - // 计算面航线 - function generateScanLines(polygon, spacing, angle = 0) { - - if (!turf.booleanValid(polygon)) throw new Error('无效的多边形'); - spacing = Math.abs(spacing); - - // 获取多边形的旋转边界框 - const bbox = turf.bbox(polygon); - const center = turf.center(polygon).geometry.coordinates; - - // 计算需要生成的线数量(加缓冲确保完全覆盖) - const diagLength = turf.distance( - turf.point([bbox[0], bbox[1]]), - turf.point([bbox[2], bbox[3]]), - ); - const lineCount = Math.ceil(diagLength / spacing) + 2; - - // 生成基础水平线 - const lines = []; - - for (let i = -1; i <= lineCount; i++) { - const y = bbox[1] + i * spacing * 0.1 - spacing * 0.1; - lines.push( - turf.lineString([ - [bbox[0] - spacing, y], - [bbox[2] + spacing, y], - ]), - ); - } - - // 旋转线条到指定角度 - const rotatedLines = lines.map((line) => turf.transformRotate(line, angle, { pivot: center })); - - // 裁剪线条到多边形内并处理结果 - const coverageLines = []; - - rotatedLines.forEach((line) => { - try { - const intersection = turf.lineIntersect(line, polygon); - - if (intersection.features.length >= 2) { - // 按与线起点距离排序交点 - const sortedPoints = intersection.features - .map((f) => f.geometry.coordinates) - .sort( - (a, b) => - turf.distance(line.geometry.coordinates[0], turf.point(a)) - - turf.distance(line.geometry.coordinates[0], turf.point(b)), - ); - - // 创建连接最远两个交点的线段 - coverageLines.push( - turf.lineString([sortedPoints[0], sortedPoints[sortedPoints.length - 1]]), - ); - } - } catch (e) { - console.warn('处理线段时出错:', e); - } - }); - - let connectedLine = connectLinesManual(turf.featureCollection(coverageLines)); - console.log('connectedLine', connectedLine); - return connectedLine; + map.addLayer(polygonGraphicLayer); } - // 连接线段 - const connectLinesManual = (lines) => { - // 确保输入是FeatureCollection - if (lines.type !== 'FeatureCollection') { - lines = turf.featureCollection([lines]); - } + const graphic = await polygonGraphicLayer.startDraw({ + type: 'polygon', + style: { + color: '#408eff', + opacity: 0.3, + outline: true, + outlineColor: '#408eff', + outlineWidth: 3.0, + clampToGround: true, + }, + }); - // 收集所有坐标点 - let allCoords = []; - lines.features.forEach((line, index) => { - console.log('line.geometry.coordinates', line.geometry.coordinates); - line.geometry.coordinates?.forEach((item, idx) => { - line.geometry.coordinates[idx].push(180); - }); + let coordinates = graphic.toJSON().positions; - if (line.geometry.type === 'LineString' && index % 2 == 0) { - allCoords = allCoords.concat(line.geometry.coordinates.reverse()); - } else { - allCoords = allCoords.concat(line.geometry.coordinates); - } - }); + coordinates.push(coordinates[0]); - console.log('allCoords', allCoords); - // 移除连续重复的点 - const cleanedCoords = []; - if (allCoords.length > 0) { - cleanedCoords.push(allCoords[0]); - for (let i = 1; i < allCoords.length; i++) { - const prev = cleanedCoords[cleanedCoords.length - 1]; - if (prev[0] !== allCoords[i][0] || prev[1] !== allCoords[i][1]) { - cleanedCoords.push(allCoords[i]); - } - } - } + polygonGeoJson.value = coordinates; - return turf.lineString(cleanedCoords); - }; + let polygon = turf.polygon([coordinates]); - // 标绘起点 - const handlerDrawStartPoint = async () => { - graphic = await graphicLayer.startDraw({ - type: 'billboard', + let spceing = parseFloat(polygonCalculateParams.value?.spacing) / 10000; + let lines = generateScanLines(polygon,spceing, 0); + + // 计算面积 + CalculateAreaInfo(polygon, lines); + // 绘制面航线 + handlerDrawPolygonLine(lines); + // 计算边长等信息 + handlerGetPolygonBorderInfo(polygonGeoJson.value); +}; + +// 测区编辑后重新计算航线 +const handlerPolygonEdit = (e)=>{ + + let coordinates = e.graphic.toJSON().positions; + + coordinates.push(coordinates[0]); + + polygonGeoJson.value = coordinates; + + let polygon = turf.polygon([coordinates]); + + let spceing = parseFloat(polygonCalculateParams.value?.spacing) / 10000; + let lines = generateScanLines(polygon,spceing, 0); + + // 计算面积 + CalculateAreaInfo(polygon, lines); + // 绘制面航线 + handlerDrawPolygonLine(lines); + // 计算边长等信息 + handlerGetPolygonBorderInfo(polygonGeoJson.value); + +} +// 绘制面航线 +const handlerDrawPolygonLine = (lines) => { + + let nodeGraphic = polygonGraphicLayer.getGraphicById("polygon-node-1"); + + if(nodeGraphic){ + nodeGraphic.setOptions({ + id: 'polygon-node-1', + name: '航点', + position: lines.geometry.coordinates[0], style: { - image: '/map/start.png', - scale: 0.7, + image: '/map/node.png', + scale: 1, horizontalOrigin: Cesium.HorizontalOrigin.CENTER, verticalOrigin: Cesium.VerticalOrigin.BOTTOM, label: { - text: '无人机起始位置', - font_size: 16, + text: '', + font_size: 14, color: '#ffffff', outline: true, outlineColor: '#000000', - pixelOffsetY: -60, + pixelOffsetY: -35, + }, + }, + }) + }else{ + const graphic = new mars3d.graphic.BillboardEntity({ + id: 'polygon-node-1', + name: '航点', + position: lines.geometry.coordinates[0], + style: { + image: '/map/node.png', + scale: 1, + horizontalOrigin: Cesium.HorizontalOrigin.CENTER, + verticalOrigin: Cesium.VerticalOrigin.BOTTOM, + label: { + text: '', + font_size: 14, + color: '#ffffff', + outline: true, + outlineColor: '#000000', + pixelOffsetY: -35, }, }, }); - // 设置贴地点 和 连接线 - }; - // 计算面状测区信息 - const CalculateAreaInfo = (polygon, lines) => { - // 测区面积 - airInfo.value.area = turf.area(polygon).toFixed(2); + polygonGraphicLayer.addGraphic(graphic); + } - // 航线长度 - airInfo.value.length = turf.length(lines).toFixed(2); - // 预计用时 - airInfo.value.time = ((airInfo.value.length * 1000) / polygonAirForm.value.speed / 60).toFixed( - 2, + // 添加起飞点 + lines.geometry.coordinates.unshift([ + polygonAirForm.value.startingPoint[0], + polygonAirForm.value.startingPoint[1], + polygonAirForm.value.startingPoint[2] + parseFloat(polygonCalculateParams.value.safeyFlyHeight), + ]); + + lines.geometry.coordinates.unshift(polygonAirForm.value.startingPoint); + + if (polygonLineGraphicLayer) { + polygonLineGraphicLayer.clear(); + polygonLineGraphicLayer.loadGeoJSON(lines); + } else { + polygonLineGraphicLayer = new mars3d.layer.GeoJsonLayer({ + name: '面航线', + data: lines, + symbol: { + type: 'polyline', + styleOptions: { + arcType: Cesium.ArcType.GEODESIC, // 使用大地线 + width: 2.0, + color: '#0aed8b', + // clampToGround: true, + }, + }, + flyTo: true, + }); + map.addLayer(polygonLineGraphicLayer); + } +}; + +// 计算面航线 +function generateScanLines(polygon, spacing, angle = 0) { + + if (!turf.booleanValid(polygon)) throw new Error('无效的多边形'); + + spacing = Math.abs(spacing); + + // 获取多边形的旋转边界框 + const bbox = turf.bbox(polygon); + const center = turf.center(polygon).geometry.coordinates; + + // 计算需要生成的线数量(加缓冲确保完全覆盖) + const diagLength = turf.distance( + turf.point([bbox[0], bbox[1]]), + turf.point([bbox[2], bbox[3]]), + ); + const lineCount = Math.ceil(diagLength / spacing) + 2; + + // 生成基础水平线 + const lines = []; + + for (let i = -1; i <= lineCount; i++) { + const y = bbox[1] + i * spacing * 0.11 - spacing * 0.11; + lines.push( + turf.lineString([ + [bbox[0] - spacing, y], + [bbox[2] + spacing, y], + ]), ); + } - // 照片数量 + // 旋转线条到指定角度 + const rotatedLines = lines.map((line) => turf.transformRotate(line, angle, { pivot: center })); + + // 裁剪线条到多边形内并处理结果 + const coverageLines = []; + + rotatedLines.forEach((line) => { + try { + const intersection = turf.lineIntersect(line, polygon); + + if (intersection.features.length >= 2) { + // 按与线起点距离排序交点 + const sortedPoints = intersection.features + .map((f) => f.geometry.coordinates) + .sort( + (a, b) => + turf.distance(line.geometry.coordinates[0], turf.point(a)) - + turf.distance(line.geometry.coordinates[0], turf.point(b)), + ); + + // 创建连接最远两个交点的线段 + coverageLines.push( + turf.lineString([sortedPoints[0], sortedPoints[sortedPoints.length - 1]]), + ); + } + } catch (e) { + console.warn('处理线段时出错:', e); + } + }); + + let connectedLine = connectLinesManual(turf.featureCollection(coverageLines)); + + + // 将航点提取并添加到airPoints + airPoints.value = []; + + connectedLine.geometry.coordinates?.forEach((item,index)=>{ + let point = { + id: index, + lng: item[0], + lat: item[1], + alt: item[2], + aircraftHorizontalAngle: 0, + cameraHorizontalAngle: 0, + cameraVerticalAngle: 0, + focalLength: 1, + } + airPoints.value?.push(point); + }) + + + return connectedLine; +} + +// 处理面航线 +const connectLinesManual = (lines) => { + // 确保输入是FeatureCollection + if (lines.type !== 'FeatureCollection') { + lines = turf.featureCollection([lines]); + } + + // 收集所有坐标点 + let allCoords = []; + lines.features.forEach((line, index) => { + + + // 相对起飞点高度 + let relativeHeight = startPosition.value[2] + parseFloat(polygonCalculateParams.value.height); + + line.geometry.coordinates?.forEach((item, idx) => { + line.geometry.coordinates[idx].push(relativeHeight); + }); + + if (line.geometry.type === 'LineString' && index % 2 == 0) { + allCoords = allCoords.concat(line.geometry.coordinates.reverse()); + } else { + allCoords = allCoords.concat(line.geometry.coordinates); + } + }); + + // 移除连续重复的点 + const cleanedCoords = []; + if (allCoords.length > 0) { + cleanedCoords.push(allCoords[0]); + for (let i = 1; i < allCoords.length; i++) { + const prev = cleanedCoords[cleanedCoords.length - 1]; + if (prev[0] !== allCoords[i][0] || prev[1] !== allCoords[i][1]) { + cleanedCoords.push(allCoords[i]); + } + } + } + + return turf.lineString(cleanedCoords); +}; + +// 标绘面状航线起点 +const handlerDrawStartPoint = async () => { + graphic = await graphicLayer.startDraw({ + type: 'billboard', + style: { + image: '/map/start.png', + scale: 0.7, + horizontalOrigin: Cesium.HorizontalOrigin.CENTER, + verticalOrigin: Cesium.VerticalOrigin.BOTTOM, + label: { + text: '无人机起始位置', + font_size: 16, + color: '#ffffff', + outline: true, + outlineColor: '#000000', + pixelOffsetY: -60, + }, + }, + }); + // 设置贴地点 和 连接线 +}; + +// 计算面状测区面积、长度、完成用时、拍摄数量 +const CalculateAreaInfo = (polygon, lines) => { + // 测区面积 + airInfo.value.area = turf.area(polygon).toFixed(2); + + // 航线长度 + airInfo.value.length = turf.length(lines).toFixed(2); + + // 预计用时 + airInfo.value.time = ((airInfo.value.length * 1000) / polygonAirForm.value.speed / 60).toFixed( + 2, + ); + + // 照片数量 +}; + +// 删除面状测区 和 面状航线 +const handlerRemovePolygonArea = () => { + if (polygonGraphicLayer) { + polygonGraphicLayer.clear(); + } + if (polygonLineGraphicLayer) { + polygonLineGraphicLayer.clear(); + } + + labelGraphicLayer ? labelGraphicLayer.clear() : null; + + polygonGeoJson.value = null; + + airInfo.value = { + area: 0, + length: 0, + time: 0, + picture: '- -', }; +}; - const uavPoints = ref([]); +// 面状航线测区、参数改变 +const calculatParamChange = (params) => { + polygonCalculateParams.value = params; + + if(polygonGeoJson.value){ + let polygon = turf.polygon([polygonGeoJson.value]); + let spceing = parseFloat(params.spacing) / 10000; + let angle = parseFloat(params.overlapAngle); + // 生成航线 + let lines = generateScanLines(polygon, spceing,angle); + // 计算面积 长度 + CalculateAreaInfo(polygon, lines); + // 绘制面航线 + handlerDrawPolygonLine(lines); + // 计算边长等信息 + handlerGetPolygonBorderInfo(polygonGeoJson.value); + } +} + +// 根据参数更新面状航线 +const updatePolygonLineByParams = ()=>{ + + if(polygonGeoJson.value && polygonCalculateParams.value){ + let polygon = turf.polygon([polygonGeoJson.value]); + let spceing = parseFloat(polygonCalculateParams.value.spacing) / 10000; + let angle = parseFloat(polygonCalculateParams.value.overlapAngle); + // 生成航线 + let lines = generateScanLines(polygon, spceing,angle); + // 计算面积 长度 + CalculateAreaInfo(polygon, lines); + // 绘制面航线 + handlerDrawPolygonLine(lines); + // 计算边长等信息 + handlerGetPolygonBorderInfo(polygonGeoJson.value); + } +} +// 计算绘制的多边形每条线的长度和中心点 +const polygonBorderInfo = ref([]); +let labelGraphicLayer:mars3d.layer.GraphicLayer; - // 绘制航点 - const handlerDrawPoint = (e) => { - if (moveTool) { - moveTool.destroy(); - moveTool = null; - } +// 计算测区各边长 +const handlerGetPolygonBorderInfo = (polygonCoords) => { - let position = mars3d.LngLatPoint.fromCartesian(e.position); + // 创建Turf多边形对象 + let polygon = turf.polygon([polygonCoords]); + + // 1. 计算边长 + let coordinates = polygon.geometry.coordinates[0]; + let edgeLengths = []; + + for (let i = 0; i < coordinates.length - 1; i++) { + let start = coordinates[i]; + let end = coordinates[i + 1]; + let distance = turf.distance(turf.point(start), turf.point(end), {units: 'meters'}); + + let midpoint = turf.midpoint(start, end); - let uuid = buildUUID(); - - // 航点 - // let graphic = new mars3d.graphic.BillboardEntity({ - // id: uuid, - // name: '航点', - // position: [position._lng, position._lat, position._alt], - // style: { - // image: '/map/node.png', - // scale: 1, - // horizontalOrigin: Cesium.HorizontalOrigin.CENTER, - // verticalOrigin: Cesium.VerticalOrigin.BOTTOM, - // label: { - // text: '航点', - // font_size: 14, - // color: '#ffffff', - // outline: true, - // outlineColor: '#000000', - // pixelOffsetY: -35, - // }, - // }, - // }); - // graphicLayer.addGraphic(graphic); - - // 航点三维模型 - let uavAngleGraphic = new mars3d.graphic.ModelEntity({ - id:uuid, - name: "航向", - position: [position._lng, position._lat, position._alt], - style: { - url: "/map/uav-angle.gltf", - scale: 0.1, - heading: 90, - distanceDisplayCondition: true, - distanceDisplayCondition_near: 0, - distanceDisplayPoint: { - color: "#00ff00", - pixelSize: 8 - }, - label: { - text: "", - font_size: 18, - color: "#ffffff", - pixelOffsetY: -50, - distanceDisplayCondition: true, - distanceDisplayCondition_far: 10000, - distanceDisplayCondition_near: 0 - } - }, - attr: { remark: "示例1" } - }) - graphicLayer.addGraphic(uavAngleGraphic) - - // 地面投影点 - let stickGraphic = new mars3d.graphic.PointEntity({ - id: 'stick' + uuid, - position: [position._lng, position._lat], - style: { - color: '#f5f5f5', - pixelSize: 8, - outline: true, - outlineColor: '#f5f5f5', - outlineWidth: 1, - clampToGround: true, - }, - }); - stickGroundPointLayer.addGraphic(stickGraphic); - - // 航点 投影点连接线 - let lineGraphic = new mars3d.graphic.PolylineEntity({ - id: 'line' + uuid, - positions: [ - [position._lng, position._lat, position._alt], - [position._lng, position._lat, 0], - ], - style: { - color: '#f5f5f5', - width: 1, - }, - }); - lineGroundPointLayer.addGraphic(lineGraphic); - - // 航点列表 - let airPointInfo = { - id: uuid, - name: '航点', - lng: position._lng, - lat: position._lat, - alt: position._alt, - aircraftHorizontalAngle: 0, - cameraHorizontalAngle: 0, - cameraVerticalAngle: 0, - focalLength: 2, - }; - airPoints.value?.push(airPointInfo); - - uavPoints.value.push(graphic); - - // 当前航点 - currentAirPoint.value = airPoints.value[airPoints.value?.length - 1]; - - // 绘制航线 - handlerDrawLine(); - }; - - // 绘制镜头 - const handlerDrawCamera = (e) => { - - // 判断是否已经添加 - const graphic = graphicLayer.getGraphicById("cameraGraphic"); - if(graphic){ // 如果存在更新数据 - graphic.setOptions({ - id: "cameraGraphic", - position: [e.lng,e.lat,e.alt], - show:true, - style: { - angle1: 30, // 椎体夹角1 - angle2: 30, // 椎体夹角2 - length: 100, // 椎体长度 - rayEllipsoid: false, - color: "rgba(0,255,255,0.3)", - outline: true, - topShow: true, - topSteps: 2, - flat: true, - cameraHpr: true, - heading:e.aircraftHorizontalAngle, - pitch: e.cameraVerticalAngle+90, // 俯仰角 0 - 360度 - roll: 0, - } - }) - }else{ - let satelliteSensor = new mars3d.graphic.RectSensor({ - id:"cameraGraphic", - position: [e.lng,e.lat,e.alt], - style: { - flat: true, - angle1: 30, // 椎体夹角1 - angle2: 30, // 椎体夹角2 - length: 100, // 椎体长度 - rayEllipsoid: false, - color: "rgba(0,255,255,0.3)", - outline: true, - topShow: true, - topSteps: 2, - cameraHpr: true, - heading:e.aircraftHorizontalAngle, - pitch: e.cameraVerticalAngle+90, // 俯仰角 0 - 360度 - roll: 0, - } - }) - graphicLayer.addGraphic(satelliteSensor) - } + edgeLengths.push({ + length: distance.toFixed(2), + center:midpoint?.geometry?.coordinates + }); } - // 更新航点 - const updateAirPoint = (e) => { - // 更新航点 - let graphic = graphicLayer.getGraphicById(e.id); - if (graphic) { - graphic.setOptions( - { - name: "航向", - position: [e.lng, e.lat, e.alt], - style: { - url: "/map/uav-angle.gltf", - scale: 0.1, - heading: e.aircraftHorizontalAngle, - distanceDisplayCondition: true, - distanceDisplayCondition_near: 0, - distanceDisplayPoint: { - color: "#00ff00", - pixelSize: 8 - }, - label: { - text: "", - font_size: 18, - color: "#ffffff", - pixelOffsetY: -50, - distanceDisplayCondition: true, - distanceDisplayCondition_far: 10000, - distanceDisplayCondition_near: 0 - } - }, - attr: { remark: "示例1" } - } - ); - } + handlerLoadLabelGraphicLayer(edgeLengths); + return edgeLengths; +} - // 更新贴地点 - let stickGraphic = stickGroundPointLayer.getGraphicById('stick' + e.id); - if (stickGraphic) { - stickGraphic.setOptions({ - position: [e.lng, e.lat], - style: { - color: '#f5f5f5', - pixelSize: 8, - outline: true, - outlineColor: '#f5f5f5', - outlineWidth: 1, - clampToGround: true, - }, - }); - } +// 绘制文本标注 +const handlerLoadLabelGraphicLayer = (info) => { - // 更新投影点连线 - let lineGraphic = lineGroundPointLayer.getGraphicById('line' + e.id); - if (lineGraphic) { - lineGraphic.setOptions({ - positions: [ - [e.lng, e.lat, e.alt], - [e.lng, e.lat, 0], - ], - style: { - color: '#f5f5f5', - width: 1, - }, - }); - } + if(labelGraphicLayer == null){ + labelGraphicLayer = new mars3d.layer.GraphicLayer({ + isAutoEditing:false + }) + map.addLayer(labelGraphicLayer); + }else{ + labelGraphicLayer.clear(); + } - let cameraGraphic = graphicLayer.getGraphicById('camera' + e.id); - if (cameraGraphic) { - cameraGraphic.setOptions({ - position: [e.lng, e.lat, e.alt], - // style: { - // angle1: 30, // 椎体夹角1 - // angle2: 30, // 椎体夹角2 - // length: 50, // 椎体长度 - // rayEllipsoid: true, - // color: "rgba(0,255,255,0.3)", - // outline: true, - // topShow: true, - // topSteps: 2, - // flat: true, - // cameraHpr: true, - // heading: 0, - // pitch: 180, - // roll: 0, // - // clippingPlanes: [{ - // distance: 0, // 设置裁剪平面在地表(0高度) - // normal: new Cesium.Cartesian3(0, 0, -1) // 法向量向下(隐藏地表以下部分) - // }] - // } - }); - } + info?.forEach((item,index)=>{ + const graphic = new mars3d.graphic.LabelEntity({ + position: [item.center[0], item.center[1], 0], + style: { + text: item.length+"m", + font_size: 15, + scale: 1, + font_family: "微软雅黑", + color: "#ffffff", + outline: true, + outlineColor: "#000000", + outlineWidth: 2, + horizontalOrigin: Cesium.HorizontalOrigin.CENTER, + verticalOrigin: Cesium.VerticalOrigin.BOTTOM, + visibleDepth: false, + clampToGround:true, + }, + attr: { remark: "示例1" } + }) + labelGraphicLayer.addGraphic(graphic) + }) +} - // 更新航线 - handlerDrawLine(); - }; +///////////////////////////////航点航线计算//////////////////////////////////////////// +// 航点移动 +const pointMove = (e, id) => { + const cartographic = mars3d.Cesium.Cartographic.fromCartesian(e.position); + const longitude = mars3d.Cesium.Math.toDegrees(cartographic.longitude); + const latitude = mars3d.Cesium.Math.toDegrees(cartographic.latitude); + const height = cartographic.height; // 高度(米) + let stickGraphic = stickGroundPointLayer.getGraphicById('stick' + id); + if (stickGraphic) { + stickGraphic.setOptions({ + position: [longitude, latitude], + style: { + color: '#f5f5f5', + pixelSize: 8, + outline: true, + outlineColor: '#f5f5f5', + outlineWidth: 1, + clampToGround: true, + }, + }); + } + let lineGraphic = lineGroundPointLayer.getGraphicById('line' + id); + if (lineGraphic) { + lineGraphic.setOptions({ + positions: [ + [longitude, latitude, height], + [longitude, latitude, 0], + ], + style: { + color: '#f5f5f5', + width: 1, + }, + }); + } - // 删除航点 - const deleteAirPoint = (e) => { - let id = e.graphic.id; + // 更新坐标数据 + airPoints.value?.forEach((item, index) => { + if (item.id == id) { + airPoints.value[index].lng = longitude; + airPoints.value[index].lat = latitude; + airPoints.value[index].alt = height; + } + }); - // 删除航点 - let point = graphicLayer.getGraphicById(id); - if (point) { - graphicLayer.removeGraphic(point); - } + // 更新航线 + handlerDrawLine(); +}; - // 删除相机 - let camera = graphicLayer.getGraphicById('camera' + id); - if (camera) { - graphicLayer.removeGraphic(camera); - } +// 绘制航线 +const handlerDrawLine = () => { + let positions = []; - // 删除数据 - airPoints.value?.forEach((item, index) => { - if (item.id == id) { - airPoints.value?.splice(index, 1); - } - }); + airPoints.value?.forEach((item, index) => { + positions.push([item.lng, item.lat, item.alt]); + }); - // 更新航线 - handlerDrawLine(); - }; + positions.unshift([startPosition.value[0], startPosition.value[1], airPoints.value[0].alt]); - let stickGraphicLayer: mars3d.layer.GraphicLayer; + positions.unshift([startPosition.value[0], startPosition.value[1], startPosition.value[2]]); - // 飞行到此处 - const flyToThere = (e) => { - if (!uavGraphicLayer) { - uavGraphicLayer = new mars3d.layer.GraphicLayer({ - isAutoEditing: false, // 是否自动激活编辑 - }); + // 判断是否已经绘制 + if (positions.length > 1) { + let lineGraphic = graphicLayer.getGraphicById('pointsLine'); - uavGraphicLayer.bindContextMenu([ - { - text: '按轴平移', - icon: 'fa fa-pencil', - callback: (event) => { - const graphic = event.graphic; - if (moveTool) { - return null; - } + if (lineGraphic) { + lineGraphic.setOptions({ + id: 'pointsLine', + positions: positions, + style: { + width: 2, + color: '#3388ff', + }, + }); + } else { + const graphic = new mars3d.graphic.PolylineEntity({ + id: 'pointsLine', + positions: positions, + style: { + width: 2, + color: '#3388ff', + }, + }); + graphicLayer.addGraphic(graphic); + } + } - // 按轴移动 - moveTool = new mars3d.thing.MatrixMove2({ - position: graphic.position, - }); - map.addThing(moveTool); - moveTool.on(mars3d.EventType.change, (event) => { - graphic.position = event.position; - uavGraphicMove(event); - }); - }, - }, - { - text: '停止平移', - icon: 'fa fa-pencil', - callback: (event) => { - const graphic = event.graphic; - if (moveTool) { - moveTool.destroy(); - moveTool = null; - } - }, - }, - { - text: '删除', - icon: 'fa fa-camera-retro', // 支持 font-class 的字体方式图标 - callback: (e) => { - deleteFlyToThere(e); - }, - }, - ]); + // 计算航线长度 + // let lineString = turf.lineString(positions); + // lineInfo.value.length = turf.length(lineString).toFixed(2); +}; + +const uavPoints = ref([]); - map.addLayer(uavGraphicLayer); - - uavGraphicLayer.on(mars3d.EventType.editMouseMove, (e) => {}); - } - - if (moveTool) { +// 绘制航点 +const handlerDrawPoint = (e) => { + if (moveTool) { moveTool.destroy(); moveTool = null; - } + } - if (!stickGraphicLayer) { - stickGraphicLayer = new mars3d.layer.GraphicLayer({ - isAutoEditing: false, // 是否自动激活编辑 - }); - map.addLayer(stickGraphicLayer); - } + let position = mars3d.LngLatPoint.fromCartesian(e.position); - uavGraphicLayer.clear(); - stickGraphicLayer.clear(); + let uuid = buildUUID(); - let position = mars3d.LngLatPoint.fromCartesian(e.position); + // 航点 + // let graphic = new mars3d.graphic.BillboardEntity({ + // id: uuid, + // name: '航点', + // position: [position._lng, position._lat, position._alt], + // style: { + // image: '/map/node.png', + // scale: 1, + // horizontalOrigin: Cesium.HorizontalOrigin.CENTER, + // verticalOrigin: Cesium.VerticalOrigin.BOTTOM, + // label: { + // text: '航点', + // font_size: 14, + // color: '#ffffff', + // outline: true, + // outlineColor: '#000000', + // pixelOffsetY: -35, + // }, + // }, + // }); + // graphicLayer.addGraphic(graphic); + + // 航点三维模型 + let uavAngleGraphic = new mars3d.graphic.ModelEntity({ + id:uuid, + name: "航向", + position: [position._lng, position._lat, position._alt], + style: { + url: "/map/uav-angle.gltf", + scale: 0.1, + heading: 90, + distanceDisplayCondition: true, + distanceDisplayCondition_near: 0, + distanceDisplayPoint: { + color: "#00ff00", + pixelSize: 8 + }, + label: { + text: "", + font_size: 18, + color: "#ffffff", + pixelOffsetY: -50, + distanceDisplayCondition: true, + distanceDisplayCondition_far: 10000, + distanceDisplayCondition_near: 0 + } + }, + attr: { remark: "示例1" } + }) + graphicLayer.addGraphic(uavAngleGraphic) + + // 地面投影点 + let stickGraphic = new mars3d.graphic.PointEntity({ + id: 'stick' + uuid, + position: [position._lng, position._lat], + style: { + color: '#f5f5f5', + pixelSize: 8, + outline: true, + outlineColor: '#f5f5f5', + outlineWidth: 1, + clampToGround: true, + }, + }); + stickGroundPointLayer.addGraphic(stickGraphic); + + // 航点 投影点连接线 + let lineGraphic = new mars3d.graphic.PolylineEntity({ + id: 'line' + uuid, + positions: [ + [position._lng, position._lat, position._alt], + [position._lng, position._lat, 0], + ], + style: { + color: '#f5f5f5', + width: 1, + }, + }); + lineGroundPointLayer.addGraphic(lineGraphic); + + // 航点列表 + let airPointInfo = { + id: uuid, + name: '航点', + lng: position._lng, + lat: position._lat, + alt: position._alt, + aircraftHorizontalAngle: 0, + cameraHorizontalAngle: 0, + cameraVerticalAngle: 0, + focalLength: 2, + }; + airPoints.value?.push(airPointInfo); + + uavPoints.value.push(graphic); + + // 当前航点 + currentAirPoint.value = airPoints.value[airPoints.value?.length - 1]; + + // 绘制航线 + handlerDrawLine(); +}; + +// 绘制镜头 +const handlerDrawCamera = (e) => { + + // 判断是否已经添加 + const graphic = graphicLayer.getGraphicById("cameraGraphic"); + if(graphic){ // 如果存在更新数据 + graphic.setOptions({ + id: "cameraGraphic", + position: [e.lng,e.lat,e.alt], + show:true, + style: { + angle1: 30, // 椎体夹角1 + angle2: 30, // 椎体夹角2 + length: 100, // 椎体长度 + rayEllipsoid: false, + color: "rgba(0,255,255,0.3)", + outline: true, + topShow: true, + topSteps: 2, + flat: true, + cameraHpr: true, + heading:e.aircraftHorizontalAngle, + pitch: e.cameraVerticalAngle+90, // 俯仰角 0 - 360度 + roll: 0, + } + }) + }else{ + let satelliteSensor = new mars3d.graphic.RectSensor({ + id:"cameraGraphic", + position: [e.lng,e.lat,e.alt], + style: { + flat: true, + angle1: 30, // 椎体夹角1 + angle2: 30, // 椎体夹角2 + length: 100, // 椎体长度 + rayEllipsoid: false, + color: "rgba(0,255,255,0.3)", + outline: true, + topShow: true, + topSteps: 2, + cameraHpr: true, + heading:e.aircraftHorizontalAngle, + pitch: e.cameraVerticalAngle+90, // 俯仰角 0 - 360度 + roll: 0, + } + }) + graphicLayer.addGraphic(satelliteSensor) + } +} + +// 更新航点 +const updateAirPoint = (e) => { + // 更新航点 + let graphic = graphicLayer.getGraphicById(e.id); + if (graphic) { + graphic.setOptions( + { + name: "航向", + position: [e.lng, e.lat, e.alt], + style: { + url: "/map/uav-angle.gltf", + scale: 0.1, + heading: e.aircraftHorizontalAngle, + distanceDisplayCondition: true, + distanceDisplayCondition_near: 0, + distanceDisplayPoint: { + color: "#00ff00", + pixelSize: 8 + }, + label: { + text: "", + font_size: 18, + color: "#ffffff", + pixelOffsetY: -50, + distanceDisplayCondition: true, + distanceDisplayCondition_far: 10000, + distanceDisplayCondition_near: 0 + } + }, + attr: { remark: "示例1" } + } + ); + } + + // 更新贴地点 + let stickGraphic = stickGroundPointLayer.getGraphicById('stick' + e.id); + if (stickGraphic) { + stickGraphic.setOptions({ + position: [e.lng, e.lat], + style: { + color: '#f5f5f5', + pixelSize: 8, + outline: true, + outlineColor: '#f5f5f5', + outlineWidth: 1, + clampToGround: true, + }, + }); + } + + // 更新投影点连线 + let lineGraphic = lineGroundPointLayer.getGraphicById('line' + e.id); + if (lineGraphic) { + lineGraphic.setOptions({ + positions: [ + [e.lng, e.lat, e.alt], + [e.lng, e.lat, 0], + ], + style: { + color: '#f5f5f5', + width: 1, + }, + }); + } + + let cameraGraphic = graphicLayer.getGraphicById('camera' + e.id); + if (cameraGraphic) { + cameraGraphic.setOptions({ + position: [e.lng, e.lat, e.alt], + // style: { + // angle1: 30, // 椎体夹角1 + // angle2: 30, // 椎体夹角2 + // length: 50, // 椎体长度 + // rayEllipsoid: true, + // color: "rgba(0,255,255,0.3)", + // outline: true, + // topShow: true, + // topSteps: 2, + // flat: true, + // cameraHpr: true, + // heading: 0, + // pitch: 180, + // roll: 0, // + // clippingPlanes: [{ + // distance: 0, // 设置裁剪平面在地表(0高度) + // normal: new Cesium.Cartesian3(0, 0, -1) // 法向量向下(隐藏地表以下部分) + // }] + // } + }); + } + + // 更新航线 + handlerDrawLine(); +}; + +// 删除航点 +const deleteAirPoint = (e) => { + let id = e.graphic.id; + + // 删除航点 + let point = graphicLayer.getGraphicById(id); + if (point) { + graphicLayer.removeGraphic(point); + } + + // 删除相机 + let camera = graphicLayer.getGraphicById('camera' + id); + if (camera) { + graphicLayer.removeGraphic(camera); + } + + // 删除数据 + airPoints.value?.forEach((item, index) => { + if (item.id == id) { + airPoints.value?.splice(index, 1); + } + }); + + // 更新航线 + handlerDrawLine(); +}; + +let stickGraphicLayer: mars3d.layer.GraphicLayer; + +// 飞行到此处 +const flyToThere = (e) => { + if (!uavGraphicLayer) { + uavGraphicLayer = new mars3d.layer.GraphicLayer({ + isAutoEditing: false, // 是否自动激活编辑 + }); + + uavGraphicLayer.bindContextMenu([ + { + text: '按轴平移', + icon: 'fa fa-pencil', + callback: (event) => { + const graphic = event.graphic; + if (moveTool) { + return null; + } + + // 按轴移动 + moveTool = new mars3d.thing.MatrixMove2({ + position: graphic.position, + }); + map.addThing(moveTool); + moveTool.on(mars3d.EventType.change, (event) => { + graphic.position = event.position; + uavGraphicMove(event); + }); + }, + }, + { + text: '停止平移', + icon: 'fa fa-pencil', + callback: (event) => { + const graphic = event.graphic; + if (moveTool) { + moveTool.destroy(); + moveTool = null; + } + }, + }, + { + text: '删除', + icon: 'fa fa-camera-retro', // 支持 font-class 的字体方式图标 + callback: (e) => { + deleteFlyToThere(e); + }, + }, + ]); + + map.addLayer(uavGraphicLayer); + + uavGraphicLayer.on(mars3d.EventType.editMouseMove, (e) => {}); + } + + if (moveTool) { + moveTool.destroy(); + moveTool = null; + } + + if (!stickGraphicLayer) { + stickGraphicLayer = new mars3d.layer.GraphicLayer({ + isAutoEditing: false, // 是否自动激活编辑 + }); + map.addLayer(stickGraphicLayer); + } + + uavGraphicLayer.clear(); + stickGraphicLayer.clear(); + + let position = mars3d.LngLatPoint.fromCartesian(e.position); - let mark = graphicLayer.getGraphicById('flytothere'); + let mark = graphicLayer.getGraphicById('flytothere'); - if (mark) { - graphicLayer.removeGraphic(mark); - } + if (mark) { + graphicLayer.removeGraphic(mark); + } - // 无人机点 - const graphic = new mars3d.graphic.BillboardEntity({ + // 无人机点 + const graphic = new mars3d.graphic.BillboardEntity({ + id: 'flytothere-uav', + name: '标点', + position: [position._lng, position._lat, position._alt+80], + style: { + image: '/map/uav-mark.png', + scale: 0.3, + horizontalOrigin: Cesium.HorizontalOrigin.CENTER, + verticalOrigin: Cesium.VerticalOrigin.BOTTOM, + label: { + text: '', + font_size: 14, + color: '#ffffff', + outline: true, + outlineColor: '#000000', + pixelOffsetY: -40, + }, + }, + }); + + // 贴地点 + const stickGraphic = new mars3d.graphic.PointEntity({ + id: 'flytothere-stick', + position: [position._lng, position._lat], + style: { + color: '#f5f5f5', + pixelSize: 8, + outline: true, + outlineColor: '#f5f5f5', + outlineWidth: 1, + clampToGround: true, + }, + }); + + stickGraphic.on(mars3d.EventType.editMouseMove, (e) => { + const cartographic = mars3d.Cesium.Cartographic.fromCartesian(e.cartesian); + // 弧度转度数 + const longitude = mars3d.Cesium.Math.toDegrees(cartographic.longitude); + const latitude = mars3d.Cesium.Math.toDegrees(cartographic.latitude); + const height = cartographic.height; // 高度(米) + stickGraphicMove([longitude, latitude, height]); + }); + + // 连接线 + let connectLine = new mars3d.graphic.PolylineEntity({ + id: 'flytothere-line', + positions: [ + [position._lng, position._lat, position._alt+80], + [position._lng, position._lat, 0], + ], + style: { + color: '#f5f5f5', + width: 1, + }, + }); + + uavGraphicLayer.addGraphic(graphic); + stickGraphicLayer.addGraphic(stickGraphic); + uavGraphicLayer.addGraphic(connectLine); + + // 获取无人机的坐标并返回 + let flyToPosition = mars3d.LngLatPoint.fromCartesian(graphic.position); + emits('flyToThere', flyToPosition); +}; + +// 移动贴地点 +const stickGraphicMove = (e) => { + return null; + let uav = uavGraphicLayer.getGraphicById('flytothere-uav'); + + if (uav) { + uav.setOptions({ id: 'flytothere-uav', name: '标点', - position: [position._lng, position._lat, position._alt+80], + position: [e[0], e[1], 200], style: { - image: '/map/uav-mark.png', - scale: 0.3, - horizontalOrigin: Cesium.HorizontalOrigin.CENTER, - verticalOrigin: Cesium.VerticalOrigin.BOTTOM, - label: { + image: '/map/uav-mark.png', + scale: 0.3, + horizontalOrigin: Cesium.HorizontalOrigin.CENTER, + verticalOrigin: Cesium.VerticalOrigin.BOTTOM, + label: { text: '', font_size: 14, color: '#ffffff', outline: true, outlineColor: '#000000', pixelOffsetY: -40, - }, }, - }); - - // 贴地点 - const stickGraphic = new mars3d.graphic.PointEntity({ - id: 'flytothere-stick', - position: [position._lng, position._lat], - style: { - color: '#f5f5f5', - pixelSize: 8, - outline: true, - outlineColor: '#f5f5f5', - outlineWidth: 1, - clampToGround: true, }, - }); + }); + } - stickGraphic.on(mars3d.EventType.editMouseMove, (e) => { - const cartographic = mars3d.Cesium.Cartographic.fromCartesian(e.cartesian); - // 弧度转度数 - const longitude = mars3d.Cesium.Math.toDegrees(cartographic.longitude); - const latitude = mars3d.Cesium.Math.toDegrees(cartographic.latitude); - const height = cartographic.height; // 高度(米) - stickGraphicMove([longitude, latitude, height]); - }); - - // 连接线 - let connectLine = new mars3d.graphic.PolylineEntity({ + let line = uavGraphicLayer.getGraphicById('flytothere-line'); + if (line) { + line.setOptions({ id: 'flytothere-line', positions: [ - [position._lng, position._lat, position._alt+80], - [position._lng, position._lat, 0], + [e[0], e[1], 200], + [e[0], e[1], 0], ], style: { - color: '#f5f5f5', - width: 1, + color: '#f5f5f5', + width: 1, }, - }); + }); + } +}; - uavGraphicLayer.addGraphic(graphic); - stickGraphicLayer.addGraphic(stickGraphic); - uavGraphicLayer.addGraphic(connectLine); +// 删除飞行到此处 +const deleteFlyToThere = (e) => { + let id = e.graphic.id; - // 获取无人机的坐标并返回 - let flyToPosition = mars3d.LngLatPoint.fromCartesian(graphic.position); - emits('flyToThere', flyToPosition); - }; + let uavGraphic = uavGraphicLayer.getGraphicById(id); + if (uavGraphic) { + uavGraphicLayer.removeGraphic(uavGraphic); + } - // 移动贴地点 - const stickGraphicMove = (e) => { - return null; - let uav = uavGraphicLayer.getGraphicById('flytothere-uav'); + let lineGraphic = uavGraphicLayer.getGraphicById('flytothere-line'); + if (lineGraphic) { + uavGraphicLayer.removeGraphic(lineGraphic); + } - if (uav) { - uav.setOptions({ - id: 'flytothere-uav', - name: '标点', - position: [e[0], e[1], 200], - style: { - image: '/map/uav-mark.png', - scale: 0.3, - horizontalOrigin: Cesium.HorizontalOrigin.CENTER, - verticalOrigin: Cesium.VerticalOrigin.BOTTOM, - label: { - text: '', - font_size: 14, - color: '#ffffff', - outline: true, - outlineColor: '#000000', - pixelOffsetY: -40, - }, - }, - }); - } + let stickGraphic = stickGraphicLayer.getGraphicById('flytothere-stick'); + if (stickGraphic) { + stickGraphicLayer.removeGraphic(stickGraphic); + } - let line = uavGraphicLayer.getGraphicById('flytothere-line'); - if (line) { - line.setOptions({ - id: 'flytothere-line', - positions: [ - [e[0], e[1], 200], - [e[0], e[1], 0], - ], - style: { - color: '#f5f5f5', - width: 1, - }, - }); - } - }; + if (moveTool) { + moveTool.destroy(); + moveTool = null; + } + emits('flyToThere', { _lng: null, _lat: null, _alt: null }); +}; - // 删除飞行到此处 - const deleteFlyToThere = (e) => { - let id = e.graphic.id; +// 无人机点按轴移动 +const uavGraphicMove = (e) => { + const cartographic = mars3d.Cesium.Cartographic.fromCartesian(e.position); - let uavGraphic = uavGraphicLayer.getGraphicById(id); - if (uavGraphic) { - uavGraphicLayer.removeGraphic(uavGraphic); - } + // 弧度转度数 + const longitude = mars3d.Cesium.Math.toDegrees(cartographic.longitude); + const latitude = mars3d.Cesium.Math.toDegrees(cartographic.latitude); + const height = cartographic.height; // 高度(米) - let lineGraphic = uavGraphicLayer.getGraphicById('flytothere-line'); - if (lineGraphic) { - uavGraphicLayer.removeGraphic(lineGraphic); - } + emits('flyToThere', { _lng: longitude, _lat: latitude, _alt: height }); - let stickGraphic = stickGraphicLayer.getGraphicById('flytothere-stick'); - if (stickGraphic) { - stickGraphicLayer.removeGraphic(stickGraphic); - } + let line = uavGraphicLayer.getGraphicById('flytothere-line'); - if (moveTool) { - moveTool.destroy(); - moveTool = null; - } - emits('flyToThere', { _lng: null, _lat: null, _alt: null }); - }; - - // 无人机点按轴移动 - const uavGraphicMove = (e) => { - const cartographic = mars3d.Cesium.Cartographic.fromCartesian(e.position); - - // 弧度转度数 - const longitude = mars3d.Cesium.Math.toDegrees(cartographic.longitude); - const latitude = mars3d.Cesium.Math.toDegrees(cartographic.latitude); - const height = cartographic.height; // 高度(米) - - emits('flyToThere', { _lng: longitude, _lat: latitude, _alt: height }); - - let line = uavGraphicLayer.getGraphicById('flytothere-line'); - - if (line) { - line.setOptions({ - id: 'flytothere-line', - positions: [ - [longitude, latitude, height], - [longitude, latitude, 0], - ], - style: { - color: '#f5f5f5', - width: 1, - }, - }); - } - - let stick = stickGraphicLayer.getGraphicById('flytothere-stick'); - if (stick) { - stick.setOptions({ - id: 'flytothere-stick', - position: [longitude, latitude], - style: { - color: '#f5f5f5', - pixelSize: 8, - outline: true, - outlineColor: '#f5f5f5', - outlineWidth: 1, - clampToGround: true, - }, - }); - } - }; - - // 预览航点航线 - const preViewPointWayLine = (position) => { - if (moveTool) { - moveTool.destroy(); - moveTool = null; - } - - let uuid = buildUUID(); - // 参考起飞点 - - let startGraphic = new mars3d.graphic.BillboardEntity({ - id: 'start-graphic', - position: startPosition.value, - style: { - image: '/map/start.png', - scale: 1, - horizontalOrigin: Cesium.HorizontalOrigin.CENTER, - verticalOrigin: Cesium.VerticalOrigin.BOTTOM, - label: { - text: '参考起飞点', - font_size: 14, - color: '#ffffff', - outline: true, - outlineColor: '#000000', - pixelOffsetY: -35, - }, - }, - }); - graphicLayer.addGraphic(startGraphic); - - // 航点 - let graphic = new mars3d.graphic.BillboardEntity({ - id: uuid, - name: '航点', - position: [position._lng, position._lat, position._alt], + if (line) { + line.setOptions({ + id: 'flytothere-line', + positions: [ + [longitude, latitude, height], + [longitude, latitude, 0], + ], style: { - image: '/map/node.png', - scale: 1, - horizontalOrigin: Cesium.HorizontalOrigin.CENTER, - verticalOrigin: Cesium.VerticalOrigin.BOTTOM, - label: { - text: '航点', + color: '#f5f5f5', + width: 1, + }, + }); + } + + let stick = stickGraphicLayer.getGraphicById('flytothere-stick'); + if (stick) { + stick.setOptions({ + id: 'flytothere-stick', + position: [longitude, latitude], + style: { + color: '#f5f5f5', + pixelSize: 8, + outline: true, + outlineColor: '#f5f5f5', + outlineWidth: 1, + clampToGround: true, + }, + }); + } +}; + +// 预览航点航线 +const preViewPointWayLine = (position) => { + if (moveTool) { + moveTool.destroy(); + moveTool = null; + } + + let uuid = buildUUID(); + // 参考起飞点 + + let startGraphic = new mars3d.graphic.BillboardEntity({ + id: 'start-graphic', + position: startPosition.value, + style: { + image: '/map/start.png', + scale: 1, + horizontalOrigin: Cesium.HorizontalOrigin.CENTER, + verticalOrigin: Cesium.VerticalOrigin.BOTTOM, + label: { + text: '参考起飞点', + font_size: 14, + color: '#ffffff', + outline: true, + outlineColor: '#000000', + pixelOffsetY: -35, + }, + }, + }); + graphicLayer.addGraphic(startGraphic); + + // 航点 + let graphic = new mars3d.graphic.BillboardEntity({ + id: uuid, + name: '航点', + position: [position._lng, position._lat, position._alt], + style: { + image: '/map/node.png', + scale: 1, + horizontalOrigin: Cesium.HorizontalOrigin.CENTER, + verticalOrigin: Cesium.VerticalOrigin.BOTTOM, + label: { + text: '航点', + font_size: 14, + color: '#ffffff', + outline: true, + outlineColor: '#000000', + pixelOffsetY: -35, + }, + }, + }); + graphicLayer.addGraphic(graphic); + + // 地面投影点 + let stickGraphic = new mars3d.graphic.PointEntity({ + id: 'stick' + uuid, + position: [position._lng, position._lat], + style: { + color: '#f5f5f5', + pixelSize: 8, + outline: true, + outlineColor: '#f5f5f5', + outlineWidth: 1, + clampToGround: true, + }, + }); + stickGroundPointLayer.addGraphic(stickGraphic); + + // 航点 投影点连接线 + let lineGraphic = new mars3d.graphic.PolylineEntity({ + id: 'line' + uuid, + positions: [ + [position._lng, position._lat, position._alt], + [position._lng, position._lat, 0], + ], + style: { + color: '#f5f5f5', + width: 1, + }, + }); + lineGroundPointLayer.addGraphic(lineGraphic); + + graphicLayer.flyTo(); + + // 绘制航线 + handlerDrawLine(); +}; + +// 预览面状航线 +const preViewPolygonWayLine = (lines) => { + handlerDrawLine(); +}; + +// 清空所有图层 +const clearAllLayer = () => { + graphicLayer ? graphicLayer.clear() : null; + stickGroundPointLayer ? stickGroundPointLayer.clear() : null; + lineGroundPointLayer ? lineGroundPointLayer.clear() : null; + + polygonGraphicLayer ? polygonGraphicLayer.clear() : null; + polygonLineGraphicLayer ? polygonLineGraphicLayer.clear() : null; + airPoints.value = []; +}; + + +//////////////////////////////机场和无人机//////////////////////////////////////////// + +// 设置机场位置 +const setAirportPosition = async () => { + if(!graphicLayer){ + return + } + if(props.airPort.longitude == null){ + return; + } + let point = graphicLayer.getGraphicById('set-airport'); + // // 创建点的经纬度信息 + let position = [props.airPort.longitude, props.airPort.latitude, 70]; + // 更新航点 + if (point) { + // point.setOptions({ + // id: 'set-airport', + // name: '机场位置', + // position: position, + // style: { + // image: '/projecthome/airport.png', + // width: 35, + // height: 59, + // scale: 1, + // horizontalOrigin: Cesium.HorizontalOrigin.CENTER, + // verticalOrigin: Cesium.VerticalOrigin.BOTTOM, + // label: { + // text: '机场', + // font_size: 14, + // color: '#ffffff', + // outline: true, + // outlineColor: '#000000', + // pixelOffsetY: -70, + // }, + // }, + // }); + } else { + let startGraphic = new mars3d.graphic.BillboardEntity({ + id: 'set-airport', + position: position, + style: { + image: '/projecthome/airport.png', + width: 35, + height: 59, + scale: 1, + horizontalOrigin: Cesium.HorizontalOrigin.CENTER, + verticalOrigin: Cesium.VerticalOrigin.BOTTOM, + label: { + text: '机场', font_size: 14, color: '#ffffff', outline: true, outlineColor: '#000000', - pixelOffsetY: -35, - }, + pixelOffsetY: -70, }, - }); - graphicLayer.addGraphic(graphic); + }, + }); + graphicLayer.addGraphic(startGraphic); + } +}; - // 地面投影点 - let stickGraphic = new mars3d.graphic.PointEntity({ - id: 'stick' + uuid, - position: [position._lng, position._lat], +// 项目首页设置机场位置 +const homeSetAirportPosition = () => { + if(!graphicLayer){ + return + } + // // 创建点的经纬度信息 + let position = [props.homeAirport.longitude, props.homeAirport.latitude, 70]; + // 更新航点 + if (homeStartGraphic) { + homeStartGraphic.position = position + } else { + homeStartGraphic = new mars3d.graphic.BillboardEntity({ + id: 'set-home-airport', + position: position, style: { - color: '#f5f5f5', - pixelSize: 8, + image: '/projecthome/airport.png', + width: 35, + height: 59, + scale: 1, + horizontalOrigin: Cesium.HorizontalOrigin.CENTER, + verticalOrigin: Cesium.VerticalOrigin.BOTTOM, + label: { + text: '机场', + font_size: 14, + color: '#ffffff', outline: true, - outlineColor: '#f5f5f5', - outlineWidth: 1, - clampToGround: true, + outlineColor: '#000000', + pixelOffsetY: -70, }, - }); - stickGroundPointLayer.addGraphic(stickGraphic); - - // 航点 投影点连接线 - let lineGraphic = new mars3d.graphic.PolylineEntity({ - id: 'line' + uuid, - positions: [ - [position._lng, position._lat, position._alt], - [position._lng, position._lat, 0], - ], - style: { - color: '#f5f5f5', - width: 1, }, - }); - lineGroundPointLayer.addGraphic(lineGraphic); - - graphicLayer.flyTo(); - - // 绘制航线 - handlerDrawLine(); - }; - - // 预览面状航线 - const preViewPolygonWayLine = (lines) => { - handlerDrawLine(); - }; - - // 清空所有图层 - const clearAllLayer = () => { - graphicLayer ? graphicLayer.clear() : null; - stickGroundPointLayer ? stickGroundPointLayer.clear() : null; - lineGroundPointLayer ? lineGroundPointLayer.clear() : null; - - polygonGraphicLayer ? polygonGraphicLayer.clear() : null; - polygonLineGraphicLayer ? polygonLineGraphicLayer.clear() : null; - airPoints.value = []; - }; - - // 设置机场位置 - const setAirportPosition = async () => { - if(!graphicLayer){ - return - } - if(props.airPort.longitude == null){ - return; - } - let point = graphicLayer.getGraphicById('set-airport'); - // // 创建点的经纬度信息 - let position = [props.airPort.longitude, props.airPort.latitude, 70]; - // 更新航点 - if (point) { - // point.setOptions({ - // id: 'set-airport', - // name: '机场位置', - // position: position, - // style: { - // image: '/projecthome/airport.png', - // width: 35, - // height: 59, - // scale: 1, - // horizontalOrigin: Cesium.HorizontalOrigin.CENTER, - // verticalOrigin: Cesium.VerticalOrigin.BOTTOM, - // label: { - // text: '机场', - // font_size: 14, - // color: '#ffffff', - // outline: true, - // outlineColor: '#000000', - // pixelOffsetY: -70, - // }, - // }, - // }); - } else { - let startGraphic = new mars3d.graphic.BillboardEntity({ - id: 'set-airport', - position: position, - style: { - image: '/projecthome/airport.png', - width: 35, - height: 59, - scale: 1, - horizontalOrigin: Cesium.HorizontalOrigin.CENTER, - verticalOrigin: Cesium.VerticalOrigin.BOTTOM, - label: { - text: '机场', - font_size: 14, - color: '#ffffff', - outline: true, - outlineColor: '#000000', - pixelOffsetY: -70, - }, - }, - }); - graphicLayer.addGraphic(startGraphic); - } - }; - - // 项目首页设置机场位置 - const homeSetAirportPosition = () => { - if(!graphicLayer){ - return - } - // // 创建点的经纬度信息 - let position = [props.homeAirport.longitude, props.homeAirport.latitude, 70]; - // 更新航点 - if (homeStartGraphic) { - homeStartGraphic.position = position - } else { - homeStartGraphic = new mars3d.graphic.BillboardEntity({ - id: 'set-home-airport', - position: position, - style: { - image: '/projecthome/airport.png', - width: 35, - height: 59, - scale: 1, - horizontalOrigin: Cesium.HorizontalOrigin.CENTER, - verticalOrigin: Cesium.VerticalOrigin.BOTTOM, - label: { - text: '机场', - font_size: 14, - color: '#ffffff', - outline: true, - outlineColor: '#000000', - pixelOffsetY: -70, - }, - }, - }); - homeStartGraphic.on(mars3d.EventType.click, function (event) { - emits('clickAirPort') - }); - graphicLayer.addGraphic(homeStartGraphic); - } - } - // 设置无人机轨迹 - const setUAVPosition = () => { - let point = graphicLayer.getGraphicById('set-uav'); - const position = [props.uavTrack.longitude, props.uavTrack.latitude, props.uavTrack.height]; - // 更新航点 - if (point) { - point.setOptions({ - id: 'set-uav', - name: '飞行器位置', - position: position, - style: { - url: '/projecthome/dajiang.gltf', - scale: 0.1, - minimumPixelSize: 100, - }, - frameRate: 1, - }); - } else { - const graphicModel = new mars3d.graphic.ModelPrimitive({ - id: 'set-uav', - name: '飞行器位置', - position: position, - style: { - url: '/projecthome/dajiang.gltf', - scale: 0.1, - minimumPixelSize: 100, - }, - frameRate: 1, - }); - graphicLayer.addGraphic(graphicModel); - } - - let route = graphicLayer.getGraphicById('uav-route'); - if (!route) { - route = new mars3d.graphic.Route({ - id: 'uav-route', - polyline: { - color: '#3388ff', - width: 2, - }, - flyTo: true, - }); - graphicLayer.addGraphic(route); - } - if (props.uavTrack.longitude) { - const positionVal = Cesium.Cartesian3.fromDegrees( - props.uavTrack.longitude, - props.uavTrack.latitude, - props.uavTrack.height, - ); - route.addTimePosition(positionVal); - } - }; - - -// 参数改变 -const calculatParamChange = (params) => { - console.log("params",params); - - let spceing = parseFloat(params.spacing) / 10000; - - console.log("spceing",spceing); - - if(polygonGeoJson.value){ - let polygon = turf.polygon([polygonGeoJson.value]); - let lines = generateScanLines(polygon, spceing, 0); - - // 计算面积 长度 - CalculateAreaInfo(polygon, lines); - - // 绘制面航线 - handlerDrawPolygonLine(lines); - } - + }); + homeStartGraphic.on(mars3d.EventType.click, function (event) { + emits('clickAirPort') + }); + graphicLayer.addGraphic(homeStartGraphic); + } } + +// 设置无人机轨迹 +const setUAVPosition = () => { + let point = graphicLayer.getGraphicById('set-uav'); + const position = [props.uavTrack.longitude, props.uavTrack.latitude, props.uavTrack.height]; + // 更新航点 + if (point) { + point.setOptions({ + id: 'set-uav', + name: '飞行器位置', + position: position, + style: { + url: '/projecthome/dajiang.gltf', + scale: 0.1, + minimumPixelSize: 100, + }, + frameRate: 1, + }); + } else { + const graphicModel = new mars3d.graphic.ModelPrimitive({ + id: 'set-uav', + name: '飞行器位置', + position: position, + style: { + url: '/projecthome/dajiang.gltf', + scale: 0.1, + minimumPixelSize: 100, + }, + frameRate: 1, + }); + graphicLayer.addGraphic(graphicModel); + } + + let route = graphicLayer.getGraphicById('uav-route'); + if (!route) { + route = new mars3d.graphic.Route({ + id: 'uav-route', + polyline: { + color: '#3388ff', + width: 2, + }, + flyTo: true, + }); + graphicLayer.addGraphic(route); + } + if (props.uavTrack.longitude) { + const positionVal = Cesium.Cartesian3.fromDegrees( + props.uavTrack.longitude, + props.uavTrack.latitude, + props.uavTrack.height, + ); + route.addTimePosition(positionVal); + } +}; +