DIAMOND
12 months ago
23 changed files with 648 additions and 2895 deletions
@ -0,0 +1,8 @@ |
|||
// 随机数
|
|||
export function guid() { |
|||
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) { |
|||
var r = (Math.random() * 16) | 0, |
|||
v = c == 'x' ? r : (r & 0x3) | 0x8; |
|||
return v.toString(16); |
|||
}); |
|||
} |
@ -0,0 +1,62 @@ |
|||
export default class HandleNodeType { |
|||
#sn; |
|||
#sensorCallback; |
|||
#modelCallback; |
|||
#markerPositionCallback; |
|||
#polylineCallBack; |
|||
#default; |
|||
|
|||
constructor(sn) { |
|||
this.#sn = sn; |
|||
} |
|||
|
|||
sensor(callback) { |
|||
this.#sensorCallback = callback; |
|||
return this; |
|||
} |
|||
|
|||
// 模型回调
|
|||
modelCallback(callback) { |
|||
this.#modelCallback = callback; |
|||
return this; |
|||
} |
|||
|
|||
// 微波雷达回调
|
|||
markerPosition(callback) { |
|||
this.#markerPositionCallback = callback; |
|||
return this; |
|||
} |
|||
|
|||
// 区域回调
|
|||
polylineCallBack(callback) { |
|||
this.#polylineCallBack = callback; |
|||
return this; |
|||
} |
|||
|
|||
default(callback) { |
|||
this.#default = callback; |
|||
return this; |
|||
} |
|||
|
|||
run() { |
|||
// 判断节点的类型
|
|||
if (!this.#sn.czmObject) { |
|||
return null; |
|||
} |
|||
// 模型类型
|
|||
let tempCondition = this.#sn.czmObject.xbsjType; |
|||
switch (tempCondition) { |
|||
case 'Model': |
|||
this.#modelCallback ? this.#modelCallback() : this.#default(); |
|||
break; |
|||
case 'Pin': |
|||
this.#markerPositionCallback ? this.#markerPositionCallback() : this.#default(); |
|||
break; |
|||
case 'Polyline': |
|||
this.#polylineCallBack ? this.#polylineCallBack() : this.#default(); |
|||
break; |
|||
default: |
|||
this.#default ? this.#default() : null; |
|||
} |
|||
} |
|||
} |
@ -0,0 +1,437 @@ |
|||
|
|||
import _ from 'lodash'; |
|||
import { useUserStore } from '/@/store/modules/user'; |
|||
import { defHttp } from '/@/utils/http/axios'; |
|||
import $mitt from '@/utils/earthMap/mitt'; |
|||
import { useMessage } from "/@/hooks/web/useMessage"; |
|||
import earthUtils from '@/utils/earthMap/earth'; |
|||
import alarmImg from '@/assets/earthMap/alarm.gif'; |
|||
const { createMessage } = useMessage(); |
|||
|
|||
let userStore = useUserStore(); |
|||
let websock: any = []; |
|||
function initWebSocket(configName) { |
|||
if ('WebSocket' in window) { |
|||
let url = ''; |
|||
switch (configName) { |
|||
case 'domianURL': //接收后台模型数据
|
|||
// WebSocket与普通的请求所用协议有所不同,ws等同于http,wss等同于https
|
|||
// const userStore = useUserStore()
|
|||
// const orgCode = userStore.userInfo?.orgCode;
|
|||
// let userId = store.getters.userInfo.id;
|
|||
let userId = userStore.userInfo?.id; |
|||
url = window._CONFIG[configName].replace('https://', 'wss://').replace('http://', 'ws://') + '/websocket/' + userId; |
|||
// url = 'ws://127.0.0.1:5004'
|
|||
websock[configName] = new WebSocket(url); |
|||
websock[configName].onopen = websocketonopen; |
|||
websock[configName].onerror = websocketonerror; |
|||
websock[configName].onmessage = websocketonmessage; |
|||
websock[configName].onclose = websocketclose; |
|||
break; |
|||
case 'clientURL': //调用客户端监控视频窗口
|
|||
url = window._CONFIG['clientURL']; |
|||
websock[configName] = new WebSocket(url); |
|||
websock[configName].onopen = websocketonopen; |
|||
websock[configName].onerror = websocketonerror; |
|||
websock[configName].onclose = websocketclose; |
|||
break; |
|||
default: |
|||
console.log('websocket初始化失败'); |
|||
} |
|||
// console.log('url', url)
|
|||
} else { |
|||
console.log('当前浏览器不支持websocket,请更换浏览器!'); |
|||
} |
|||
} |
|||
function websocketonopen(e) { |
|||
console.log('WebSocket连接成功'); |
|||
} |
|||
function websocketonerror(e) { |
|||
console.log('WebSocket连接发生错误'); |
|||
} |
|||
const loreadAlarmInfo = _.debounce( |
|||
(url, eventSerialNum) => { |
|||
defHttp |
|||
.get( |
|||
{ |
|||
url: url, |
|||
params: eventSerialNum, |
|||
}, |
|||
{ isTransformResponse: false } |
|||
) |
|||
// getAction(url, {eventSerialNum: eventSerialNum})
|
|||
.then((res) => { |
|||
if (!res.success) { |
|||
console.log('重新发送websocket报警数据失败!'); |
|||
} else { |
|||
console.log('重新发送websocket报警数据成功!'); |
|||
} |
|||
}); |
|||
}, |
|||
2000, |
|||
{ maxWait: 3000, trailing: true } |
|||
); |
|||
|
|||
//
|
|||
async function websocketonmessage(e) { |
|||
//接收后端数据
|
|||
var data = eval('(' + e.data + ')'); |
|||
const cesium = window.Cesium; |
|||
// Cesium Math
|
|||
const math = cesium.Math; |
|||
// earth
|
|||
const earth = window.$earth; |
|||
//处理订阅信息
|
|||
if (data.cmd == 'new_warn_info') { |
|||
//有新增的预警信息
|
|||
//1.调起客户端窗体
|
|||
// chrome.call("formactive");
|
|||
//2.若警示界面打开着,则刷新列表
|
|||
if ($('.infoList').css('visibility') == 'visible') { |
|||
$mitt.emit('getWarnData'); |
|||
} |
|||
//3.弹出监控窗口或围栏信息
|
|||
if (data.msgTxt != undefined && data.dealStatus == 1) { |
|||
$mitt.emit('listenerVideoNum', data.msgTxt); |
|||
//显示报警位置
|
|||
window.$earth.sceneTree.$refs[data.labelCode].czmObject.color = [1, 0.09803921568627451, 0, 1]; |
|||
} else if (data.msgTxt != undefined && data.dealStatus == 3) { |
|||
this.$notification.open({ |
|||
key: 'fenceInfo', |
|||
message: '围栏信息通知', |
|||
description: data.msgTxt + '!', |
|||
duration: 0, |
|||
}); |
|||
} else if (data.dealStatus == 2) { |
|||
//消除单个报警位置
|
|||
window.$earth.sceneTree.$refs[data.labelCode].czmObject.color = [0.08235294117647059, 1, 0, 1]; |
|||
} else if (data.dealStatus == 0) { |
|||
//消除所有报警位置
|
|||
window.$earth.sceneTree.$refs.sensor.children.forEach((data, index) => { |
|||
data.czmObject.color = [0.08235294117647059, 1, 0, 1]; |
|||
}); |
|||
} |
|||
|
|||
//4.提示音
|
|||
if (data.dealStatus !== 2 && data.dealStatus !== 0) { |
|||
await this.$refs.audio.play(); |
|||
setTimeout(() => { |
|||
this.$refs.audio.pause(); //N秒后暂停播放
|
|||
}, data.alarmNum * 1000); |
|||
} |
|||
} else if (data.cmd == 'new_microwave_warn_info' || data.cmd == 'new_radar_warn_info' || data.cmd == 'new_video_warn_info') { |
|||
if (this.alarmInfoMap.has(data.serialNum)) { |
|||
return; |
|||
} |
|||
const evalString = ` |
|||
if(p._div){ |
|||
return |
|||
} |
|||
let left=p.winPos[0]; |
|||
let bottom=p.winPos[3]; |
|||
const div = document.createElement('div'); |
|||
div.style="position: absolute;left:"+left+"px;bottom:"+bottom+"px " |
|||
const img = document.createElement('img'); |
|||
img.src="${alarmImg}"; |
|||
img.style="width:60px;height:60px" |
|||
div.appendChild(img); |
|||
div.onclick=()=>{ |
|||
p.flyTo() |
|||
} |
|||
p._div = div; |
|||
const root=document.getElementById('earthContainer'); |
|||
root.appendChild(div); |
|||
XE.MVVM.watch(p.winPos,() => { |
|||
left=p.winPos[0]-30; |
|||
bottom=p.winPos[3]; |
|||
div.style="position: absolute;left:"+left+"px;bottom:"+bottom+"px " |
|||
}) |
|||
`;
|
|||
const pinConfig: any = { |
|||
name: 'Pin1', |
|||
xbsjType: 'Pin', |
|||
position: [math.toRadians(data.lon), math.toRadians(data.lat), 0], |
|||
evalString: evalString, |
|||
// imageUrl: alarmImg,
|
|||
isDivImage: true, |
|||
show: false, |
|||
far: 3000, |
|||
}; |
|||
// scanline
|
|||
const scanlineConfig: any = { |
|||
name: 'AlarmScanline', |
|||
xbsjType: 'Scanline', |
|||
position: [math.toRadians(data.lon), math.toRadians(data.lat), 0], |
|||
playing: true, |
|||
radius: 30, |
|||
timeDuration: 0.5, |
|||
color: [1, 0, 0, 1], |
|||
show: false, |
|||
}; |
|||
const pin = new window.XE.Obj.Pin(window.$earth); |
|||
const scanline = new window.XE.Obj.Scanline(window.$earth); |
|||
//1、获取到世界坐标
|
|||
let start = cesium.Cartesian3.fromDegrees(data.lon, data.lat, 0); |
|||
let height = await window.$earth.czm.viewer.scene.clampToHeightMostDetailed([start]).then(function (clampedCartesians) { |
|||
//2、获取到经纬高度
|
|||
let ellipsoid = window.$earth.czm.viewer.scene.globe.ellipsoid; |
|||
let cartographic = ellipsoid.cartesianToCartographic(clampedCartesians[0]); |
|||
return cartographic.height; |
|||
}); |
|||
if (height > 0) { |
|||
pinConfig.position[2] = height; |
|||
} else if (window.$earth.sceneTree.$refs.terrain.czmObject.show) { |
|||
height = await cesium.sampleTerrainMostDetailed(earth._viewer.terrainProvider, [start]).then((updatedPositions) => { |
|||
return updatedPositions[0].height ? updatedPositions[0].height : 0; |
|||
}); |
|||
pinConfig.position[2] = height; |
|||
} else { |
|||
pinConfig.position[2] = 0; |
|||
} |
|||
|
|||
// 保存报警类型到对象上
|
|||
let customProp: any = {}; |
|||
customProp.alarmType = data.cmd; |
|||
pinConfig.customProp = JSON.stringify(customProp); |
|||
scanlineConfig.customProp = JSON.stringify(customProp); |
|||
pin.xbsjFromJSON(pinConfig); |
|||
scanline.xbsjFromJSON(scanlineConfig); |
|||
// 判断现在相机的高度来显示报警相关模型
|
|||
if (this._earth.camera.position[2] < 100) { |
|||
// 隐藏 pin, 显示 scanline
|
|||
pin._div.hidden = true; |
|||
scanline.show = true; |
|||
} else { |
|||
// 隐藏 scanline, 显示 pin
|
|||
pin._div.hidden = false; |
|||
scanline.show = false; |
|||
} |
|||
scanline.flyTo(); |
|||
this.alarmInfoMap.set(data.serialNum, { pin: pin, scanline: scanline, timestamp: Date.now() }); |
|||
//报警弹窗
|
|||
this.videoWindowProps.title = `实时报警窗口(${data.cameraName})`; |
|||
this.videoWindowProps.videoUrl = data.cameraCode; //相机编码
|
|||
this.videoWindowProps.isAlarm = true; |
|||
this.videoWindowProps.visible = true; |
|||
this.videoWindowProps.playRecord = false; |
|||
|
|||
this.videoWindowProps.warnEvent.happenTime = data.happenTime; |
|||
this.videoWindowProps.warnEvent.happenLoc = `${Number(data.lon).toFixed(6)},${Number(data.lat).toFixed(6)}`; |
|||
this.videoWindowProps.warnEvent.warnNum = 1; |
|||
this.videoWindowProps.warnEvent.warnLevel = filterDictTextByCache('ms_warn_level', data.warnLevel); |
|||
this.videoWindowProps.warnEvent.warnType = filterDictTextByCache('ms_warn_type', data.warnType); |
|||
this.videoWindowProps.warnEvent.warnContent = data.warnContent; |
|||
|
|||
//若警示界面打开着,则刷新列表
|
|||
if ($('.infoList').css('visibility') == 'visible') { |
|||
$mitt.emit('getWarnData'); |
|||
} |
|||
|
|||
//提示音
|
|||
await this.$refs.audio.play(); |
|||
setTimeout(() => { |
|||
this.$refs.audio.pause(); //N秒后暂停播放
|
|||
}, 3 * 1000); |
|||
} else if (data.cmd == 'earthMap_model_realtime_info') { |
|||
console.log(data); |
|||
console.log(this.radarAlarmDataMap); |
|||
// 雷达轨迹报警数据
|
|||
const alarmContent = data.content; |
|||
|
|||
if (this.radarAlarmDataMap.has(data.eventSerialNum)) { |
|||
// 存在雷达报警数据
|
|||
let radarAlarmData = this.radarAlarmDataMap.get(data.eventSerialNum); |
|||
let targetMap = radarAlarmData.target; |
|||
if (targetMap.has(data.modelId)) { |
|||
// 存在目标数据
|
|||
let targetData = targetMap.get(data.modelId); |
|||
let pathModel = targetData.path; |
|||
let groundImageModel = targetData.groundImage; |
|||
//更新目标数据
|
|||
// 更新报警数据
|
|||
let positionRadian = earthUtils.degreeToRadianInLngLatHeight(alarmContent.lon, alarmContent.lat, 0); |
|||
// 更新路径
|
|||
pathModel.positions.push(positionRadian); |
|||
groundImageModel.position = positionRadian; |
|||
if (pathModel.positions.length > 1) { |
|||
pathModel.show = true; |
|||
groundImageModel.show = true; |
|||
} |
|||
} else { |
|||
// 不存在目标数据
|
|||
// 创建目标数据
|
|||
let positionRadian = earthUtils.degreeToRadianInLngLatHeight(alarmContent.lon, alarmContent.lat, 0); |
|||
// 路径
|
|||
let pathModel = new window.XE.Obj.Path(window.$earth); |
|||
let pathConfig = { |
|||
name: 'path', |
|||
xbsjType: 'Path', |
|||
positions: [positionRadian], |
|||
loop: false, |
|||
playing: true, |
|||
width: 2, |
|||
color: [1, 0, 0, 1], |
|||
show: false, |
|||
showDirection: false, |
|||
currentSpeed: 30, |
|||
alwaysAlongThePath: true, |
|||
material: { |
|||
type: 'Color', |
|||
color: [1, 0, 0, 1], |
|||
}, |
|||
}; |
|||
pathModel.xbsjFromJSON(pathConfig); |
|||
// 地面图片
|
|||
let groundImageModel = new window.XE.Obj.GroundImage(window.$earth); |
|||
let imageUrls: any = []; |
|||
if (data.mainTarget) { |
|||
imageUrls.push(window._CONFIG['staticDomainURL'] + '/keyi_point1.png'); |
|||
imageUrls.push(window._CONFIG['staticDomainURL'] + '/keyi_point2.png'); |
|||
} else { |
|||
imageUrls.push(window._CONFIG['staticDomainURL'] + '/keyi_point3.png'); |
|||
imageUrls.push(window._CONFIG['staticDomainURL'] + '/keyi_point4.png'); |
|||
} |
|||
let groundImageConfig = { |
|||
name: 'groundImage', |
|||
xbsjType: 'GroundImage', |
|||
position: positionRadian, |
|||
width: 3, |
|||
height: 3, |
|||
playing: true, |
|||
imageUrls: imageUrls, |
|||
show: false, |
|||
}; |
|||
groundImageModel.xbsjFromJSON(groundImageConfig); |
|||
// 保存目标数据
|
|||
let targetData = { |
|||
path: pathModel, |
|||
groundImage: groundImageModel, |
|||
}; |
|||
targetMap.set(data.modelId, targetData); |
|||
} |
|||
// 更新时间
|
|||
const updateTime = Date.now(); |
|||
radarAlarmData.timestamp = updateTime; |
|||
// 更新 pin 的时间
|
|||
let alarm = this.alarmInfoMap.get(data.eventSerialNum); |
|||
if (alarm) { |
|||
alarm.timestamp = updateTime; |
|||
} |
|||
} else { |
|||
// 不存在报警数据
|
|||
// 路径
|
|||
let pathModel = new window.XE.Obj.Path(window.$earth); |
|||
let pathConfig = { |
|||
name: 'path', |
|||
xbsjType: 'Path', |
|||
positions: [earthUtils.degreeToRadianInLngLatHeight(alarmContent.lon, alarmContent.lat, 0)], |
|||
loop: false, |
|||
playing: true, |
|||
width: 2, |
|||
color: [1, 0, 0, 1], |
|||
show: false, |
|||
showDirection: false, |
|||
currentSpeed: 30, |
|||
alwaysAlongThePath: true, |
|||
material: { |
|||
type: 'Color', |
|||
color: [1, 0, 0, 1], |
|||
}, |
|||
}; |
|||
// 地面图片
|
|||
let groundImage = new window.XE.Obj.GroundImage(window.$earth); |
|||
let imageUrls: any = []; |
|||
if (data.mainTarget) { |
|||
imageUrls.push(window._CONFIG['staticDomainURL'] + '/keyi_point1.png'); |
|||
imageUrls.push(window._CONFIG['staticDomainURL'] + '/keyi_point2.png'); |
|||
} else { |
|||
imageUrls.push(window._CONFIG['staticDomainURL'] + '/keyi_point3.png'); |
|||
imageUrls.push(window._CONFIG['staticDomainURL'] + '/keyi_point4.png'); |
|||
} |
|||
let groundImageConfig = { |
|||
name: 'groundImage', |
|||
xbsjType: 'GroundImage', |
|||
playing: true, |
|||
width: 3, |
|||
height: 3, |
|||
position: earthUtils.degreeToRadianInLngLatHeight(alarmContent.lon, alarmContent.lat, 0), |
|||
imageUrls: imageUrls, |
|||
show: false, |
|||
}; |
|||
// 创建路径
|
|||
groundImage.xbsjFromJSON(groundImageConfig); |
|||
// 创建地面图片
|
|||
pathModel.xbsjFromJSON(pathConfig); |
|||
|
|||
// 保存数据到map中
|
|||
let target = { |
|||
path: pathModel, |
|||
groundImage: groundImage, |
|||
mainTarget: alarmContent.mainTarget, |
|||
}; |
|||
let targetMap = new Map(); |
|||
targetMap.set(data.modelId, target); |
|||
this.radarAlarmDataMap.set(data.eventSerialNum, { |
|||
target: targetMap, |
|||
timestamp: Date.now(), |
|||
}); |
|||
|
|||
if (!this.alarmInfoMap.has(data.eventSerialNum)) { |
|||
// 不存在告警信息(小灯或扫描线)时发送
|
|||
// 事件编号到后台使其重新发送websocket报警数据
|
|||
await new Promise((r) => setTimeout(r, 500)); |
|||
if (!this.alarmInfoMap.has(data.eventSerialNum)) { |
|||
console.log('发送websocket报警数据'); |
|||
this.loreadAlarmInfo(this.url.sendRadarAlarmByWebSocket, data.eventSerialNum); |
|||
} |
|||
} |
|||
} |
|||
if (this.videoWindowProps.visible) { |
|||
this.videoWindowProps.warnEvent.warnNum = this.radarAlarmDataMap.get(data.eventSerialNum).target.size; |
|||
} |
|||
// console.debug('雷达轨迹报警数据', this.radarAlarmDataMap);
|
|||
} else if (data.cmd == '') { |
|||
earth.sceneTree.$refs[data.eventSerialNum].destroy(); |
|||
} else if (data.cmd == 'eventPublish') { |
|||
window.getEventData(); |
|||
} |
|||
} |
|||
function websocketclose(e) { |
|||
console.log('connection closed (' + e.code + ')'); |
|||
createMessage.warn('websocket连接已断开', 3); |
|||
} |
|||
function websocketdosend(configName) { |
|||
//发送数据
|
|||
this.spinning = !this.spinning; //加载状态
|
|||
console.log('this.websock[configName]', websock[configName]); |
|||
let message = { |
|||
topic: 'Show_Single_Video', |
|||
msg: '192.168.1.65', |
|||
}; |
|||
//readyState:0:正在连接中,1:已建立连接,2:连接正在关闭,3:连接已关闭或连接失败
|
|||
if (websock[configName].readyState == 1) { |
|||
websock[configName].send(JSON.stringify(message)); |
|||
that.spinning = !that.spinning; //加载状态
|
|||
console.log('已发送'); |
|||
} else { |
|||
//重新连接websocket
|
|||
initWebSocket('clientURL'); |
|||
setTimeout(function () { |
|||
if (websock[configName].readyState == 1) { |
|||
websock[configName].send(JSON.stringify(message)); |
|||
} |
|||
that.spinning = !that.spinning; //加载状态
|
|||
}, 3000); |
|||
} |
|||
} |
|||
|
|||
export { |
|||
initWebSocket, |
|||
websocketonopen, |
|||
websocketonerror, |
|||
loreadAlarmInfo, |
|||
websocketclose, |
|||
websocketonmessage, |
|||
websocketdosend, |
|||
websock, |
|||
} |
File diff suppressed because it is too large
Loading…
Reference in new issue