<!-- * @Description: 监控图层 * @Author: 王晓颖 * @Date: 2021-09-15 10:04:45 --> <template> <div> <!--<div v-if="layerShow" :class="{'video-dialog': !maxWindow, 'max-window': maxWindow}">--> <!--<div style="height:30px;color:white;margin-top:20px;width:100%;text-align:center;font-size: 18px;">实时监控</div>--> <!--<img :src="require('@/assets/img/map/maximum.png')" width="20" height="20" class="max-btn" @click="maxWindow = !maxWindow">--> <!--<img :src="require('@/assets/img/map/close.png')" width="20" height="20" class="close-btn" @click="closeVideo">--> <!--<div class="video-div">--> <!--<video :src="videoSrc" autoPlay="" width="100%"></video>--> <!--</div>--> <!--</div>--> </div> </template> <script> import Leaflet from 'leaflet' import commonMixin from '@/components/leafletMap/base/mixins/common.js' import { getDeviceList, getDeviceInfo } from '@/api/overview' import { getPathBounds, getCenterByBounds, getZoomByBounds } from '@/utils/maputils' export default { name: 'PipeLayer', mixins: [commonMixin('layer')], props: { show: { type: Boolean, default: true }, // 是否显示 iconSize: { type: Array, default: () => { return [20, 20] } }, // 图标大小 iconAnchor: { type: Array, default: () => { return [10, 20] } }, // 图标位移 popupAnchor: { type: Array, default: () => { return [0, -20] } }, // 弹窗位移 refreshTime: { type: Number, default: 60 } // 定时刷新时间 }, data () { return { maxWindow:false, // 窗口最大化 layerShow: false, dataList: [], // 数据列表 wellCoverLayer: null, // 井盖图层 liquidLayer: null, // 液位图层 noiseLayer: null, // 噪声图层 harmfulLayer: null, // 有害气体监测仪图层 layerGroup: [], // 图层组 wellIcon: require('@/assets/img/map/wellCover.png'), liquidIcon: require('@/assets/img/map/liquid.png'), noiseIcon: require('@/assets/img/map/noise.png'), poisonIcon: require('@/assets/img/map/poison.png'), timer: null // 定时器 } }, watch: { show (val) { if (val) { this.initLayer() } else { this.clearLayer() } } }, methods: { load () { if (this.show) { this.initLayer() } }, // 初始化图层 initLayer () { const {map} = this this.layerGroup = [] // 先清空LayerGroup // 初始化图层组 /* eslint-disable new-cap */ this.noiseLayer = new Leaflet.layerGroup().addTo(map) this.wellCoverLayer = new Leaflet.layerGroup().addTo(map) this.liquidLayer = new Leaflet.layerGroup().addTo(map) this.harmfulLayer = new Leaflet.layerGroup().addTo(map) this.layerGroup.push(this.noiseLayer) this.layerGroup.push(this.wellCoverLayer) this.layerGroup.push(this.liquidLayer) this.layerGroup.push(this.harmfulLayer) console.log('initLayer') this.loadData() }, // 清除图层 clearLayer () { console.log('clearLayer') const {map, layerGroup} = this layerGroup.forEach(item => map.removeLayer(item)) }, // 加载全部数据 loadData () { const {wellCoverLayer, noiseLayer, liquidLayer, harmfulLayer, wellIcon, liquidIcon, noiseIcon, poisonIcon} = this // 获取全部井列表 getDeviceList().then(response => { if (response.code === 200) { const wells = response.data if (wells.length > 0) { const centerxs = [] // 存储所有坐标,用于计算中点 const centerys = [] for (const well of wells) { centerxs.push(parseFloat(well.coordinateX)) centerys.push(parseFloat(well.coordinateY)) } // 坐标排序取最中间的为中心 centerxs.sort() centerys.sort() const index = Math.floor(centerxs.length / 2) this.center = [centerxs[index], centerys[index]] console.log('总数据数:'+this.dataList.length) // 按照设备类型分层 const wellCoverList = wells.filter(item=>item.deviceType=='1') const liquidList = wells.filter(item=>item.deviceType=='2') const harmfulList = wells.filter(item=>item.deviceType=='3') const noiseList = wells.filter(item=>item.deviceType=='8') this.addPointOnMap(wellCoverList, wellCoverLayer, wellIcon ) this.addPointOnMap(liquidList, liquidLayer, liquidIcon ) this.addPointOnMap(harmfulList, harmfulLayer, poisonIcon ) this.addPointOnMap(noiseList, noiseLayer, noiseIcon ) this.setZoom(wells) } } }) }, // 将点加到地图上 addPointOnMap(dataList, layer, iconType) { const {iconSize, iconAnchor, popupAnchor} = this layer.clearLayers() // 图标 const icon = Leaflet.icon({ iconUrl: iconType, iconSize: iconSize, iconAnchor: iconAnchor, popupAnchor: popupAnchor }) dataList.forEach(item => { // let popupStr = '<div class="popup-div">' + // '<div class="popup-title">'+item.wellCode+'</div>' + // '<div class="dashed-line"></div>' + // '<div class="popup-item"><label>井名称</label>'+item.wellName+'</div>' + // // '<div class="popup-item"><label>井类型</label>'+item.wellTypeName+'</div>' + // '<div class="popup-item"><label>位置:</label>'+item.position+'</div>' // // '<div class="popup-item"><label>时间</label>'+item.alarmTime+'</div>' // // '<div class="popup-button" id="real-video">查看实时监控</div>' // popupStr += '</div>' // const popup = Leaflet.popup().setContent(popupStr) const coordinateX = parseFloat(item.coordinateX) const coordinateY = parseFloat(item.coordinateY) if (coordinateX > 0 && coordinateY > 0) { // 添加marker const marker = Leaflet.marker([coordinateY, coordinateX], { icon: icon, id: item.id }).addTo(layer) // 点击获取详情并弹窗 marker.on('click', (e) => { if (e.target.dragging._marker._popup) { e.target.dragging._marker.unbindPopup() } getDeviceInfo(e.target.options.id).then(res => { const data = res.data let popupStr = '<div class="popup-div">' + '<div class="popup-title">' + data.deviceName + '</div>' + '<div class="dashed-line"></div>' + '<div class="popup-item"><label>设备编号</label>'+data.devcode+'</div>' + '<div class="popup-item"><label>设备类型</label>'+data.deviceTypeName+'</div>' + '<div class="popup-item"><label>位置</label>'+data.position+'</div>' + '<div class="popup-item"><label>权属单位</label>'+data.deptName+'</div>' if (data.realtimeData) { for(const item of data.realtimeData){ popupStr += '<div class="popup-item"><label>'+item.typeName+'</label>' + item.value + '</div>' popupStr += '<div class="popup-item"><label>更新时间</label>' + item.logtime+ '</div>' } }else{ popupStr += '<div class="popup-item"><label>实时数据</label> -- </div>' } popupStr += '</div>' const popup = Leaflet.popup().setContent(popupStr) e.target.dragging._marker.bindPopup(popup).openPopup() }) }) } }) }, setZoom (points) { if (points.length > 0) { // 计算边界 const { maxLng, minLng, maxLat, minLat } = getPathBounds(points,'coordinateX','coordinateY') // 计算中心点 const { cenLat, cenLng } = getCenterByBounds({ maxLng, minLng, maxLat, minLat }) // 计算缩放 const zoom = getZoomByBounds({ maxLng, minLng, maxLat, minLat }) console.log({ lat: cenLat, lng: cenLng }, zoom) this.map.setView({ lat: cenLat, lng: cenLng }, zoom) } } } } </script> <style rel="stylesheet/scss" lang="scss" scoped> .video-dialog{ position: absolute; top: 50%; left:50%; transform: translate(-50%,-50%); z-index:1000; width: 600px; height: 400px; background-color: rgba(7,10,23,0.8); border-radius: 10px; .max-btn{ position: absolute; top:20px; right:60px; } .close-btn{ position: absolute; top:20px; right:20px; } .close-btn:hover{ animation:turn 1s linear infinite; } .video-div{ width: 100%; padding: 0px 20px; } } .max-window{ position: fixed; top: 0; left:0; z-index:1000; width: 100%; height: 100%; background-color: rgba(7,10,23,0.8); border-radius: 10px; .max-btn{ position: absolute; top:20px; right:60px; } .close-btn{ position: absolute; top:20px; right:20px; } .close-btn:hover{ animation:turn 1s linear infinite; } .video-div{ width: 100%; padding: 0px 20px; } } @keyframes turn{ 0%{-webkit-transform:rotate(0deg);} 25%{-webkit-transform:rotate(90deg);} 50%{-webkit-transform:rotate(180deg);} 75%{-webkit-transform:rotate(270deg);} 100%{-webkit-transform:rotate(360deg);} } </style> <style rel="stylesheet/scss" lang="scss" > .leaflet-popup-content-wrapper, .leaflet-popup-tip{ color: white; background-color: rgba(10,26,123,0.8); } .leaflet-popup-content { .popup-div { font-size: 14px; padding: 5px; } .popup-title { font-weight: bold; } .dashed-line { border-bottom: 1px dashed #dddddd; margin: 10px -10px; } .popup-item { padding-bottom: 6px; label { font-weight: bold; padding-right: 15px; } } .popup-subitem { padding-bottom: 6px; font-size: 12px; } .popup-button{ color:#67E0E3; text-align: center; margin-top: 5px; text-decoration: underline; } .popup-button:hover{ color: #36b7ff; cursor: pointer; } } </style>