<template> <div ref="map" :id="id" class="base-map"> <slot/> </div> </template> <script> import L from 'leaflet' import 'leaflet/dist/leaflet.css' import { crsDict } from './base/crsUtils' // import 'leaflet-canvas-marker' import 'leaflet-canvas-marker-xrr2021' import { getWellInfo, getWellAlarms, getWellList } from '@/api/overview' // import { getLatLng } from './base/commonTools' export default { name: 'LeafletMap', props: { id: { type: String, required: true }, // id basemaps: { type: Array, required: true }, // 图层地址列表 zoom: { // 缩放层级 type: Number, default: 21 }, zooms: { type: Array, default: () => { return [15, 21] } }, // 缩放范围 autoResize: { // 自动重绘 type: Boolean, default: true }, size: { // marker大小 type: Array, default: function() { return [30, 30] } }, center: { type: Array, default: () => { return [116.4, 39.9] } }, // 地图中心 crs: { type: String, default: '3857' }, // 支持坐标系 alarmMarkers: { // 报警Marker,原数据 type: Array, default: function() { return [] } }, normalMarkers: { // 正常Marker,原数据 type: Array, default: function() { return [] } }, anchor: { // 位移 type: Array, default: () => [15, 30] }, popupTemplate: { // 弹窗html内容 type: String, default: '<div>hello</div>' }, popupAnchor: { // 弹窗位移 type: Array, default: function() { return [0, -24] } }, // 是否显示全部井 showAll: { type: Boolean, default: false }, // 是否显示报警 showAlarm: { type: Boolean, default: true } }, data() { return { map: null, // 底图 basebasemaps: [], // 地图图层的地址 overlays: [], // 地图上的标注,报警的 ciLayer: null, // 告警图层 queryString: '', // 地图筛选条件 normalCoverage: null // 正常井图层 } }, watch: { basemaps: { handler(val) { console.log(val) this.clearBaseMaps() this.addBaseMaps() }, deep: true }, zoom(val) { this.map.setZoom(val) }, center(val, oldVal) { console.log('中点', val) }, // 报警的井列表 alarmMarkers(val) { console.log('报警的井列表') if (this.showAll) { this.renderNormalMarkers() // 画正常井 } else { this.renderMarkers() } }, // 正常井列表 normalMarkers() { console.log('正常的井列表') if (this.showAll) { this.renderNormalMarkers() } }, // 是否展示全部井 showAll(val) { if (!val) { // 不显示全部井 if (this.ciLayer) { this.map.removeLayer(this.ciLayer) this.renderMarkers() } } } }, mounted() { this.initMap() }, methods: { // 初始化地图 initMap() { const { zooms, zoom, center, crs } = this const map = L.map(this.$refs.map, { minZoom: zooms[0], maxZoom: zooms[1], center: center, zoom: zoom, zoomControl: false, doubleClickZoom: false, // 禁用双击放大 attributionControl: true, // 默认情况下,是否将 attribution 版权控件添加到地图中。 crs: crsDict[crs] }) map.doubleClickZoom.disable() this.map = map // data上需要挂载 this.$emit('onload', map) this.clearBaseMaps() // 清除所有图层 // 加载图层 this.addBaseMaps() }, // 添加图层 addBaseMaps() { console.log('添加底图') const { map, basemaps } = this basemaps.forEach(layerInfo => { if (layerInfo.show) { const options = {} if (layerInfo.zooms) { options.minZoom = layerInfo.zooms[0] options.maxZoom = layerInfo.zooms[1] }// 缩放情况 const layer = L.tileLayer(layerInfo.url, options) this.basebasemaps.push({ name: layerInfo.name, layer: layer.addTo(map) }) } }) }, // 清除所有图层 clearBaseMaps() { const { map } = this this.basebasemaps.forEach(layer => { map.removeLayer(layer) }) this.basebasemaps = [] }, // 加载报警markers renderMarkers() { console.log('render.markers') const { map, alarmMarkers, size, anchor, popupAnchor } = this if (!map) { return } if (this.ciLayer) { console.log('清理图层') map.removeLayer(this.ciLayer) } // 告警图层 this.ciLayer = L.canvasIconLayer({}).addTo(map) this.overlays = [] // 遍历所有报警井信息 for (const item of alarmMarkers) { console.log('画图层') const icon = L.icon({ iconUrl: './static/images/map_images/alarm-well1.png', iconSize: size, iconAnchor: [18, 15], popupAnchor: popupAnchor }) const opts = { icon: icon, title: item.wellCode, wellId: item.wellId } // console.log(item) // console.log('坐标', [item.position.lat, item.position.lng]) const marker = L.marker([item.position.lat, item.position.lng], opts) this.ciLayer.addLayer(marker) this.overlays.push(marker) } map.setView(map.getCenter()) const that = this // 监听点击marker this.ciLayer.addOnClickListener(function(e, data) { // console.log('监听到点击告警信息') // console.log(e) // console.log(data[0].data.options) // 某井报警信息 getWellAlarms(data[0].data.options.wellId).then(response => { if (response.code === 200) { const wellInfo = response.data const alarmInfo = { wellCode: wellInfo.wellCode, position: wellInfo.position, deptName: wellInfo.deptName, wellTypeName: wellInfo.wellTypeName, alarms: wellInfo.alarmList, deep: wellInfo.deep } let dom = "<div class='alarm-window'>" + "<div style='line-height: 20px;color: red;font-weight: bold;'>" + alarmInfo.wellCode + '</div>' + "<div style='line-height: 23px;font-size: 14px;'>" for (const alarm of alarmInfo.alarms) { dom += "<div>告警原因:<span style='color:red'>" + alarm.alarmContent + '</span></div>' + '<div>设备编号:<span style="font-weight: bold;">' + alarm.devcode + '</span></div>' } dom += "<div class='divider'></div>" + '<div>井类型: ' + alarmInfo.wellTypeName + '</div>' + '<div>权属单位:' + alarmInfo.deptName + '</div>' + '<div>详细地址:' + alarmInfo.position + '</div>' + '</div>' + '</div>' console.log('setPopupContent_inrender') that.$emit('popupCenter', [e.latlng.lat, e.latlng.lng]) // 显示popup L.popup() .setLatLng([e.latlng.lat, e.latlng.lng]) .setContent(dom) .openOn(map) } }) }) }, // 加载正常井markers renderNormalMarkers() { // console.log('渲染正常井图层') const { map, normalMarkers, size, anchor, popupAnchor } = this if (!map) { return } this.renderMarkers() // 正常图层 // 遍历所有报警井信息 for (const item of normalMarkers) { console.log('画正常井图层') const icon = L.icon({ iconUrl: './static/images/map_images/1.png', iconSize: [12, 16], iconAnchor: [6, 8], popupAnchor: popupAnchor }) const opts = { icon: icon, title: item.wellCode, wellId: item.id // 井id } const marker = L.marker([item.coordinateY, item.coordinateX], opts) this.ciLayer.addLayer(marker) } // map.setView(map.getCenter()) }, // 打开弹窗 openAlarmInfoWindow(wellId) { const { map } = this for (const overlay of this.overlays) { if (overlay.options.wellId === wellId) { getWellAlarms(wellId).then(response => { if (response.code === 200) { const wellInfo = response.data const alarmInfo = { wellCode: wellInfo.wellCode, position: wellInfo.position, deptName: wellInfo.deptName, wellTypeName: wellInfo.wellTypeName, alarms: wellInfo.alarmList, deep: wellInfo.deep } let dom = "<div class='alarm-window'>" + "<div style='line-height: 20px;color: red;font-weight: bold;'>" + alarmInfo.wellCode + '</div>' + "<div style='line-height: 23px;font-size: 14px;'>" for (const alarm of alarmInfo.alarms) { dom += "<div>告警原因:<span style='color:red'>" + alarm.alarmContent + '</span></div>' + '<div>设备编号:<span style="font-weight: bold;">' + alarm.devcode + '</span></div>' } dom += "<div class='divider'></div>" + '<div>井类型: ' + alarmInfo.wellTypeName + '</div>' + '<div>权属单位:' + alarmInfo.deptName + '</div>' + '<div>详细地址:' + alarmInfo.position + '</div>' + '</div>' + '</div>' // map.setZoom(17) map.setZoom(37) console.log('ppp') console.log([overlay.getLatLng().lat, overlay.getLatLng().lng]) this.$emit('popupCenter', [overlay.getLatLng().lat, overlay.getLatLng().lng]) setTimeout(() => { map.flyTo([overlay.getLatLng().lat, overlay.getLatLng().lng]) // map.panTo([overlay.getLatLng().lat, overlay.getLatLng().lng]) // 显示popup L.popup() .setLatLng([overlay.getLatLng().lat, overlay.getLatLng().lng]) .setContent(dom) .openOn(map) }) } }) } } }, // 关闭弹窗 closePopup() { this.map.closePopup() } } } </script> <style rel="stylesheet/scss" lang="scss" scoped> .base-map { width:100%; // height: calc(100vh - 84px); height: calc(100vh - 115px); } .alarm-window{ max-width: 250px; background-color: #ffeaf1; .alarm-header { padding: 10px 10px 5px 10px; line-height: 30px; color: red; font-weight: bold; background-color: #ffecec; } .alarm-body{ padding: 5px 10px 10px 10px; line-height: 23px; font-size: 14px; .alarm-red{ color: #ff0000; } } } </style>