<template> <div id="map" ref="mapDiv" class="baseMap"> <slot/> </div> </template> <script> import L, { map } from 'leaflet' import "leaflet.markercluster" import 'leaflet/dist/leaflet.css' import "leaflet.markercluster/dist/MarkerCluster.css" import "leaflet.markercluster/dist/MarkerCluster.Default.css" var esri = require('esri-leaflet') export default { name: 'LeafletMap', props: { satellite: { type: Boolean, default: true }, showAllWell: { type: Boolean, default: false } }, data () { return { map: null, baseLayer: [], satelliteLayer: null, alarmMarkers: [], // 选点 icon: null, alarmIcon: null, group: null, // layerGroups: [], // 图层组,用于控制一组内容显示或者隐藏 gxLayers: [], allWellLayers: [], // 所有的井图层 聚合点 alarmWellLayers: [], // 报警井的图层 } }, mounted () { this.initMap() }, watch: { satellite (val, oldVal) { if (val&&!oldVal) { this.satelliteLayer = L.tileLayer(this.baseConfig.satelliteUrl, { maxZoom: 22 }) this.satelliteLayer.addTo(this.map) } else { this.map.removeLayer(this.satelliteLayer) } } }, methods: { initMap () { this.icon = L.icon({ iconUrl: require(`@/assets/map/marker.png`), iconSize: [20, 30], iconAnchor: [10, 30], popupAnchor: [0, -30] }) this.alarmIcon = L.icon({ iconUrl: require(`@/assets/map/markerAlarm.png`), iconSize: [20, 30], iconAnchor: [10, 30], popupAnchor: [0, -30] }) this.group = L.layerGroup() const map = L.map(this.$refs.mapDiv, { minZoom: 14, maxZoom: 25, center: this.baseConfig.center, zoom: this.baseConfig.zoom, zoomControl: false, attributionControl: false, crs: L.CRS.EPSG3857 }) map.doubleClickZoom.disable() this.map = map // data上需要挂载 window.map = map this.$emit('onload', map) this.map.addLayer(this.group) // 加载图层 this.addLayers() }, addLayers () { // 加载天地图底图和标注 const tdtMap = L.tileLayer(this.baseConfig.mapUrl, { maxZoom: 22 }) const tdtLabel = L.tileLayer(this.baseConfig.labelUrl, { maxZoom: 22 }) this.satelliteLayer = L.tileLayer(this.baseConfig.satelliteUrl, { maxZoom: 22 }) this.baseLayer.push(tdtMap.addTo(this.map)) if (this.satellite) { this.baseLayer.push(this.satelliteLayer.addTo(this.map)) } this.baseLayer.push(tdtLabel.addTo(this.map)) // this.addPartsLayer() // this.addPartsLayer(2) // 雨水管线附属物 // this.addPartsLayer(3) // 污水管线附属物 this.addPartsLayer(4) // 雨水管线 this.addPartsLayer(5) // 污水管线 }, addPartsLayer: function(index) { const item = { url: `${this.baseConfig.baseGisUrl}${this.baseConfig.gxServerUrl}/${index}`, minZoom: this.baseConfig.zoom } const layer = esri.featureLayer(item).addTo(this.group) this.gxLayers.push(layer) // this.layerGroups.push(layer) }, addWellLayer: function(wellList) { // 清除之前的图层 this.allWellLayers.forEach(layer => { this.group.removeLayer(layer) }) this.allWellLayers = [] const clusterLayer = L.markerClusterGroup({ showCoverageOnHover: false, disableClusteringAtZoom: 18 })// 全部井的海量点图层 for (let i = 0; i < wellList.length; i++) { const well = wellList[i] if (well.coordinateX !== "" && well.coordinateY !== "") { const latlng = L.latLng([well.coordinateY, well.coordinateX]) const marker = L.marker(latlng, {icon: this.icon}) // 弹窗样式 const popupStr = '<div class="popup-div">' + '<div class="popup-title">井信息</div>' + '<div class="dashed-line"></div>' + '<div class="popup-item"><label>井编号</label>' + well.wellCode + '</div>' + '<div class="popup-item"><label>井名称</label>' + well.wellName + '</div>' + '<div class="popup-item"><label>位置</label>' + well.position + '</div>' + '</div>' const popup = marker.bindPopup(popupStr) clusterLayer.addLayer(marker) } } this.allWellLayers.push(clusterLayer) // this.layerGroups.push(clusterLayer) this.group.addLayer(clusterLayer) this.showOrHideAllWell(this.showAllWell) }, addAlarmWellLayer: function(alarmList) { const alarmLayer = L.layerGroup() this.alarmMarkers = [] for (let i = 0; i < alarmList.length; i++) { const alarm = alarmList[i] if (alarm.coordinateX !== "" && alarm.coordinateY !== "") { const latlng = L.latLng([alarm.coordinateY, alarm.coordinateX]) const marker = L.marker(latlng, {icon: this.alarmIcon, code: alarm.wellCode}) // 弹窗样式 const popupStr = '<div class="popup-div">' + '<div class="popup-title">报警信息</div>' + '<div class="dashed-line"></div>' + '<div class="popup-item"><label>报警内容</label>' + alarm.alarmContent + '</div>' + '<div class="popup-item"><label>报警时间</label>' + alarm.alarmTime + '</div>' + '<div class="popup-item"><label>井编号</label>' + alarm.wellCode + '</div>' + '<div class="popup-item"><label>设备编号</label>' + alarm.devcode + '</div>' + '<div class="popup-item"><label>井类型</label>' + alarm.wellTypeName + '</div>' + '<div class="popup-item"><label>位置</label>' + alarm.position + '</div>' + '</div>' const popup = marker.bindPopup(popupStr) alarmLayer.addLayer(marker) // 加到marker列表中 this.alarmMarkers.push(marker) } } this.alarmWellLayers.push(alarmLayer) // this.layerGroups.push(alarmLayer) this.group.addLayer(alarmLayer) }, locateWell: function(wellCode) { const wellFilted = this.alarmMarkers.filter(well => well.options.code === wellCode) if (wellFilted.length > 0) { const well = wellFilted[0] this.map.setView([well.getLatLng().lat, well.getLatLng().lng], 20) well.openPopup(); } }, showOrHideAllWell(show) { if (show) { this.allWellLayers.forEach(layer => { this.group.addLayer(layer) }) } else { this.allWellLayers.forEach(layer => { this.group.removeLayer(layer) }) } }, showOrHideAlarmWell(show) { if (show) { this.alarmWellLayers.forEach(layer => { this.group.addLayer(layer) }) } else { this.alarmWellLayers.forEach(layer => { this.group.removeLayer(layer) }) } }, resetMapView() { this.map.setView(this.baseConfig.center, this.baseConfig.zoom) } } } </script> <style scoped> .baseMap { height: 100vh; width: 100%; /*border: 1px solid #DCDCDC;*/ /*border-radius: 4px;*/ } </style> <style> .leaflet-container a.leaflet-popup-close-button { top: 5px; /* 修改弹窗关闭按钮样式 */ right: 10px; /* 修改弹窗关闭按钮样式 */ } .leaflet-popup-content .popup-div { font-size: 15px; padding: 6px; } .leaflet-popup-content .popup-title { font-weight: bold; } .leaflet-popup-content .dashed-line { border-bottom: 1px dashed #dddddd; margin: 10px -10px; } .leaflet-popup-content .popup-item { padding-bottom: 6px; } .leaflet-popup-content .popup-item label { font-weight: bold; padding-right: 15px; } .leaflet-popup-content .popup-subitem { padding-bottom: 6px; font-size: 12px; } </style>