数字孪生Web 后台dt( digital twin)2.0版本 统一命名格式
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1698 lines
55 KiB

<!--
电子地图
-编辑页面
-->
<template>
<div>
<div id="earthContainer" ref="earthContainer" style="width: 100%; height: 100%; top: 300px"></div>
<div class="earthUI_header" v-if="PropsEarthHeaderShow">
<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" :all="this.all"></Toolbar>
<!-- 左下角显隐控件 -->
<ShowHideControl v-if="toolbarShow"></ShowHideControl>
<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>
<!-- AIS信息显示窗口 -->
<AISInfoWindow v-if="AISInfoWindowShow" :ship_guid="ship_guid" :ship_aisData="ship_aisData"></AISInfoWindow>
</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 ShowHideControl from '/@/components/earthMap/ShowHideControl.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 AISInfoDetail from '@/components/earthMap/AISInfoDetail.vue';
import AISInfoWindow from '@/components/earthMap/AISInfoWindow.vue';
import { getRealTime } from '@/utils/date';
import $mitt from '@/utils/earthMap/mitt';
import guid from '@/utils/earthMap/guid';
import HandleNodeType from '@/utils/earthMap/handleNodeType';
import { handleNodeType } from '@/utils/earthMap/handleNodeType';
import { getRandomArr, getHeigthByLonLat } from '@/utils/earthMap/earth';
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 { useMessage } from '/@/hooks/web/useMessage';
import { CircleScan } from '@/utils/earthMap/radarEntity';
import { radianToDegreeInLngLatHeight } from '@/utils/earthMap/earth';
import listenMouseHandlerSence from '@/utils/earthMap/listenMouseHandlerSence';
import listenMouseHandler from '@/utils/earthMap/listenMouseHandler';
import getLineInfo from '@/utils/earthMap/getLineInfo';
import getCameraInfo from '@/utils/earthMap/getCameraInfo';
import getLabelInfo from '@/utils/earthMap/getLabelInfo';
import { setLabelStatus, setAllLabelStatus } from '@/utils/earthMap/setLabelStatus';
import keyControlInit from '@/utils/earthMap/keyControlInit';
import createRealTimeObj from '@/utils/earthMap/createRealTimeObj';
import sceneTreePopContextMenu from '@/utils/earthMap/sceneTreePopContextMenu';
import { drawInit } from '@/utils/earthMap/earthDraw';
import { cloneModel, cloneShamNode } from '@/utils/earthMap/clone';
import {
initWebSocket,
websocketonopen,
websocketonerror,
loreadAlarmInfo,
websocketclose,
websocketonmessage,
websocketdosend,
websock,
} from '@/utils/earthMap/websocket';
import setIconByRef from '@/utils/earthMap/setIconByRef';
import dwPng from '@/assets/images/rotationXYZ.png';
import rotationXYZ from '@/assets/images/rotationXYZ.png';
import circleDot2 from '@/assets/earthMap/circleDot2.png';
import circleDot1 from '@/assets/earthMap/circleDot1.png';
import circleDot3 from '@/assets/earthMap/circleDot3.png';
import { nextTick } from 'vue';
const { createMessage } = useMessage();
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';
}
1 year ago
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,
ShowHideControl,
VideoSplitScreen,
VideoWindow,
WarnInfoList,
AddModelWin,
AddRoamVideo,
VideoFusionWin,
AISInfoDetail,
AISInfoWindow,
},
props: {
//全部显示
all: {
type: Boolean,
default: false,
},
//头部显示
earthHeaderShow: {
type: Boolean,
default: false,
},
//图层显示
sceneTreeShow: {
type: Boolean,
default: false,
},
//状态栏
statusBarShow: {
type: Boolean,
default: true,
},
//主工具栏
mainBar: {
type: Boolean,
default: false,
},
//监听事件
listenMouseHandlerOpen: {
type: Boolean,
default: false,
},
//监听mitt
listenMittHandlerOpen: {
type: Boolean,
default: false,
},
//地图路线资源
createBBHLineOpen: {
type: Boolean,
default: false,
},
//加载区域
getLineInfoShow: {
type: Boolean,
default: false,
},
//加载站点
getCameraInfoShow: {
type: Boolean,
default: false,
},
//加载微波和雷达
getLabelInfoShow: {
type: Boolean,
default: false,
},
//加载绘图
drawInitShow: {
type: Boolean,
default: false,
},
//加载重点监控区域
keyControlInitShow: {
type: Boolean,
default: false,
},
//后台场景管理点击
enablePointer: {
type: Boolean,
default: false,
},
//后台场景管理点击事件监听
listenMouseHandlerSenceOpen: {
type: Boolean,
default: false,
},
//后台区域管理事件
msMapLineHandler: {
type: Boolean,
default: false,
},
//后台监控点位管理事件
msCameraSiteHandle: {
type: Object,
default: null,
},
},
})
export default class EarthComp extends Vue {
/**
* 资源创建
*/
userStore = useUserStore();
store = useEarthMapStore();
setLabelStatus: any = setLabelStatus;
setIconByRef: any = setIconByRef;
earthTitle = '态势监控一张图';
realTime = '……';
// 注意:Earth和Cesium的相关变量放在vue中,必须使用下划线作为前缀!
// _earth = 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 = [];
1 year ago
//处理props 由于从父组件传来props,为作区分其他变量,则采用首字母大写命名
PropsEarthHeaderShow = this.earthHeaderShow;
PropsSceneTreeShow = this.sceneTreeShow;
PropsListenMouseHandlerOpen = this.listenMouseHandlerOpen;
PropsListenMittHandlerOpen = this.listenMittHandlerOpen;
PropsCreateBBHLineOpen = this.createBBHLineOpen;
PropsGetLineInfoShow = this.getLineInfoShow;
PropsGetCameraInfoShow = this.getCameraInfoShow;
PropsGetLabelInfoShow = this.getLabelInfoShow;
PropsDrawInitShow = this.drawInitShow;
PropsKeyControlInitShow = this.keyControlInitShow;
///////////////////////////////////////////////////////////////////////////
//AIS信息窗口显示
AISInfoWindowShow = false;
// 船只guid
ship_guid = '123456';
// 船只ais信息
ship_aisData = {};
// 添加地图上的鼠标监听事件
// pin: any = undefined;
// viewer: any = undefined;
// // 鼠标样式
// cursorCss = "grab";
// position: any = null;
// rotation: any = null;
// fov: any = null;
mounted() {
let that = this;
//随机数
window.guid = 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);
}
});
}
}
// 打开视频融合
roamPathSet() {
// 打开视频融合
this.VideoFusionWinShow = true;
// 关闭相机列表
this.cameraModalShow = false;
}
// 后台区域管理事件
areaHandler(){
// 取消双击旋转事件
window.$viewer.cesiumWidget.screenSpaceEventHandler.removeInputAction(
window.Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK
);
this.$nextTick(() => {
$mitt.emit('msMapLineHandler', this.msMapLineHandler);
})
}
// 后台监控点位管理事件
cameraSiteHandler(){
// 取消双击旋转事件
window.$viewer.cesiumWidget.screenSpaceEventHandler.removeInputAction(
window.Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK
);
this.$nextTick(() => {
$mitt.emit('msCameraSiteHandle', this.msCameraSiteHandle);
})
}
// 控制子元素的显示或者隐藏
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.store.nodeCheckedByRef.set(ref, parentChecked);
this.showOrHideChild(child, earthUI, parentChecked);
}
}
}
}
// 告警模型显示/隐藏
showAlarmPin(show) {
this.store.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;
//使用store存储XbsjEarthUI
this.store.xbsjEarthUI = XbsjEarthUI;
//处理props
if (this.all) {
this.PropsEarthHeaderShow = true;
this.PropsSceneTreeShow = true;
this.PropsListenMouseHandlerOpen = true;
this.PropsListenMittHandlerOpen = true;
this.PropsCreateBBHLineOpen = true;
this.PropsGetLineInfoShow = true;
this.PropsGetCameraInfoShow = true;
this.PropsGetLabelInfoShow = true;
this.PropsDrawInitShow = true;
this.PropsKeyControlInitShow = true;
}
//创建地球
XbsjEarthUI.create('earthContainer').then(async (earthUI: any) => {
// 设置全局变量,可调试
window.$uia = earthUI;
window.$earth = earthUI.earth;
window.$viewer = earthUI.earth.czm.viewer;
earthUI.controls.mainBar.show = false; //隐藏主工具栏
earthUI.controls.statusBar.show = true; //状态栏
//图层管理
let sceneTree = earthUI.tools.sceneTree;
// 显示图层管理
1 year ago
sceneTree.show = this.PropsSceneTreeShow;
// 设置图层管理 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 }) => {
sceneTreePopContextMenu({ item, vueObject }, earthUI, this);
};
earthUI.tools.featureProperty.disabled = true; //禁用对象属性面板
window.$earth = earthUI.earth;
window.$earth.interaction.picking.enabled = true; // 全局打开点击事件权限
window.$earth.czm.viewer.scene.globe.depthTestAgainstTerrain = true; //开启深度检测
window.$earth.terrainEffect.subSurfaceEnabled = false; //开启地表透明模式
// this._viewer = earthUI.earth.czm.viewer;
window.$viewer.scene.fxaa = true; //图像改善
window.$viewer.scene.globe.baseColor = window.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'];
window.$earth.sceneTree.root = {
expand: true,
title: '场景树',
children: [this.sceneTree],
};
// 监控相机数据
XE.MVVM.watch(window.$earth.camera, 'position', () => {
this.cameraPositionChange(this);
});
// 飞入方法
await this.fly();
//创建工具栏
this.toolbarShow = true;
//加载地图实时资源(无人机、车辆、人员、巡逻路线等)
// createRealTimeObj(earthUI)
//监听鼠标事件
if (this.PropsListenMouseHandlerOpen) listenMouseHandler(that);
//监听鼠标事件(场景管理)
if (this.listenMouseHandlerSenceOpen) listenMouseHandlerSence(this.enablePointer, this);
//监听mitt
if (this.PropsListenMittHandlerOpen) this.listenMittHandler();
//加载地图线路资源
if (this.PropsCreateBBHLineOpen) await this.createBBHLine();
//使用后台区域管理事件 绘制区域等操作
if (this.msMapLineHandler) this.areaHandler()
//使用后台监控点位管理事件 设置监控杆等操作
if (this.msCameraSiteHandle) this.cameraSiteHandler()
});
}
1 year ago
//飞入方法
async fly() {
if (this.$attrs.onCustomFly) {
// 如果外部传入了customFly方法则调用外部的
this.$emit('customFly');
return;
}
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) => {
1 year ago
//飞入 所属场景下的位置
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;
window.$earth.camera.flyTo(position, viewDistance, rotation, duration);
// 地图复原事件
window.$flyTo = this.flyTo = () => {
window.$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 = () => {
window.$viewer._container.style.cursor = 'pointer';
};
pin.onmouseout = () => {
window.$viewer._container.style.cursor = 'default';
};
pin.onclick = function () {
window.$earth.camera.flyTo(position, viewDistance, rotation, duration);
};
}
/* 使用async/await 处理异步方法顺序执行。成功的操作放到try里,失败的放在catch里 */
async createBBHLine() {
// console.log('MyScene', this.userStore.userInfo?.sceneId);
let labelItems: any = undefined;
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: [],
});
}
1 year ago
// console.log('models',models);
// 加载区域
// console.log("加载区域");
if (this.PropsGetLineInfoShow) await getLineInfo(models, type);
// 加载站点
// console.log("加载站点");
if (this.PropsGetCameraInfoShow) await getCameraInfo(models, type);
// 加载雷达和微波
// console.log("加载雷达和微波");
if (this.PropsGetLabelInfoShow) labelItems = await getLabelInfo(models, type);
//加载绘画资源
if (this.PropsDrawInitShow) await drawInit();
//加载重点监控区域
if (this.PropsKeyControlInitShow) 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.store.hostDeviceMapById.has(customProp.deviceId)) {
let device = that.store.hostDeviceMapById.get(customProp.deviceId);
// 设置状态
setLabelStatus(device, customProp.labelCode, child.ref, 2);
}
// 设置图标
setIconByRef(child.ref, eventTarget);
}
});
}
if (nodeObject.czmObject && nodeObject.czmObject.xbsjType == 'Pin') {
setIconByRef(ref, el);
}
// ref不为空并且大于0时 设置为input的id属性
if (ref && ref.length > 0) {
inputEl.id = ref;
}
// 首次展开添加元素默认为true,显示展示的对象
if (that.store.nodeCheckedByRef.size <= 0) {
// item.checkStatus = 'checked'
inputEl.checked = true;
//***设置样式为选中 */
setClassChecked(setClassEl1, setClassEl2, item);
that.store.nodeCheckedByRef.set(ref, true);
} else {
// 之后的展开根据ref获取应该显示的状态是选中还是非选中
let checked = that.store.nodeCheckedByRef.get(ref);
if (checked == undefined) {
checked = true;
if (ref && ref.length > 0 && ref.startsWith('node_')) {
// 分割ref
const refSplit = ref.split('_');
// 取出真实对象
const readyNode = window.$uia.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.store.nodeCheckedByRef.set(ref, checked);
setClassEl(setClassEl, setClassEl2, checked, item);
} else {
setClassEl(setClassEl, setClassEl2, checked, item);
}
}
// 显示隐藏样式监听
classMutationObserver(setClassEl1, setClassEl2, that.store.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 = window.$uia.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 = window.$uia.earth.sceneTree.$refs[refSplit[1]];
} else if (ref && ref.length > 0 && ref.startsWith('nodeSecondary_')) {
// 分割ref
const refSplit = ref.split('_');
// 取出真实对象
readyNode = window.$uia.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, window.$uia, 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.store.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 = () => {
window.$viewer._container.style.cursor = 'pointer';
};
window.$earth.sceneTree.$refs[itemId].czmObject.onmouseout = () => {
window.$viewer._container.style.cursor = 'default';
};
}
});
});
// 隐藏图层管理 "地图场景" 一栏
// document.getElementsByClassName('XbsjVritualTreeItem').item(0).style.display = 'none'
window.$earth.sceneTree.root.children.splice(1, 0, models);
}
listenMittHandler() {
let that = this;
{
$mitt.on('winShow', function (e: any) {
that.VideoFusionWinShow = e;
});
//其他页面调用本页面的methods方法
$mitt.on('listenMouseHandler', function () {
listenMouseHandler(that);
});
$mitt.on('removeHandler', function () {
that.removeHandler();
});
$mitt.on('createBBHLine', function () {
that.createBBHLine();
});
$mitt.on('createRealTimeObj', function () {
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('失败');
createMessage.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');
}
/**
* 保存更改的ref到模型和后台数据中;
* @param {Object} model 当前模型
* @param {string} newRef 新的ref
* @param {string} oldRef 旧的ref
*/
changeRef = _.debounce(function (model, newRef, oldRef) {
// 当数值改变时且旧值不等于空时,更新模型的ref
if (newRef !== oldRef && oldRef !== '') {
// 修改后台的数据
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;
createMessage.success('修改成功');
} else {
createMessage.error('修改失败: ' + res.message);
}
})
.catch((err) => {
createMessage.error('修改失败: ' + err);
});
})
.modelCallback(() => {
// 传感器标志线不能修改ref,因为 ref 是后台数据库的ID;
createMessage.warning('无法修改传感器标志线的ref');
})
.run();
}
}, 150);
radarAlarmTimeOutCheck() {
const now = Date.now();
const timeout = 5 * 60 * 1000;
// 遍历报警数据
this.store.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();
}
this.store.radarAlarmDataMap.delete(eventNum);
}
}
clearAlarmModel(eventNum) {
// let alarmInfoMap = this.store.alarmInfoMap;
// let radarAlarmDataMap = this.store.radarAlarmDataMap;
if (this.store.alarmInfoMap.has(eventNum)) {
let alarmData = this.store.alarmInfoMap.get(eventNum);
// 清除报警
alarmData.pin && alarmData.pin._div.remove();
alarmData.pin && alarmData.pin.destroy();
alarmData.scanline && alarmData.scanline.destroy();
this.store.alarmInfoMap.delete(eventNum);
}
this.clearRadarAlarmModel(this.store.radarAlarmDataMap, eventNum);
}
// 获取当前实时时间
getRealTime() {
this.timer2 = setInterval(() => {
this.realTime = getRealTime();
}, 1000);
}
// 资源销毁
beforeDestroy() {
// vue程序销毁时,需要清理相关资源
console.log('vue程序销毁');
window.$earth = window.$earth && window.$earth.destroy();
websocketclose(null);
//清除定时器
clearInterval(this.timer);
clearInterval(this.timer2);
clearInterval(this.alarmTrackClearTimer);
}
// 资源销毁
destroy() {
// vue程序销毁时,需要清理相关资源
console.log('vue程序销毁', window.$earth);
// websocketclose();
//清除定时器
clearInterval(this.timer);
clearInterval(this.timer2);
clearInterval(this.alarmTrackClearTimer);
// window.$uia.tools.sceneTree.destroy()
// window.$earth = window.$earth && window.$earth.destroy();
//利用store.xbsjEarthUI 重新赋值 window.XbsjEarthUI
window.XbsjEarthUI = this.store.xbsjEarthUI;
window.$earth = undefined;
}
}
</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>