import { lodLayer, viewer } from '@/components/dt-scene/index.vue' import Menus from '@/components/menus/index.vue' import Tools from '@/components/tools/index.vue' import DtScene from '@/components/dt-scene/index.vue' import InfoBar from '@/components/info-bar/index.vue' import TwinSituation from './components/twin-situation/index.vue' import TaskManage from './components/task-manage/index.vue' import PicturesList from './components/pictures-list/index.vue' import deviceManage from './components/device-manage/index.vue' import deviceManage1 from './components/device1-manage/index.vue' import userList from './components/user-list/index.vue' // 新增空间态势统计 // 台风列表 import SceneInfo from '@/mixin/scene-info' import { mapMutations, mapGetters, mapActions } from 'vuex' import * as DT from 'dt-sdk' import moment from 'moment' import { connectWebSocket, disconnectWebSocket } from '@/utils/web-socket' import { ICON_MODE } from '@/enum' import { getResourceList } from '@/api/home' import { getWeatherInfo } from '@/api/user' import axios from 'axios' let handler = undefined let broadcastChannel = null let broadcastChannelInterval = null let radarViewer = null let radarLayer = null let socketInstance = null let stompClientInstance = null let entityCollection = new DT.Cesium.AssociativeArray() let linePicture = {} let currentPicture = null let shipEntities = new DT.Cesium.AssociativeArray() let aisCollection = [] export default { name: 'Home', components: { Menus, Tools, DtScene, InfoBar, TwinSituation, TaskManage, PicturesList, deviceManage, deviceManage1, userList }, mixins: [SceneInfo], data() { return { timelineConfig: { height: 90 }, //menus组件 配置 menus: { situation: { index: 0, name: '系统主页', icon: 'ri-home-7-line', // defaultColor: 'rgba(75, 236, 255, 1)', defaultColor: 'rgb(255,255,255)', active: true, group: 'top' }, deviceManage: { index: 1, name: '设备管理', icon: 'ri-radar-line', // defaultColor: 'rgb(230,157,55)', defaultColor: 'rgb(255,255,255)', active: false, group: 'top' }, taskManage: { index: 2, name: '任务管理', icon: 'ri-function-line', // defaultColor: 'rgb(230,157,55)', defaultColor: 'rgb(255,255,255)', active: false, group: 'top' }, pictures: { index: 3, name: '图片管理', icon: 'ri-file-image-line', // defaultColor: 'rgb(217,52,173)', defaultColor: 'rgb(255,255,255)', active: false, group: 'top' }, userList: { index: 4, name: '用户管理', icon: 'ri-file-image-line', defaultColor: 'rgb(255,255,255)', active: false, group: 'top' } // rightManage: { // index: 0, // name: '权限', // icon: 'iconfont icon-gongju1', // defaultColor: 'rgb(27,229,41)', // active: false, // group: 'top' // } // timeline: { // index: 99, // name: '时间轴', // icon: 'ri-time-fill', // defaultColor: '#42b555', // active: false, // group: 'bottom' // } }, loadingCount: 0, sceneComplete: false, multiplierStep: [1, 3, 5, 10, 30, 60, 180, 300], // 工具栏场景加速步长数组 // 工具栏插槽按钮 tools: [ { name: '能力', type: 'ability', active: false, show: false, iconDefault: 'iconfont icon-kongjianzhichi', iconActive: 'iconfont icon-kongjianzhichi' }, { name: '实体名称', type: 'entityName', active: true, show: true, iconDefault: 'ri-lightbulb-line', iconActive: 'ri-lightbulb-flash-line' } ], hasRightPanel1: false, hasRightPanel2: false, activeTabs: [], resourceList: { visible: true, activeTabId: 1, groupList: [ { name: '全部', id: 1 }, { name: '小队1', id: 2 }, { name: '小队2', id: 3 }, { name: '小队3', id: 4 }, { name: '小队4', id: 5 }, { name: '小队5', id: 6 }, { name: '小队6', id: 7 } ], data: [], // typeDict: { // 1: '小队', // 2: '无人机', // 3: '人', // 4: '救援车', // 5: '消防车' // }, typeDict: { 1: '无人机', 2: '消防车', 3: '成员' } }, taskList: { visible: true, data: [ { id: 1, executeIcon: 'ri-dv-line', executeName: '无人机1', typeIcon: 'el-icon-camera', taskName: '拍照任务', taskProgress: 30, isFinish: false, taskProgressName: '30%', executeClass: '2', taskTime: '2024-12-28 14:00:00' }, ] }, weatherInfo: { visible: false, warning: '', windDirection: '东南风', airQuality: '50', hourForecast: [], windForecast: [2, 2, 3, 3.1, 1, 0.8], rainForecast: [0, 0, 0, 0, 0, 0], chart: { data: [ { type: 'line', name: '能见度', symbol: 'none', areaStyle: { color: '#81d3f8' }, style: { color: '#81d3f8', }, lineStyle: { color: '#81d3f8', }, data: [ [0, 80], [1, 80], [2, 68], [3, 60], [4, 58], [5, 40], ] } ], tooltip: { show: false }, legend: [{ show: false }], title: [{ show: false }], grid: [{ left: 0, top: 0, right: 0, bottom: 0, borderWidth: 0 }], xAxis: [ { type: 'value', min: 0, max: 5, axisLine: { show: false }, axisTick: { show: false }, axisLabel: { show: false }, splitLine: { show: false }, } ], yAxis: [ { type: 'value', min: 0, max: 100, axisLine: { show: false }, axisTick: { show: false }, axisLabel: { show: false }, splitLine: { show: false }, } ] } }, weatherInfo2: { visible: true, wendu: '-', shidu: '-', quality: '-', pm25: '-', pm10: '-', weekData: [], chart: { data: [ { type: 'line', name: '温度', symbol: 'none', areaStyle: { color: '#81d3f8' }, style: { color: '#81d3f8', }, lineStyle: { color: '#066893', }, data: [ ] } ], tooltip: { show: false }, legend: [{ show: false }], title: [{ show: false }], grid: [{ left: 0, top: 0, right: 0, bottom: 0, borderWidth: 0 }], xAxis: [ { type: 'value', min: 0, // max: 5, axisLine: { show: false }, axisTick: { show: false }, axisLabel: { show: false }, splitLine: { show: false }, } ], yAxis: [ { type: 'value', min: 0, max: 60, axisLine: { show: false }, axisTick: { show: false }, axisLabel: { show: true }, splitLine: { show: false }, } ] } }, radarInfo: { visible: true, }, availableList: [ { id: 1, name: '成员2' }, { id: 2, name: '成员3' } ], groupForm: { groupId: undefined, visible: false, name: '', children: [], description: '', }, groupFormRules: { name: [ { required: true, message: '请输入名称', trigger: 'blur' }, { min: 1, max: 8, message: '长度在 1 到 8 个字符', trigger: 'blur' } ], children: [ { required: true, message: '请选择组员', trigger: 'change' }, ], }, detailInfo: { visible: false, baseInfo: {}, taskList: [ { id: 1, executeIcon: 'ri-dv-line', executeName: '无人机1', typeIcon: 'el-icon-camera', taskName: '拍照任务', taskProgress: 30, isFinish: false, taskProgressName: '30%', executeClass: '2', taskTime: '2024-12-28 14:00:00' }, { id: 6, executeIcon: 'ri-dv-line', executeName: '无人机1', typeIcon: 'el-icon-camera', taskName: '拍照任务', taskProgress: 100, isFinish: true, taskProgressName: '完成', executeClass: '2', taskTime: '2024-12-27 15:00:00' }, ], pictureList: [ require('@/assets/img/test.png'), require('@/assets/img/test.png'), require('@/assets/img/test.png'), require('@/assets/img/test.png'), require('@/assets/img/test.png'), ] }, messageBox: { visible: false, showRecord: false, name: '', content: '', id: '', }, reqQueue: [], isSending: false, chartInfo: { unRead: 0, visible: false, }, aisBoat: { visible: false, data: [], boatTypeLegend: [] }, moveInfoBar: false } }, computed: { ...mapGetters([ 'currentTime', 'iconMode', 'showSatelliteLabel', 'shouldAnimate', 'multiplier', 'showTrack', 'showFrontier', 'showDayNight', 'showLonLatGrid', 'viewMode', 'showRoadNet', 'isFullscreen', 'iconMode', 'showGlobalAtmosphere', 'duringPlay', 'theme', 'showCloud', 'mapType', 'userId', 'splitVisible', 'menusChose' ]), isIconModeLarge() { return this.iconMode === ICON_MODE.LARGE } }, watch: { menusChose: { handler: function (nv) { window.localStorage.setItem('menusChose', nv) switch (nv) { case '1': this.menus.situation.active = true this.menus.taskManage.active = false this.menus.pictures.active = false this.menus.deviceManage.active = false this.menus.userList.active = false break case '2': this.menus.deviceManage.active = true this.menus.situation.active = false this.menus.taskManage.active = false this.menus.pictures.active = false this.menus.userList.active = false break case '3': this.menus.taskManage.active = true this.menus.situation.active = false this.menus.pictures.active = false this.menus.deviceManage.active = false this.menus.userList.active = false break case '4': this.menus.pictures.active = true this.menus.taskManage.active = false this.menus.situation.active = false this.menus.deviceManage.active = false this.menus.userList.active = false break case '5': this.menus.userList.active = true this.menus.pictures.active = false this.menus.taskManage.active = false this.menus.situation.active = false this.menus.deviceManage.active = false break; } }, }, // viewMode(nv) { // this.sendMessageByBroadcastChannel({ type: 'viewMode', form: 'home', value: nv }) // }, // showDayNight(nv) { // this.sendMessageByBroadcastChannel({ type: 'showDayNight', form: 'task', value: nv }) // }, // showFrontier(nv) { // this.sendMessageByBroadcastChannel({ type: 'showFrontier', form: 'task', value: nv }) // }, // showLonLatGrid(nv) { // this.sendMessageByBroadcastChannel({ type: 'showLonLatGrid', form: 'task', value: nv }) // }, // isFullscreen(nv) { // this.sendMessageByBroadcastChannel({ type: 'isFullscreen', form: 'task', value: nv }) // }, // mapType(nv) { // this.sendMessageByBroadcastChannel({ type: 'mapType', form: 'task', value: nv }) // }, }, created() { const menusChose = window.localStorage.getItem('menusChose') this.SET_MENUS_CHOSE(menusChose) // this.init() // this.getResourceData() // 获取字典 this.getDict() }, mounted() { // this.$refs.tools.handleMapChange('sat') // this.createBroadcastChannel() // TODO 部署打开 // window.open(window.config.homeUrl + 'task', '_blank') // window.open(window.config.homeUrl + 'monitor', '_blank') // TODO // this.resourceClick(this.resourceList.data[0]) return; viewer.entities.add({ show: true, id: 'image1', name: '美女1', rectangle: { coordinates: DT.Cesium.Rectangle.fromDegrees( 115.914508, 40.357867, 115.916869, 40.361485 ), height: 0, material: new DT.Cesium.ImageMaterialProperty({ image: process.env.BASE_URL + 'static/img/meinv.png', transparent: 1 }) } }) viewer.entities.add({ show: true, id: 'image2', name: '美女2', rectangle: { coordinates: DT.Cesium.Rectangle.fromDegrees( 115.914508, 40.357867, 115.916869, 40.361485 ), height: 100, material: new DT.Cesium.ImageMaterialProperty({ image: process.env.BASE_URL + 'static/img/meinv.png', }) } }) }, beforeDestroy() { if (handler) { handler.removeInputAction(DT.Cesium.ScreenSpaceEventType.LEFT_CLICK) } if (stompClientInstance) { disconnectWebSocket(stompClientInstance) socketInstance = null stompClientInstance = null } // if (broadcastChannel) { // this.closeBroadcastChannel() // } linePicture = {} currentPicture = null aisCollection = [] }, methods: { ...mapMutations('scene-control', [ 'SET_SWITCH', 'SET_ANIMATE', 'SET_MULTIPLIER', 'SET_TRACK', 'SET_FRONTIER', 'SET_DAY_NIGHT', 'SET_LON_LAT_GRID', 'SET_VIEW_MODE', 'SET_FULL_SCREEN', 'SET_ROAD_NET', 'SET_INIT_STATE', 'SET_GLOBAL_ATMOSPHERE_SHOW', 'SET_SATELLITE_LABEL', 'SET_INTER_VISIBLE', 'SET_VIEWABLE_VISIBLE', 'SET_CLOUD', 'SET_MAP_TYPE', 'SET_SPLIT_VISIBLE', ]), ...mapMutations('app', ['SET_THEME', 'SET_MENUS_CHOSE']), ...mapActions('dict', ['getDict']), // 工具栏操作 toggleTools(tool) { tool.active = !tool.active switch (tool.type) { case 'entityName': this.handleGlobeLabelVisible(tool.active) break case 'ability': this.abilityShow = tool.active break } }, /** * 菜单点击事件 * @author wangxueshen * @date 2022-04-29 * @param {any} menu * @param {any} active * @returns {any} */ menuClick(menu, active) { const blackList = ['setting', 'timeline'] if (blackList.includes(menu.type)) return switch (menu.type) { case 'situation': // 遥感卫星能力展示 this.menus.taskManage.active = false this.menus.pictures.active = false this.menus.deviceManage.active = false break case 'taskManage': this.menus.situation.active = false this.menus.pictures.active = false this.menus.deviceManage.active = false break case 'pictures': this.menus.taskManage.active = false this.menus.situation.active = false this.menus.deviceManage.active = false break case 'deviceManage': this.menus.situation.active = false this.menus.taskManage.active = false this.menus.pictures.active = false break } }, handleSceneComplete() { let that = this this.$nextTick(() => { this.SET_DAY_NIGHT(false) this.sceneComplete = true // this.addHandler() // this.$refs.tools.handleMapChange('sat') let position = DT.Cesium.Cartesian3.fromDegrees(window.config.defaultLocation[0], window.config.defaultLocation[1], 1000) viewer.cesiumViewer.scene.camera.flyTo({ destination: position, duration: 1 }) viewer.cesiumViewer.scene.imagerySplitPosition = 1.0 // this.temp() // this.createRadar() // this.testLine() // 移动相机 // viewer.cesiumViewer.scene.camera.moveBackward(10000000) // 加载湘江流域3Dtiles场景 // loadXJLYSceneasync(DT) // viewer.cesiumViewer.scene.camera.changed.addEventListener(function(ev) { // that.refreshRadar() // }) }) // this.startWebSocket() // this.createWebsocket() }, temp() { let position1 = [ 119.767992, 35.588417, 119.767992, 35.566652, 119.799480, 35.566652, 119.799480, 35.588417, ]; let test1Entity = viewer.entities.add({ id: 'test1', polygon: { // hierarchy: DT.Cesium.Cartesian3.fromDegreesArrayHeights(cby_bg_data), hierarchy: DT.Cesium.Cartesian3.fromDegreesArray(position1), perPositionHeight: true, material: new DT.Cesium.ImageMaterialProperty({ image: process.env.BASE_URL + 'static/img/test5.png', color: DT.Cesium.Color.fromCssColorString('rgba(255,255,255,0.95)') }),//new Cesium.Color(0.29, 0.85, 0.89, 0.5), //Cesium.Color.PALETURQUOISE.withAlpha(0.5), outline: false, // outlineColor: DT.Cesium.Color.WHITE, outlineWidth: 2, //很多电脑当宽度>1时,没用 } }); let position2 = [ 119.745771, 35.608493, 119.745771, 35.589935, 119.750658, 35.589935, 119.750658, 35.608493, ]; let test2Entity = viewer.entities.add({ id: 'test2', polygon: { // hierarchy: DT.Cesium.Cartesian3.fromDegreesArrayHeights(cby_bg_data), hierarchy: DT.Cesium.Cartesian3.fromDegreesArray(position2), perPositionHeight: true, material: new DT.Cesium.ImageMaterialProperty({ image: process.env.BASE_URL + 'static/img/temp2.jpg', }),//new Cesium.Color(0.29, 0.85, 0.89, 0.5), //Cesium.Color.PALETURQUOISE.withAlpha(0.5), outline: false, outlineColor: DT.Cesium.Color.WHITE, outlineWidth: 2, //很多电脑当宽度>1时,没用 } }); let obj = { test1: test1Entity, test2: test2Entity, } let currentPicture = null let pictureHandler = new DT.Cesium.ScreenSpaceEventHandler( viewer.cesiumViewer.scene.canvas ) pictureHandler.setInputAction(({ position }) => { let pick = viewer.cesiumViewer.scene.pick(position) if (pick && pick.id && pick.id.id && pick.id.id.indexOf('test') !== -1) { let show = obj[pick.id.id].show currentPicture = obj[pick.id.id] currentPicture.show = !show } else { if (currentPicture) { currentPicture.show = !currentPicture.show } } }, DT.Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK) }, getWeather() { getWeatherInfo().then(res => { console.log('000000000000', res) if (res.data.code === 200) { let data = res.data.data this.weatherInfo2.wendu = data.wendu this.weatherInfo2.shidu = data.shidu this.weatherInfo2.quality = data.quality this.weatherInfo2.pm25 = data.pm25 this.weatherInfo2.pm10 = data.pm10 let list = data.forecast.slice(0, 5) let chart = [] list.forEach((item, index) => { let low = item.low.split(' ')[1] let high = item.high.split(' ')[1] item.temperatureRange = [low, high] // chart.push([item.week, parseFloat(high)]) chart.push([index, parseFloat(high)]) }) this.weatherInfo2.weekData = list this.weatherInfo2.chart.data[0].data = chart console.log('数据', this.weatherInfo2.chart.data) this.$refs.chart.updateData(this.weatherInfo2.chart.data) } else { this.$message.error(res.data.message) } }) }, /** * @description 添加地面站点击事件 * @author wzw * @date 2022年3月30日 */ addHandler() { let that = this handler = new DT.Cesium.ScreenSpaceEventHandler( viewer.cesiumViewer.scene.canvas ) handler.setInputAction(event => { let evt = viewer.cesiumViewer.scene.pick(event.position) // 卫星和地面站的点击事件 if (evt && evt.primitive && evt.primitive.entityId) { let id = evt.primitive.entityId // 点击的是地面站 if (id.includes('station')) { // 激活实体详情面板 if (!this.visible.entityDetail) { this.visible.entityDetail = true } let data = undefined for (let i = 0; i < this.sceneInfo.stationList.length; i++) { if ('station-' + this.sceneInfo.stationList[i].staId === id) { data = JSON.parse(JSON.stringify(this.sceneInfo.stationList[i])) break } } } // 点击的是卫星 if (id.includes('satellite')) { // 激活实体详情面板 if (!this.visible.entityDetail) { this.visible.entityDetail = true } let satId = id.split('-')[1] let satelliteInfo = this.sceneInfo.satelliteList.find( item => item.satId === +satId ) let info = JSON.parse(JSON.stringify(satelliteInfo)) this.showSatelliteInfo(info) } } // 覆盖范围属于那个卫星的提示框 if (evt && evt.id && evt.id.id.includes('area')) { let position1 let feature = viewer.cesiumViewer.scene.pick(event.position) if (feature) { position1 = viewer.cesiumViewer.scene.pickPosition(event.position) } else { let ray = viewer.cesiumViewer.scene.camera.getPickRay( event.position ) position1 = viewer.cesiumViewer.scene.globe.pick( ray, viewer.cesiumViewer.scene ) } let cartographic = viewer.cesiumViewer.scene.globe.ellipsoid.cartesianToCartographic( position1 ) let id = evt.id.id let isExist = that.eventTips.findIndex(item => { return item.id === id }) if (isExist !== -1) { that.eventTips[isExist].showAnimation = false that.eventTips[isExist].position = [ DT.Cesium.Math.toDegrees(cartographic.longitude), DT.Cesium.Math.toDegrees(cartographic.latitude), 500 ] Reflect.deleteProperty(that.eventTips[isExist], 'disappearTime') Reflect.deleteProperty(that.eventTips[isExist], 'animationTime') } else { that.eventTips.push({ id, name: evt.id.name, show: true, showAnimation: false, position: [ DT.Cesium.Math.toDegrees(cartographic.longitude), DT.Cesium.Math.toDegrees(cartographic.latitude), 500 ] }) } } else { that.eventTips.forEach(item => { item.animationTime = moment().format('YYYY-MM-DD HH:mm:ss') item.disappearTime = moment() .add(2, 's') .format('YYYY-MM-DD HH:mm:ss') }) } }, DT.Cesium.ScreenSpaceEventType.LEFT_CLICK) }, /*********************业务代码**********************/ //#region 测试代码 testLine() { let lineData = [ { lon: 116.538201, lat: 40.141529 }, { lon: 116.538216, lat: 40.143778 }, { lon: 116.546478, lat: 40.143742 }, { lon: 116.546193, lat: 40.141043 }, { lon: 116.546097, lat: 40.137875 }, { lon: 116.537818, lat: 40.138056 }, { lon: 116.537725, lat: 40.134348 } ] let cartesian3Positions = [] let minLon, maxLon, minLat, maxLat lineData.forEach((item, index) => { if (index === 0) { minLon = item.lon maxLon = item.lon minLat = item.lat maxLat = item.lat } else { minLon = Math.min(minLon, item.lon) maxLon = Math.max(maxLon, item.lon) minLat = Math.min(minLat, item.lat) maxLat = Math.max(maxLat, item.lat) } cartesian3Positions.push(DT.Cesium.Cartesian3.fromDegrees(item.lon, item.lat)) }) let pathEntity = new DT.DirectionPath({ positions: cartesian3Positions, dataFit: false, // currentPosition:current, autoStep: false, equalsEpsilon: 0.01, stepDistance: 30, leadLineOption: { width: 4, dashLength: 20, color: DT.Cesium.Color.fromCssColorString('#15cfcd'), image: process.env.BASE_URL + 'static/img/dash.png' }, passLineOption: { width: 4, color: DT.Cesium.Color.fromCssColorString('#15cfcd'), }, labelConfig: { font: '21pt Lucida Console', horizontalOrigin: DT.Cesium.HorizontalOrigin.LEFT, outlineColor: DT.Cesium.Color.BLACK, outlineWidth: 2, pixelOffset: new DT.Cesium.Cartesian2(5, -4), scale: 0.5, show: true, style: DT.Cesium.LabelStyle.FILL_AND_OUTLINE, text: '无人机', verticalOrigin: DT.Cesium.VerticalOrigin.CENTER, disableDepthTestDistance: 10000 }, billboardConfig: { image: process.env.BASE_URL + 'static/img/icon_wrj.png', disableDepthTestDistance: 10000 // enableRotation: true }, enableRepeatAdjust: false, }) lodLayer.add(pathEntity) // 适当扩大视角范围 let lonDiff = (maxLon - minLon) / 2 let latDiff = (maxLat - minLat) / 2 minLon -= lonDiff maxLon += lonDiff minLat -= latDiff maxLat += latDiff let boundingPosition = [ DT.Cesium.Cartesian3.fromDegrees(minLon, minLat), DT.Cesium.Cartesian3.fromDegrees(minLon, maxLat), DT.Cesium.Cartesian3.fromDegrees(maxLon, minLat), DT.Cesium.Cartesian3.fromDegrees(maxLon, maxLat), ] // console.log('最小最大', minLon, maxLon, minLat, maxLat) viewer.cesiumViewer.camera.flyToBoundingSphere(DT.Cesium.BoundingSphere.fromPoints(boundingPosition), { duration: 0.1 }) this.addMarkPicture() }, addMarkPicture() { // const layer=viewer.imageryLayers.addImageryProvider( new Cesium.SingleTileImageryProvider({ // url: "图片url", // })); let cby_bg_data = [ 116.540165, 40.138266, 116.540190, 40.137485, 116.541745, 40.137458, 116.541714, 40.138282, ]; let entity = viewer.entities.add({ id: 'picture-1', name: '背景', polygon: { // hierarchy: DT.Cesium.Cartesian3.fromDegreesArrayHeights(cby_bg_data), hierarchy: DT.Cesium.Cartesian3.fromDegreesArray(cby_bg_data), perPositionHeight: true, material: new DT.Cesium.ImageMaterialProperty({ image: process.env.BASE_URL + 'static/img/pic.png', }),//new Cesium.Color(0.29, 0.85, 0.89, 0.5), //Cesium.Color.PALETURQUOISE.withAlpha(0.5), outline: true, outlineColor: DT.Cesium.Color.WHITE, outlineWidth: 2, //很多电脑当宽度>1时,没用 } }); let markPosition = DT.Cesium.Cartesian3.fromDegrees(116.540265, 40.138066, 1) let markArr = [ 116.540265, 40.138066, 1, 116.540265, 40.137866, 1, 116.540845, 40.137866, 1, 116.540845, 40.138066, 1, 116.540265, 40.138066, 1, ] let markLine = viewer.entities.add({ id: 'picture-text-1', show: false, position: markPosition, label: { text: '标注点', font: '12px sans-serif', fillColor: DT.Cesium.Color.RED, horizontalOrigin: DT.Cesium.HorizontalOrigin.LEFT, verticalOrigin: DT.Cesium.VerticalOrigin.TOP, disableDepthTestDistance: 10000, showBackground: false, backgroundColor: DT.Cesium.Color.BLACK, style: DT.Cesium.LabelStyle.FILL_AND_OUTLINE, }, polyline: { positions: DT.Cesium.Cartesian3.fromDegreesArrayHeights(markArr), // positions: DT.Cesium.Cartesian3.fromDegreesArray(markArr), width: 1, material: DT.Cesium.Color.RED, depthFailMaterial: DT.Cesium.Color.RED, zIndex: 3, } }) linePicture['picture-1'] = { picEntity: entity, mark: markLine } let handler = new DT.Cesium.ScreenSpaceEventHandler( viewer.cesiumViewer.scene.canvas ) handler.setInputAction(({ position }) => { let pick = viewer.cesiumViewer.scene.pick(position) if (pick && pick.id && pick.id.id && pick.id.id.indexOf('picture') !== -1) { currentPicture = linePicture['picture-1'] currentPicture.picEntity.polygon.outlineColor = DT.Cesium.Color.RED currentPicture.mark.show = true } else { if (currentPicture) { currentPicture.picEntity.polygon.outlineColor = DT.Cesium.Color.WHITE currentPicture.mark.show = false } } }, DT.Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK) handler.setInputAction(({ position }) => { if (currentPicture) { currentPicture.picEntity.show = !currentPicture.picEntity.show currentPicture.mark.show = !currentPicture.mark.show } }, DT.Cesium.ScreenSpaceEventType.RIGHT_CLICK) }, //#endregion //#region 资源列表 getResourceData() { getResourceList({ onlyshowonline: true }).then(response => { console.log('资源列表', response) if (response.data.code == 200) { let data = response.data.data data.forEach(item => { if (item.type === 4) { item.expand = false item.id = 'group' + item.groupId item.nickName = item.groupName } }) this.resourceList.data = response.data.data } else { } }) }, /** * 获取装备信号强度css类 * @param strength * @returns {string} */ getDeviceSignalClass(strength) { if (strength < 20) { return 'device-status__disconnect' } else if (strength < 60) { return 'device-status__weak' } else { return 'device-status__normal' } }, /** * 车航程css * @param value * @returns {string} */ getCarDistanceClass(value) { if (value < 50) { return 'battery-danger' } else if (value < 200) { return 'battery-weak' } else { return 'battery-normal' } }, /** * 获取装备电池css类 * @param strength * @returns {string} */ getDeviceBatteryClass(strength) { if (strength < 20) { return 'battery-danger' } else if (strength < 60) { return 'battery-weak' } else { return 'battery-normal' } }, /** * 切换资源列表分组 * @param tab */ resourceTabClick(tab) { if (this.resourceList.activeTabId !== tab.id) { this.resourceList.activeTabId = tab.id } }, resourceClick(info) { this.detailInfo.visible = false this.detailInfo.baseInfo = JSON.parse(JSON.stringify(info)) console.log('信息', this.detailInfo.baseInfo) this.detailInfo.visible = true }, openCreateGroupForm() { this.groupForm.name = '' this.groupForm.children = [] this.groupForm.description = '' this.groupForm.visible = true }, /** * 编辑小队 * @param info */ editResourceTeam(info) { console.log('编辑i嘻嘻你', info) this.groupForm.groupId = info.id this.groupForm.name = info.name this.groupForm.visible = true }, submitGroupForm() { this.$refs.groupForm.validate((valid) => { if (valid) { this.$message.success('添加成功') this.closeGroupForm() } else { console.log('error submit!!'); return false; } }); }, closeGroupForm() { this.groupForm = { visible: false, name: '', children: [], description: '', groupId: undefined, } }, closeGroup() { this.$confirm('确定界山吗', '提示', { confirmButtonText: '确定', cancelButtonText: '取消', type: 'warning' }).then(res => { this.closeGroupForm() }).catch(err => { }) }, //#endregion //#region tab通信相关代码 createBroadcastChannel() { this.closeBroadcastChannel() broadcastChannel = new BroadcastChannel('channel') broadcastChannel.onmessage = this.handleChannelMessage; broadcastChannelInterval = setInterval(() => { this.sendMessageByBroadcastChannel({ type: 'heartbeat', form: 'home' }) }, 5000) }, handleChannelMessage(data) { console.log('home收到消息', data) switch (data.data.type) { case 'heartbeat': let fromTab = data.data.from let find = this.activeTabs.find(item => item.name === fromTab) if (find) { find.lastTime = new Date().getTime() } else { this.activeTabs.push({ name: fromTab, lastTime: new Date().getTime(), }) } break case 'viewMode': console.log('收到viewmode消息') if (this.viewMode !== data.data.value) { this.SET_VIEW_MODE(data.data.value) } break case 'showDayNight': console.log('收到showDayNight消息') if (this.showDayNight !== data.data.value) { // this.SET_DAY_NIGHT(data.data.value) } break case 'showFrontier': console.log('收到showFrontier消息') if (this.showFrontier !== data.data.value) { this.SET_FRONTIER(data.data.value) } break case 'showLonLatGrid': console.log('收到showLonLatGrid消息') if (this.showLonLatGrid !== data.data.value) { this.SET_LON_LAT_GRID(data.data.value) } break case 'isFullscreen': console.log('收到isFullscreen消息') if (this.isFullscreen !== data.data.value) { this.SET_FULL_SCREEN(data.data.value) } break case 'mapType': console.log('收到mapType消息') if (this.mapType !== data.data.value) { this.SET_MAP_TYPE(data.data.value) } break } }, sendMessageByBroadcastChannel(msg) { if (broadcastChannel) { broadcastChannel.postMessage(msg) } }, closeBroadcastChannel() { if (broadcastChannel) { broadcastChannel.close() broadcastChannel = null } if (broadcastChannelInterval) { window.clearInterval(broadcastChannelInterval) broadcastChannelInterval = null } }, //#endregion //#reigion 雷达 createRadar() { let position = viewer.cesiumViewer.scene.camera.position.clone() let position2 = DT.Cesium.Cartographic.fromCartesian(position) let calHeight = Math.min(position2.height * 2, 1000000) calHeight = Math.max(calHeight, 10000) let radarPosition = DT.Cesium.Cartesian3.fromRadians(position2.longitude, position2.latitude, calHeight) let tilingScheme, satMap, vectorMap, roadMap, arcgisMap tilingScheme = new DT.Cesium.WebMercatorTilingScheme() // 开发环境或者内网生产环境,访问内网地图服务 /******************天地图************************/ let token = '0d38858cdf49c0e0ff31ebd03376c7e2'; // 服务域名 let tdtUrl = 'https://t{s}.tianditu.gov.cn/'; // 服务负载子域 let subdomains = ['0', '1', '2', '3', '4', '5', '6', '7']; let tdtImgMap = new DT.Cesium.UrlTemplateImageryProvider({ url: tdtUrl + 'DataServer?T=img_w&x={x}&y={y}&l={z}&tk=' + token, subdomains: subdomains, tilingScheme: new DT.Cesium.WebMercatorTilingScheme(), maximumLevel: 18 }); let tdtVecMap = new DT.Cesium.UrlTemplateImageryProvider({ url: tdtUrl + 'DataServer?T=vec_w&x={x}&y={y}&l={z}&tk=' + token, subdomains: subdomains, tilingScheme: new DT.Cesium.WebMercatorTilingScheme(), maximumLevel: 18 }); // 叠加国界服务 let tdtIboMap = new DT.Cesium.UrlTemplateImageryProvider({ url: tdtUrl + 'DataServer?T=ibo_w&x={x}&y={y}&l={z}&tk=' + token, subdomains: subdomains, tilingScheme: new DT.Cesium.WebMercatorTilingScheme(), maximumLevel: 10 }); // 影像注记 let tdtImageMarkMap = new DT.Cesium.UrlTemplateImageryProvider({ url: tdtUrl + 'DataServer?T=cia_w&x={x}&y={y}&l={z}&tk=' + token, subdomains: subdomains, tilingScheme: new DT.Cesium.WebMercatorTilingScheme(), // maximumLevel : 10 }); // 叠加地形服务 let terrainUrls = new Array(); for (let i = 0; i < subdomains.length; i++) { // let url = tdtUrl.replace('{s}', subdomains[i]) + 'mapservice/swdx?T=elv_c&tk=' + token; let url = tdtUrl.replace('{s}', subdomains[i]) + 'mapservice/swdx?tk=' + token; terrainUrls.push(url); } /**********************************************************/ radarViewer = new DT.Viewer(this.$refs.radarCanvas, { imageryProvider: tdtImgMap, sceneMode: 2, mapProjection: new DT.Cesium.WebMercatorProjection(), mapMode2D: DT.Cesium.MapMode2D.INFINITE_SCROLL, }) radarViewer.cesiumViewer.imageryLayers.addImageryProvider(tdtVecMap, 1) radarViewer.cesiumViewer.imageryLayers.addImageryProvider(tdtIboMap, 2) radarViewer.cesiumViewer.imageryLayers.addImageryProvider(tdtImageMarkMap, 3) radarViewer.cesiumViewer.imageryLayers.get(1).show = false let vtxf_dpr = window.devicePixelRatio while (vtxf_dpr >= 2.0) { vtxf_dpr /= 2.0 } radarViewer.cesiumViewer.resolutionScale = vtxf_dpr radarLayer = new DT.LODSceneLayer() radarViewer.addLayer(radarLayer) radarViewer.cesiumViewer.scene.screenSpaceCameraController.enableTranslate = false radarViewer.cesiumViewer.scene.screenSpaceCameraController.enableRotate = false radarViewer.cesiumViewer.scene.screenSpaceCameraController.enableZoom = false radarViewer.cesiumViewer.scene.screenSpaceCameraController.enableTilt = false radarViewer.cesiumViewer.scene.screenSpaceCameraController.tiltEventTypes = [] // 去掉版权 radarViewer.cesiumViewer._innerCreditContainer.style.display = 'none' radarViewer.cesiumViewer.scene.camera.flyTo({ destination: radarPosition, duration: 0 }) radarHandler = new DT.Cesium.ScreenSpaceEventHandler( radarViewer.cesiumViewer.scene.canvas ) this.$nextTick(() => { this.refreshRadar() }) // radarHandler.setInputAction(event => { // let car = radarViewer.cesiumViewer.scene.globe.pick(radarViewer.cesiumViewer.scene.camera.getPickRay(event.position),radarViewer.cesiumViewer.scene); // let updateCartographic = DT.Cesium.Cartographic.fromCartesian(car) // let sourceCamera = DT.Cesium.Cartographic.fromCartesian(viewer.cesiumViewer.scene.camera.position.clone()) // viewer.cesiumViewer.scene.camera.flyTo({ // destination: DT.Cesium.Cartesian3.fromRadians(updateCartographic.longitude, updateCartographic.latitude, sourceCamera.height), // duration: 1 // }) // }, DT.Cesium.ScreenSpaceEventType.LEFT_CLICK) }, refreshRadar() { let position = viewer.cesiumViewer.scene.camera.position.clone() let position2 = DT.Cesium.Cartographic.fromCartesian(position) let calHeight = Math.min(position2.height * 2, 10000000) // let calHeight = position2.height * 2 calHeight = Math.max(calHeight, 10000) let radarPosition = DT.Cesium.Cartesian3.fromRadians(position2.longitude, position2.latitude, calHeight) radarViewer.cesiumViewer.scene.camera.flyTo({ destination: radarPosition, duration: 1 }) }, dealMapChange(map) { if (this.$refs.twinSituation) { this.$refs.twinSituation.dealMapChange(map) } // switch (map) { // case 'sat': // // viewer.cesiumViewer.camera.flyHome() // radarViewer.cesiumViewer.imageryLayers.get(0).show = true // radarViewer.cesiumViewer.imageryLayers.get(1).show = false // // viewer.cesiumViewer.imageryLayers.get(2).show = true // // viewer.cesiumViewer.imageryLayers.get(3).show = false // break // case 'vec': // // viewer.cesiumViewer.camera.flyHome() // radarViewer.cesiumViewer.imageryLayers.get(0).show = false // radarViewer.cesiumViewer.imageryLayers.get(1).show = true // // viewer.cesiumViewer.imageryLayers.get(2).show = // // window.config.env === 'online' // // viewer.cesiumViewer.imageryLayers.get(2).show = true // // viewer.cesiumViewer.imageryLayers.get(3).show = false // break // // } }, //#endregion //#region socket createWebsocket() { let options = { url: window.config.api + '/ws', topic: [ { name: '/topic/status', callback: this.handleWebsocketStatus }, { name: '/topic/wave', callback: this.handleWebsocketWave }, { name: '/topic/image', callback: this.handleWebsocketImage }, ], success: () => { console.log('自身websocket链接成功2') } } let { socket, stompClient } = connectWebSocket(options) socketInstance = socket stompClientInstance = stompClient }, handleWebsocketStatus(info) { // console.log('status socket', JSON.parse(info.body)) }, handleWebsocketWave(info) { // console.log('wave socket', JSON.parse(info.body)) }, handleWebsocketImage(info) { // console.log('wave socket', JSON.parse(info.body)) }, handleWebsocket(res) { let data = JSON.parse(res.body) console.log('websocket数据66666', data) this.updatePeople(data) }, stopTempWebSocket() { if (socketInstance) { disconnectWebSocket(socketInstance) socketInstance = null stompClientInstance = null } }, updatePeople(data) { let entity = lodLayer.getEntityById(data.userid) let updatePosition = DT.Cesium.Cartesian3.fromDegrees( data.lon, data.lat, Math.min(data.high, 1000) ) if (entity) { entity.position = updatePosition } else { entity = new DT.BillboardEntity({ id: data.userid, position: updatePosition, labelConfig: { text: data.username, font: '12px Microsoft YaHei', verticalOrigin: DT.Cesium.VerticalOrigin.CENTER, outlineColor: DT.Cesium.Color.BLACK, outlineWidth: 2, style: DT.Cesium.LabelStyle.FILL_AND_OUTLINE, pixelOffset: new DT.Cesium.Cartesian2(10, 0), // distanceDisplayCondition: new DT.Cesium.DistanceDisplayCondition( // 0, // 10000000 // ) }, billboardConfig: { image: process.env.BASE_URL + 'data/images/people.png', disableDepthTestDistance: Number.POSITIVE_INFINITY, width: 24, height: 24 } }) lodLayer.add(entity) entityCollection.set(data.userid, entity) } }, //#endregion sarChange(val) { // this.moveInfoBar = val }, //#region ais船 getAisData() { }, toggleAisBoat() { this.aisBoat.visible = !this.aisBoat.visible if (this.aisBoat.visible) { axios.get(process.env.BASE_URL + 'data/ais.json').then(res => { console.log('ais', res) this.addShipEntity(res.data) // res.data.forEach(element => { // // }) }) // 添加船舶 // this.addShipEntity([]) // 添加相机事件 // this.addCameraListener() } else { this.clearShipEntity() } }, toggleSplit() { let show = !this.splitVisible this.SET_SPLIT_VISIBLE(show) }, /** * 添加相机事件 * @author wangxueshen * @date 2024-01-23 * @returns {any} */ addCameraListener() { viewer.cesiumViewer.camera.percentageChanged = 0.05 //设置相机变化的识别精度,默认值为0.5 viewer.cesiumViewer.camera.changed.addEventListener(() => { const height = viewer.cesiumViewer.camera.positionCartographic.height shipEntities.values.forEach(ship => { if (ship.billboard) { ship.billboard.image = height <= 310000 ? ship.shapeIcon : ship.typeIcon } }) }) }, /** * 添加船舶 * @author wangxueshen * @date 2025-06-29 * @param {any} data * @returns {any} */ addShipEntity(data) { data.forEach(ship => { const shipEntity = viewer.entities.add({ // id: 'ship-' + ship.mmsi, position: DT.Cesium.Cartesian3.fromDegrees(ship['经度(度)'], ship['纬度(度)'], 100), billboard: { image: process.env.BASE_URL + 'data/images/boat8.png', rotation: DT.Cesium.Math.toRadians(ship['船艏向(度)']), scaleByDistance: new DT.Cesium.NearFarScalar(0, 1, 1, 0.5), }, label: { text: ship['船名'], show: true, font: '14px sans-serif', horizontalOrigin: DT.Cesium.HorizontalOrigin.LEFT, verticalOrigin: DT.Cesium.VerticalOrigin.CENTER, disableDepthTestDistance: 10000, pixelOffset: new DT.Cesium.Cartesian2(10, 0), scaleByDistance: new DT.Cesium.NearFarScalar(0, 1, 1, 0.8), distanceDisplayCondition: new DT.Cesium.DistanceDisplayCondition(0, 200000), } }) aisCollection.push(shipEntity) }) }, clearShipEntity() { aisCollection.forEach(ship => { viewer.entities.remove(ship) }) aisCollection = [] } //#endregion } }