<!-- * @Description: 管网分布专题 * @Author: 王晓颖 * @Date: 2021-04-13 --> <template> <layout-map> <!--地图--> <Map :url="configUrl" @onload="onMapload" /> <!--地图切换按钮--> <div class="map-btn-group"> <select-button :select="routeShow" name="巡检人员" icon="icon-people" @click="showRoute(routeShow)"/> <select-button :select="station2Show" name="站场" icon="icon-station2" @click="showStation2(station2Show)"/> <select-button :select="valveChamberShow" name="阀室" icon="valve" @click="showValveChamber(valveChamberShow)"/> <select-button :select="liquidFactoryShow" name="液化工厂" icon="icon-liquidFactory" @click="showLiquidFactory(liquidFactoryShow)"/> <select-button :select="hcaShow" name="高后果区" icon="icon-heat" @click="showHca(hcaShow)"/> <select-button :select="constructionThreatShow" name="第三方施工" icon="icon-construction" @click="showConstructionThreat(constructionThreatShow)"/> <select-button :select="sinkThreatShow" name="塌陷隐患" icon="icon-sink" @click="showSinkThreat(sinkThreatShow)"/> <select-button :select="waterThreatShow" name="水保隐患" icon="icon-water" @click="showWaterThreat(waterThreatShow)"/> <select-button :select="disasterShow" name="气象预警" icon="icon-disaster" @click="showDisaster(disasterShow)"/> <select-button :select="earthquakeShow" name="地震分布" icon="icon-earthquake" @click="showEarthquake(earthquakeShow)"/> <!--<select-button :select="cameraShow" name="监控分布" icon="icon-camera" @click="showCamera(cameraShow)"/>--> </div> <threat-dialog ref="threatDialog"/> <high-consequence-dialog ref="hcaDialog"/> </layout-map> </template> <script> import Map from '@/components/Map/MarsMap.vue' import 'mars3d-heatmap' import axios from 'axios' import SelectButton from '@/components/SelectTool/components/selectButton' import LayoutMap from '../../layout/layoutMap' import ThreatDialog from './components/threatDialog' import HighConsequenceDialog from './components/highConsequenceDialog' import { getDisasterList } from '@/api/weather' import { getEarthquakeList, getRoutesData } from '@/api/pipe' import { getHighConsequence } from '@/api/hca' import { getToday } from '@/utils/dateutils' export default { name: 'PipeOverview', components: { HighConsequenceDialog, ThreatDialog, LayoutMap, Map, SelectButton }, data() { return { map: null, // 地图 configUrl: 'static/config/config.json', alpha: 100, // 透明度 underground: null, // ? routeShow: true, // 显示巡检人员 station2Show: false, // 站场 valveChamberShow: false, // 阀室 liquidFactoryShow: false, // 液化工厂 hcaShow: false, // 显示高后果区 stationShow: true, // 显示管理处 waterThreatShow: false, // 显示水保隐患位置 constructionThreatShow: false, // 显示第三方施工位置 sinkThreatShow: false, // 显示塌陷隐患位置 disasterShow: false, // 显示气象灾害图层 earthquakeShow: false, cameraShow: false, boardData: { name: '巡检人员', value: 6 }, // 统计版展示数据 disaster: { '台风': '01', '暴雨': '02', '暴雪': '03', '寒潮': '04', '大风': '05', '沙尘暴': '06', '高温': '07', '干旱': '08', '雷电': '09', '冰雹': '10', '霜冻': '11', '大雾': '12', '霾': '13', '道路结冰': '14' }, // 灾害与数字对应表 disasterLevel: { '蓝色': '01', '黄色': '02', '橙色': '03', '红色': '04' }, // 灾害等级与数字对应表 manageStations: [], station2: [], // 站场列表 valveChambers: [], // 阀室 liquidFactory: [], // 液化工厂 routeData: [], // 巡检人员数据 highConsequence: [], // 高后果区列表 constructionThreatArea: [], // 第三方施工隐患列表 waterThreatArea: [], // 水保隐患列表 sinkThreatArea: [], // 塌陷列表 stationLayer: null, // 管理站图层 hcaLayer: null, // 高后果区图层 constructionThreatLayer: null, // 第三方施工分布图层 waterThreatLayer: null, // 水保隐患分布图层 sinkThreatLayer: null, // 塌陷隐患分布图层 factoryModelLayer: null, // 液化工厂 station2Layer: null, // 站场 valveChamberLayer: null, // 阀室 disasterLayer: null, // 气象灾害图层 earthquakeLayer: null, // 地震图层 cameraLayer: null, // 监控图层 pointColorArr: ['#f33349', '#f79a2c', '#f2fa19', '#95e40c', '#1ffee6'], routeLayer: null, // 巡检图层 timer: null, // 轮训定时器 clock: 86400 // 间隔时间 } }, methods: { // 地图构造完成回调 onMapload(map) { // 以下为演示代码 this.map = map // 背景透明 this.map._viewer.scene.backgroundColor = new this.Cesium.Color(0.0, 0.0, 0.0, 0.0) this.map._viewer.scene.globe.baseColor.alpha = 0 // this.addHcaPosition() // 添加管理处 // this.addStation() this.addRoute() // this.addCamera() // this.addEarthquake() // this.addFactoryModel() // this.addStation2() // this.addValveChamber() // this.addStationDiv() // 添加水保隐患隐患点 // this.addWaterThreatPosition() this.refreshData() }, // 添加巡线人员位置 addRoute() { const { mars3d, Cesium } = this if (this.routeLayer) { this.map.removeLayer(this.routeLayer) } // 创建DIV数据图层 var graphicLayer = new mars3d.layer.DivLayer() this.routeLayer = graphicLayer this.map.addLayer(graphicLayer) graphicLayer.on(mars3d.EventType.click, event => { console.log('监听layer,单击了矢量对象', event) }) graphicLayer.bindPopup(event => { const route = event.graphic.attr const html = '<div>姓名:' + route.name + '<br/>电话:' + route['phone'] + '<br/>岗位:' + route['duty'] + '<br/>站名:' + route['unitname'] + '<br/>时间:' + route.locationdate + '</div>' return html }) const date = getToday() getRoutesData(date).then((res) => { if (res.status === 200) { const data = res.data.map(item => { return { name: item['WD60_03'], lng: parseFloat(item['WD60_05']), lat: parseFloat(item['WD60_06']), locationdate: item['WD60_04'], time: new Date(item['WD60_04']), duty: item['WD60_11'], sex: item['WD60_09'], phone: item['WD60_10'], idcard: item['WD60_12'], unitname: item['WD60_08'] } }) this.routeData = [] // 遍历所有数据,去除重复数据 for (const route of data) { // 去routeData里查找是否有同一个人 const result = this.routeData.findIndex(item => item.name == route.name && item.phone == route.phone) if (result === -1) { // 查找不到直接添加 this.routeData.push(route) } else { // 查找到,对比时间,时间大则替换 if (this.routeData[result].time < route.time) { this.routeData.splice(result, 1, route) } } } this.boardData.value = this.routeData.length for (const route of this.routeData) { const graphic = new mars3d.graphic.DivGraphic({ position: [route.lng, route.lat, 10], style: { html: '<img src="static/images/map/pe02.gif" style="width:20px;height:20px;" ></img>', distanceDisplayCondition: new Cesium.DistanceDisplayCondition(0, 2000000), // 按视距距离显示 horizontalOrigin: Cesium.HorizontalOrigin.CENTER, verticalOrigin: Cesium.VerticalOrigin.CENTER, attr: route }, attr: route, pointerEvents: true // false时不允许拾取和触发任意鼠标事件,但可以穿透div缩放地球 }) graphicLayer.addGraphic(graphic) } } }) }, // 高后果区位置 addHcaPosition() { const { mars3d } = this if (this.hcaLayer) { this.map.removeLayer(this.hcaLayer) } // 创建DIV数据图层 var graphicLayer = new mars3d.layer.DivLayer() this.hcaLayer = graphicLayer this.map.addLayer(graphicLayer) graphicLayer.on(mars3d.EventType.click, event => { console.log('监听layer,单击了矢量对象', event) this.$refs.hcaDialog.initDialog(event.graphic.attr) }) getHighConsequence().then(res => { let data = res.data.filter(item => item['DES02'] !== '无') data = data.map(item => { return { '高后果区编号': item['DES07'], '经度': parseFloat(item['DES02']), '纬度': parseFloat(item['DES03']), '位置描述': item['DES05'], '行政区域': item['DES09'], '地区级别': item['DES10'], '高后果区特征描述': item['DES11'], '机构名称': item['DES12'], '高后果区长度': item['DES08'], '识别时间': item['WD01_03'], '高后果区级别': item['WD02_04'], '所属管理处': item['DES01'], '影响人数范围': item['WD58_03'], '识别单位及负责人': item['DES04'] } }) this.highConsequence = data.filter(item => item['高后果区级别'] !== '无') this.boardData.value = this.highConsequence.length this.addFeatures(graphicLayer, this.highConsequence, 'hca', '#f79a2c') }) }, // 水保隐患位置 addWaterThreatPosition() { const { mars3d } = this // 创建DIV数据图层 var graphicLayer = new mars3d.layer.DivLayer() this.waterThreatLayer = graphicLayer graphicLayer.on(mars3d.EventType.click, event => { console.log('监听layer,单击了矢量对象', event) this.$refs.threatDialog.initDialog(event.graphic.attr) }) this.map.addLayer(graphicLayer) axios.get('static/config/waterThreat.json').then((res) => { res = res.data if (res.code === 200) { // 过滤掉经度为null的 this.waterThreatArea = res.data.filter(item => item['经度'] !== null) this.addFeatures(graphicLayer, this.waterThreatArea, 'waterThreat', '#1ffee6') } }) }, // 第三方施工隐患位置 addConstructionThreatPosition() { const { mars3d } = this // 创建DIV数据图层 var graphicLayer = new mars3d.layer.DivLayer() this.constructionThreatLayer = graphicLayer graphicLayer.on(mars3d.EventType.click, event => { console.log('监听layer,单击了矢量对象', event) this.$refs.threatDialog.initDialog(event.graphic.attr) }) this.map.addLayer(graphicLayer) axios.get('static/config/threat.json').then((res) => { res = res.data if (res.code === 200) { // 过滤掉经度为null的 this.constructionThreatArea = res.data.filter(item => item['经度'] !== null) this.addFeatures(graphicLayer, this.constructionThreatArea, 'construction', '#fbfe2d') } }) }, // 塌陷隐患位置 addSinkThreatPosition() { const { mars3d } = this // 创建DIV数据图层 var graphicLayer = new mars3d.layer.DivLayer() this.sinkThreatLayer = graphicLayer this.map.addLayer(graphicLayer) graphicLayer.on(mars3d.EventType.click, event => { console.log('监听layer,单击了矢量对象', event) this.$refs.threatDialog.initDialog(event.graphic.attr) }) axios.get('static/config/sinkThreat.json').then((res) => { res = res.data if (res.code === 200) { // 过滤掉经度为null的 this.sinkThreatArea = res.data.filter(item => item['经度'] !== null) this.addFeatures(graphicLayer, this.sinkThreatArea, 'sinkThreat', '#2c06a1') } }) }, // 添加隐患点: type类型,arr数组, clr颜色 addFeatures(graphicLayer, arr, type, clr) { const { mars3d, Cesium } = this // 创建DIV数据图层\ for (var i = 0, len = arr.length; i < len; i++) { const item = arr[i] var jd = item['经度'] var wd = item['纬度'] var graphic = new mars3d.graphic.DivGraphic({ position: Cesium.Cartesian3.fromDegrees(jd, wd, 0), style: { html: '<div class="mars3d-animation-point" style="color:' + clr + ';"><p></p></div>', distanceDisplayCondition: new Cesium.DistanceDisplayCondition(0, 2000000) // 按视距距离显示 }, attr: item }) graphicLayer.addGraphic(graphic) } }, // 管理处 addStation() { const { mars3d } = this var graphicLayer = new mars3d.layer.GraphicLayer() this.stationLayer = graphicLayer this.map.addLayer(graphicLayer) axios.get('static/config/manageStation.json').then((res) => { res = res.data if (res.code === 200) { this.manageStations = res.data for (const station of this.manageStations) { const graphic = new mars3d.graphic.ModelEntity({ name: station.name, position: [station.x, station.y, 0], style: { url: 'static/gltf/output/guanlizhan.gltf', scale: 5, heading: 90, minimumPixelSize: 30 }, tooltip: station.name }) graphicLayer.addGraphic(graphic) } } }) }, // 站场 addStation2() { const { mars3d } = this var graphicLayer = new mars3d.layer.GraphicLayer() this.station2Layer = graphicLayer this.map.addLayer(graphicLayer) axios.get('static/config/station.json').then((res) => { res = res.data if (res.code === 200) { this.station2 = res.data for (const station of this.station2) { const graphic = new mars3d.graphic.ModelEntity({ name: station.name, position: [station.x, station.y, 0], style: { url: 'static/gltf/output/zhanchang.gltf', scale: 5, heading: 90, minimumPixelSize: 30 }, tooltip: station.name }) graphicLayer.addGraphic(graphic) } } }) }, // 阀室 addValveChamber() { const { mars3d } = this var graphicLayer = new mars3d.layer.GraphicLayer() this.valveChamberLayer = graphicLayer this.map.addLayer(graphicLayer) axios.get('static/config/valveChamber.json').then((res) => { res = res.data if (res.code === 200) { this.valveChambers = res.data for (const station of this.valveChambers) { const graphic = new mars3d.graphic.ModelEntity({ name: station.name, position: [station.x, station.y, 0], style: { url: 'static/gltf/output/fashi.gltf', scale: 4, heading: 0, minimumPixelSize: 15 }, tooltip: station.name }) graphicLayer.addGraphic(graphic) } } }) }, // 液化工厂三维模型 addFactoryModel() { const { mars3d } = this axios.get('static/config/liquidFactory.json').then((res) => { res = res.data if (res.code === 200) { // 获取液化工厂数据 this.liquidFactory = res.data[0].data const factoryModelLayer = new mars3d.layer.ModelLayer({ name: '液化工厂', url: 'static/gltf/output/yehuagongchang.gltf', style: { scale: 3, heading: 0, minimumPixelSize: 30, clampToGround: true }, positions: this.liquidFactory.map(item => { return { lng: parseFloat(item.value[0]), lat: parseFloat(item.value[1]), alt: 0 } }) }) this.factoryModelLayer = factoryModelLayer this.map.addLayer(factoryModelLayer) } }) }, // 显示气象灾害分布 addDisaster() { const { mars3d, Cesium } = this if (this.disasterLayer) { this.map.removeLayer(this.disasterLayer) } const graphicLayer = new mars3d.layer.GraphicLayer() this.disasterLayer = graphicLayer this.map.addLayer(graphicLayer) const date = getToday() getDisasterList(date).then((res) => { if (res.data.length === 0) { this.$message.info('今日无预警') } else { let data = res.data.map(item => { return { name: item['WD52_03'].trim(), lng: parseFloat(item['WD52_06'].trim()), lat: parseFloat(item['WD52_05'].trim()), value: item['WD52_08'].trim(), zhlx: item['WD52_12'].trim(), zhdj: item['WD52_13'].trim() } }) data = data.filter(item => item.lng != null) for (const item of data) { const img = 'static/images/weather_disaster/' + this.disaster[item.zhlx] + this.disasterLevel[item.zhdj] + '.png' const graphic = new mars3d.graphic.BillboardEntity({ name: '气象灾害', position: [item.lng, item.lat, 100], style: { image: img, pixelOffsetX: 0, pixelOffsetY: -20, scale: 0.5, horizontalOrigin: Cesium.HorizontalOrigin.CENTER, verticalOrigin: Cesium.VerticalOrigin.BOTTOM } }) var html = ` <div class="popup-win"><span class="title">${item.name}</span><br/> <div style="color:#FFB861">预警:${item.zhlx}${item.zhdj}</div> <div style="color:#63AEFF">时间:${item.value}</div> </div>` graphic.bindTooltip(html, { anchor: [0, -20] }).openTooltip() graphicLayer.addGraphic(graphic) } } }) }, // 添加地震 addEarthquake() { const { mars3d, Cesium } = this if (this.earthquakeLayer) { this.map.removeLayer(this.earthquakeLayer) } const graphicLayer = new mars3d.layer.GraphicLayer() this.earthquakeLayer = graphicLayer this.map.addLayer(graphicLayer) const date = getToday() getEarthquakeList(date).then((res) => { if (res.data.length === 0) { this.$message.info('今日无地震') } else { const data = res.data.map(item => { return { name: item['WD53_09'], lng: parseFloat(item['WD53_05'].trim()), lat: parseFloat(item['WD53_06'].trim()), level: item['WD53_07'].trim(), deep: item['WD53_08'].trim(), time: item['WD53_04'].trim() } }) for (const item of data) { const img = 'static/images/map/earthquake.png' const graphic = new mars3d.graphic.BillboardEntity({ name: '地震', position: [item.lng, item.lat, 0], style: { image: img, width: 70, height: 70, scale: 0.5, clampToGround: true, horizontalOrigin: Cesium.HorizontalOrigin.CENTER, verticalOrigin: Cesium.VerticalOrigin.BOTTOM } }) var html = ` <div class="popup-win"><span class="title">${item.name}</span><br/> <div style="color:#FFB861">震级:${item.level} 级</div> <div style="color:#FFB861">震源深度:${item.deep} km</div> <div style="color:#63AEFF">时间:${item.time}</div> </div>` graphic.bindTooltip(html, { anchor: [0, -20] }).openTooltip() graphicLayer.addGraphic(graphic) } } }) }, // 添加视频 addCamera() { const { mars3d, Cesium } = this const graphicLayer = new mars3d.layer.GraphicLayer() this.cameraLayer = graphicLayer this.map.addLayer(graphicLayer) getDisasterList().then((res) => { const data = res.data for (const item of data) { const img = 'static/images/map/camera.png' const graphic = new mars3d.graphic.BillboardEntity({ name: '监控点', position: new mars3d.LatLngPoint(item.lng, item.lat, 0), style: { image: img, width: 70, height: 70, // hasPixelOffset: true, // pixelOffsetX: 100, // pixelOffsetY: -50, scale: 0.5, clampToGround: true, horizontalOrigin: Cesium.HorizontalOrigin.CENTER, verticalOrigin: Cesium.VerticalOrigin.BOTTOM } }) graphicLayer.addGraphic(graphic) } }) }, // 是否显示高后果区 showHca(show) { // 现在正在显示 if (show) { // 移除 this.hcaShow = false this.map.removeLayer(this.hcaLayer, true) } else { this.hcaShow = true this.addHcaPosition() } }, // 是否显示水保隐患 showWaterThreat(show) { // 现在正在显示 if (show) { // 移除 this.waterThreatShow = false this.map.removeLayer(this.waterThreatLayer, true) } else { this.waterThreatShow = true this.addWaterThreatPosition() } }, // 是否显示第三方施工 showConstructionThreat(show) { // 现在正在显示 if (show) { // 移除 this.constructionThreatShow = false this.map.removeLayer(this.constructionThreatLayer, true) } else { this.constructionThreatShow = true this.addConstructionThreatPosition() } }, // 是否显示塌陷 showSinkThreat(show) { // 现在正在显示 if (show) { // 移除 this.sinkThreatShow = false this.map.removeLayer(this.sinkThreatLayer, true) } else { this.sinkThreatShow = true this.addSinkThreatPosition() } }, // 显示管理处 showStation(show) { // 现在正在显示 if (show) { // 移除 this.stationShow = false this.map.removeLayer(this.stationLayer, true) this.stationLayer = null // this.map.removeLayer(this.graphicLayer, true) } else { this.stationShow = true this.addStation() // this.addStationDiv() } }, // 显示巡检人员 showRoute(show) { if (show) { // 移除 this.routeShow = false this.map.removeLayer(this.routeLayer, true) this.routeLayer = null } else { this.routeShow = true this.addRoute() } }, // 显示站场 showStation2(show) { if (show) { // 移除 this.station2Show = false this.map.removeLayer(this.station2Layer, true) this.station2Layer = null } else { this.station2Show = true this.addStation2() } }, // 显示阀室 showValveChamber(show) { if (show) { // 移除 this.valveChamberShow = false this.map.removeLayer(this.valveChamberLayer, true) this.valveChamberLayer = null } else { this.valveChamberShow = true this.addValveChamber() } }, // 显示液化工厂 showLiquidFactory(show) { if (show) { // 移除 this.liquidFactoryShow = false this.map.removeLayer(this.factoryModelLayer, true) this.factoryModelLayer = null } else { this.liquidFactoryShow = true this.addFactoryModel() } }, // 灾害 showDisaster(show) { if (show) { // 移除 this.disasterShow = false this.map.removeLayer(this.disasterLayer, true) this.disasterLayer = null } else { this.disasterShow = true this.addDisaster() } }, // 显示地震 showEarthquake(show) { if (show) { // 移除 this.earthquakeShow = false this.map.removeLayer(this.earthquakeLayer, true) this.earthquakeLayer = null } else { this.earthquakeShow = true this.addEarthquake() } }, // 显示摄像头 showCamera(show) { console.log('func showCamera:' + show) if (show) { // 移除 this.cameraShow = false this.map.removeLayer(this.cameraLayer, true) } else { this.cameraShow = true this.addCamera() } console.log('func showCamera over:' + this.cameraShow) }, refreshData() { this.timer = setInterval(() => { console.log('refreshData') if (this.routeLayer) { this.addRoute() } if (this.earthquakeLayer) { this.this.addEarthquake() } if (this.disasterLayer) { this.addDisaster() } if (this.hcaLayer) { this.addHcaPosition() } }, this.clock * 1000) } } } </script> <style rel="stylesheet/scss" lang="scss" scoped> .label-div{ position: absolute; top: 140px; left:31rem; z-index:100; color: white; padding:2rem 3rem 1.5rem 3rem; background-image: url("../../assets/button_images/board-box1.png"); background-size: 100% 100%; .label{ margin-bottom: 1rem; font-size:1.2rem; } .value{ font-family: DS-DigitalBold; font-size:2.5rem; } } .map-btn-group{ position: absolute; bottom:3rem; left:50%; transform: translateX(-50%); display: flex; justify-content: center; } </style>