skyeyesystem/frontend/Skyeye-sys-ui/src/views/home/index.js

1612 lines
49 KiB
JavaScript
Raw Normal View History

2026-01-25 16:02:00 +08:00
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: []
}
}
},
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)
2026-01-25 16:02:00 +08:00
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)
2026-01-25 16:02:00 +08:00
// 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']),
2026-01-25 16:02:00 +08:00
...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], 400000)
2026-01-25 16:02:00 +08:00
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
//#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
}
}