<!-- * @Description: 水保隐患专题 * @Author: 王晓颖 * @Date: 2021-04-07 --> <template> <layout-map> <!--选择区--> <!--<select-all-construction @change="selectChange" />--> <!--<!–统计结果显示–>--> <!--<div class="label-div">--> <!--<div class="label">--> <!--{{ boardData.name | boardNameFilter }}--> <!--</div>--> <!--<div class="value">--> <!--{{ boardData.value }}--> <!--</div>--> <!--</div>--> <!--地图--> <Map :url="configUrl" @onload="onMapload" /> <div class="map-btn-group"> <!--<select-button :select="heatShow" name="热力图" icon="icon-heat" @click="showHeat(heatShow)"/>--> <select-button :select="positionShow" name="点位分布" icon="icon-position" @click="showPosition(positionShow)"/> <select-button :select="stationShow" name="管理处" icon="icon-station" @click="showStation(stationShow)"/> </div> </layout-map> </template> <script> import Map from '@/components/Map/MarsMap.vue' import 'mars3d-heatmap' import axios from 'axios' import SelectAllConstruction from './components/selectAllConstruction' import SelectButton from '@/components/SelectTool/components/selectButton' import { getTimes } from '@/utils/dateutils' import LayoutMap from '@/layout/layoutMap' import { getWaterThreat } from '@/api/threat' export default { name: 'WaterThreat', components: { LayoutMap, SelectAllConstruction, Map, SelectButton }, filters: { boardNameFilter(val) { if (val === '全部' || val === '') { return '全省水保隐患' } else { return val + '区域水保隐患' } } }, data() { return { map: null, // 地图 configUrl: 'static/config/config.json', alpha: 100, // 透明度 underground: null, // ? heatShow: false, // 显示热力图 stationShow: true, // 显示管理处 positionShow: true, // 显示位置 boardData: { name: '全部', value: 196 }, // 统计版展示数据 threatLevel: { '1': 'A级', '2': 'B级', '3': 'C级', '4': '问题' }, // 隐患等级 manageStations: [ { 'x': 112.73874, 'y': 37.693689, 'z': 0, 'name': '晋中管理处' }, { 'x': 111.121552, 'y': 37.5245, 'z': 0, 'name': '吕梁管理处' }, { 'x': 112.929902, 'y': 39.622888, 'z': 0, 'name': '同朔管理处' }, { 'x': 112.72496, 'y': 38.415485, 'z': 0, 'name': '忻州管理处' }, { 'x': 113.58249, 'y': 37.851892, 'z': 0, 'name': '阳泉管理处' }, { 'x': 110.980927, 'y': 35.010828, 'z': 0, 'name': '运城管理处' }, { 'x': 113.038394, 'y': 35.850111, 'z': 0, 'name': '长晋管理处' }, { 'x': 111.491467, 'y': 36.064572, 'z': 0, 'name': '临汾管理处' } ], threatAreaStation: [ { x: 112.73874, y: 37.693689, id: 0, name: '晋中管理处', count: 158 }, { x: 111.121552, y: 37.5245, id: 0, name: '吕梁管理处', count: 10 }, { x: 112.929902, y: 39.622888, id: 0, name: '同朔管理处', count: 44 }, { x: 112.72496, y: 38.415485, id: 0, name: '忻州管理处', count: 9 }, { x: 113.58249, y: 37.851892, id: 0, name: '阳泉管理处', count: 21 }, { x: 110.980927, y: 35.010828, id: 0, name: '运城管理处', count: 21 }, { x: 113.038394, y: 35.850111, id: 0, name: '长晋管理处', count: 11 }, { x: 111.491467, y: 36.064572, id: 0, name: '临汾管理处', count: 30 } ], threatArea: [], // 第三方隐患列表 stationLayer: null, // 管理站图层 heatLayer: null, // 水保隐患热力图 threatLayer: null, // 水保隐患分布图层 pointColorArr: ['#f33349', '#f79a2c', '#f2fa19', '#95e40c', '#1ffee6'], graphicLayer: null // 管理站标签图层 } }, 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.addWaterHeat() // 添加管理处 this.addStation() this.addStationDiv() // 添加水保隐患隐患点 this.addThreatPosition() }, // 高后果区热力图 addWaterHeat() { const { mars3d } = this getWaterThreat().then((res) => { let data = res.data.filter(item => item['DES02'] !== '无') data = data.map(item => { return { '经度': parseFloat(item['DES08']), '纬度': parseFloat(item['DES09']), '位置描述': item['DES02'], '村庄地址': item['DES03'], '发现人': item['DES04'], '隐患描述': item['DES05'], '业主单位': item['DES06'], '隐患类型': item['DES01'], '隐患发现时间': item['WD01_03'], '创建时间': item['DES07'], '隐患级别': item['WD54_03'], '所属管理处': item['DES10'], '状态': item['WD56_03'] } }) // 过滤掉经度为null的 this.threatArea = data.filter(item => item['经度'] !== null) this.boardData.value = this.threatArea.length const heatLayer = new mars3d.layer.HeatLayer({ positions: this.threatArea.map(item => { return { lng: item['经度'], lat: item['纬度'], value: 1 } }), heatStyle: { radius: 30, // 半径 blur: 1 // 模糊因子 }, // 以下为矩形矢量对象的样式参数 style: { opacity: 0.8, clampToGround: false, height: 10000 }, redrawZoom: true, flyTo: false }) this.heatLayer = heatLayer this.map.addLayer(heatLayer) }) }, // 水保隐患位置 addThreatPosition() { getWaterThreat().then((res) => { let data = res.data data = data.map(item => { return { '经度': parseFloat(item['DES08']), '纬度': parseFloat(item['DES09']), '位置描述': item['DES02'], '村庄地址': item['DES03'], '发现人': item['DES04'], '隐患描述': item['DES05'], '业主单位': item['DES06'], '隐患类型': item['DES01'], '隐患发现时间': item['WD01_03'], '创建时间': item['DES07'], '隐患级别': item['WD54_03'], '所属管理处': item['DES10'], '状态': item['WD56_03'] } }) debugger this.threatArea = data.filter(item => item['经度'] !== null) this.boardData.value = this.threatArea.length this.addFeatures(this.threatArea) }) }, // 添加隐患点 addFeatures(arr) { const { mars3d, Cesium, threatLevel } = this // 创建DIV数据图层 var graphicLayer = new mars3d.layer.DivLayer() this.threatLayer = graphicLayer this.map.addLayer(graphicLayer) // 在layer上绑定监听事件 graphicLayer.on(mars3d.EventType.click, function(event) { console.log('监听layer,单击了矢量对象', event) }) graphicLayer.bindPopup(function(event) { const item = event.graphic.attr var html = '位置描述:' + item['位置描述'] + '<br />村庄地址:' + item['村庄地址'] + '<br />发现人:' + item['发现人'] + '<br />隐患描述:' + item['隐患描述'] + '<br />创建时间:' + item['创建时间'] + '<br />隐患等级:' + threatLevel[item['隐患等级']] return html }) for (var i = 0, len = arr.length; i < len; i++) { const item = arr[i] var jd = item['经度'] var wd = item['纬度'] const level = parseInt(item['隐患等级']) - 1 var clr = this.pointColorArr[level] 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 const stationLayer = new mars3d.layer.ModelLayer({ name: '管理处', url: './static/gltf/output/guanlizhan.gltf', // url: './static/gltf/house02.gltf', style: { scale: 10, heading: 0, minimumPixelSize: 30, clampToGround: true }, positions: this.manageStations.map(item => { return { lng: item.x, lat: item.y, alt: 0 } }) }) this.stationLayer = stationLayer this.map.addLayer(stationLayer) }, // 选框发生变化 selectChange({ area, state, time, level }) { area = area === '全部' ? '' : area time = time === '全部' ? '' : time level = level === '全部' ? '' : level // 解析时间 let beginTime = '' let endTime = '' if (time) { const result = getTimes(time) beginTime = result.beginDate endTime = result.endDate } this.boardData.name = area // 查询数据 let count = 0 debugger for (const hca of this.threatArea) { let flag = true // 标记是否合格 // 比较区域 if (area && hca['所属管理处'] && hca['所属管理处'].indexOf(area) === -1) { flag = false } // 比较时间 if (time) { const real_date = new Date(hca['识别时间']) if (real_date && (real_date < beginTime || real_date > endTime)) { flag = false } } // 比较级别 if (level && hca['隐患等级'] && hca['隐患等级'] === level) { flag = false } if (flag) { count++ } } this.boardData.value = count }, // 自定义的弹窗 addStationDiv() { const { Cesium, mars3d } = this const graphicLayer = new mars3d.layer.GraphicLayer() this.graphicLayer = graphicLayer this.map.addLayer(graphicLayer) for (const station of this.threatAreaStation) { var graphic = new mars3d.graphic.DivGraphic({ position: Cesium.Cartesian3.fromDegrees(station.x, station.y, 10100), style: { html: `<div class="divpoint divpoint-theme-29baf1"> <div class="divpoint-wrap"> <div class="area"> <div class="arrow-lt"></div> <div class="b-t"></div> <div class="b-r"></div> <div class="b-b"></div> <div class="b-l"></div> <div class="arrow-rb"></div> <div class="label-wrap"> <div class="title">${station.name}</div> <div class="label-content"> <div class="data-li"> <div class="data-label">水保隐患数量:</div> <div class="data-value"><span class="label-num">${station.count}</span><span class="label-unit">个</span> </div> </div> <div class="data-li"> <div class="data-label">经度:</div> <div class="data-value"><span class="label-num">${station.x}</span> </div> </div> <div class="data-li"> <div class="data-label">纬度:</div> <div class="data-value"><span class="label-num">${station.y}</span> </div> </div> `, // anchor: [0, 0], horizontalOrigin: Cesium.HorizontalOrigin.LEFT, verticalOrigin: Cesium.VerticalOrigin.BOTTOM, distanceDisplayCondition: new Cesium.DistanceDisplayCondition(10000, 500000), // 按视距距离显示 scaleByDistance: new Cesium.NearFarScalar(10000, 1.0, 500000, 0.1), clampToGround: true, heightReference: Cesium.HeightReference.CLAMP_TO_GROUND }, pointerEvents: false // false时不允许拾取和触发任意鼠标事件,但可以穿透div缩放地球 }) graphicLayer.addGraphic(graphic) graphic.testPoint = false // 打开测试点,与DIV点进行对比位置调整css } }, // 是否显示热力图 showHeat(show) { // 现在正在显示 if (show) { // 移除 this.heatShow = false this.map.removeLayer(this.heatLayer, true) } else { this.heatShow = true this.addWaterHeat() } }, // 显示管理处 showStation(show) { // 现在正在显示 if (show) { // 移除 this.stationShow = false this.map.removeLayer(this.stationLayer, true) this.map.removeLayer(this.graphicLayer, true) } else { this.stationShow = true this.addStation() this.addStationDiv() } }, // 显示隐患分布 showPosition(show) { if (show) { // 移除 this.positionShow = false this.map.removeLayer(this.threatLayer, true) } else { this.positionShow = true this.addThreatPosition() } } } } </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>