<!-- * @Description: 综合业务 * @Author: 王晓颖 * @Date: 2021-04-08 --> <template> <layout-map> <!--地图--> <Map :url="configUrl" @onload="onMapload" /> <!--下方图层选择按钮--> <div class="map-btn-group"> <select-button :select="areaNeedSupplyShow" name="区域供需情况" icon="icon-supply" @click="showAreaSupplyNeed(areaNeedSupplyShow)"/> <select-button :select="factoryStorageShow" name="液化工厂储量" icon="icon-liquidFactory" @click="showFactoryStorage(factoryStorageShow)"/> <select-button :select="stationStorageShow" name="加气站储量" icon="icon-gasStation" @click="showStationStorage(stationStorageShow)"/> <select-button :select="factoryShow" name="液化工厂加气站分布" icon="icon-position" @click="showPosition(factoryShow)"/> </div> <!--PNG,LNG选择按钮--> <div v-show="areaNeedSupplyShow" class="select-btns-gas"> <button1 :selected="type=='all'" @click.native="changeType('all')">全部</button1> <button1 :selected="type=='png'" @click.native="changeType('png')">PNG</button1> <button1 :selected="type=='lng'" @click.native="changeType('lng')">LNG</button1> </div> <!--遮罩--> </layout-map> </template> <script> import Map from '@/components/Map/MarsMap.vue' import 'mars3d-echarts' import axios from 'axios' import SelectButton from '@/components/SelectTool/components/selectButton' import LayoutMap from '@/layout/layoutMap' import { getAreaSupply } from '@/api/needSupply' import { getIndex } from '@/utils/mathUtils' import Button1 from '@/components/Button/button1' export default { name: 'StorageTopic', components: { Button1, LayoutMap, Map, SelectButton }, filters: { liquidNameFilter(val) { return val + '液化工厂' }, gasNameFilter(val) { return val + '加气站' } }, data() { return { map: null, // 地图 configUrl: 'static/config/config.json', underground: null, // ? index: null, // 供需放大倍数 storageIndex: null, // 储量放大倍数 type: 'all', // 全部,LNG,PNG colorList: ['#d75111', '#d75111', '#d75111', '#fcaf17', '#fcaf17', '#fcaf17', '#4fffc3', '#4fffc3', '#4fffc3', '#39c53d', '#39c53d'], // 柱子颜色 areaNeedSupplyShow: true, // 区域供需显示 factoryShow: false, // 显示液化工厂 // gasStationShow: false, // 显示加气站 factoryStorageShow: false, // 液化工厂储量 stationStorageShow: false, // 加气站储量 liquidFactoryData: { name: '全部', value: 196 }, gasStationData: { name: '全部', value: 196 }, // 统计版展示数据 cities: [], // 各城市供需数据 citiesPositions: { '太原市': { 'x': 112.549248, 'y': 37.857014 }, '大同市': { 'x': 113.295258, 'y': 40.090309 }, '阳泉市': { 'x': 113.583282, 'y': 37.861187 }, '晋中市': { 'x': 113.290072, 'y': 37.388188 }, '长治市': { 'x': 113.113556, 'y': 36.191113 }, '晋城市': { 'x': 112.851273, 'y': 35.497555 }, '临汾市': { 'x': 111.517975, 'y': 36.084148 }, '运城市': { 'x': 111.00396, 'y': 35.022778 }, '朔州市': { 'x': 112.433388, 'y': 39.331261 }, '忻州市': { 'x': 112.733536, 'y': 38.41769 }, '吕梁市': { 'x': 111.134338, 'y': 37.524364 } }, filteredData: [], // 过滤后的供需数据,过滤png,lng liquidFactory: [], // 液化工厂数据 gasStation: [], // 加气站 areaNeedSupplyLayer: null, // 区域供需数据 factoryStorageLayer: null, // 液化工厂分布图层 stationStorageLayer: null, // 加气站存储层 factoryModelLayer: null, // 液化工厂模型层 stationModelLayer: null, // 加气站模型层 factoryLineLayer: null, // 飞线层 graphicLayer: null, // 管理站模型图层 timer: null, // 定时器, 刷新数据的 tooltipTimer: null, // 定时器,弹出tooltip的 clock: 120 // 间隔时间 } }, watch: { // type变更则更新供需图层 type(val) { if (this.areaNeedSupplyLayer) { this.map.removeLayer(this.areaNeedSupplyLayer, true) } this.addNeedSupply() } }, created() { // 获取液化工厂数据 this.fetchFactoryData() }, destroyed() { clearInterval(this.timer) }, 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.addNeedSupply() this.refreshData() }, // 获取供应需求数据 addNeedSupply() { const { mars3d, colorList } = this const graphicLayer = new mars3d.layer.GraphicLayer() if (this.areaNeedSupplyLayer) { this.map.removeLayer(this.areaNeedSupplyLayer) } this.areaNeedSupplyLayer = graphicLayer this.map.addLayer(graphicLayer) // 获取数据 getAreaSupply().then(res => { if (res.status === 200) { const data = res.data.map(item => { return { name: item['WD09_05'], pngSupply: item['DL03'] / 10000.0, pngNeed: item['DL03'] / 10000.0, lngSupply: item['DL02'] / 10000.0, lngNeed: item['DL02'] / 10000.0, supply: (item['DL03'] + item['DL02']) / 10000.0, need: (item['DL03'] + item['DL02']) / 10000.0 } }) this.cities = data this.filteredData = this.filterData() if (this.index == null) { this.index = getIndex(this.filteredData.map(item => item.supply)) } for (const item of this.filteredData) { const need = item.need const supply = item.supply const position = [this.citiesPositions[item.name].x, this.citiesPositions[item.name].y] const html = `${item['name']}<br/> <span style="color:#FFB861">实时供给:${supply.toFixed(2)}万m³</span>` const color = colorList[Math.floor((supply / need) * 10)] this.addWall(graphicLayer, position, supply * this.index, need * this.index, color, html, 4000) } // 开启定时循环弹窗 const graphics = this.areaNeedSupplyLayer.graphics.filter(item => item.name === 'supply') this.timerTooltip(this.areaNeedSupplyLayer, graphics, graphics.length, 0) } }) }, // 定时弹窗 timerTooltip(layer, graphics, length, i) { this.tooltipTimer = setTimeout(() => { if (i === length) { this.timerTooltip(layer, graphics, length, 0) } else { graphics[i].openTooltip() this.timerTooltip(layer, graphics, length, i + 1) } }, 10000) }, // 过滤数据 filterData() { const { type } = this if (type === 'all') { return this.cities } else if (type === 'lng') { return this.cities.map(item => { return { name: item.name, need: item.lngNeed, supply: item.lngSupply } }) } else if (type === 'png') { return this.cities.map(item => { return { name: item.name, need: item.pngNeed, supply: item.pngSupply } }) } }, // 获取液化工厂和加气站数据 fetchFactoryData() { axios.get('static/config/liquidFactory.json').then((res) => { res = res.data if (res.code === 200) { // 获取液化工厂数据 this.liquidFactory = res.data[0].data this.liquidFactoryData.value = res.data[0].total // 加气站数据 this.gasStation = res.data[1].data this.gasStationData.value = res.data[1].total if (this.storageIndex == null) { this.storageIndex = getIndex(this.liquidFactory.map(item => item.liquid_level)) console.log('storageIndex', this.storageIndex) } } }) }, // 液化工厂储量效果图 addFactoryStorage() { if (this.liquidFactory.length > 0) { // 添加点位 this.addFeatures(this.liquidFactory, 'liquidFactory') } else { this.fetchFactoryData() } }, // 显示加气站储量 addStationStorage() { if (this.gasStation.length > 0) { this.addFeatures(this.gasStation, 'gasStation') } else { this.fetchFactoryData() } }, // 液化工厂三维模型 addFactoryModel() { const { mars3d } = this 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) }, // 加气站三维模型 addStationModel() { const { mars3d } = this const stationModelLayer = new mars3d.layer.ModelLayer({ name: '加气站', url: './static/gltf/output/jiaqizhan.gltf', style: { scale: 3, heading: 0, minimumPixelSize: 30, clampToGround: true }, positions: this.gasStation.map(item => { return { lng: parseFloat(item.value[0]), lat: parseFloat(item.value[1]), alt: 0 } }) }) this.stationModelLayer = stationModelLayer this.map.addLayer(stationModelLayer) }, // 液化工厂和加气站位置飞线 addFactoryPosition() { if (this.liquidFactory.length <= 0) { return } this.addFactoryModel() // 添加液化工厂三维模型 // this.addStationModel() // 添加加气站三维模型 const lineColor = ['#f6fb05', '#f6fb05', '#00fcff'] // 城市点位图标 const symbol1 = 'image://static/images/map/symbol2.png' const symbol2 = 'image://static/images/map/symbol1.png' // 线上的动态运动点图标 var pointSymbol = 'image://static/images/map/linePoint1.png' // 工厂加symbol const factorys = this.liquidFactory.map(item => { return { ...item, symbol: symbol1 } }) // 加气站加symbol const stations = this.gasStation.map(item => { return { ...item, symbol: symbol2 } }) // 遍历获取关联关系 const lineArr = [] for (const station of stations) { if (station.belong && station.value[0] !== '0') { for (const factory of factorys) { if (station.belong === factory.name && factory.value[0] !== '0') { lineArr.push([ { coord: [parseFloat(factory.value[0]), parseFloat(factory.value[1])] }, { coord: [parseFloat(station.value[0]), parseFloat(station.value[1])] } ]) break } } } } const curveness = 0.5 var seriesZero = [ { type: 'effectScatter', layout: 'none', coordinateSystem: 'GLMap', symbolSize: [20, 20], symbolOffset: [0, -10], zlevel: 3, circular: { rotateLabel: true }, itemStyle: { normal: { shadowColor: 'none' } }, data: factorys } ] var seriesThree = [ { name: '', type: 'lines', coordinateSystem: 'GLMap', zlevel: 1, blendMode: 'lighter', effect: { show: true, smooth: false, trailLength: 0, symbol: pointSymbol, symbolSize: [10, 30], period: 4 }, lineStyle: { width: 2, color: lineColor[0], curveness: curveness }, data: lineArr } ] var seriesData = [...seriesZero, ...seriesThree] const option = { animation: false, GLMap: {}, series: seriesData } var echartsLayer = new this.mars3d.layer.EchartsLayer(option) this.factoryLineLayer = echartsLayer this.map.addLayer(echartsLayer) }, // 添加点位储量柱状图 addFeatures(arr, type) { const { mars3d, colorList } = this if (type === 'liquidFactory') { const factoryStorageLayer = new mars3d.layer.GraphicLayer() this.factoryStorageLayer = factoryStorageLayer this.map.addLayer(factoryStorageLayer) for (const item of arr) { const realData = item.liquid_level const totalData = item.contain const position = [parseFloat(item.value[0]), parseFloat(item.value[1])] const html = `${item['name']}<br/> <span style="color:#63AEFF">库容:${realData} 吨</span><br/> <span style="color:#FFB861">储量:${totalData} 吨</span><br/> <span style="color:#FFB861">液位值:${realData} 米</span>` const color = colorList[Math.floor(realData / totalData * 10)] this.addColumn(factoryStorageLayer, position, realData * this.storageIndex, totalData * this.storageIndex, color, html, 6000) } } else if (type === 'gasStation') { const stationStorageLayer = new mars3d.layer.GraphicLayer() this.stationStorageLayer = stationStorageLayer this.map.addLayer(stationStorageLayer) for (const item of arr) { const realData = item.liquid_level const totalData = item.contain const position = [parseFloat(item.value[0]), parseFloat(item.value[1])] const color = colorList[Math.floor(realData / totalData * 10)] const html = `${item['name']}<br/> <span style="color:#63AEFF">库容:${realData} 吨</span><br/> <span style="color:#FFB861">储量:${totalData} 吨</span><br/> <span style="color:#FFB861">液位值:${realData} 米</span>` this.addColumn(stationStorageLayer, position, realData * this.storageIndex, totalData * this.storageIndex, color, html, 2000, false) } } }, // 添加墙 addWall(graphicLayer, position, supply, need, color, html, radius) { const { mars3d, Cesium } = this // 下方实际数据 var positions1 = mars3d.PolyUtil.getEllipseOuterPositions({ position: Cesium.Cartesian3.fromDegrees(position[0], position[1], 0), radius: radius, // 半径 count: 50 // 共返回(count*4)个点 }) var positions2 = mars3d.PolyUtil.getEllipseOuterPositions({ position: Cesium.Cartesian3.fromDegrees(position[0] - 0.1, position[1], 0), radius: radius, // 半径 count: 50 // 共返回(count*4)个点 }) // 供应 var graphic1 = new mars3d.graphic.WallPrimitive({ name: 'supply', positions: positions1, style: { diffHeight: supply, closure: true, material: mars3d.MaterialUtil.createMaterial(mars3d.MaterialType.LineFlow, { image: 'static/images/map/fence.png', color: '#fffb33', speed: 10, axisY: true }) } }) // // 需求 // var graphic2 = new mars3d.graphic.WallPrimitive({ // name: 'need', // positions: positions2, // style: { // diffHeight: need, // closure: true, // material: mars3d.MaterialUtil.createMaterial(mars3d.MaterialType.LineFlow, { // image: 'static/images/map/fence.png', // color: '#46e7ff', // speed: 10, // axisY: true // }) // } // }) graphic1.bindTooltip(html) // graphic2.bindTooltip(html) graphicLayer.addGraphic(graphic1) // graphicLayer.addGraphic(graphic2) }, // 添加柱子 addColumn(graphicLayer, position, realData, totalData, color = '#63AEFF', html, radius, showColumn2 = true) { const { mars3d, Cesium } = this // 下方实际数据 const p = Cesium.Cartesian3.fromDegrees(position[0], position[1], Math.floor(realData / 2)) const height = realData var graphic1 = new mars3d.graphic.CylinderEntity({ position: p, style: { length: height, topRadius: radius, bottomRadius: radius, opacity: 1, color: color } }) graphic1.bindTooltip(html) graphicLayer.addGraphic(graphic1) // 上方空缺白色,表示未空余容量 if (showColumn2) { const p2 = Cesium.Cartesian3.fromDegrees(position[0], position[1], Math.floor(realData + (totalData - realData) / 2)) const height2 = totalData - realData var graphic2 = new this.mars3d.graphic.CylinderEntity({ position: p2, style: { length: height2, topRadius: radius, bottomRadius: radius, opacity: 0.3, color: '#edf4ff' } }) graphicLayer.addGraphic(graphic2) graphic2.bindTooltip(html) } }, // 添加文字 addText(graphicLayer, data, position, height) { const { mars3d, Cesium } = this var primitive = new mars3d.graphic.LabelPrimitive({ position: Cesium.Cartesian3.fromDegrees(position[0], position[1], height), style: { text: data, font_size: 18, font_family: '楷体', style: Cesium.LabelStyle.FILL_AND_OUTLINE, fillColor: Cesium.Color.fromCssColorString('#00ff00'), outlineColor: Cesium.Color.BLACK, outlineWidth: 1, horizontalOrigin: Cesium.HorizontalOrigin.CENTER, verticalOrigin: Cesium.VerticalOrigin.BOTTOM, pixelOffset: new Cesium.Cartesian2(0, -20) } }) graphicLayer.addGraphic(primitive) }, // 选框发生变化 selectChange({ area, dept }) { area = area === '全部' ? '' : area this.boardData.name = area }, // 显示区域供需情况 showAreaSupplyNeed(show) { // 现在正在显示 if (show) { // 移除 this.areaNeedSupplyShow = false this.map.removeLayer(this.areaNeedSupplyLayer, true) this.areaNeedSupplyLayer = null clearTimeout(this.tooltipTimer) this.tooltipTimer = null } else { this.areaNeedSupplyShow = true this.type = 'all' this.addNeedSupply() } }, // 显示工厂 showFactoryStorage(show) { // 现在正在显示 if (show) { // 移除 this.factoryStorageShow = false this.map.removeLayer(this.factoryStorageLayer, true) } else { this.factoryStorageShow = true this.addFactoryStorage() } }, // 显示加气站 showStationStorage(show) { // 现在正在显示 if (show) { // 移除 this.stationStorageShow = false this.map.removeLayer(this.stationStorageLayer, true) } else { this.stationStorageShow = true this.addStationStorage() } }, // 显示液化工厂位置 showPosition(show) { if (show) { // 移除 this.factoryShow = false this.map.removeLayer(this.factoryModelLayer, true) // this.map.removeLayer(this.stationModelLayer, true) this.map.removeLayer(this.factoryLineLayer, true) } else { this.factoryShow = true this.addFactoryPosition() } }, // 点击全部/png/lng更改类型 changeType(type) { console.log('clickChange') this.type = type }, // 打开轮询,定时刷新数据 refreshData() { this.timer = setInterval(() => { console.log('refreshData') this.fetchFactoryData()// 刷新液化工厂和加气站数据 if (this.areaNeedSupplyLayer) { // 如果供需图层不为空,刷新工薪数据 this.addNeedSupply() } }, this.clock * 1000) } } } </script> <style rel="stylesheet/scss" lang="scss" scoped> .label-container{ position: absolute; top: 140px; left:31rem; z-index:100; .label-div{ color: white; padding:1.5rem 2.5rem 1rem 2.5rem; background-image: url("../../assets/button_images/board-box1.png"); background-size: 100% 100%; margin-bottom: 20px; .label{ margin-bottom: 1rem; font-size:1rem; } .value{ font-family: DS-DigitalBold; font-size:2rem; } } } .map-btn-group{ position: absolute; bottom:3rem; left:50%; transform: translateX(-50%); display: flex; justify-content: center; } .select-btns-gas{ position:absolute; top:150px; left:50%; transform: translateX(-50%); display: flex; justify-content: center; } </style>