<!-- 电子地图 -编辑页面 --> <template> <div> <div id="earthContainer" ref="earthContainer" style="width: 100%; height: 100%; top: 300px"></div> <div class="earthUI_header"> <header> <p>{{ earthTitle }}</p> <p>{{ realTime }}</p> </header> </div> <div> <a-radio-group default-value="satellite" button-style="solid" size="small" @change="radioChange" class="radioBtn" v-show="radioBtnShow"> <a-radio-button value="satellite"> 卫星影像</a-radio-button> <a-radio-button value="vector"> 矢量地图</a-radio-button> </a-radio-group> <a-spin size="large" tip="地图切换中,请稍候..." :spinning="earthChangeSpin" class="earthChangeSpin"></a-spin> </div> <!-- 预警列表 --> <!-- <WarnInfoList /> --> <!-- 电线杆弹窗 --> <div id="cameraModal" class="cameraModal" v-show="cameraModalShow" ref="cameraModal"> <a-spin size="large" :spinning="spinning" class="spinning"></a-spin> <a-button @click="roamPathSet()">视频融合</a-button> </div> <!-- 视频融合 --> <VideoFusionWin v-if="VideoFusionWinShow" :cameraList="cameraList" :monitorPosition="monitorPosition" :updateModel="toItemObj.updateModel" :isUpdate="toItemObj.isUpdate" :userSave="toItemObj.userSave" ></VideoFusionWin> <!-- 地标弹窗 --> <!-- <div id="poiModal" class="poiModal" v-show="poiModalShow" ref="poiModal"> <div class="poiModal-content"> <div class="poiModal-header"></div> <div class="poiModal-body"></div> </div> </div>--> <!-- 警示弹窗 --> <video-split-screen /> <!-- 警示音频 --> <audio ref="audio" loop> <source src="@/assets/earthMap/audio/notify.mp3" /> </audio> <!-- 云台控制弹窗 --> <video-window :id="videoWindowProps.id" :visible.sync="videoWindowProps.visible" :title="videoWindowProps.title" :videoUrl="videoWindowProps.videoUrl" :cameraIp="videoWindowProps.cameraIp" :cameraUser="videoWindowProps.cameraUser" :cameraPwd="videoWindowProps.cameraPwd" :isAlarm="videoWindowProps.isAlarm" :playRecord="videoWindowProps.playRecord" :warnTime="videoWindowProps.warnTime" :warnEvent="videoWindowProps.warnEvent" /> <!-- 左侧操作栏 --> <Toolbar v-if="toolbarShow" :setLabelStatus="setLabelStatus"></Toolbar> <AddModelWin v-if="addModelWinShow" :setLabelStatus="setLabelStatus" :czmObject="czmObject" :node="node" :type="type" :lineId="lineId" :areaCode="areaCode" :areaByNodeId="areaByNodeIdModel" :setIconByRef="setIconByRef" :el="el" :eidtId="eidtId" ></AddModelWin> <AddRoamVideo v-if="addRoamVideoShow"></AddRoamVideo> </div> </template> <script lang="ts"> import { Options, Vue } from 'vue-class-component'; import sceneTree from '@/assets/earthMap/resjson/sc.json'; import { defHttp } from '/@/utils/http/axios'; import earthUtils from '@/utils/earthMap/earth'; import _ from 'lodash'; import $ from 'jquery'; import { useUserStore } from '/@/store/modules/user'; import { useEarthMapStore } from '/@/store/modules/earthMap'; import Toolbar from '@/components/earthMap/Toolbar.vue'; import AddModelWin from '@/components/earthMap/toolbar/AddModelWin.vue'; import AddRoamVideo from '@/components/earthMap/toolbar/AddRoamVideo.vue'; import VideoSplitScreen from '@/components/earthMap/VideoSplitScreen.vue'; import VideoWindow from '@/components/earthMap/VideoWindow.vue'; import WarnInfoList from '@/components/earthMap/WarnInfoList.vue'; import { getRealTime } from '@/utils/date'; import $mitt from '@/utils/earthMap/mitt'; import { drawInit } from '@/utils/earthMap/earthDraw'; import { keyControlInit } from '@/utils/earthMap/keyControlInit'; import redFlag from '@/assets/earthMap/redFlag.png'; import { addModel, addPin, addViewShedRadar, addShipGroundImg, addShipTrack } from '@/utils/earthMap/earthObj'; import { drawAllShips } from '@/utils/earthMap/shipDraw'; import hidePng from '@/assets/earthMap/hide.png'; import alarmImg from '@/assets/earthMap/alarm.gif'; import VideoFusionWin from './components/VideoFusionWin.vue'; import circleDot2 from '@/assets/earthMap/circleDot2.png'; import circleDot1 from '@/assets/earthMap/circleDot1.png'; import circleDot3 from '@/assets/earthMap/circleDot3.png'; import ship from '@/assets/images/ship.png'; 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; } } } function setClassEl(setClassEl1, setClassEl2, checked) { if (checked) { setClassChecked(setClassEl1, setClassEl2); } else { setClassNoChecked(setClassEl1, setClassEl2); } } function setClassChecked(setClassEl1, setClassEl2) { // node.checkStatus = 'checked' // node.disabled = '' //***设置样式为选中 */ setClassEl1.className = 'xbsj-checkbox-wrapper xbsj-checkbox-wrapper-checked xbsj-checkbox-default'; setClassEl2.className = 'xbsj-checkbox xbsj-checkbox-checked'; } function setClassNoChecked(setClassEl1, setClassEl2) { // node.checkStatus = '' // node.disabled = 'disabled' // 设置为非选中 setClassEl1.className = 'xbsj-checkbox-wrapper xbsj-checkbox-wrapper-disabled xbsj-checkbox-default'; setClassEl2.className = 'xbsj-checkbox xbsj-checkbox-disabled'; } function classMutationObserver(el, el1, checkedStauts, id) { // 观察器的配置(需要观察什么变动) 属性,子节点or后代节点 const config = { attributes: true, childList: false, subtree: false }; const callback1 = function (mutationsList, observer) { const checked = checkedStauts.get(id); const oldClassName = el.className; const trueClassName = 'xbsj-checkbox-wrapper xbsj-checkbox-wrapper-checked xbsj-checkbox-default'; const noClassName = 'xbsj-checkbox-wrapper xbsj-checkbox-wrapper-disabled xbsj-checkbox-default'; if (checked) { if (oldClassName == trueClassName) { return; } else { setClassChecked(el, el1); } } else { if (oldClassName == noClassName) { return; } else { setClassNoChecked(el, el1); } } }; // 创建一个观察器实例并传入回调函数 const observer1 = new MutationObserver(callback1); // 以上述配置开始观察目标节点 observer1.observe(el, config); } function disabledMutationObserver(el) { const config = { attributes: true, childList: false, subtree: false }; const callback1 = function (mutationsList, observer) { const el1 = mutationsList[0]; if (el1.attributeName == 'disabled') { el.removeAttribute('disabled'); } }; const observe1 = new MutationObserver(callback1); // 以上述配置开始观察目标节点 observe1.observe(el, config); } @Options({ components: { Toolbar, VideoSplitScreen, VideoWindow, WarnInfoList, AddModelWin, AddRoamVideo, VideoFusionWin, }, props: {}, }) export default class EarthComp extends Vue { /** * 资源创建 */ userStore = useUserStore(); store = useEarthMapStore(); earthTitle = '态势监控一张图'; realTime = '……'; // 注意:Earth和Cesium的相关变量放在vue中,必须使用下划线作为前缀! _earth = undefined; _earthUI = undefined; _viewer = undefined; _pin = undefined; _handler = undefined; // sceneTree= require('@/assets/earthMap/resjson/sc.json'), // sceneTree= new URL(`@/assets/earthMap/resjson/sc.json`, import.meta.url).href, sceneTree: any = sceneTree; // areaB= require('@/assets/earthMap/resjson/area_b.json'), url: any = { queryLabelList: 'military/msMapLabel/queryLabelAndDeviceList', queryLineList: 'military/msMapLine/list', queryCameraInfo: 'military/camera/site/getCameraInfoForEarth', queryAllModelInfo: 'military/msModelPosition/queryAllModelInfo', queryPatrolRouteInfo: 'military/msPatrolLine/getLineDetail', queryBayoneByParam: 'military/msBayonetStatistics/getBayoneByParam', queryAisInfo: 'military/checkpoint/msAisInfo/list', keepAlive: 'military/mapInfo/keepAlive', //雷达扫描列表 radarList: '/military/RadarConfig/list', // 删除模型 // 传感器 deleteSensor: '/military/msModelPosition/deleteByEventSerialNum', // 站点 deleteSite: '/military/camera/site/delete', // 标志点 deleteMapLabel: '/military/msMapLabel/delete', updateMapLine: '/military/msMapLine/edit', deleteMapLine: '/military/msMapLine/delete', saveMapLine: '/military/msMapLine/add', // 编辑 模型 // 传感器 updateSensor: '/military/msModelPosition/editByEventSerialNum', // 站点 updateSite: '/military/camera/site/edit', // 标志点 updateMapLabel: '/military/msMapLabel/edit', // 模型 保存 // 传感器 SaveSensorModel: '/military/msModelPosition/add', // 站点 saveCameraSiteModel: '/military/camera/site/add', // 标志点 saveMapLabel: '/military/msMapLabel/addMapLabel', // 通过 线路名称 查询 线路 queryMapLine: '/military/msMapLine/queryByName', querySiteById: '/military/camera/site/queryById', // 查询设备列表 queryDeviceInfoList: '/military/msDeviceInfo/list', setDefenseArea: '/military/netty/microwaveDetector/defenceArea', perimeterRegionList: '/third/api/perimeterRegionList', perimeterControl: '/third/api/perimeterControl', // 雷达重新发送报警信息 sendRadarAlarmByWebSocket: '/military/warn/sendRadarAlarmByWebSocket', }; cameraData: any = {}; cameraModalShow = false; poiModalShow = false; radioBtnShow = true; glmId: any = []; spinning = false; earthChangeSpin = false; websock: any = []; timer: any = null; // 保活定时器 timer2: any = null; // 时间定时器 // 报警清除-定时器 alarmTrackClearTimer: any = null; videoWindowProps: any = { visible: false, isAlarm: false, id: '', title: '', videoUrl: '', cameraIp: '', cameraUser: '', cameraPwd: '', playRecord: false, warnTime: null, warnEvent: { happenTime: '', happenLoc: '', warnNum: 0, warnLevel: 0, warnType: 0, warnContent: '', }, }; // 图层管理- 模型 ref 旧值 sceneTreeOldRefValue = ''; sceneInfo: any = null; // 区域节点By Ref划分 nodeConfigByRef = new Map(); nodeCheckedByRef = new Map(); areaByNodeId = new Map(); statusByNodeId = new Map(); imgByRef = new Map(); radarAlarmDataMap = new Map(); wbUnifiedResponse = false; hostDeviceMapById = new Map(); alarmInfoMap = new Map(); toolbarShow = false; //addModelWin addModelWinShow = false; czmObject: any = null; node: any = null; type = ''; lineId = ''; areaCode = ''; areaByNodeIdModel = ''; el: any = null; eidtId: any = null; //addroamVideo addRoamVideoShow = false; // 控制窗口显示 VideoFusionWinShow = false; //传到子组件的值 toItemObj: any = { updateModel: {}, isUpdate: true, userSave: {}, }; // 节点值 domKey: any = ''; // 监控相机列表 cameraList: any = []; // 监控相机位置 monitorPosition: any = []; /////////////////////////////////////////////////////////////////////////// mounted() { let that = this; //随机数 window.guid = this.guid; //创建地球资源 this.createEarth(); //获取实时日期时间 this.getRealTime(); //初始化websocket // this.initWebSocket('domianURL') //阻止浏览器右键事件 document.oncontextmenu = function (e) { return false; }; { //将回调延迟到下次 DOM 更新循环之后执行(针对由jq动态增加的元素绑定事件) this.$nextTick(() => { { //监控点击事件 $('.cameraModal').on('click', '.openIframe', function (e: any) { // web插件播放视频流 let videoWindowProps = that.videoWindowProps; videoWindowProps.id = $(this).attr('id'); videoWindowProps.title = $(this).text(); videoWindowProps.videoUrl = $(this).attr('videoUrl'); videoWindowProps.cameraIp = $(this).attr('cameraIP'); videoWindowProps.cameraUser = $(this).attr('cameraUser'); videoWindowProps.cameraPwd = $(this).attr('cameraPsd'); videoWindowProps.isAlarm = false; videoWindowProps.visible = true; videoWindowProps.playRecord = false; }); } // 轮询 { //一个小时调用一次空接口,保持系统session不过期 this.timer = setInterval(() => { this.keepAlive(); }, 60 * 60 * 1000); this.alarmTrackClearTimer = setInterval(() => { this.radarAlarmTimeOutCheck(); }, 6 * 1000); } }); } } // 随机数 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); }); } // 打开视频融合 roamPathSet() { // 打开视频融合 this.VideoFusionWinShow = true; // 关闭相机列表 this.cameraModalShow = false; } // 控制子元素的显示或者隐藏 showOrHideChild(clickNode, earthUI, parentChecked) { const childs = clickNode.children; if (childs && childs.length > 0) { for (const child of childs) { const ref = child.ref; const inputEl: any = document.getElementById(ref); if (inputEl) { inputEl.checked = parentChecked; const event = new Event('change'); inputEl.dispatchEvent(event); } else { if (ref.startsWith('node_')) { const readyNode = earthUI.earth.sceneTree.$refs[ref.split('_')[1]]; if (readyNode && readyNode.czmObject) { readyNode.czmObject.show = parentChecked; } } else if (ref.startsWith('nodeSecondary_')) { const readyNode = earthUI.earth.sceneTree.$refs[ref.split('_')[1]]; if (readyNode && readyNode.czmObject) { readyNode.czmObject.show = parentChecked; let guid = readyNode.czmObject.pinXbsjGuid; let pin = window.$earth.getObject(guid); pin.show = !pin.show; } } else { if (child && child.czmObject) { child.czmObject.show = parentChecked; } } this.nodeCheckedByRef.set(ref, parentChecked); this.showOrHideChild(child, earthUI, parentChecked); } } } } // 告警模型显示/隐藏 showAlarmPin(show) { this.alarmInfoMap.forEach((item, _index) => { item.pin.show = show; item.pin._div.hidden = !show; item.scanline.show = !show; }); } cameraPositionChange = _.debounce( (that) => { let height = window.$earth.camera.position[2]; if (height < 100) { // 相机高度小于1000米,告警显示扫描线 that.showAlarmPin(false); } else if (height >= 100) { // 相机高度大于1000米,告警显示图标 that.showAlarmPin(true); } }, 500, { maxWait: 1000 } ); createEarth() { let that = this; XbsjEarthUI.create('earthContainer').then(async (earthUI: any) => { // 设置全局变量,可调试 window.$uia = earthUI; window.$earth = earthUI.earth; earthUI.controls.mainBar.show = false; //隐藏主工具栏 earthUI.controls.statusBar.show = true; //状态栏 //图层管理 let sceneTree = earthUI.tools.sceneTree; // 显示图层管理 sceneTree.show = true; // 设置图层管理 ref 输入框的 回车 事件 // ref 输入框的 let sceneTreeInput = sceneTree._comp.$el.getElementsByClassName('xbsj-model-content-box')[0].children[1]; // 地图右键菜单和ref输入框控制 this.$nextTick(() => { // 删除ref 的 输入框 sceneTreeInput.remove(); // ----右键菜单样式控制--start // 选择需要观察变动的节点 const targetNode = document.getElementsByClassName('menu-box')[0]; // 观察器的配置(需要观察什么变动) 属性,子节点or后代节点 const config = { attributes: true, childList: false, subtree: false }; // 当观察到变动时执行的回调函数 const callback = function (mutationsList, observer) { // 右键会弹出菜单的样式 此时可以活的菜单这个元素 const el = mutationsList[0].target; // 菜单的展示属性 const elDisplay = el.style.display; // 如果菜单的展示属性本来就是none 则什么也不做 if (elDisplay == 'none') { return; } // 获取到菜单项的集合 const childList = el.children[0].children; // 菜单长度 const liSize = childList.length; // 当菜单为none时 不显示 if (liSize == 0) { el.style.display = 'none'; } else { // 长度大于零 但第一个元素是 添加文件夹时也不显示 const text = childList[0].textContent; if ('添加文件夹 ' == text) { el.style.display = 'none'; } } }; // 创建一个观察器实例并传入回调函数 const observer = new MutationObserver(callback); // 以上述配置开始观察目标节点 observer.observe(targetNode, config); // -----右键菜单控制----end }); let XE = window.XE; // ref 的 输入框 // 设置 回车 事件 sceneTreeInput.onkeydown = function (e) { if (e.code === 'Enter') { // 回车事件 that.changeRef(earthUI.earth.sceneTree.currentSelectedNode, sceneTree._comp.$data.refvalue, that.sceneTreeOldRefValue); } }; // 设置失去焦点事件 sceneTreeInput.onblur = function () { that.changeRef(earthUI.earth.sceneTree.currentSelectedNode, sceneTree._comp.$data.refvalue, that.sceneTreeOldRefValue); }; // 修改图层管理中,右键菜单的显示 sceneTree._comp.popContextMenu = ({ item, vueObject }) => { that.sceneTreePopContextMenu({ item, vueObject }, earthUI); }; earthUI.tools.featureProperty.disabled = true; //禁用对象属性面板 this._earthUI = earthUI; this._earth = earthUI.earth; this._earth.interaction.picking.enabled = true; // 全局打开点击事件权限 this._earth.czm.viewer.scene.globe.depthTestAgainstTerrain = true; //开启深度检测 this._earth.terrainEffect.subSurfaceEnabled = false; //开启地表透明模式 this._viewer = earthUI.earth.czm.viewer; this._viewer.scene.fxaa = true; //图像改善 this._viewer.scene.globe.baseColor = Cesium.Color.BLACK; //加载场景资源 // console.log("this.sceneTree",this.sceneTree); // console.log("window._CONFIG['earthMapURL']",window._CONFIG['earthMapURL']); // console.log("window._CONFIG['satellite']",window._CONFIG['satellite']); this.sceneTree.children[0].czmObject.xbsjImageryProvider.TileMapServiceImageryProvider.url = window._CONFIG['earthMapURL'] + window._CONFIG['satellite']; this.sceneTree.children[1].czmObject.xbsjImageryProvider.TileMapServiceImageryProvider.url = window._CONFIG['earthMapURL'] + window._CONFIG['vector']; this.sceneTree.children[2].czmObject.xbsjTerrainProvider.XbsjCesiumTerrainProvider.url = window._CONFIG['earthMapURL'] + window._CONFIG['terrain']; // this.sceneTree.children.push(this.areaB) this._earth.sceneTree.root = { expand: true, title: '场景树', children: [this.sceneTree], }; // 监控相机数据 XE.MVVM.watch(this._earth.camera, 'position', () => { this.cameraPositionChange(this); }); //加载地图实时资源(无人机、车辆、人员、巡逻路线等) // this.createRealTimeObj(earthUI) //监听鼠标事件 this.listenMouseHandler(earthUI); //监听mitt this.listenMittHandler(earthUI); // 飞入方法 await this.fly(); //加载地图线路资源 await this.createBBHLine(earthUI); //创建工具栏 this.toolbarShow = true; }); } //飞入方法 async fly() { let position, rotation, viewDistance, duration; const sceneId = this.userStore.userInfo?.sceneId; await defHttp .get( { url: '/military/msMapScene/list', params: { pageNo: 1, pageSize: 999, sceneId: sceneId + '*', column: 'sceneId', order: 'asc', }, }, { isTransformResponse: false } ) .then((response) => { console.log('fly', response); // 设置岛屿信息为数组 this.sceneInfo = response.result.records; return response.result.records; }) .then((res) => { //飞入 所属场景下的位置 position = [res[0].cameraLon, res[0].cameraLat, res[0].cameraAltitude]; rotation = [res[0].rotationX, res[0].rotationY, res[0].rotationZ]; viewDistance = res[0].viewDistance; duration = res[0].duration; this._earth.camera.flyTo(position, viewDistance, rotation, duration); // 地图复原事件 window.$flyTo = this.flyTo = () => { this._earth.camera.flyTo(position, viewDistance, rotation, duration); }; }); } setLoginPoint(data) { let position = [data.lon, data.lat, 0]; let rotation = [data.rotationX, data.rotationY, data.rotationZ]; let viewDistance = data.viewDistance; let duration = data.duration ? data.duration : 1; const leafConfig = { name: '岛屿', xbsjType: 'Pin', // far: 2500000, near: 3000000, position: position, // imageUrl: require('@/assets/redFlag.png'), imageUrl: redFlag, pinBuilder: { extText: data.sceneName, extTextFont: '30px 楷体', extTextPixelOffset: [30, -40], fillColor: [1, 1, 1, 0.9], outlineColor: [0, 0, 0, 0.9], }, }; const pin = new window.XE.Obj.Pin(window.$earth); pin.xbsjFromJSON(leafConfig); position[2] = data.altitude; //鼠标事件 pin.onmouseover = () => { this._viewer._container.style.cursor = 'pointer'; }; pin.onmouseout = () => { this._viewer._container.style.cursor = 'default'; }; pin.onclick = function () { this._earth.camera.flyTo(position, viewDistance, rotation, duration); }; } //设置按钮颜色状态 setIconByRef(ref, el) { const status = this.statusByNodeId.get(ref); if (status != undefined && status != null) { let img = this.imgByRef.get(ref); const icon = el.children[0].children[2]; if (!img) { img = document.createElement('img'); this.imgByRef.set(ref, img); } if (icon.nodeName == 'I') { icon.replaceWith(img); } if (status == 1) { img.src = circleDot2; } else if (status == 0) { img.src = circleDot1; } else { img.src = circleDot3; } img.setAttribute('style', 'width:16px;height:16px;margin-top:7px'); } } /* 使用async/await 处理异步方法顺序执行。成功的操作放到try里,失败的放在catch里 */ async createBBHLine(earthUI = null) { console.log('MyScene', this.userStore.userInfo?.sceneId); let type = 1; //** let models: any = { ref: this.sceneInfo[0].sceneId, expand: true, title: this.sceneInfo[0].sceneName, children: [], }; for (let record of this.sceneInfo) { if (record.sceneId == this.userStore.userInfo?.sceneId) { continue; } models.children.push({ ref: record.sceneId, expand: false, title: record.sceneName, children: [], }); } // console.log('models',models); // 加载区域 // console.log("加载区域"); await this.getLineInfo(models, type); // 加载站点 // console.log("加载站点"); await this.getCameraInfo(models, type); // 加载雷达和微波 // console.log("加载雷达和微波"); const labelItems: any = await this.getLabelInfo(models, type); //加载绘画资源 await drawInit(); //加载重点监控区域 await keyControlInit(); // 监听树的dom节点变化 // console.log("监听树的dom节点变化"); this.$nextTick(() => { // ----树节点复选框控制--start // 容器元素 const target1 = document.getElementById('earthContainer')?.children[0].children[0].children[4].children[2].children[0].children[0]; // 配置子元素变动时触发 const config1 = { attributes: false, childList: true, subtree: false }; // this的别称 const that = this; // 回调事件 const callback1 = function (mutationsList, observer) { for (const mutation of mutationsList) { // 新增元素 const el = mutation.addedNodes[0]; // 删除元素时不触发 if (!el) { continue; } // 样式设置1 const setClassEl1 = el.children[0].children[1]; // 样式设置2 const setClassEl2 = setClassEl1.children[0]; // 查找input元素 const inputEl = setClassEl2.querySelector('input'); // 移除input元素的禁用属性 inputEl.removeAttribute('disabled'); const item = el.__vue__.item; // item.checkStatus = 'ignored' // 从元素中拿到这个元素节点对象 const nodeObject = item._inner.sn; // console.log("nodeObject",nodeObject); // 记录ref const ref = nodeObject.ref; if (ref.startsWith('wbList') || ref.startsWith('ldList')) { // 展开菜单图标元素 const iel = el.children[0].children[0]; iel.addEventListener('click', function (e) { if (iel.className == 'xbsj-icon xbsj-icon-ios-arrow-forward XbsjVritualTreeItemExpandIcon') { console.log('收起菜单'); return; } // 获取展开菜单下的元素并设置图标 let eventTarget; // console.log(nodeObject.children); for (let index in nodeObject.children) { if (index === '0') { eventTarget = el.nextElementSibling; } else { eventTarget = eventTarget.nextElementSibling; } const child = nodeObject.children[index]; let customProp = JSON.parse(child.czmObject.customProp); if (that.hostDeviceMapById.has(customProp.deviceId)) { let device = that.hostDeviceMapById.get(customProp.deviceId); // 设置状态 that.setLabelStatus(device, customProp.labelCode, child.ref, 2); } // 设置图标 that.setIconByRef(child.ref, eventTarget); } }); } if (nodeObject.czmObject && nodeObject.czmObject.xbsjType == 'Pin') { that.setIconByRef(ref, el); } // ref不为空并且大于0时 设置为input的id属性 if (ref && ref.length > 0) { inputEl.id = ref; } // 首次展开添加元素默认为true,显示展示的对象 if (that.nodeCheckedByRef.size <= 0) { // item.checkStatus = 'checked' inputEl.checked = true; //***设置样式为选中 */ setClassChecked(setClassEl1, setClassEl2, item); that.nodeCheckedByRef.set(ref, true); } else { // 之后的展开根据ref获取应该显示的状态是选中还是非选中 let checked = that.nodeCheckedByRef.get(ref); if (checked == undefined) { checked = true; if (ref && ref.length > 0 && ref.startsWith('node_')) { // 分割ref const refSplit = ref.split('_'); // 取出真实对象 const readyNode = earthUI.earth.sceneTree.$refs[refSplit[1]]; if (readyNode && readyNode.czmObject) { checked = readyNode.czmObject.show; } } else { if (nodeObject && nodeObject.czmObject) { checked = nodeObject.czmObject.show; } } inputEl.checked = checked; that.nodeCheckedByRef.set(ref, checked); setClassEl(setClassEl, setClassEl2, checked, item); } else { setClassEl(setClassEl, setClassEl2, checked, item); } } // 显示隐藏样式监听 classMutationObserver(setClassEl1, setClassEl2, that.nodeCheckedByRef, ref); // input disabled属性监听 disabledMutationObserver(inputEl); /**调整触发顺序,阻止默认的input change事件,并绑定自己的change事件 */ inputEl.addEventListener( 'change', function (e) { // 阻止其他同类型事件调用 e.stopImmediatePropagation(); // input元素获取 const el = e.target; // 获取ref const ref = el.id; // 点击元素的earthSdk对象 const clickNode = earthUI.earth.sceneTree.$refs[ref]; // 真实的earthSdk对象 let readyNode: any = null; // 当ref大于0,并且以node_开头时,此为虚假的对象 if (ref && ref.length > 0 && ref.startsWith('node_')) { // 分割ref const refSplit = ref.split('_'); // 取出真实对象 readyNode = earthUI.earth.sceneTree.$refs[refSplit[1]]; } else if (ref && ref.length > 0 && ref.startsWith('nodeSecondary_')) { // 分割ref const refSplit = ref.split('_'); // 取出真实对象 readyNode = earthUI.earth.sceneTree.$refs[refSplit[1]]; let guid = readyNode.czmObject.pinXbsjGuid; let pin = window.$earth.getObject(guid); pin.show = !pin.show; } else if (ref && ref.length > 0) { // 真实对象就是本身 readyNode = clickNode; } // 控制子节点的状态同步 that.showOrHideChild(clickNode, earthUI, el.checked); if (readyNode != null) { // 隐藏对象 if (!el.checked) { if (readyNode && readyNode.czmObject) { readyNode.czmObject.show = false; } // 设置属性 setClassNoChecked(setClassEl1, setClassEl2, item); } else { // 显示对象 if (readyNode && readyNode.czmObject) { readyNode.czmObject.show = true; } // 设置属性 setClassChecked(setClassEl1, setClassEl2, item); } // 设置属性 setClassNoChecked(setClassEl1, setClassEl2, item); } else { // 显示对象 if (readyNode && readyNode.czmObject) { readyNode.czmObject.show = true; } // 设置属性 setClassChecked(setClassEl1, setClassEl2, item); } // 记录当前节点状态 that.nodeCheckedByRef.set(ref, el.checked); }, true ); } }; // 创建一个观察器实例并传入回调函数 const observer1 = new MutationObserver(callback1); // 以上述配置开始观察目标节点 observer1.observe(target1, config1); // 设置label的鼠标事件 labelItems.forEach((itemId) => { if (window.$earth.sceneTree.$refs[itemId]) { window.$earth.sceneTree.$refs[itemId].czmObject.onmouseover = () => { this._viewer._container.style.cursor = 'pointer'; }; window.$earth.sceneTree.$refs[itemId].czmObject.onmouseout = () => { this._viewer._container.style.cursor = 'default'; }; } }); }); // 隐藏图层管理 "地图场景" 一栏 // document.getElementsByClassName('XbsjVritualTreeItem').item(0).style.display = 'none' this._earth.sceneTree.root.children.splice(1, 0, models); } async createRealTimeObj(earthUI = null) { let that = this; let models = { expand: true, title: '地图实况', children: [ { expand: false, title: '巡逻路线', children: [], }, { expand: false, title: '执勤巡逻', children: [], }, { expand: false, title: '预警/报警', children: [], }, { expand: false, title: 'AIS', children: [], }, ], }; try { await this.getAllModelInfo(models); await this.getPatrolRouteInfo(models); //添加对象到场景树 // this._earth.sceneTree.root.children.push(models); this._earth.sceneTree.root.children.splice(1, 0, models); } catch (e) { console.log(e); } } //加载区域 getLineInfo(models, type) { const that = this; return new Promise((resolve, reject) => { //请求线路信息 defHttp .get( { url: this.url.queryLineList, params: { pageNo: 1, pageSize: 99999, sceneId: this.userStore.userInfo?.sceneId + '*', }, }, { isTransformResponse: false } ) .then(async (res) => { // console.log('加载区域',res); if (res.success) { //一级区域 let parentArea: any = []; //二级区域 let childArea: any = []; res.result.records.forEach((data) => { if (data.parentCode) { childArea.push(data); } else { parentArea.push(data); } }); parentArea.forEach((data) => { // console.log(data); // data.sceneId let updatedPositions: any = []; let positionsData = JSON.parse(data.positions); if (!positionsData) { positionsData = []; } updatedPositions = positionsData; let lineOptions: any = { maxShowHeight: 30000, customProp: data.lineCode, }; lineOptions.name = data.name; lineOptions.xbsjType = 'Polyline'; lineOptions.width = data.width; lineOptions.positions = updatedPositions; lineOptions.loop = Boolean(data.isLoop); lineOptions.depthTest = Boolean(data.isDepthCheck); lineOptions.arcType = data.interpolation; let material: any = {}; switch (data.materialType) { // 实线 case 0: material.type = 'XbsjColorMaterial'; material.XbsjColorMaterial = {}; if (!data.color || data.color.length <= 0) { data.color = '[1,1,1,1]'; } material.XbsjColorMaterial.color = JSON.parse(data.color); break; // 虚线 case 1: material.type = 'XbsjPolylineDashMaterial'; material.XbsjPolylineDashMaterial = {}; material.XbsjPolylineDashMaterial.color = JSON.parse(data.color); material.XbsjPolylineDashMaterial.gapColor = JSON.parse(data.intervalColor); material.XbsjPolylineDashMaterial.dashLength = data.dashLength; material.XbsjPolylineDashMaterial.dashPattern = data.dashStyle; break; // 箭头线 case 2: material.type = 'XbsjPolylineArrowMaterial'; material.XbsjPolylineArrowMaterial = {}; material.XbsjPolylineArrowMaterial.color = JSON.parse(data.color); break; // 轨迹线 case 3: material.type = 'XbsjODLineMaterial'; material.XbsjODLineMaterial = {}; material.XbsjODLineMaterial.color = JSON.parse(data.color); material.XbsjODLineMaterial.totoalFrameCount = data.cycleFrame; break; } lineOptions.material = material; let currentChildArea: any = []; if (childArea.length) { childArea.forEach((element) => { let obj = {}; if (data.id == element.parentCode) { obj = { expand: false, title: element.name, ref: 'nodeSecondary_' + element.id, children: [], }; let updatedPositions: any = []; let positionsData = JSON.parse(element.positions); if (!positionsData) { positionsData = []; } updatedPositions = positionsData; let lineOptions: any = { maxShowHeight: 30000, customProp: element.lineCode, }; lineOptions.name = element.name; lineOptions.xbsjType = 'Polyline'; lineOptions.width = element.width; lineOptions.positions = updatedPositions; lineOptions.loop = Boolean(element.isLoop); lineOptions.depthTest = Boolean(element.isDepthCheck); lineOptions.arcType = element.interpolation; let material: any = {}; switch (element.materialType) { // 实线 case 0: material.type = 'XbsjColorMaterial'; material.XbsjColorMaterial = {}; if (!element.color || element.color.length <= 0) { element.color = '[1,1,1,1]'; } material.XbsjColorMaterial.color = JSON.parse(element.color); break; // 虚线 case 1: material.type = 'XbsjPolylineDashMaterial'; material.XbsjPolylineDashMaterial = {}; material.XbsjPolylineDashMaterial.color = JSON.parse(element.color); material.XbsjPolylineDashMaterial.gapColor = JSON.parse(element.intervalColor); material.XbsjPolylineDashMaterial.dashLength = element.dashLength; material.XbsjPolylineDashMaterial.dashPattern = element.dashStyle; break; // 箭头线 case 2: material.type = 'XbsjPolylineArrowMaterial'; material.XbsjPolylineArrowMaterial = {}; material.XbsjPolylineArrowMaterial.color = JSON.parse(element.color); break; // 轨迹线 case 3: material.type = 'XbsjODLineMaterial'; material.XbsjODLineMaterial = {}; material.XbsjODLineMaterial.color = JSON.parse(element.color); material.XbsjODLineMaterial.totoalFrameCount = element.cycleFrame; break; } let pos = [0, 0, 0]; positionsData.forEach((element) => { pos[0] += element[0]; pos[1] += element[1]; pos[2] += element[2]; }); pos[0] = pos[0] / positionsData.length; pos[1] = pos[1] / positionsData.length; pos[2] = pos[2] / positionsData.length; let pinBuilder = { extTextFont: '30px 宋体', extTextPixelOffset: [-40, 10], fillColor: [0, 0.3450980392156863, 1, 0.9], outlineColor: [1, 1, 1, 1], extText: element.name, }; let pin = addPin(element.name, hidePng, { position: pos, scale: 0.8, pinBuilder, far: 107374 }); lineOptions.pinXbsjGuid = pin.xbsjGuid; lineOptions.material = material; that._earth.sceneTree.root.children.push({ czmObject: lineOptions, ref: element.id }); currentChildArea.push(obj); // 如果是总部 if (type == 1) { this.nodeConfigByRef.set('nodeSecondary_' + element.id, obj); } } }); } //配置信息 const node = { ref: 'node_' + data.id, expand: false, title: '<防区>' + data.name, children: [ { expand: false, title: '监控点位', ref: 'monitor_' + window.guid(), children: [], }, { expand: false, title: '雷达点位', ref: 'ldList_' + window.guid(), children: currentChildArea, }, { expand: false, title: '微波点位', ref: 'wbList_' + window.guid(), children: [], }, ], }; if (data.sceneId == models.ref) { // console.log("当前场景下"); //该防区为当前场景下 //压入树 models.children.push(node); this.nodeConfigByRef.set(node.ref, node); this.areaByNodeId.set(node.ref, data.sceneId); // return } else { const childs = models.children; for (const child of childs) { if (child.ref == data.sceneId) { //该防区为子场景下 // console.log("子场景下"); child.children.push(node); this.nodeConfigByRef.set(node.ref, node); this.areaByNodeId.set(node.ref, data.sceneId); } } } //放进世界场景树 that._earth.sceneTree.root.children.push({ czmObject: lineOptions, ref: data.id }); }); //加载二级区域模型 childArea.forEach((data) => {}); this.$nextTick(() => { const divs = $('#earthContainer>div>div>div:nth-child(5)') .children('div') .eq(1) .children() .eq(0) .children() .eq(0) .children() .each((index, element) => { // const paddingLeft = $(element).children().eq(0).css('padding-left') $(element).css('display', 'none'); }); }); // console.log("models",models); resolve(models); } }); }); } //加载相机 getCameraInfo(models, type) { return new Promise((resolve, reject) => { //请求电线杆信息 defHttp.get({ url: this.url.queryCameraInfo }, { isTransformResponse: false }).then(async (res) => { if (res.success) { // console.log("res",res); this.setCamera(res.result, models, type); this.cameraData = res.result; resolve(models); } }); }); } async setCamera(res, models, type) { //根据经纬度算出该点地形高度 let posArr: any = [], updatedPositions: any = []; const that = this; //地形是否开启 if (window.$earth.sceneTree.$refs.terrain.czmObject.show) { res.forEach((data, index) => { if (data.msCameraSiteList != null) { data.msCameraSiteList.forEach((data, index) => { posArr.push(window.Cesium.Cartographic.fromDegrees(data.longitude, data.latitude)); }); } }); var promise = window.Cesium.sampleTerrainMostDetailed(this._viewer.terrainProvider, posArr); updatedPositions = await window.Cesium.when(promise); } else { res.forEach((data, index) => { if (data.msCameraSiteList != null) { data.msCameraSiteList.forEach((data, index) => { updatedPositions.push(window.Cesium.Cartographic.fromDegrees(data.longitude, data.latitude, 0)); }); } }); } // console.log("根据经纬度算出该点地形高度",res); // console.log("根据经纬度算出该点地形高度",updatedPositions); //设置电线杆 res.forEach((data, index) => { // console.log("data",data); let siteConfig: any = null; const lineId = data.id; let childs: any = null; if (type == 2) { childs = models.children; for (const child of childs) { if ('node_' + data.id == child.ref) { siteConfig = child.children[0]; } } } else { const parentNode = that.nodeConfigByRef.get('node_' + data.id); if (!parentNode) { return; } childs = parentNode.children; siteConfig = childs[0]; // console.log("parentNode",parentNode); } if (!siteConfig) { return; } if (data.msCameraSiteList != null) { data.msCameraSiteList.forEach((data, index) => { // 判断电线杆状态 let num = 0; if (data.msCameraSettingList != null) { data.msCameraSettingList.forEach((data, index) => { if (data.status == '3') { //1-在线,2-离线,3-异常 num = num + 1; } }); } let gltfStr; if (!data.modelUrl) { return; } let fileInfos = data.modelUrl.split('.'); if (num == 0) { // gltfStr = window._CONFIG['domianURL'] + '/sys/common/static/' + fileInfos[0] + '.' + fileInfos[1]; gltfStr = '/dt/sys/common/static/' + fileInfos[0] + '.' + fileInfos[1]; } else if (num < data.msCameraSettingList.length) { let newName = fileInfos[0].substring(0, fileInfos[0].length - 1) + 'R'; // gltfStr = window._CONFIG['domianURL'] + '/sys/common/static/' + newName + '.' + fileInfos[1]; gltfStr = '/dt/sys/common/static/' + newName + '.' + fileInfos[1]; } else if (num == data.msCameraSettingList.length) { let newName = fileInfos[0].substring(0, fileInfos[0].length - 1) + 'Y'; // gltfStr = window._CONFIG['domianURL'] + '/sys/common/static/' + newName + '.' + fileInfos[1]; gltfStr = '/dt/sys/common/static/' + newName + '.' + fileInfos[1]; } const modelConfig = { ref: data.id, name: lineId, czmObject: { name: data.sitename, xbsjType: 'Model', url: gltfStr, // "color": [0.52, 0.6, 0.58, 1], minimumPixelSize: data.minimumPixelSize, // maximumScale: 0.02, scale: data.scale, xbsjScale: data.xyzScale ? data.xyzScale.split(',') : [1, 1, 1], xbsjPosition: [window.Cesium.Math.toRadians(data.longitude), window.Cesium.Math.toRadians(data.latitude), data.height], xbsjRotation: [ window.Cesium.Math.toRadians(data.yaw), window.Cesium.Math.toRadians(data.pitch), window.Cesium.Math.toRadians(data.roll), ], viewDistance: 150, distanceDisplayCondition: [1.0, 30000.0], customProp: data.id, }, }; window.$earth.sceneTree.root.children.push(modelConfig); //鼠标事件 window.$earth.sceneTree.$refs[data.id].czmObject.onmouseover = () => { this._viewer._container.style.cursor = 'pointer'; }; window.$earth.sceneTree.$refs[data.id].czmObject.onmouseout = () => { this._viewer._container.style.cursor = 'default'; }; this.$nextTick(() => { const divs = $('#earthContainer>div>div>div:nth-child(5)') .children('div') .eq(1) .children() .eq(0) .children() .eq(0) .children() .each((index, element) => { $(element).css('display', 'none'); }); }); //加载相机 let cameraList: any = []; if (data.msCameraSettingList) { for (let camera of data.msCameraSettingList) { let name = camera.cameraName; const obj = { ref: 'camera_' + camera.id, expand: false, title: name, czmObject: { name: name, xbsjType: 'Model', }, }; // let id = camera.id cameraList.push(obj); // 默认设置为在线 } } // 杆 const node = { ref: 'node_' + data.id, title: data.sitename, expand: false, children: cameraList, }; siteConfig.children.push(node); }); } }); } // 加载雷达和微波 async getLabelInfo(models, type) { return new Promise((resolve, reject) => { //请求地图标志信息 defHttp.get({ url: this.url.queryLabelList }, { isTransformResponse: false }).then(async (res) => { // console.log("请求地图标志信息",res); if (res.success) { const labelItems = await this.setLabel(res.result, models, type); resolve(labelItems); } }); }); } //地图标志信息 async setLabel(res, models, type) { // console.log("res",res); const that = this; const args = { pageNo: 1, pageSize: 999 }; await defHttp .get( { url: this.url.queryDeviceInfoList, params: args, }, { isTransformResponse: false } ) .then((reponse) => { if (reponse.success) { // console.log("queryDeviceInfoList",reponse); const hostDeviceList = reponse.result.records; for (const hostDevice of hostDeviceList) { that.hostDeviceMapById.set(hostDevice.id, hostDevice); } return that.hostDeviceMapById; } else { console.error('获取主机信息错误', reponse); } }) .catch(() => { throw '获取主机信息错误'; }); //根据经纬度算出该点地形高度 let posArr: any = [], updatedPositions: any = []; res.forEach((data, index) => { updatedPositions.push(window.Cesium.Cartographic.fromDegrees(data.mapLabel.labelLon, data.mapLabel.labelLat, data.mapLabel.labelHeight)); }); const labelItems: any = []; //设置标志 res.forEach((data, index) => { const item: any = data.mapLabel; labelItems.push(item.id); const objConfig3 = { ref: item.id, name: item.lineId, czmObject: { customProp: '{"labelAttr":' + item.labelAttr + ',"labelCode":"' + item.labelCode + '","deviceId":"' + data.deviceId + '"}', name: item.labelName, xbsjType: 'Pin', imageUrl: window._CONFIG['staticDomainURL'] + '/' + item.labelImgUrl, position: [updatedPositions[index].longitude, updatedPositions[index].latitude, Number(item.labelHeight)], scale: item.labelAttr == 4 ? 1 : 0.7, pinBuilder: { extText: item.labelName, extTextFont: '30px 楷体', extTextPixelOffset: item.labelAttr == 4 ? [30, -20] : [15, -20], fillColor: [1, 1, 1, 0.9], outlineColor: [0, 0, 0, 0.9], }, far: 25000, }, }; if (item.labelAttr == 4) { // console.log("雷达",item); that.statusByNodeId.set(item.id, 1); that.addLabelNodeToTree(item, models, objConfig3, type); } else { // console.log("微波",item); that.statusByNodeId.set(item.id, -10); that.addLabelNodeToTree(item, models, objConfig3, type); const device = that.hostDeviceMapById.get(data.deviceId); if (device) { //参数3 2为查询状态 that.setLabelStatus(device, item.labelCode, item.id, 2); } } }); return labelItems; } addLabelNodeToTree(item, models, objConfig3, type) { const that = this; //微波 if (item.labelAttr == 10) { if (type == 2) { let childs1 = models.children; for (const child of childs1) { if ('node_' + item.lineId == child.ref) { child.children[2].children.push(objConfig3); } } } else { const parentNode = that.nodeConfigByRef.get('node_' + item.lineId); if (!parentNode) { return; } let childs2 = parentNode.children; childs2[2].children.push(objConfig3); } } //雷达 else if (item.labelAttr == 4) { if (type == 2) { let childs1 = models.children; for (const child of childs1) { if ('node_' + item.lineId == child.ref) { child.children[1].children.push(objConfig3); } } } else { const parentNode = that.nodeConfigByRef.get('node_' + item.lineId); if (!parentNode) { return; } let childs2 = parentNode.children; childs2[1].children.push(objConfig3); } } //雷达(已弃用) else if (item.labelAttr == 4) { console.log('leida'); if (type == 2) { let childs3 = models.children; for (const child of childs3) { for (const element of child.children[1].children) { if ('nodeSecondary_' + item.lineId == element.ref) { element.children.push(objConfig3); } } } } else { const parentNode1 = that.nodeConfigByRef.get('nodeSecondary_' + item.lineId); // console.log("nodeSecondary_",parentNode1); if (!parentNode1) { return; } const childs4 = parentNode1.children; childs4.push(objConfig3); } } } setLabelStatus(device, labelCode, id, code) { const args = { device: device, code: code, // 命令码:0-撤防 1-布防 2-状态查询 3-其他预留 deviceType: 2, // 设备类型:1-探测主机 2-探测器 3-串口设备 4-预留 deviceSn: labelCode, // 设备条码 }; // console.log("device",device); if (device.deviceType_dictText.indexOf('微波探测器') > -1) { // console.log("微波探测器"); return ( defHttp .post({ url: '/military/netty/microwaveDetector/maintenance', params: args }, { isTransformResponse: false }) // postAction('netty/microwaveDetector/maintenance', args) .then((response) => { // console.log('response',response); if (response.success) { const status = response; this.statusByNodeId.set(id, status); } else { this.statusByNodeId.set(id, -10); } return response; }) .catch((error) => { // console.log('error',error); this.statusByNodeId.set(id, -10); return error; }) ); } else if (device.deviceType_dictText.indexOf('雷达') > -1) { this.statusByNodeId.set(id, 1); //雷达周界防区列表 return defHttp .get({ url: this.url.perimeterRegionList, params: { regionType: 2 } }, { isTransformResponse: false }) .then( (res) => { // console.log(res); if (res.success) { // (未测试) res.result.forEach((element) => { if (element.id == id) { // this.statusByNodeId.set(id, element.isOnline) } }); } else { this.statusByNodeId.set(id, 1); } return res; }, (err) => { this.statusByNodeId.set(id, 1); return err; } ) .catch((err) => { this.statusByNodeId.set(id, 1); return err; }); } } getAllModelInfo(models) { return new Promise((resolve, reject) => { //模型位置 defHttp.get({ url: this.url.queryAllModelInfo }, { isTransformResponse: false }).then(async (res) => { if (res.success) { res.result.forEach((data, index) => { let childrenConfig: any = {}, objConfig: any = {}, pathConfig: any = {}, viewshedConfig: any = {}, pinConfig: any = {}; let positions: any = [], rotations: any = []; switch (data.modelType) { case 1: //无人机 childrenConfig = { expand: false, title: '无人机_' + (index + 1) + '号', children: [], }; objConfig = { ref: data.eventSerialNum, czmObject: { name: '无人机', xbsjType: 'Model', url: window._CONFIG['staticDomainURL'] + '/uav.gltf', minimumPixelSize: 1000, maximumScale: 20, xbsjPosition: earthUtils.degreeToRadianInLngLatHeight(data.lon, data.lat, data.height), distanceDisplayCondition: [10.0, 25000.0], }, }; childrenConfig.children.push(objConfig); // 加载视域 viewshedConfig = { ref: 'viewshed_' + data.eventSerialNum, czmObject: { xbsjType: 'Viewshed', name: '视域', position: earthUtils.degreeToRadianInLngLatHeight(data.lon, data.lat, data.height), rotation: earthUtils.degreeToRadianInLngLatHeight(data.yaw, data.pitch, data.roll), near: 1.0, far: 1500, enabled: false, show: false, }, }; childrenConfig.children.push(viewshedConfig); //加载历史轨迹 data.msModelTrajectoryList.forEach((data, index) => { positions.push(earthUtils.degreeToRadianInLngLatHeight(data.lon, data.lat, data.height)); rotations.push(earthUtils.degreeToRadianInLngLatHeight(data.yaw, data.pitch, data.roll)); }); pathConfig = { ref: 'path_' + data.eventSerialNum, czmObject: { xbsjType: 'Path', name: '轨迹', positions: positions, rotations: rotations, enabled: false, show: true, loop: false, showDirection: false, playing: true, loopPlay: true, alwaysAlongThePath: true, currentSpeed: 30, }, }; childrenConfig.children.push(pathConfig); /* // 显示当前坐标 pinConfig = { "ref": "pin_" + data.eventSerialNum, "czmObject": { "xbsjType": "Pin", "name": "当前位置", "position": earthUtils.degreeToRadianInLngLatHeight(data.lon, data.lat, data.height), "evalString": "const width = 430;\nconst height = 70;\nfunction createLabelCanvas(p) {\n if (p._labelDiv) {\n p._earth.czm.viewer.container.removeChild(p._labelDiv);\n p._labelDiv = undefined;\n }\n const labelDiv = document.createElement('div');\n labelDiv.style = 'width:'+width+'px;height: '+height+'px;position: absolute; pointer-events: none;'\n\n p._earth.czm.viewer.container.appendChild(labelDiv);\n p._labelDiv = labelDiv;\n\n var dis = XE.MVVM.watch(() => {\n labelDiv.style.display = p.enabled ? 'block' : 'none';\n });\n\n p.disposers.push(() => {\n if (p._labelDiv) {\n p._earth.czm.viewer.container.removeChild(p._labelDiv);\n p._labelDiv = undefined;\n }\n dis();\n });\n\n const labelCanvas = document.createElement('canvas');\n labelCanvas.style = 'width: 100%;height: 100%;';\n\n labelCanvas.width = width;\n labelCanvas.height = height;\n labelDiv.appendChild(labelCanvas);\n return labelCanvas;\n}\n\nfunction createDrawFunc(p) {\n const labelCanvas = createLabelCanvas(p);\n const ctx = labelCanvas.getContext('2d');\n\n function draw(w) {\n ctx.clearRect(0, 0, width, height);\n\n ctx.save();\n ctx.lineWidth = 2;\n ctx.strokeStyle = 'rgb(31, 255,255)';\n ctx.beginPath();\n ctx.moveTo(width, height);\n ctx.lineTo(width-height, 22);\n ctx.lineTo(0, 22);\n ctx.stroke();\n ctx.restore();\n ctx.font = \"15px console\"; \n ctx.fillStyle = 'rgb(255, 255, 0)';\n ctx.fillText('" + "经度:" + data.lon + "/" + "纬度:" + data.lat + "/" + "高度:" + data.height + "', 0, 20);\n ctx.restore();\n }\n\n p._dDraw = draw;\n}\n\ncreateDrawFunc(p);\n\nlet d = 0;\nlet c = 0;\np._dDraw(c);\nconst preUpdateListener = p._earth.czm.scene.preUpdate.addEventListener(() => {\n if (d !== c) {\n c += (d - c) * 0.1;\n if (Math.abs(c - d) < 0.1) {\n c = d;\n }\n p._dDraw(c);\n }\n});\np.disposers.push(() => preUpdateListener && preUpdateListener());\n\nconst container = p._earth.czm.viewer.container;\nconst unwatch = XE.MVVM.watch(() => [...p.winPos], winPos => {\n if (p._labelDiv) {\n p._labelDiv.style.left = (winPos[0] - p._labelDiv.clientWidth) + 'px';\n p._labelDiv.style.bottom = winPos[3]+'px';\n } \n});\np.disposers.push(() => {\n unwatch && unwatch();\n});", "isDivImage": true, "pinBuilder": {}, "far": 25000 } }; childrenConfig.children.push(pinConfig); */ //加入树 models.children[1].children.push(childrenConfig); break; case 2: //执勤人员 childrenConfig = { expand: false, title: '执勤人员_' + (index + 1) + '号', children: [], }; objConfig = { ref: data.eventSerialNum, czmObject: { xbsjType: 'GroundImage', name: '执勤人员', playing: true, width: 90, height: 90, position: earthUtils.degreeToRadianInLngLatHeight(data.lon, data.lat, 0), imageUrls: [window._CONFIG['staticDomainURL'] + '/xunluo_point1.png', window._CONFIG['staticDomainURL'] + '/xunluo_point2.png'], }, }; childrenConfig.children.push(objConfig); //加载历史轨迹 data.msModelTrajectoryList.forEach((data, index) => { positions.push(earthUtils.degreeToRadianInLngLatHeight(data.lon, data.lat, data.height)); rotations.push(earthUtils.degreeToRadianInLngLatHeight(data.yaw, data.pitch, data.roll)); }); pathConfig = { ref: 'path_' + data.eventSerialNum, czmObject: { xbsjType: 'Path', name: '轨迹', positions: positions, rotations: rotations, enabled: false, show: true, loop: false, showDirection: false, playing: true, loopPlay: true, alwaysAlongThePath: true, currentSpeed: 30, }, }; childrenConfig.children.push(pathConfig); //加入树 models.children[1].children.push(childrenConfig); break; case 3: //可疑人员 childrenConfig = { expand: false, title: '可疑人员_' + (index + 1) + '号', children: [], }; objConfig = { ref: data.eventSerialNum, czmObject: { xbsjType: 'GroundImage', name: '可疑人员', playing: true, width: 90, height: 90, position: earthUtils.degreeToRadianInLngLatHeight(data.lon, data.lat, 0), imageUrls: [window._CONFIG['staticDomainURL'] + '/keyi_point1.png', window._CONFIG['staticDomainURL'] + '/keyi_point2.png'], }, }; childrenConfig.children.push(objConfig); //加载历史轨迹 data.msModelTrajectoryList.forEach((data, index) => { positions.push(earthUtils.degreeToRadianInLngLatHeight(data.lon, data.lat, data.height)); rotations.push(earthUtils.degreeToRadianInLngLatHeight(data.yaw, data.pitch, data.roll)); }); pathConfig = { ref: 'path_' + data.eventSerialNum, czmObject: { xbsjType: 'Path', name: '轨迹', positions: positions, rotations: rotations, enabled: false, show: true, loop: false, showDirection: false, playing: true, loopPlay: true, alwaysAlongThePath: true, currentSpeed: 30, }, }; childrenConfig.children.push(pathConfig); //加入树 models.children[2].children.push(childrenConfig); break; case 11: //传感器 objConfig = { ref: data.eventSerialNum, czmObject: { name: data.eventSerialNum, xbsjType: 'Model', url: window._CONFIG['staticDomainURL'] + '/zalan.gltf', minimumPixelSize: 1000, maximumScale: 0.01, // xbsjPosition: [window.Cesium.Math.toRadians(data.lon), window.Cesium.Math.toRadians(data.lat), data.height], xbsjPosition: earthUtils.degreeToRadianInLngLatHeight(data.lon, data.lat, data.height), xbsjRotation: earthUtils.degreeToRadianInLngLatHeight(data.yaw, data.pitch, data.roll), distanceDisplayCondition: [10.0, 25000.0], customProp: data.eventSerialNum, color: [0.08235294117647059, 1, 0, 1], luminanceAtZenith: 2, }, }; //加入树 models.children[0].children[0].children.push(objConfig); break; default: } }); resolve(models); } }); }); } getPatrolRouteInfo(models) { return new Promise((resolve, reject) => { //执勤巡逻路线 defHttp.get({ url: this.url.queryPatrolRouteInfo }, { isTransformResponse: false }).then(async (res) => { if (res.success) { res.result.forEach((data, index) => { //将路线上的点拼成坐标数组 let positions: any = []; data.msLineConstList.forEach((data, index) => { positions.push(earthUtils.degreeToRadianInLngLatHeight(data.lon, data.lat, data.height)); }); const objConfig = { ref: data.lineCode, czmObject: { name: data.lineName, xbsjType: 'Polyline', width: 2, material: { type: 'XbsjODLineMaterial', XbsjODLineMaterial: { bgColor: [0.5, 0.5, 0.5, 1], color: [0, 1, 0.11, 1], totoalFrameCount: 200, }, }, positions: positions, }, }; models.children[0].children.push(objConfig); }); resolve(models); } }); }); } listenMouseHandler(earthUI = null) { let that: any = this; this._handler = new window.Cesium.ScreenSpaceEventHandler(this._viewer.scene.canvas); //取消双击旋转事件 this._viewer.cesiumWidget.screenSpaceEventHandler.removeInputAction(window.Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK); /* MOUSE事件(有性能问题,慎用!) */ /* 鼠标左键事件 */ { this._handler.setInputAction((click: any) => { if (typeof this._pin !== 'undefined') { // 销毁指示线 this._pin.destroy(); } let pickedFeature = this._viewer.scene.pick(click.position); if (pickedFeature && pickedFeature.id) { if (pickedFeature.id.xbsjType && pickedFeature.id.xbsjType === 'Model') { //点击电线杆触发弹窗 this.cameraData.forEach((data) => { if (!$.isEmptyObject(data.msCameraSiteList)) { if (!data.msCameraSiteList) { return; } data.msCameraSiteList.forEach((data) => { if (pickedFeature.id.customProp === data.id) { if ($('.cameraModal ul').length > 0) { $('.cameraModal ul').remove(); } $('.cameraModal').append('<ul></ul>'); if (!data.msCameraSettingList) return; // 将监控相机列表传入弹窗组件中 this.cameraList = data.msCameraSettingList; // 将监控点位置传入弹窗组件中 this.monitorPosition = pickedFeature.id._primitive.xbsjPosition; data.msCameraSettingList.forEach((data, index) => { let camera_img = data.type == '4' ? window._CONFIG['staticDomainURL'] + '/qiuji.png' : data.type == '3' ? window._CONFIG['staticDomainURL'] + '/qiangji.png' : window._CONFIG['staticDomainURL'] + '/qiangji.png'; let cameraStatus = data.status == '1' ? 'successStatus' : data.status == '2' ? 'offlineStatus' : 'errorStatus'; let rtspUrl = data.cameraCode; // 'rtsp://' + data.user + ':' + data.password + '@' + data.ip + window._CONFIG['cameraMain'] $('.cameraModal ul').append( '<li><a class="openIframe" id="' + data.id + '" videoUrl="' + rtspUrl + '" cameraIP="' + data.ip + '" cameraUser="' + data.user + '" cameraPsd="' + data.password + '"><img src="' + camera_img + '" /><div class="' + cameraStatus + '">' + data.cameraName + '</div> </a></li>' ); }); cameraModal.style.left = click.position.x + -45 + 'px'; cameraModal.style.top = click.position.y + -180 + 'px'; this.cameraModalShow = true; } }); } }); } //雷达扫描范围 if ( pickedFeature.id._xbsjOwner && pickedFeature.id._xbsjOwner.customProp && JSON.parse(pickedFeature.id._xbsjOwner.customProp).labelAttr == '4' ) { let labelCode = JSON.parse(pickedFeature.id._xbsjOwner.customProp).labelCode; console.log(pickedFeature.id._xbsjOwner); if (pickedFeature.id._xbsjOwner.addViewShedReturn) { //显示/不显示雷达扫码效果 // pickedFeature.id._xbsjOwner.addViewShedReturn.show = !pickedFeature.id._xbsjOwner.addViewShedReturn.show; // console.log("pickedFeature.id._xbsjOwner.addViewShedReturn",pickedFeature.id._xbsjOwner.addViewShedReturn); //清空当前雷达,并将该方法指向undefined(清空) pickedFeature.id._xbsjOwner.addViewShedReturn.clear(); pickedFeature.id._xbsjOwner.addViewShedReturn = undefined; } else { defHttp.get({ url: this.url.radarList, params: { radarCode: labelCode } }, { isTransformResponse: false }).then((res) => { if (res.success) { if (res.result.records.length > 0) { let data = res.result.records[0]; let rgb; if (data.customProp) { rgb = JSON.parse(data.customProp).color; } let radarRadius = data.workingRadius; let radarRange = data.elevation; let radarShifting = data.angularRadian; let left = Number(radarShifting) - Number(radarRange) / 2; //参数:经纬度、半径、起始角度(正北方向)、结束角度 console.log('雷达扫描范围', data); //弧度转角度 let degreePosition = radianToDegreeInLngLatHeight( pickedFeature.id._xbsjOwner.position[0], pickedFeature.id._xbsjOwner.position[1], 0.1 ); //创建雷达扫描 深度 // this._viewer.scene.globe.depthTestAgainstTerrain = true; let rader = new CircleScan(this._viewer); rader.add(degreePosition, null, radarRadius, 10000); pickedFeature.id._xbsjOwner.addViewShedReturn = rader; // 雷达扫描2 // let rader2 = this._viewer.entities.add({ // position: Cesium.Cartesian3.fromDegrees(113.528333, 22.156109), // name: '雷达扫描', // ellipse: { // semiMajorAxis: 5000.0, // semiMinorAxis: 5000.0, // material: new Cesium.RadarScanMaterialProperty({ // color: new Cesium.Color(1.0, 1.0, 0.0, 0.7), // speed: 20.0, // }), // height: 20.0, // heightReference: Cesium.HeightReference.RELATIVE_TO_GROUND, // outline: true, // outlineColor: new Cesium.Color(1.0, 1.0, 0.0, 1.0) // } // }) // pickedFeature.id._xbsjOwner.addViewShedReturn= addViewShedRadar( // pickedFeature.id._xbsjOwner.position, // radarRadius, // left, // Number(radarRange) / 2 + Number(radarShifting), // [rgb.r / 255, rgb.g / 255, rgb.b / 255, rgb.a] // ); } } }); } } } else { //关闭所有气泡窗 that.cameraModalShow = false; that.poiModalShow = false; } console.debug('点击到的模型', pickedFeature); }, window.Cesium.ScreenSpaceEventType.LEFT_CLICK); } /* 鼠标右键事件 */ { this._handler.setInputAction((click) => { // 判断点击位置是否有实体 //返回具有 `primitive` 属性的对象,该属性包含场景中特定窗口坐标处的第一个(顶部)图元,如果该位置没有任何内容,则返回未定义的对象。其他属性可能会根据基元的类型进行设置,并可用于进一步识别拾取的对象。 let pickedFeature = this._viewer.scene.pick(click.position); // console.log("pick",pickedFeature); let entity = pickedFeature && pickedFeature.id; console.log('pick', pickedFeature); console.log('entity', entity); if (entity == undefined) { return; } if (typeof pickedFeature !== 'undefined' && pickedFeature.id.xbsjType == 'Model') { //点击电线杆触发弹窗 this.cameraData.forEach((data) => { if (!$.isEmptyObject(data.msCameraSiteList)) { if (!data.msCameraSettingList) { return; } data.msCameraSiteList.forEach((data) => { if (pickedFeature.id.customProp === data.id) { window.$uia.contextMenu.pop([ { text: '监控视域分析属性', func: () => { let testConfig = { ref: 'testView', name: '雷达视域分析', position: [1.514482876761954, 0.8497520519403554, -0.7553906497788317], rotation: [4.535844766941594, 0.32288591161895097, 0], near: 1, far: 400, fovH: Math.PI / 3, fovV: Math.PI / 6, show: false, }; let Viewshed = new window.XE.Obj.Viewshed(window.$earth); Viewshed.xbsjFromJSON(testConfig); window.$uia.showPropertyWindow(Viewshed); }, }, ]); } }); } }); } //巡检监控视频 else if (typeof pickedFeature !== 'undefined' && entity._name == '视频图元') { // console.log(pickedFeature) // console.log("entity",entity) window.$uia.contextMenu.pop([ { text: '编辑', func: () => { $mitt.emit('addRoamPathVideoClose'); // store.commit('customPrimitive', entity.xbsjGuid); this.store.customPrimitive = entity.xbsjGuid; // 打开对应的创建巡检视频窗口 this.$nextTick(() => { this.addRoamVideoShow = true; }); // window.$uia.showPropertyWindow( // {}, // { // component: addroamVideo, // } // ); }, }, { text: '删除', func: () => { window.$uia.confirm('确认删除?', () => { // console.log('confirmed') // axios({ // method: 'delete', // url: '/military/msAreaCustomPrimitive/delete', // params: { id: entity.id }, // }) defHttp .delete( { url: '/military/msAreaCustomPrimitive/delete', params: { id: entity.id }, }, { isTransformResponse: false, joinParamsToUrl: true } ) .then((response) => { if (response.code == 200) { let customPrimitiveList = this.store.customPrimitiveList; // console.log("a",customPrimitiveList); customPrimitiveList.forEach((element, index) => { const model = window.$earth.getObject(element); // console.log("model.id",model.id); // console.log("entity.id",entity.id); if (model.id == entity.id) { let customPrimitive = customPrimitiveList.splice(index, 1)[0]; model.destroy(); } }); // store.dispatch('asyncCustomPrimitive', customPrimitiveList); this.store.customPrimitiveList = customPrimitiveList; // notification.close("RoamVideoSet"); // sessionStorage.setItem("RoamVideoSet", "false"); } else { // Msg.error('删除失败'); $mitt.emit('openNotification', { msg: '删除失败', dt: 2, type: 'error', top: '50px' }); console.error('删除失败', response); } }) .catch((res) => { console.error('错误', res); }); }); }, }, ]); } //绘画图形 else if (typeof pickedFeature !== 'undefined' && entity.name == '绘画') { // console.log("entity", entity); window.$uia.contextMenu.pop([ { text: '编辑', func: () => { window.$uia.showPropertyWindow(entity); //记录编辑前信息 let oldEntity = { depthTest: entity.depthTest, //深度检测 color: [...entity.color], //颜色 outline: { color: [...entity.outline.color], //边框颜色 show: entity.outline.show, //边框显示 width: entity.outline.width, //边框宽度 }, positions: [...entity.positions], }; this.$nextTick(() => { // 主要ui窗口 const mainUI = window.$uia._vm.$refs.mainUI; // 所有打开的ui窗口Ref值 const windowsAttrList = Object.keys(mainUI.$refs); // 寻找当前窗体的工具对象 const modelToolKey = windowsAttrList.filter((f) => f.indexOf(entity.guid) > -1)[0]; const modelTool = mainUI.$refs[modelToolKey][0]; // 当前窗体的元素 const el = modelTool.$el; // this.cloneEl(el) // 样式 el.style.width = '380px'; //宽度 el.children[2].style.padding = '0px'; el.children[2].style.transition = 'none'; el.children[2].children[0].children[0].style.minWidth = '370px'; // 关闭名称input el.children[2].children[0].children[0].children[0].style.display = 'none'; // 关闭创建按钮 el.children[2].children[0].children[0].children[1].children[0].children[1].style.display = 'none'; // 关闭贴地 el.children[2].children[0].children[0].children[2].children[0].style.display = 'none'; // 关闭拉伸 el.children[2].children[0].children[0].children[3].children[0].style.display = 'none'; el.children[2].children[0].children[0].children[3].children[1].style.display = 'none'; el.children[2].children[0].children[0].children[3].children[2].style.display = 'none'; el.children[2].children[0].children[0].children[3].children[3].style.marginLeft = '8px'; // 右上角关闭 const cancelTopRightBtn = el.children[1].children[1]; // 取消按钮元素 const cancelBtn = el.children[3].children[0]; // 确认按钮元素 const okBtn = el.children[3].children[1]; // 取消按钮 cancelTopRightBtn.onclick = cancelBtn.onclick = function () { //恢复原来设置 // console.log("oldEntity", oldEntity); // console.log("entity", entity); // entity.xbsjFromJSON(oldEntity) // entity = JSON.parse(oldEntity) entity.depthTest = oldEntity.depthTest; entity.color = oldEntity.color; entity.outline = oldEntity.outline; entity.positions = oldEntity.positions; entity.editing = false; }; okBtn.onclick = function () { let params = { id: entity.customProp?.id, drawData: JSON.stringify(entity), }; // console.log("submit", entity); defHttp .post( { url: '/military/dtMapDraw/edit', params: params, }, { isTransformResponse: false } ) .then((response) => { $mitt.emit('openNotification', { msg: '编辑成功', dt: 2, type: 'success', top: '50px' }); // console.error('编辑成功', response); }) .catch((response) => { $mitt.emit('openNotification', { msg: '编辑失败', dt: 2, type: 'error', top: '50px' }); // console.error('删除失败', response); }); }; }); }, }, { text: '删除', func: () => { window.$uia.confirm('确认删除?', () => { defHttp .delete( { url: '/military/dtMapDraw/delete', params: { id: entity.customProp?.id }, }, { isTransformResponse: false, joinParamsToUrl: true } ) .then((response) => { if (response.code == 200) { let shapeList = this.store.shapeList; shapeList.forEach((element, index) => { const model = window.$earth.getObject(element); if (model.id == entity.customProp?.id) { let shape = shapeList.splice(index, 1)[0]; model.destroy(); } }); this.store.shapeList = shapeList; } else { $mitt.emit('openNotification', { msg: '删除失败', dt: 2, type: 'error', top: '50px' }); console.error('删除失败', response); } }) .catch((res) => { console.error('错误', res); }); }); }, }, ]); } }, window.Cesium.ScreenSpaceEventType.RIGHT_CLICK); //右键事件 } /* picked事件 */ { /* let canvasbox = this._viewer.canvas, pickPosition = {}, cameraModal = this.$refs.cameraModal;//操作cameraModal组件 canvasbox.onclick = e => { pickPosition.x = e.offsetX; pickPosition.y = e.offsetY; var picked = this._viewer.scene.pick(pickPosition); console.log("picked", picked); if (picked !== undefined && picked.id !== undefined) { console.log(e) } else { that.cameraModalShow = false; } } */ } } listenMittHandler(earthUI = null) { let that = this; { $mitt.on('winShow', function (e: any) { that.VideoFusionWinShow = e; }); //其他页面调用本页面的methods方法 $mitt.on('openNotification', (res: any) => { // that.openNotification(msg, dt, type, top) that.openNotification(res.msg, res.dt, res.type, res.top); }); $mitt.on('listenMouseHandler', function () { that.listenMouseHandler(); }); $mitt.on('removeHandler', function () { that.removeHandler(); }); $mitt.on('createBBHLine', function () { that.createBBHLine(); }); $mitt.on('createRealTimeObj', function () { that.createRealTimeObj(); }); $mitt.on('radioChangeBtnShow', function (callback) { that.radioChangeBtnShow(callback); }); $mitt.on('loadingStatus', function () { that.loadingStatus(); }); $mitt.on('clearAlarmModel', (mittData: any) => { let { isWarnEvent, eventSerialNum } = mittData; // 清除告警模型 if (isWarnEvent) { // 是告警事件 先去后台查询预警事件获取事件编号 let url = 'military/msWarnEvent/queryWarnEventDetailList'; let params = { eventSerialNum: eventSerialNum, }; defHttp.get({ url, params }, { isTransformResponse: false }).then((res) => { if (res.success) { // 成功 let data = res.result; for (const warnEventInfo of data) { this.clearAlarmModel(warnEventInfo.eventSerialNum); } } else { // 失败 console.log('失败'); this.$message.error(res.message); } }); } else { // 不是告警事件,直接清除 this.clearAlarmModel(eventSerialNum); } }); // 监听mqtt消息 $mitt.on('deviceCmd', (message: any) => { drawAllShips(message); }); } } removeHandler() { this._handler.removeInputAction(window.Cesium.ScreenSpaceEventType.MOUSE_MOVE); //移除鼠标事件 this._handler.removeInputAction(window.Cesium.ScreenSpaceEventType.LEFT_CLICK); //移除鼠标事件 } radioChange(e) { this.loadingStatus(); if (`${e.target.value}` == 'satellite') { window.$earth.sceneTree.$refs.satellite.czmObject.show = true; window.$earth.sceneTree.$refs.vector.czmObject.show = false; } else if (`${e.target.value}` == 'vector') { window.$earth.sceneTree.$refs.vector.czmObject.show = true; window.$earth.sceneTree.$refs.satellite.czmObject.show = false; } } radioChangeBtnShow(callback) { this.radioBtnShow = !this.radioBtnShow; callback(this.radioBtnShow); //回调返回当前状态 } loadingStatus() { this.earthChangeSpin = !this.earthChangeSpin; //加载状态 setTimeout(() => { this.earthChangeSpin = !this.earthChangeSpin; //3秒后去除加载状态 }, 3000); } keepAlive() { defHttp.get({ url: this.url.keepAlive }, { isTransformResponse: false }).then((res) => {}); } closeClient() { chrome.call('close'); } /* websocket-start */ 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 = this.userStore.userInfo?.id; url = window._CONFIG[configName].replace('https://', 'wss://').replace('http://', 'ws://') + '/websocket/' + userId; // url = 'ws://127.0.0.1:5004' this.websock[configName] = new WebSocket(url); this.websock[configName].onopen = this.websocketonopen; this.websock[configName].onerror = this.websocketonerror; this.websock[configName].onmessage = this.websocketonmessage; this.websock[configName].onclose = this.websocketclose; break; case 'clientURL': //调用客户端监控视频窗口 url = window._CONFIG['clientURL']; this.websock[configName] = new WebSocket(url); this.websock[configName].onopen = this.websocketonopen; this.websock[configName].onerror = this.websocketonerror; this.websock[configName].onclose = this.websocketclose; break; default: console.log('websocket初始化失败'); } // console.log('url', url) } else { console.log('当前浏览器不支持websocket,请更换浏览器!'); } } websocketonopen(e) { console.log('WebSocket连接成功'); } websocketonerror(e) { console.log('WebSocket连接发生错误'); } 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 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 = { 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 = { 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 = {}; 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(); } } websocketclose(e) { console.log('connection closed (' + e.code + ')'); this.openNotification('websocket连接已断开', 3, 'warning'); } websocketdosend(configName) { //发送数据 this.spinning = !this.spinning; //加载状态 console.log('this.websock[configName]', this.websock[configName]); let that = this; let message = { topic: 'Show_Single_Video', msg: '192.168.1.65', }; //readyState:0:正在连接中,1:已建立连接,2:连接正在关闭,3:连接已关闭或连接失败 if (that.websock[configName].readyState == 1) { that.websock[configName].send(JSON.stringify(message)); that.spinning = !that.spinning; //加载状态 console.log('已发送'); } else { //重新连接websocket this.initWebSocket('clientURL'); setTimeout(function () { if (that.websock[configName].readyState == 1) { that.websock[configName].send(JSON.stringify(message)); } that.spinning = !that.spinning; //加载状态 }, 3000); } } /* websocket-end */ openNotification(msg, dt = 2, type = 'info', top = '300px') { // console.log("openNotification收到"); // console.log("proxy",this); // console.log("window",window); // debugger this.$message.config({ top: top, duration: dt, maxCount: 3, }); switch (type) { case 'info': this.$message.info(msg); break; case 'success': this.$message.success(msg); break; case 'error': this.$message.error(msg); break; case 'warning': this.$message.warning(msg); break; default: } } getRandomArr(arr, count) { //从数组随机抽取元素 var shuffled = arr.slice(0), i = arr.length, min = i - count, temp, index; while (i-- > min) { //打乱数组 index = Math.floor((i + 1) * Math.random()); temp = shuffled[index]; shuffled[index] = shuffled[i]; shuffled[i] = temp; } return shuffled.slice(min); } // 根据经纬度获取高度 async getHeigthByLonLat(lon = 88.8296258, lat = 27.4061859) { var positions = [window.Cesium.Cartographic.fromDegrees(lon, lat)]; // var promise = Cesium.sampleTerrain(this._viewer.terrainProvider, 13, positions); var promise = window.Cesium.sampleTerrainMostDetailed(this._viewer.terrainProvider, positions); return new Promise((resolve, reject) => { window.Cesium.when(promise, function (updatedPositions) { // updatedPositions[0].height ? updatedPositions[0].height : 0; resolve(updatedPositions); }); }); /* var terCartographic = new Cesium.Cartographic(1.5503694435245020004000376611976, 0.47832817936864542131039019315313, 0) var terHigh = this._viewer.scene.globe.getHeight(terCartographic); return terHigh; */ } cloneModel(modelObject) { if (modelObject.czmObject.xbsjType === 'Model') { const modelConfig = { ref: '', name: modelObject.name, czmObject: { name: modelObject.czmObject.name, xbsjType: modelObject.czmObject.xbsjType, url: modelObject.czmObject.url, // "color": [0.52, 0.6, 0.58, 1], minimumPixelSize: modelObject.czmObject.minimumPixelSize, // maximumScale: 0.02, scale: modelObject.czmObject.scale, xbsjScale: [...modelObject.czmObject.xbsjScale], xbsjPosition: [...modelObject.czmObject.xbsjPosition], xbsjRotation: [...modelObject.czmObject.xbsjRotation], viewDistance: 150, distanceDisplayCondition: [1.0, 30000.0], }, }; const index = modelObject.parent.children.push(modelConfig); return index; // const model = new window.XE.Obj.Model(window.$earth) // model.xbsjFromJSON(modelConfig) // const leaf = new window.XE.SceneTree.Leaf(model) // window.$earth.sceneTree.root.push(leaf) } else { const objConfig3 = { ref: '', name: modelObject.name, czmObject: { customProp: modelObject.czmObject.customProp, name: modelObject.czmObject.name, xbsjType: modelObject.czmObject.xbsjType, imageUrl: modelObject.czmObject.imageUrl, position: [...modelObject.czmObject.position], scale: modelObject.czmObject.scale, pinBuilder: { extText: modelObject.czmObject.pinBuilder.extText, extTextFont: '30px 楷体', extTextPixelOffset: [30, -20], fillColor: [1, 1, 1, 0.9], outlineColor: [0, 0, 0, 0.9], }, far: 1073741824, }, }; const index = modelObject.parent.children.push(objConfig3); return index; } // return model } cloneShamNode(oldRef, id, title) { const shamNode = window.$earth.sceneTree.$refs['node_' + oldRef]; const newShamNode = { ref: 'node_' + id, title: title, expand: false, children: [], }; // that.currentModel = response.result shamNode.parent.children.push(newShamNode); } getAreaCode(item) { const currentRef = item._inner.sn.ref; if (!this.areaByNodeId.has(currentRef)) { if (item.parent) { return this.getAreaCode(item.parent); } } else { return this.areaByNodeId.get(currentRef); } } setAllLabelStatus(selectRef, item, wbUnifiedResponse) { const that = this; //监控点 if (selectRef.startsWith('monitor')) { let grandsons: any = []; const childs = item.children; for (const child of childs) { const grandson1 = child.children; if (grandson1 && grandson1.length > 0) { grandsons = grandsons.concat(grandson1); } } for (const grandson of grandsons) { const xbsjObject = grandson._inner.sn; const ref = xbsjObject.ref; if (ref.startsWith('camera_')) { const state = that.statusByNodeId.get(ref); if (state == 1) { that.statusByNodeId.set(ref, 0); const img = that.imgByRef.get(ref); img.src = require('@/assets/earthMap/circleDot1.png'); } else if (state == 0) { that.statusByNodeId.set(ref, 1); const img = that.imgByRef.get(ref); img.src = require('@/assets/earthMap/circleDot1.png'); } } } } //微波 else if (selectRef.startsWith('wbList')) { const parentNode = item.parent; let areaCode = null; if (parentNode) { const falseNodeRef = item.parent._inner.sn.ref; const nodeRef = falseNodeRef.split('_')[1]; const trueNode = window.$earth.sceneTree.$refs[nodeRef]; areaCode = trueNode.czmObject.customProp; } const childs1 = item.children; if (!childs1 || childs1.length < 0) { return; } const length = childs1.length; let index = -1; for (const child of childs1) { index++; let xbsjObject = child._inner.sn; let jsonObj = JSON.parse(xbsjObject.czmObject.customProp); let deviceId = jsonObj.deviceId; let device = that.hostDeviceMapById.get(deviceId); if (!device) { console.error('主机设备为null'); continue; } const args = { device: device, isDefence: wbUnifiedResponse, defenceArea: areaCode, detectorList: null, }; defHttp .post( { url: this.url.setDefenseArea, params: args, }, { isTransformResponse: false } ) // postAction(this.url.setDefenseArea, args) .then((response) => { if (!response.success) { return; } else { for (let i = index; i < length; i++) { const child1 = childs1[i]; const xbsjObject1 = child1._inner.sn; const ref1 = xbsjObject1.ref; if (ref1 && ref1.length > 0) { const state1 = that.statusByNodeId.get(ref1); if (state1 == 0 && wbUnifiedResponse) { that.statusByNodeId.set(ref1, 1); const img1 = that.imgByRef.get(ref1); if (!img1) return; img1.src = require('@/assets/earthMap/circleDot2.png'); } else if (state1 == 1 && !wbUnifiedResponse) { that.statusByNodeId.set(ref1, 0); const img1 = that.imgByRef.get(ref1); if (!img1) return; img1.src = require('@/assets/earthMap/circleDot1.png'); } } } } console.log(response); }); break; } } else if (selectRef.startsWith('nodeSecondary')) { const childs1 = item.children; if (!childs1 || childs1.length < 0) { return; } for (const child of childs1) { let xbsjObject = child._inner.sn; let jsonObj = JSON.parse(xbsjObject.czmObject.customProp); let deviceId = jsonObj.deviceId; let device = that.hostDeviceMapById.get(deviceId); if (!device) { console.error('主机设备为null'); continue; } let regionIdList: any = []; if (item.children.length > 0) { item.children.forEach((element) => { regionIdList.push(element._inner.sn.ref); }); } const args = { regionIdList: regionIdList, // 周界防区区域ID列表(雷达设备列表的ID) regionStatus: wbUnifiedResponse ? 1 : 0, // 布防状态 0 - 未布防 1 - 布防 defenceRule: { // 布防规则 startTime: 'yyyy-MM-dd HH:mm:ss', // 布防开始时间 每日循环情况下只包含时分秒,格式:"HH:mm:ss" 非每日循环情况下包含年月日、时分秒,格式:"yyyy-MM-dd HH:mm:ss" endTime: 'yyyy-MM-dd HH:mm:ss', // 布防结束时间 每日循环情况下只包含时分秒,格式:"HH:mm:ss" 非每日循环情况下包含年月日、时分秒,格式:"yyyy-MM-dd HH:mm:ss" dailyCycle: true, // 每日循环布防 true - 是 false - 否 }, }; // putAction(this.url.perimeterControl,{}) console.log(device, that.statusByNodeId, xbsjObject); let ref1 = xbsjObject.ref; let state1 = that.statusByNodeId.get(ref1); //一键布防撤防测试使用 if (wbUnifiedResponse) { state1 = 0; } else { state1 = 1; } if (state1 == 0 && wbUnifiedResponse) { that.statusByNodeId.set(ref1, 1); const img1 = that.imgByRef.get(ref1); if (!img1) return; img1.src = require('@/assets/earthMap/circleDot2.png'); } else if (state1 == 1 && !wbUnifiedResponse) { that.statusByNodeId.set(ref1, 0); const img1 = that.imgByRef.get(ref1); if (!img1) return; console.log(img1); img1.src = require('@/assets/earthMap/circleDot1.png'); } // break } } } // 图层管理-模型右键菜单 sceneTreePopContextMenu({ item, vueObject }, earthUI) { let that: any = this; let earth = window.$earth; let XE = window.XE; let sceneTree = earthUI.tools.sceneTree; let sceneTreeComp = sceneTree._comp; // 转换方法 let transform = window.Cesium.Math; //右键之后设置当前 node item._inner.sn.isSelected = true; const el = vueObject.$el; let baseItems = [ { text: '克隆', keys: '', func: () => { let sn: any = null; if (item._inner.sn.ref.startsWith('node_')) { const objectId = item._inner.sn.ref.split('_')[1]; sn = earth.sceneTree.$refs[objectId]; } else { sn = item._inner.sn; } if (sn) { let newSn: any = null; let newSnData: any = null; let index = 0; if (sn.czmObject.xbsjType !== 'Polyline') { index = that.cloneModel(sn); newSn = sn.parent.children[index - 1]; newSnData = newSn.czmObject; if (newSnData.xbsjType === 'Model') { that.$nextTick(() => { const divs = $('#earthContainer>div>div>div:nth-child(5)') .children('div') .eq(1) .children() .eq(0) .children() .eq(0) .children() .each((index, element) => { if (index <= 1) { return; } const paddingLeft = $(element).children().eq(0).css('padding-left'); if (paddingLeft === '10px') { $(element).css('display', 'none'); } }); }); } } // 保存数据到数据库中 that .handleNodeType(sn) // 传感器 .sensor(() => { // debugger // 设置 ref 属性 防止数据库中 eventSerialNum 重复 newSn.ref += '_copy'; // 发送请求 保存到数据库中 let saveSensorModelParameter = { eventSerialNum: newSn.ref, lon: transform.toDegrees(newSnData.xbsjPosition[0]).toFixed(5), lat: transform.toDegrees(newSnData.xbsjPosition[1]).toFixed(5), height: newSnData.xbsjPosition[2].toFixed(2), yaw: transform.toDegrees(newSnData.xbsjRotation[0]).toFixed(2), pitch: transform.toDegrees(newSnData.xbsjRotation[1]).toFixed(2), roll: transform.toDegrees(newSnData.xbsjRotation[2]).toFixed(2), isShow: 1, modelType: '11', eventType: 1, }; defHttp .post( { url: this.url.SaveSensorModel, params: saveSensorModelParameter, }, { isTransformResponse: false } ) // postAction(this.url.SaveSensorModel, saveSensorModelParameter) .then((res) => { if (res.success) { that.$message.success('克隆成功'); } else { newSn.parent.children.splice(index, 1); that.$message.error('克隆失败: ', res.message ? res.message : ''); } }); }) // 标志点 微波雷达回调 .markerPosition(() => { // debugger newSn.title += '_copy'; let pinImage = newSnData.imageUrl; const staticDomainURL = window._CONFIG['staticDomainURL'] + '/'; // 去除 image 地址中的 staticDomainURL 链接 let imageUri = pinImage.substring(pinImage.indexOf(staticDomainURL) + staticDomainURL.length, pinImage.length); const jsonObj = JSON.parse(newSnData.customProp); const labelAttr = jsonObj.labelAttr; let savePinModelParameter = { mapLabel: { labelName: newSnData.name, labelLon: transform.toDegrees(newSnData.position[0]).toFixed(5), labelLat: transform.toDegrees(newSnData.position[1]).toFixed(5), labelHeight: newSnData.position[2].toFixed(2), labelImgUrl: imageUri, // 1 启用, 0 禁用 labelStatus: 1, // 标记属性-> 3: 标记位置 labelAttr: labelAttr, labelCode: '', lineId: newSn.name, }, deviceId: jsonObj.deviceId, }; defHttp .post( { url: this.url.saveMapLabel, params: savePinModelParameter, }, { isTransformResponse: false } ) // postAction(this.url.saveMapLabel, savePinModelParameter) .then((res) => { if (res.success) { // 修改 ref 成 数据库返回的 id newSn.ref = res.result; that.setIconByRef(newSn.ref, newSn.ref); newSn.czmObject.pinBuilder.extText = newSnData.name; jsonObj.labelCode = ''; newSn.czmObject.customProp = JSON.stringify(jsonObj); // 保存成功 that.$message.success('克隆成功'); } else { newSn.parent.children.splice(index, 1); that.$message.error('克隆失败: ', res.message ? res.message : ''); } }) .catch((err) => { newSn.parent.children.splice(index, 1); that.$message.error('克隆失败'); }); }) //区域回调 .polylineCallBack(() => { // debugger const currentModel = new window.XE.Obj.Polyline(window.$earth); const submitData: any = {}; const poistions = sn.czmObject.positions; if (poistions.length <= 0) { return; } submitData.name = sn.czmObject.name + '_copy'; submitData.lineCode = currentModel.guid; submitData.isLoop = Number(sn.czmObject.loop); submitData.isDepthCheck = Number(sn.czmObject.depthTest); submitData.width = sn.czmObject.width; submitData.interpolation = sn.czmObject.arcType; submitData.positions = JSON.stringify(poistions); switch (sn.czmObject.material.type) { // 实线 case 'XbsjColorMaterial': submitData.materialType = 0; submitData.color = JSON.stringify(sn.czmObject.material.XbsjColorMaterial.color); submitData.intervalColor = null; submitData.dashLength = 0; submitData.dashStyle = 0; break; // 虚线 case 'XbsjPolylineDashMaterial': submitData.materialType = 1; submitData.color = JSON.stringify(sn.czmObject.material.XbsjPolylineDashMaterial.color); submitData.intervalColor = JSON.stringify(sn.czmObject.material.XbsjPolylineDashMaterial.gapColor); submitData.dashLength = sn.czmObject.material.XbsjPolylineDashMaterial.dashLength; submitData.dashStyle = sn.czmObject.material.XbsjPolylineDashMaterial.dashPattern; break; // 箭头线 case 'XbsjPolylineArrowMaterial': submitData.materialType = 2; submitData.color = JSON.stringify(sn.czmObject.material.XbsjPolylineArrowMaterial.color); submitData.intervalColor = null; submitData.dashLength = 0; submitData.dashStyle = 0; break; // 轨迹线 case 'XbsjODLineMaterial': submitData.materialType = 3; submitData.color = JSON.stringify(sn.czmObject.material.XbsjODLineMaterial.color); submitData.intervalColor = null; submitData.dashLength = 0; submitData.dashStyle = 0; submitData.cycleFrame = sn.czmObject.material.XbsjODLineMaterial.totoalFrameCount; break; } defHttp .post( { url: this.url.saveMapLine, params: submitData, }, { isTransformResponse: false } ) // postAction(this.url.saveMapLine, submitData) .then((response) => { if (response.success) { currentModel.name = submitData.name; currentModel.loop = submitData.isLoop; currentModel.depthTest = submitData.isDepthCheck; currentModel.width = submitData.width; currentModel.arcType = submitData.interpolation; currentModel.positions = JSON.parse(submitData.positions); switch (sn.czmObject.material.type) { // 实线 case 'XbsjColorMaterial': currentModel.material.type = 'XbsjColorMaterial'; currentModel.material.color = submitData.color; break; // 虚线 case 'XbsjPolylineDashMaterial': currentModel.material.type = 'XbsjPolylineDashMaterial'; currentModel.material.color = submitData.color; currentModel.material.XbsjPolylineDashMaterial.gapColor = submitData.intervalColor; currentModel.material.XbsjPolylineDashMaterial.dashLength = submitData.dashLength; currentModel.material.XbsjPolylineDashMaterial.dashPattern = submitData.dashStyle; break; // 箭头线 case 'XbsjPolylineArrowMaterial': currentModel.material.type = 'XbsjPolylineArrowMaterial'; currentModel.material.XbsjPolylineArrowMaterial.color = submitData.color; break; // 轨迹线 case 'XbsjODLineMaterial': currentModel.material.type = 'XbsjODLineMaterial'; currentModel.material.XbsjODLineMaterial.color = submitData.color; currentModel.material.XbsjODLineMaterial.totoalFrameCount = submitData.cycleFrame; break; } const leaf = new XE.SceneTree.Leaf(currentModel); leaf.ref = response.result; sn.parent.children.push(leaf); } else { throw '克隆区域数据出错'; } }) .catch((e) => { currentModel.destroy(); // $mitt.emit('openNotification', '克隆区域数据出错', 2, 'error', '50px') $mitt.emit('openNotification', { msg: '克隆区域数据出错', dt: 2, type: 'error', top: '50px' }); }); }) //监控点 .modelCallback(() => { this.$message.warning('监控点不支持克隆'); }) .run(); } }, }, { text: '删除', keys: '', func: () => { earthUI.confirm('确认删除图层?', () => { try { // debugger let sn: any = null; const ref = item._inner.sn.ref; // update:-- 判断方式要修改 if (ref.startsWith('node_')) { const objectId = item._inner.sn.ref.split('_')[1]; sn = earth.sceneTree.$refs[objectId]; } else { sn = item._inner.sn; } let id = sn.ref; // 删除数据库中的数据 that .handleNodeType(sn) // 传感器 .sensor(() => { // 发送请求 删除数据库中的数据 that.handlerModelDelete(this.url.deleteSensor, { eventSerialNum: id }); }) // 标志点 .markerPosition(() => { if (sn.czmObject.addViewShedReturn) { window.$earth.czm.viewer.entities.remove(sn.czmObject.addViewShedReturn); } if (sn.czmObject.customProp) { let prop = JSON.parse(sn.czmObject.customProp); if (prop.labelAttr == 4) { defHttp.delete( { url: '/military/RadarConfig/deleteByRadarCode', params: { radarCode: prop.labelCode }, }, { isTransformResponse: false, joinParamsToUrl: true } ); // deleteAction("/military/RadarConfig/deleteByRadarCode", {radarCode: prop.labelCode}).then(res => { // // console.log(res,'delete'); // }) } } this.handlerModelDelete(this.url.deleteMapLabel, { id: id, }); }) // 线 .modelCallback(() => { that.handlerModelDelete(this.url.deleteSite, { id: id }).then(() => { sn.destroy(); const node = item._inner.sn; const childList = node.parent.children; childList.splice(childList.indexOf(node), 1); node.destroy(); }); }) .polylineCallBack(() => { const childList = item._inner.sn.children; for (const child of childList) { if (child.children.length > 0) { this.$message.warning('存在下级数据无法删除'); throw '存在下级数据无法删除'; } } that.handlerModelDelete(this.url.deleteMapLine, { id: id }).then(() => { const nodeRef = 'node_' + id; const node = $earth.sceneTree.$refs[nodeRef]; const childList = node.parent.children; childList.splice(childList.indexOf(node), 1); node.destroy(); }); }) .run(); const index = sn.parent.children.indexOf(sn); sn.parent.children.splice(index, 1); } catch (error) {} }); }, }, ]; const bf = { text: '布防/撤防', keys: '', func: () => { const xbsjObject = item._inner.sn; if (!xbsjObject || !xbsjObject.czmObject) return; const jsonObj = JSON.parse(xbsjObject.czmObject.customProp); const deviceId = jsonObj.deviceId; if (!deviceId) { console.error('主机设备为空'); return; } const labelCode = jsonObj.labelCode; if (!labelCode) { console.error('设备编码为null'); return; } const device = that.hostDeviceMapById.get(deviceId); const ref = xbsjObject.ref; if (device.deviceType_dictText.indexOf('微波探测器') > -1) { if (ref && ref.length > 0) { const state = that.statusByNodeId.get(ref); if (state == 1) { that.setLabelStatus(device, labelCode, ref, 0).then((response) => { that.setIconByRef(ref, el); }); } else if (state == 0) { that.setLabelStatus(device, labelCode, ref, 1).then((response) => { that.setIconByRef(ref, el); }); } else { that.$message.error('设备不在线'); } } } else if (device.deviceType_dictText.indexOf('雷达') > -1) { // console.log("leida"); //处理单个雷达布防撤防 //参数 // { // "regionIdList": [ // 2 // ], // 周界防区区域ID列表(雷达设备列表的ID) // "regionStatus": 0, // 布防状态 0 - 未布防 1 - 布防 // "defenceRule": { // 布防规则 // "startTime": "yyyy-MM-dd HH:mm:ss", // 布防开始时间 每日循环情况下只包含时分秒,格式:"HH:mm:ss" 非每日循环情况下包含年月日、时分秒,格式:"yyyy-MM-dd HH:mm:ss" // "endTime": "yyyy-MM-dd HH:mm:ss", // 布防结束时间 每日循环情况下只包含时分秒,格式:"HH:mm:ss" 非每日循环情况下包含年月日、时分秒,格式:"yyyy-MM-dd HH:mm:ss" // "dailyCycle": true // 每日循环布防 true - 是 false - 否 // } // } // putAction(this.url.perimeterControl,{}) } }, }; const selectRef = item._inner.sn.ref; if (selectRef.startsWith('wbList') || selectRef.startsWith('nodeSecondary_')) { baseItems = [ { text: '一键布防', keys: '', func: () => { that.setAllLabelStatus(selectRef, item, true); }, }, { text: '一键撤防', keys: '', func: () => { that.setAllLabelStatus(selectRef, item, false); }, }, ]; earthUI.contextMenu.pop(baseItems); return; } else if (selectRef.startsWith('monitor') || selectRef.startsWith('ldList')) { earthUI.contextMenu.pop([]); return; } else if (item.level <= 2) { if (!item._inner.sn.ref.startsWith('node_')) { earthUI.contextMenu.pop([]); return; } else { baseItems.splice(0, 1); } } else { if (selectRef.startsWith('camera')) { // baseItems = [bf] // earthUI.contextMenu.pop(baseItems) return; } else if (!selectRef.startsWith('node_')) { //站点 baseItems.unshift({ type: 'divider', }); baseItems.unshift(bf); } } let num = 2; //判断定位的位置 if ( item.level <= 2 || selectRef.startsWith('monitor') || selectRef.startsWith('wbList') || selectRef.startsWith('ldList') || //站点 selectRef.startsWith('node_') ) num = 0; baseItems.splice(num, 0, { text: '定位', keys: '', func: () => { // const czmObject = item._inner.sn.czmObject // czmObject.flyTo() const ref = item._inner.sn.ref; let czmObject: any = null; if (ref.startsWith('node_')) { const objectId = ref.split('_')[1]; const sn = earth.sceneTree.$refs[objectId]; czmObject = sn.czmObject; } else { const sn = item._inner.sn; czmObject = sn.czmObject; } czmObject.flyTo(); }, }); baseItems.push( ...[ { type: 'divider', }, { text: '属性', func: () => { $mitt.emit('windowCancel'); // 属性面板 const mainUI = earthUI._vm.$refs.mainUI; const areaCode = that.getAreaCode(item); let sn: any = null; if (item._inner.sn.ref.startsWith('node_')) { const objectId = item._inner.sn.ref.split('_')[1]; sn = earth.sceneTree.$refs[objectId]; // window.XE.MVVM.watch(() => { // item._inner.sn.title = sn.title // }) sn.czmObject.distanceDisplayCondition = [1.0, 30000.0]; if (sn.czmObject.xbsjType == 'Model') { const lineId = item.parent.parent._inner.sn.ref.split('_')[1]; this.czmObject = sn.czmObject; this.node = item; this.type = 'jkd'; this.lineId = lineId; this.areaCode = areaCode; this.areaByNodeIdModel = that.areaByNodeId; // this.addModelWinShow = true this.$nextTick(() => { this.addModelWinShow = true; }); ////////////////////////// // 只有组件中有getBind属性才能传递属性 // this._earthUI.showPropertyWindow( // { // czmObject: sn.czmObject, // node: item, // type: 'jkd', // lineId: lineId, // areaCode: areaCode, // areaByNodeId: that.areaByNodeId, // }, // { // // component: addModelModal, // component: addModelWin, // } // ) return; } } else { sn = item._inner.sn; if (sn.czmObject.xbsjType == 'Pin') { const jsonObj = JSON.parse(sn.czmObject.customProp); const lineId = jsonObj.labelAttr == 4 ? item.parent._inner.sn.ref.split('_')[1] : item.parent.parent._inner.sn.ref.split('_')[1]; this.czmObject = sn.czmObject; this.node = item; this.type = jsonObj.labelAttr == 4 ? 'ld' : 'wb'; this.lineId = lineId; this.areaCode = areaCode; this.eidtId = sn.ref; this.areaByNodeIdModel = that.areaByNodeId; // setLabelStatus: that.setLabelStatus, 已经有了 // setIconByRef: that.setIconByRef, (this.el = el), this.$nextTick(() => { this.addModelWinShow = true; }); // 只有组件中有getBind属性才能传递属性 // this._earthUI.showPropertyWindow( // { // czmObject: sn.czmObject, // node: item, // type: jsonObj.labelAttr == 4 ? 'ld' : 'wb', // lineId: lineId, // areaCode: areaCode, // areaByNodeId: that.areaByNodeId, // eidtId: sn.ref, // setLabelStatus: that.setLabelStatus, // setIconByRef: that.setIconByRef, // el: el, // }, // { // // component: addModelModal, // component: addModelWin, // } // ) return; } } let index = sn.parent.children.indexOf(sn); let tempData = sn.czmObject.toAllJSON(); // 设置属性面板的确定按钮方法 // 显示属性面板 earthUI.showPropertyWindow(sn.czmObject); that.$nextTick(() => { // 模型窗口 const windowsAttrList = Object.keys(mainUI.$refs); // 找到该模型设置属性窗口 const modelToolKey = windowsAttrList.filter((f) => f.indexOf(sn.czmObject.guid || sn.guid) > -1)[0]; const modelTool = mainUI.$refs[modelToolKey][0]; // 对应处理方法 that .handleNodeType(sn) // 感应器 .sensor(() => { // 禁用模型名称编辑 modelTool.$el.getElementsByClassName('xbsj-flatten')[0].children[0].children[1].setAttribute('disabled', 'disabled'); }) .default(() => { // 启用模型名称编辑 modelTool.$el.getElementsByClassName('xbsj-flatten')[0].children[0].children[1].removeAttribute('disabled'); }) .run(); // modelTool modelTool.ok = () => { // 确定时清除这个事件 $mitt.off('windowCancel'); // 保存前端数据 const modelToolObj = modelTool._czmObj; if (!modelToolObj) { return; } modelToolObj.positionEditing = false; if (modelToolObj.isCreating) { modelToolObj.isCreating = false; const sceneObject = new XE.SceneTree.Leaf(modelToolObj); earthUI.addSceneObject(sceneObject); } // 保存到数据库 that.propertiesWindowConfirm(modelTool, sn, index); // 关闭属性面板 modelTool.close(); }; modelTool.cancel = () => { // 清除这个事件 $mitt.off('windowCancel'); // 关闭属性面板 modelTool.close(); let t = modelTool._czmObj; // 如果是创建的话,需要删除 t && t.positionEditing === false && t.isCreating && t.isCreating === false && t.destroy(); // 恢复之前的数据 t && t.xbsjFromJSON(tempData); }; $mitt.on('windowCancel', modelTool.cancel); // 下面的代码,是切换属性面板里选项窗口, 必须 // 否侧 ok cancel 等方法执行是原本的方法而不是已经修改的方法 modelTool.tabShow = '3'; modelTool.tabShow = '1'; }); }, }, ] ); // 右键菜单-重命名 // 先销毁之前的 on-change-title 事件 vueObject.$off('on-change-title', that.handleChangeTitle); // 重命名时 on-change-title 事件 vueObject.$on('on-change-title', that.handleChangeTitle); // 弹出右键菜单 earthUI.contextMenu.pop(baseItems); } // 重命名 on-change-title 事件 使用 lodash.debounce 函数(防抖) handleChangeTitle = _.debounce(function (options) { const sn = options.item._inner.sn; const newTitle = options.title; // 修改模型属性后,提交到后台。先判断模型的节点,调用不同的接口 this.handleNodeType(sn) // 感应器 .sensor(() => { // 不支持修改名称 this.$message.warning('不支持修改感应器的名称'); }) // 传感器标志线 .modelCallback(() => { // 发送请求 保存模型属性 let editCameraSiteModelParameter = { id: sn.ref, sitename: newTitle, }; defHttp .put( { url: this.url.updateSite, params: editCameraSiteModelParameter, }, { isTransformResponse: false } ) // putAction(this.url.updateSite, editCameraSiteModelParameter) .then((res) => { if (res.success) { this.$message.success('修改成功'); } else { this.$message.error('修改失败'); } }) .catch((error) => { this.$message.error('修改失败'); }); }) .markerPosition(() => { // 发送请求 保存模型属性 let editPinModelParameter = { id: sn.ref, labelName: newTitle, }; defHttp .put( { url: this.url.updateMapLabel, params: editPinModelParameter, }, { isTransformResponse: false } ) // putAction(this.url.updateMapLabel, editPinModelParameter) .then((res) => { if (res.success) { // 修改扩展文本 sn.czmObject.pinBuilder.extText = newTitle; this.$message.success('修改成功'); } else { this.$message.error('修改失败'); } }) .catch((error) => { this.$message.error('修改失败'); }); }) .run(); }, 150); // 右键菜单删除按钮的删除方法 handlerModelDelete(url, params) { // return deleteAction(url, params).then((res) => { return defHttp .delete( { url: url, params: params, }, { isTransformResponse: false, joinParamsToUrl: true } ) .then((res) => { if (res.success) { this.$message.success('删除成功'); } else { this.$message.error('删除失败'); console.log('asdasdasd'); } }); } // 属性面板确定按钮方法 propertiesWindowConfirm(propertiesWindow, sn, index) { // 属性面板 所修改的模型 let model: any = null; if (sn.ref && !sn.ref.startsWith('node_')) { model = sn; } else { model = sn.parent.children[index]; } let modelData = model.czmObject; // 转换方法 let transform = window.Cesium.Math; // 修改模型属性后,提交到后台。先判断模型的节点,调用不同的接口 this.handleNodeType(sn) // 传感器 .sensor(() => { // 发送请求 保存模型属性 let editSensorParams = { eventSerialNum: model.ref, lon: transform.toDegrees(modelData.xbsjPosition[0]).toFixed(5), lat: transform.toDegrees(modelData.xbsjPosition[1]).toFixed(5), height: modelData.xbsjPosition[2].toFixed(2), yaw: transform.toDegrees(modelData.xbsjRotation[0]).toFixed(2), pitch: transform.toDegrees(modelData.xbsjRotation[1]).toFixed(2), roll: transform.toDegrees(modelData.xbsjRotation[2]).toFixed(2), isShow: 1, // 传感器类型 modelType: '11', // 事件类型 eventType: 1, }; defHttp .put( { url: this.url.updateSensor, params: editSensorParams, }, { isTransformResponse: false } ) // putAction(this.url.updateSensor, editSensorParams) .then((res) => { if (res.success) { this.$message.success('修改成功'); } else { this.$message.error('修改失败: ', res.message); } }); }) // 站点 .modelCallback(() => { let startNum = modelData.url.lastIndexOf('/') + 1; let modelName = ''; if (startNum > 0) { modelName = modelData.url.substring(startNum, modelData.url.length); } // 发送请求 保存模型属性 let editCameraSiteModelParameter = { id: model.ref, longitude: transform.toDegrees(modelData.xbsjPosition[0]).toFixed(6), latitude: transform.toDegrees(modelData.xbsjPosition[1]).toFixed(6), height: modelData.xbsjPosition[2], yaw: transform.toDegrees(modelData.xbsjRotation[0]).toFixed(6), pitch: transform.toDegrees(modelData.xbsjRotation[1]).toFixed(6), roll: transform.toDegrees(modelData.xbsjRotation[2]).toFixed(6), modelUrl: modelName, sitename: modelData.name, }; defHttp .put( { url: this.url.updateSite, params: editCameraSiteModelParameter, }, { isTransformResponse: false } ) // putAction(this.url.updateSite, editCameraSiteModelParameter) .then((res) => { if (res.success) { modelData.pinBuilder.extText = modelData.name; this.$message.success('修改成功'); } else { this.$message.error('修改失败'); } }); }) // 标志点 .markerPosition(() => { let pinImage = modelData.imageUrl; const staticDomainURL = window._CONFIG['staticDomainURL'] + '/'; // 去除 image 地址中的 staticDomainURL 链接 let imageUri = pinImage.substring(pinImage.indexOf(staticDomainURL) + staticDomainURL.length, pinImage.length); let editPinModelParameter = { id: model.ref, labelName: modelData.name, labelLon: transform.toDegrees(modelData.position[0]).toFixed(5), labelLat: transform.toDegrees(modelData.position[1]).toFixed(5), labelHeight: modelData.position[2].toFixed(2), labelImgUrl: imageUri, }; defHttp .put( { url: this.url.updateMapLabel, params: editPinModelParameter, }, { isTransformResponse: false } ) // putAction(this.url.updateMapLabel, editPinModelParameter) .then((res) => { if (res.success) { modelData.pinBuilder.extText = modelData.name; this.$message.success('修改成功'); } else { this.$message.error('修改失败'); } }) .catch((error) => { this.$message.error('修改失败'); }); }) .polylineCallBack(() => { const submitData: any = {}; const poistions = modelData.positions; if (poistions.length <= 0) { return; } submitData.id = model.ref; submitData.name = modelData.name; if (!modelData.customProp) { submitData.lineCode = modelData.guid; } submitData.isLoop = Number(modelData.loop); submitData.isDepthCheck = Number(modelData.depthTest); submitData.width = modelData.width; submitData.interpolation = modelData.arcType; submitData.positions = JSON.stringify(poistions); switch (modelData.material.type) { // 实线 case 'XbsjColorMaterial': submitData.materialType = 0; // material.XbsjColorMaterial = {} submitData.color = JSON.stringify(modelData.material.XbsjColorMaterial.color); submitData.intervalColor = null; submitData.dashLength = 0; submitData.dashStyle = 0; break; // 虚线 case 'XbsjPolylineDashMaterial': submitData.materialType = 1; submitData.color = JSON.stringify(modelData.material.XbsjPolylineDashMaterial.color); submitData.intervalColor = JSON.stringify(modelData.material.XbsjPolylineDashMaterial.gapColor); submitData.dashLength = modelData.material.XbsjPolylineDashMaterial.dashLength; submitData.dashStyle = modelData.material.XbsjPolylineDashMaterial.dashPattern; // material.XbsjPolylineDashMaterial = {} // material.XbsjPolylineDashMaterial.dashLength = data.dashLength // material.XbsjPolylineDashMaterial.dashPattern = data.dashStyle break; // 箭头线 case 'XbsjPolylineArrowMaterial': submitData.materialType = 2; // material.XbsjPolylineArrowMaterial = {} submitData.color = JSON.stringify(modelData.material.XbsjPolylineArrowMaterial.color); submitData.intervalColor = null; submitData.dashLength = 0; submitData.dashStyle = 0; break; // 轨迹线 case 'XbsjODLineMaterial': submitData.materialType = 3; submitData.color = JSON.stringify(modelData.material.XbsjODLineMaterial.color); submitData.intervalColor = null; submitData.dashLength = 0; submitData.dashStyle = 0; submitData.cycleFrame = modelData.material.XbsjODLineMaterial.totoalFrameCount; // material.XbsjODLineMaterial = {} // material.XbsjODLineMaterial.color = JSON.parse(data.color) // material.XbsjODLineMaterial.totoalFrameCount = data.cycleFrame break; } defHttp .put( { url: this.url.updateMapLine, params: submitData, }, { isTransformResponse: false } ) // putAction(this.url.updateMapLine, submitData) .then((res) => { if (res.success) { // $mitt.emit('openNotification', '修改成功', 2, 'info') $mitt.emit('openNotification', { msg: '修改成功!', dt: 2, type: 'info', top: '50px' }); sn.title = submitData.name; window.$earth.sceneTree.$refs['node_' + sn.ref].title = submitData.name; } else { // $mitt.emit('openNotification', '修改失败', 2, 'error', '50px') $mitt.emit('openNotification', { msg: '修改失败', dt: 2, type: 'error', top: '50px' }); } }) .catch((error) => { // $mitt.emit('openNotification', '修改失败', 2, 'error', '50px') $mitt.emit('openNotification', { msg: '修改失败', dt: 2, type: 'error', top: '50px' }); }); }) .run(); } /** * 保存更改的ref到模型和后台数据中; * @param {Object} model 当前模型 * @param {string} newRef 新的ref * @param {string} oldRef 旧的ref */ changeRef = _.debounce(function (model, newRef, oldRef) { // 当数值改变时且旧值不等于空时,更新模型的ref if (newRef !== oldRef && oldRef !== '') { // 修改后台的数据 this.handleNodeType(model) .sensor(() => { defHttp .put( { url: this.url.updateSensor + `?eventSerialNum=${oldRef}`, params: { eventSerialNum: newRef }, }, { isTransformResponse: false } ) // putAction(this.url.updateSensor + `?eventSerialNum=${oldRef}`, {eventSerialNum: newRef}) .then((res) => { if (res.success) { // 设置保存的 ref this.sceneTreeOldRefValue = ''; // 更新模型的名称 model.title = newRef; this.$message.success('修改成功'); } else { this.$message.error('修改失败: ' + res.message); } }) .catch((err) => { this.$message.error('修改失败: ', err); }); }) .modelCallback(() => { // 传感器标志线不能修改ref,因为 ref 是后台数据库的ID; this.$message.warning('无法修改传感器标志线的ref'); }) .run(); } }, 150); handleNodeType(sn) { return new HandleNodeType(sn); } radarAlarmTimeOutCheck() { const now = Date.now(); const timeout = 5 * 60 * 1000; // 遍历报警数据 this.alarmInfoMap.forEach((value, key) => { // 获取当前时间与报警时间的时间差 const timeDiff = now - value.timestamp; // 如果时间差大于5分钟,则清除报警 if (timeDiff > timeout) { // 清除报警,有雷达告警则清除雷达告警和雷达轨迹 this.clearAlarmModel(key); } }); } clearRadarAlarmModel(radarAlarmDataMap, eventNum) { if (radarAlarmDataMap.has(eventNum)) { let alarmData = radarAlarmDataMap.get(eventNum); for (let target of alarmData.target) { let pathModel = target.path; let groundImageModel = target.groundImage; // 销毁模型 pathModel && pathModel.destroy(); groundImageModel && groundImageModel.destroy(); } radarAlarmDataMap.delete(eventNum); } } clearAlarmModel(eventNum) { let alarmInfoMap = this.alarmInfoMap; let radarAlarmDataMap = this.radarAlarmDataMap; if (alarmInfoMap.has(eventNum)) { let alarmData = alarmInfoMap.get(eventNum); // 清除报警 alarmData.pin && alarmData.pin._div.remove(); alarmData.pin && alarmData.pin.destroy(); alarmData.scanline && alarmData.scanline.destroy(); this.alarmInfoMap.delete(eventNum); } this.clearRadarAlarmModel(radarAlarmDataMap, eventNum); } // 获取当前实时时间 getRealTime() { this.timer2 = setInterval(() => { this.realTime = getRealTime(); }, 1000); } // 资源销毁 beforeDestroy() { // vue程序销毁时,需要清理相关资源 this._earth = this._earth && this._earth.destroy(); this.websocketclose(); //清除定时器 clearInterval(this.timer); clearInterval(this.timer2); clearInterval(this.alarmTrackClearTimer); } } </script> <style> .xbsj-model-box, .detail-model, .xbsj-modal-box { background: linear-gradient(360deg, rgba(9, 39, 76, 0.9), rgba(9, 39, 76, 0.6)) !important; /* border: 1px solid #2c58a6; */ box-shadow: 0 0 10px #2c58a6; } .xbsjSceneTreeBox { left: initial !important; width: 280px !important; height: 600px !important; right: 0 !important; top: 0 !important; background: -webkit-linear-gradient(270deg, RGBA(9, 39, 76, 0.9), RGBA(9, 39, 76, 0.1)) !important; background: -o-linear-gradient(270deg, RGBA(9, 39, 76, 0.9), RGBA(9, 39, 76, 0.1)) !important; background: -moz-linear-gradient(270deg, RGBA(9, 39, 76, 0.9), RGBA(9, 39, 76, 0.1)) !important; background: linear-gradient(270deg, RGBA(9, 39, 76, 0.9), RGBA(9, 39, 76, 0.1)) !important; box-shadow: none !important; } .xbsjSceneTreeBox .xbsj-model-close { display: none; } .xbsjcesium + div { background: -webkit-linear-gradient(360deg, RGBA(9, 39, 76, 0.9), RGBA(9, 39, 76, 0.1)) !important; background: -o-linear-gradient(360deg, RGBA(9, 39, 76, 0.9), RGBA(9, 39, 76, 0.1)) !important; background: -moz-linear-gradient(360deg, RGBA(9, 39, 76, 0.9), RGBA(9, 39, 76, 0.1)) !important; background: linear-gradient(360deg, RGBA(9, 39, 76, 0.9), RGBA(9, 39, 76, 0.1)) !important; } .distance-legend { background: RGBA(9, 39, 76, 0.8); } /* 标题 */ .earthUI_header header { position: relative; top: -3px; height: 4rem; background: url(../../../assets/earthMap/head_bg.png) no-repeat top center; background-size: 100% 90%; } .earthUI_header p { font-family: 'Arial', 'Microsoft YaHei', '黑体', '宋体', sans-serif; color: #00ffe4; text-align: center; margin: 0; padding: 0; } .earthUI_header header > p:first-child { font-size: 1.1rem; line-height: 28px; padding-top: 0.5vh; /* 文字间隔 */ letter-spacing: 5px; } .earthUI_header header > p:last-child { font-family: Microsoft YaHei; font-size: 0.8rem; font-weight: 400; /* 文字间隔 */ letter-spacing: 0.5px; } .quitBtn { position: relative; text-align: center; font-size: 12px; min-width: 100px; width: 120px; height: 30px; padding: 0 7px; margin-left: 100px; line-height: 30px; border-radius: 100px; border: 1px solid #c9c9c9; background-color: #fff; color: #555; cursor: pointer; display: none; } /* 视频窗口 */ .videos { display: none; border: 1px solid #080808; /*position: fixed; right: 0; bottom: 2px; */ position: absolute; left: 0; top: 0; z-index: 100; width: 420px; height: 380px; -webkit-box-shadow: 0px 3px 3px #c8c8c8; -moz-box-shadow: 0px 3px 3px #c8c8c8; box-shadow: 0px 3px 3px #c8c8c8; } .vclose { position: absolute; right: 1%; top: 1%; border-radius: 100%; cursor: pointer; } .videosSpan1 { position: absolute; left: 1%; top: 1%; color: #000; font-size: 15px; font-weight: bold; font-family: 黑体; border-radius: 100%; } .videosSpan2 { position: absolute; right: 1%; bottom: 1%; color: #000; font-size: 16px; font-weight: bold; font-family: 黑体; border-radius: 100%; } /* 相机状态点 */ .successStatus, .offlineStatus, .errorStatus { position: relative; } .successStatus::before { content: ' '; position: absolute; height: 7px; width: 7px; top: -60px; left: 0; /*transform: translateY(-50%);*/ border-radius: 50%; background: rgb(0, 255, 0); } .offlineStatus::before { content: ' '; position: absolute; height: 7px; width: 7px; top: -60px; left: 0; /*transform: translateY(-50%);*/ border-radius: 50%; background: rgb(170, 170, 170); } .errorStatus::before { content: ' '; position: absolute; height: 7px; width: 7px; top: -60px; left: 0; /*transform: translateY(-50%);*/ border-radius: 50%; background: rgb(255, 0, 0); } /* 相机状态点 */ /* 电线杆气泡窗 */ .cameraModal { margin: 20px auto; position: absolute; left: 0; top: 0; width: auto; line-height: 25px; color: white; text-align: center; font-size: 14px; border: 1px solid rgb(255, 255, 255); opacity: 0.9; border-radius: 5px; background: rgb(255, 255, 255); } .cameraModal::after { /* 箭头靠下边 */ content: ''; position: absolute; width: 0; height: 0; left: 35px; bottom: -15px; border-left: 10px solid transparent; border-right: 10px solid transparent; border-top: 15px solid rgb(255, 255, 255); } .cameraModal ul { margin: 20px; padding: 0px; list-style: none; } .cameraModal li { float: left; list-style-type: none; display: inline; margin: 5px; width: 120px; border: 2px solid #fff; } .cameraModal li:hover { border-bottom-color: #00ffe4; } .cameraModal li > a { color: rgb(19, 15, 15); text-decoration: none; cursor: pointer; } .cameraModal img { width: 80px; height: 60px; display: block; margin: 0 auto; } .spinning { position: absolute; left: 50%; top: 35%; z-index: 999; } /* 电线杆气泡窗 */ /* 地标气泡窗 */ /*.poiModal { margin: 20px auto; padding: 5px; position: absolute; left: 0; top: 0; height: 160px; width: 300px; color: white; text-align: center; font-size: 14px; border: 1px solid RGBA(12, 177, 177, 0.8); border-radius: 5px; filter: alpha(opacity=50); background: RGBA(12, 177, 177, 0.9); } .poiModal::after { !* 箭头靠下边 *! content: ''; position: absolute; width: 0; height: 0; left: 140px; bottom: -15px; border-left: 10px solid transparent; border-right: 10px solid transparent; border-top: 15px solid RGBA(12, 177, 177, 0.8); } .poiModal-content { width: 100%; height: 100%; box-shadow: 0 5px 8px 0 rgba(0, 0, 0, 0.2), 0 7px 20px 0 rgba(0, 0, 0, 0.2); animation-name: modalopen; animation-duration: 1s; } .poiModal-header h2 { margin: 0; color: white; } .poiModal-header { line-height: 40px; } .poiModal-body { text-align: left; font-size: 16px; padding-left: 5px; } .poiModal-body span { color: #ffeb3b; }*/ /* 地标气泡窗 */ /* 地图切换按钮 */ .radioBtn { position: absolute; bottom: 40px; right: 15px; } .radioBtn span { transition: color 0.3s linear; } .radioBtn span:hover { color: #00ffe4bb !important; transition: color 0.3s linear; } .ant-radio-button-wrapper-checked { background: #00ffe4bb !important; border-color: #00ffe4 !important; } .ant-radio-button-wrapper-checked:not(.ant-radio-button-wrapper-disabled)::before { background-color: #00ffe4 !important; } .earthChangeSpin { position: absolute; left: 45%; top: 35%; } .ant-spin { color: #00ffe4; } .ant-spin-dot-item { background-color: #00ffe4; } /* 地图切换按钮 */ /* 比例尺和指南针属性 */ #distanceLegendDiv .distance-legend { bottom: 80px !important; background-color: rgba(9, 39, 76, 0.7) !important; } #navigationDiv > div { top: unset !important; /*去掉已有的top值使bottom生效 */ bottom: 120px !important; right: 40px !important; } .compass-outer-ring-background { border: 12px solid rgba(9, 39, 76, 0.7) !important; } .compass-gyro-background { background-color: rgba(9, 39, 76, 0.7) !important; } /* 比例尺和指南针属性 */ body { user-select: none; } </style>