<!--suppress ALL --> <template> <div class="overview-map-container"> <div id="mars3dContainer" class="mars3d-container" :style="{height:(bodyHeight-20)+'px'}" /> <div class="cover"> <div v-for="(item,index) in layerName" :key="item" class="cover-item"> <span v-if="index<=7"><img :src="'/../../../static/images/'+layerName[index]+'.png'" style="width: 15px;height:15px"></span> <span v-else :style="{color: colors[index-8],fontWeight: 600}">——</span> {{ item }} </div> </div> <!--搜索框--> <map-search-comp :list="resultList" placeholder="点位编号/名称/位置" style="background: #00000000" @search="search" @change-page="searchPageChange" @click-item="searchItemClick" @clear="clearSearch" /> <el-slider v-model="alpha" style="width: 220px; position: absolute;top:0px; right: 20px" /> <!--报警列表--> <alarm-list :show="showAlarm" :data="alarmList" @row-click="alarmRowClick" /> <!--工具箱--> <tool-box style="position: absolute; width:300px;top:25px;right: 0px" :show="!loading" :layers="layers" :layer-checked="checkedLayer" :tool-menu="menus.menuList" @change-base-map="changeBaseMap" @layer-change="filterLayer" @click-menu="clickMenu" @close-menu-pop="closeAllPopup" /> <!--数据筛选窗口--> <popup-data-filter :show="menus.dataFilterWindowShow" :well-type-list="wellTypeList" @filter="dataFilter" @close="closePopupDataFilter" /> <!--坐标定位窗口--> <popup-location ref="popupLocation" :show="menus.locationWindowShow" @search="setCenter" @picker="pickerPosition" @close="closePopupLocation" /> </div> </template> <script> import { mapGetters } from 'vuex' import { getWellType } from '@/api/well/well' import { getWellList, getWellInfo, getAlarmsNow, getWellAlarms } from '@/api/overview/wellOverview' import { getDeviceAllList, getDeviceType } from '@/api/device/device' import { toPixel, toLngLat, toSize } from '@/components/Amap/utils/convert-helper' import DeptSelect from '../../components/DeptSelect/index' import AMapContainer from '@/components/Amap/AMapContainer' import AlarmInfoWindow from './components/infoWindowAlarm' import WellInfoWindow from './components/infoWindowWell' import AMapMarker from '@/components/Amap/AMapMarker' import AlarmList from './components/alarmList' import Vue from 'vue' import ToolBox from '@/views/overview/components/toolBox' import PopupDataFilter from '@/views/overview/components/popupDataFilter' import PopupLocation from '@/views/overview/components/popupLocation' import MapSearchComp from '@/views/overview/components/mapSearchComp' import axios from 'axios' // import 'cesium/Source/Widgets/widgets.css'// 导入必须的样式表 // import 'cesium/Source/Cesium'// 导入必须的样式表 // var Cesium = require('../../../node_modules/cesium/Source/Cesium') var Cesium = require('../../../node_modules/mars3d-cesium/Build/Cesium/Cesium') import 'mars3d/dist/mars3d.css' import 'mars3d/dist/mars3d.js' import * as mars3d from 'mars3d' import store from '@/store' import { breadcrumb } from '@/settings' var underground = null var line_layer = [] var line_layer_3D = [] var point_layer = [] var point_layer_3D = [] var dev_layer = [] var dev_layer_3D = [] var wellLoc = {} export default { name: 'Overview3D', components: { MapSearchComp, PopupLocation, PopupDataFilter, ToolBox, AlarmList, AMapMarker, AMapContainer, DeptSelect }, data() { return { initWell: false, // 是否初始化井信息 showLine: true, showModel: false, colors: ['#7f0000', '#804000', '#00ff00', '#ff7fe9', '#ff7fe9', '#ff0000', '#00bfff', '#00ff00', '#ff0000'], layerName: ['雨水附属物', '污水附属物', '天然气附属物', '燃气附属物', '给水附属物', '电信附属物', '电力附属物', '标识器', '雨水管线', '污水管线', '通信管线', '天然气管线', '燃气管线', '路灯管线', '给水管线', '电信管线', '电力管线'], baseLayer: 'gaode_vec', // 底图图层 layers: [{ id: 'well', name: '井图层', children: [] }, { id: 'line', name: '管线图层', children: [] }, { id: 'dev', name: '设备图层', children: [] }, { id: 'alarm', name: '报警图层' }], // 图层列表 checkedLayer: [], // 选中的图层 center: ['114.88', '25.68'], // 地图中心 // center: [this.$store.getters.lng, this.$store.getters.lat], // 地图中心 zoom: 12, // 地图缩放比例 type: this.baseConfig.showPointType, // 加载数据方式:massMarkers海量点或cluster聚合点 refreshType: this.baseConfig.refreshType, // 刷新数据方式:clock定时器或websocket推送 alarmIcon: require('@/assets/icons/icon-alarm1.png'), // 报警图标 alarmIconSize: [30, 30], // 报警图标大小 alarmOffset: [-15, -30], // 报警图标偏移量 wellIcon: require('@/assets/overview/icon-location-small.png'), // 井图标 wellIconSize: [16, 16], // 井图标大小 wellOffset: [-8, -16], // 井偏移量 massMarkerUrl: './static/overview/icon-location-small.png', massMarkerSize: [15, 15], massMarkerOffset: [0, 8], searchResultSize: [24, 30], searchResultOffset: [-12, -30], searchResultIcon: require('@/assets/overview/pure-position-icon.png'), // 报警图标 showAlarm: true, // 是否显示报警 alpha: 100, toolShow: false, // 工具栏是否显示 menus: { menuList: [ { icon: 'search', menu: 'dataFilter', name: '数据筛选' }, { icon: 'coordinate', menu: 'location', name: '坐标定位' } ], dataFilterWindowShow: false, // 数据筛选窗口是否显示 locationWindowShow: false // 坐标定位窗口是否显示 }, // 工具栏菜单 listQuery: { keywords: '', // 关键字 wellType: '', // 点位类型 deptid: '' // 组织机构 }, // 筛选条件 count: 30, // 倒计时显示时间 clock: null, // 计时器 showWellType: false, // 是否显示点位类型下拉,默认边上 wellTypeList: [], // 点位类型列表 deviceTypeList: [], // 设备类型列表 commonIcon: 'well-common-green', // 通用图标 绿 commonIconAlarm: 'well-common-red', // 通用图标 红 alarmListOri: [], // 原始报警列表 alarmList: [], // 显示报警列表 alarmWells: [], // 报警井列表 resultList: [], // 搜索结果列表 searchMarkers: [], // 当前搜索页展示marker集合 latestAlarmTime: '', // 列表中最新报警事件 alarmFirstAmount: true, // 是否初次加载报警 firstAmount: true, // 是否第一次加载井数据 loading: true, // 加载图标是否显示 markers: [], // 所有井的点原始数据 massMarks: null, // 海量点对象 mapMarkers: [], // 查询结果列表 clusters: [], // 聚合 tempMarker: null, showClearBtn: false, // 是否显示清除查询按钮 bloomEffect: null, layerProvider: '', options: {} } }, computed: { ...mapGetters([ 'needRefresh', 'bodyHeight' ]) }, watch: { alpha(val) { window.map.basemap.opacity = val / 100 underground.alpha = val / 100 // if (val <= 90 && window.map.level >= 19) { // line_layer.forEach(layer => { // layer.show = false // }) // } else { // line_layer.forEach(layer => { // layer.show = true // }) // } }, needRefresh(val) { // 需要刷新报警 if (val) this.refreshAlarm() }, 'menus.locationWindowShow'(val) { // 打开弹窗设置默认中心,关闭弹窗清空屏幕 if (val) { this.$refs.popupLocation.setQuery(this.center) } else { // window.map.remove(this.tempMarker) } } }, beforeCreate() { this.$store.dispatch('settings/changeSetting', { key: 'breadcrumb', value: false }) this.$store.dispatch('settings/changeSetting', { key: 'tagsView', value: false }) }, created() { this.fetchWellType() }, mounted() { this.$nextTick(() => { this.windowResize(window.innerHeight, window.innerWidth) this.initmars3d() this.resultList = [] }) }, beforeDestroy() { this.$store.dispatch('settings/changeSetting', { key: 'breadcrumb', value: true }) this.$store.dispatch('settings/changeSetting', { key: 'tagsView', value: true }) if (this.clock) { clearInterval(this.clock) this.clock = null } }, methods: { windowResize(height, width) { // 查找header高度 const el_header = document.getElementById('app-header') let bodyHeight = height - (el_header ? el_header.clientHeight : 56) if (store.getters.tagsView) { const el_tagsView = document.getElementById('tags-view-container') bodyHeight -= el_tagsView ? el_tagsView.clientHeight : 34 } if (breadcrumb) { const el_navbar = document.getElementsByClassName('navbar') bodyHeight -= el_navbar ? el_navbar[0].clientHeight : 48 } // 减去2个padding bodyHeight -= 5 store.dispatch('settings/ChangeHeight', bodyHeight) }, // 初始化放这里 async initmars3d() { const mapOptions = { scene: { // 默认视角参数 center: { lat: this.center[1], lng: this.center[0], alt: 10000, heading: 360, pitch: -45 }, showSun: true, // showMoon: true, // showSkyBox: true, showSkyAtmosphere: false, // 关闭球周边的白色轮廓 map.scene.skyAtmosphere = false fog: true, fxaa: true, // 以下是Cesium.Globe对象相关参数 globe: { depthTestAgainstTerrain: true, // 是否启用深度监测 baseColor: '#1A2126', // 地球默认背景色 showGroundAtmosphere: false, // 是否在地球上绘制的地面大气 enableLighting: false // 是否显示昼夜区域 }, control: { infoBox: false }, // 以下是Cesium.ScreenSpaceCameraController对象相关参数 cameraController: { zoomFactor: 3.0, // 鼠标滚轮放大的步长参数 minimumZoomDistance: 1, // 地球放大的最小值(以米为单位) maximumZoomDistance: 5000, // 地球缩小的最大值(以米为单位) enableRotate: true, // 2D和3D视图下,是否允许用户旋转相机 enableTranslate: true, // 2D和哥伦布视图下,是否允许用户平移地图 enableTilt: true, // 3D和哥伦布视图下,是否允许用户倾斜相机 enableZoom: true, // 是否允许 用户放大和缩小视图 enableCollisionDetection: true // 是否允许 地形相机的碰撞检测 } }, basemaps: [ { pid: 10, id: 1111, name: '天地图', type: 'group', layers: [ { name: '注记', type: 'tdt', layer: 'ter_z', key: ['216ee92889e17ab1b083fae665d522b8'] }, { name: '注记', type: 'tdt', layer: 'img_z', key: ['216ee92889e17ab1b083fae665d522b8'] } ] }, { 'id': 1112, 'pid': 10, 'name': '天地图电子', 'icon': 'http://mars3d.cn/example/img/basemaps/tdt_vec.png', 'type': 'group', 'layers': [ { 'name': '底图', 'type': 'tdt', 'layer': 'vec_d', 'key': ['216ee92889e17ab1b083fae665d522b8'] }, { 'name': '注记', 'type': 'tdt', 'layer': 'vec_z', 'key': ['216ee92889e17ab1b083fae665d522b8'] } ] }, { 'id': 1113, 'pid': 10, 'name': '天地图影像', 'icon': 'http://mars3d.cn/example/img/basemaps/tdt_img.png', 'type': 'tdt', 'layer': 'img_d', 'key': ['216ee92889e17ab1b083fae665d522b8'], 'show': true } ] } const map = new mars3d.Map('mars3dContainer', mapOptions) map.basemap = 1113 map.scene.screenSpaceCameraController.enableCollisionDetection = false // 设置鼠标 map.scene.screenSpaceCameraController.tiltEventTypes = [Cesium.CameraEventType.RIGHT_DRAG] // 缩放设置 重新设置缩放成员 map.scene.screenSpaceCameraController.zoomEventTypes = [Cesium.CameraEventType.MIDDLE_DRAG, Cesium.CameraEventType.WHEEL, Cesium.CameraEventType.PINCH] // 鼠标左键平移 map.scene.screenSpaceCameraController.rotateEventTypes = [Cesium.CameraEventType.LEFT_DRAG] window.map = map underground = new mars3d.thing.Underground({ alpha: this.alpha / 100 }) map.addThing(underground) this.bloomEffect = new mars3d.effect.BloomEffect({ enabled: true }) map.addEffect(this.bloomEffect) window.map.basemap.opacity = this.alpha / 100 // 崩溃后刷新 // map.on(mars3d.EventType.renderError, function(event) { // window.location.reload() // }) const that = this map.on(mars3d.EventType.load, function(event) { window.map.on(mars3d.EventType.cameraChanged, that.cameraChange, that) that.initLine() that.initPoint() }) }, initLine() { for (let i = 8; i <= 16; i++) { // 三维地下管线 (19) const wfsLayer = new mars3d.layer.ArcGisWfsLayer({ name: this.layerName[i], popup: 'all', url: 'http://111.198.10.15:13002/arcgis/rest/services/gztest/MapServer/' + i, minimumLevel: 19, symbol: { type: 'polylineVolumeP', styleOptions: { color: this.colors[i - 8], shape: 'pipeline', radius: 0.1 }, callback: function(attr, styleOpt) { return { setHeight: -2 } } // callback: function(attr, styleOpt) { // var val = { attr }.attr // return { addHeight: [-2, -2] } // } } }) line_layer_3D.push(wfsLayer) window.map.addLayer(wfsLayer) // 二维管线 const queryLineserver = new mars3d.query.QueryArcServer({ url: 'http://111.198.10.15:13002/arcgis/rest/services/gztest/MapServer/' + i, popup: 'all', pageSize: 3000 }) const layer = new mars3d.layer.GeoJsonLayer({ name: this.layerName[i], // enablePickFeatures: false, symbol: { type: 'polylineC', styleOptions: { color: this.colors[i - 8], width: 3, hasShadows: true, shadows: Cesium.ShadowMode.ENABLED } }, popup: 'all' // flyTo: true }) line_layer.push(layer) window.map.addLayer(layer) queryLineserver.query({ success: (result) => { layer.load({ data: result.geojson }) }, error: (error, msg) => { console.log('服务访问错误', error) } }) } }, initPoint(condition = '') { point_layer = [] point_layer_3D = [] let comp_layer = 0 const that = this for (let i = 0; i <= 7; i++) { const queryPointserver = new mars3d.query.QueryArcServer({ url: 'http://111.198.10.15:13002/arcgis/rest/services/gztest/MapServer/' + i, popup: 'all', pageSize: 3000 }) const point = new mars3d.layer.GeoJsonLayer({ name: this.layerName[i], symbol: { type: 'billboard', styleOptions: { image: '../static/images/' + this.layerName[i] + '.png', scale: 0.6, pixelOffsetY: -10, scaleByDistance: true, scaleByDistance_far: 30000, scaleByDistance_farValue: 0.6, scaleByDistance_near: 0, scaleByDistance_nearValue: 2, clampToGround: true, highlight: { type: 'click', image: '../static/images/gz-high.png' } } }, popup: 'all' }) point_layer.push(point) window.map.addLayer(point) const point3D = new mars3d.layer.GeoJsonLayer({ name: this.layerName[i], enablePickFeatures: false, onCreateGraphic: function(options) { // 在里面就可以处理geojson内部的数据 const points = options.position // 坐标 const attr = options.attr // 属性信息 const primitive = new mars3d.graphic.ModelPrimitive({ allowDrillPick: true, // attr: attr, id: attr.编号, position: points, style: { url: '../static/model/ys.gltf', scale: 1.5, setHeight: -2 } }) point3D.addGraphic(primitive) }, show: false }) // point3D.on(mars3d.EventType.load, function(e) { // console.log('绘制矢量对象完成', e) // console.log(point3D) // }) if (i !== 7) { window.map.addLayer(point3D) point_layer_3D.push(point3D) } if (condition === '') { queryPointserver.query({ success: (result) => { if (result.count === 0) { this.$message.warning('未查询到相关记录!') point.load({ data: { features: null }}) point3D.load({ data: { features: null }}) return } point.load({ data: result.geojson }) point3D.load({ data: result.geojson }) if (!this.initWell && comp_layer < 7) { comp_layer++ } if (!this.initWell && comp_layer === 7) { this.initWell = true point_layer_3D.forEach(layer => { layer.options.data.features.forEach(item => { that.$set(wellLoc, item.properties.编号, item.geometry.coordinates) }) }) that.mapReady() } }, error: (error, msg) => { this.$message.error('服务访问错误,' + error) } }) } else { // 按列查询 queryPointserver.query({ column: 'LineWt', text: condition, success: (result) => { if (result.count === 0) { this.$message.warning('未查询到相关记录!') point.load({ data: { features: null }}) point3D.load({ data: { features: null }}) return } point.load({ data: result.geojson }) point3D.load({ data: result.geojson }) }, error: (error, msg) => { this.$message.error('服务访问错误,' + error) } }) } } }, // 控制二维线的显隐 cameraChange() { console.log('map-level:' + window.map.level) console.log('alpha:' + this.alpha) if (window.map.level <= 19) { // 远 // 线 if (!this.showLine) { const lineTypes = this.checkedLayer.filter(item => item.indexOf('line-') > -1).map(item => item.substring(5)) line_layer.forEach(layer => { layer.show = lineTypes.indexOf(layer.options.name) > -1 }) this.showLine = true } if (this.showModel) { point_layer_3D.forEach(layer => { layer.show = false }) this.showModel = false } } else if (this.alpha < 80) { // 近,透 if (this.showLine) { line_layer.forEach(layer => { layer.show = false }) this.showLine = false } if (!this.showModel) { const wellTypes = this.checkedLayer.filter(item => item.indexOf('well-') > -1).map(item => item.substring(5)) point_layer_3D.forEach(layer => { layer.show = wellTypes.indexOf(layer.options.name) > -1 }) this.showModel = true } } else { // 近,不透 if (this.showLine) { line_layer.forEach(layer => { layer.show = false }) this.showLine = false } if (this.showModel) { point_layer_3D.forEach(layer => { layer.show = false }) this.showModel = false } } }, // 初始化放这里 mapReady() { this.fetchDeviceList() this.firstAmount = true this.toolShow = true this.refreshAlarm() if (this.refreshType === 'clock') { // 如果需要倒计时刷新的 setTimeout(() => { this.countDown() }, 1000) } }, // 过滤图层 filterLayer(checkedLayer) { this.checkedLayer = checkedLayer // 1.过滤井图层 const wellTypes = checkedLayer.filter(item => item.indexOf('well-') > -1).map(item => item.substring(5)) const lineTypes = checkedLayer.filter(item => item.indexOf('line-') > -1).map(item => item.substring(5)) // 点 point_layer.forEach(layer => { layer.show = wellTypes.indexOf(layer.options.name) > -1 }) point_layer_3D.forEach(layer => { layer.show = wellTypes.indexOf(layer.options.name) > -1 }) // 线 line_layer.forEach(layer => { layer.show = lineTypes.indexOf(layer.options.name) > -1 }) line_layer_3D.forEach(layer => { layer.show = lineTypes.indexOf(layer.options.name) > -1 }) // 2.选中or没选中报警图层 if (checkedLayer.indexOf('alarm') !== -1) { this.showAlarm = true } else { this.showAlarm = false } }, // 切换底图 changeBaseMap(type) { this.baseLayer = type if (type === 'gaode_vec') { window.map.basemap = 1112 if (this.bloomEffect !== null) { this.bloomEffect.enabled = false } } else { window.map.basemap = 1113 if (this.bloomEffect !== null) { this.bloomEffect.enabled = true } } }, // 倒计时函数 countDown() { this.clock = setInterval(() => { this.count-- if (this.count < 0) { // 当倒计时小于0时清除定时器 this.refreshAlarm() this.count = this.baseConfig.refreshTime } }, 1000) }, // 获取点位类型,显示点位类型下拉 fetchWellType() { // getWellType().then(response => { // this.wellTypeList = [] // // 如果该用户支持的点位类型只有一个,则不显示该筛选框 // const supportWellTypes = this.$store.getters.wellTypes // this.wellTypeList = response.data.filter(wellType => { // return supportWellTypes.findIndex(item => item == wellType.value) > -1 // }) // }) this.wellTypeList = this.layerName.map((item, index) => { return { value: item, name: item } }) this.wellTypeList.length = 8 const wellLayer = { id: 'well', name: '井图层', children: this.wellTypeList.map(item => { return { id: 'well-' + item.value, name: item.name } }) } const lineLayer = { id: 'line', name: '管线图层', children: this.layerName.map(item => { return { id: 'line-' + item, name: item } }).splice(8, 9) } const deviceTypes = this.$store.getters.deviceTypes this.layers.splice(0, 1, wellLayer) this.layers.splice(1, 1, lineLayer) if (this.baseConfig.showAllWells) { // this.checkedLayer = [...this.checkedLayer, 'well', this.wellTypeList.map(item => 'well-' + item.value), 'line', lineLayer.children.map(item => item.id)] this.checkedLayer = ['well', 'line'] this.wellTypeList.forEach(item => this.checkedLayer.push('well-' + item.value)) lineLayer.children.forEach(item => this.checkedLayer.push('line-' + item.value)) } else { this.checkedLayer = [...this.checkedLayer] } if (this.wellTypeList.length <= 1) { this.showWellType = false } getDeviceType(this.listQuery).then(response => { this.deviceTypeList = [] // 过滤掉该单位不支持的设备类型 const deviceTypes = this.$store.getters.deviceTypes for (const deviceType of response.data) { if (deviceTypes.indexOf(deviceType.value) !== -1) { this.deviceTypeList.push(deviceType) } } const devLayer = { id: 'dev', name: '设备图层', children: this.deviceTypeList.map(item => { return { id: 'dev-' + item.value, name: item.name } }) } this.layers.splice(2, 1, devLayer) }) }, /** * 数据筛选 * @param listQuery 筛选条件 * @param showMessage 是否告知筛选结果 */ dataFilter(listQuery, showMessage = true) { if (this.type === 'massMarkers') { // 过滤海量点 this.filterMassMarker(listQuery, showMessage) this.filterAlarm(listQuery, showMessage) } else if (this.type === 'cluster') { // 过滤聚合点 // this.filterClusters(listQuery, showMessage) this.filterAlarm(listQuery, showMessage) } }, // 清空查询 clearSearch() { this.searchMarkers = [] this.resultList = [] }, // 数据查询 search(keywords) { if (keywords === '') { this.$message.warning('搜索条件不能为空') } else { this.resultList = this.markers.filter(item => { if (item.wellCode.includes(keywords) || item.wellName.includes(keywords) || item.position.includes(keywords)) { return true } else { return false } }) this.initPoint(keywords) } }, // 搜索结果页面变化,触发地图展示列表中所有 searchPageChange(currentMarkers) { // 增加查询展示图层 this.searchMarkers = currentMarkers }, // 点击搜索结果项居中,弹窗 searchItemClick(marker) { // this.center = marker.lnglat // this.openInfoWindow(marker.wellId, marker.lnglat, this.searchResultOffset[1]) }, // 过滤海量点,给markers赋visible值 filterMassMarker(listQuery, showMessage = false) { const hideWellIds = []// 要隐藏的点位编号 let center = [] // 待移动到的地图中心 // 2. 整理查询条件 const keywords = listQuery.keywords // 关键字 const wellTypes = listQuery.wellTypes ? listQuery.wellTypes : listQuery.wellType ? [listQuery.wellType] : [] // 点位类型 let deptids = [] // 所有权属 if (listQuery.deptid) { deptids = this.fetchDeptList(listQuery.deptid) // 获取所有下级 } // 3.查询全部井,是否匹配,只要有一项不匹配则show为false for (const marker of this.markers) { let show = true // 关键字不为空,且没有匹配成功,不显示, 关键字匹配点位编号和位置 if (keywords && keywords !== '' && !(marker.wellCode.indexOf(keywords) !== -1 || marker.position.indexOf(keywords) !== -1)) { show = false } // 部门不为空, 且没有匹配成功,多部门匹配 if (deptids.length > 0 && deptids.indexOf(marker.deptid) === -1) { show = false } // 点位类型不为空,且没有匹配成功 if (wellTypes && wellTypes.length > 0 && wellTypes.indexOf(marker.wellType) === -1) { show = false } // 如果show为false,放入需要隐藏的井id列表 if (show === false) { hideWellIds.push(marker.wellId) } else { center = marker.lnglat } marker.visible = show } this.resetMassMarker() }, // 过滤报警 filterAlarm(listQuery, showMessage = false) { const hideWellIds = []// 要隐藏的点位编号 // 整理筛选条件 const keywords = listQuery.keywords const wellTypes = listQuery.wellTypes ? listQuery.wellTypes : listQuery.wellType ? [listQuery.wellType] : [] // 点位类型 let deptids = [] // 所有权属 if (listQuery.deptid) { deptids = this.fetchDeptList(listQuery.deptid) // 获取所有下级 } // 查询报警的井 for (const marker of this.alarmWells) { let show = true // 关键字不为空,且没有匹配成功,不显示, 关键字匹配点位编号和位置 if (keywords && keywords !== '' && !(marker.wellCode.indexOf(keywords) !== -1 || marker.position.indexOf(keywords) !== -1)) { show = false } // 部门不为空, 且没有匹配成功,多部门匹配 if (deptids.length > 0 && deptids.indexOf(marker.deptid) === -1) { show = false } // 点位类型不为空,且没有匹配成功 if (wellTypes && wellTypes.length > 0 && wellTypes.indexOf(marker.wellType) === -1) { show = false } // 如果show为false,放入需要隐藏的井id列表 if (show === false) { hideWellIds.push(marker.wellId) } marker.visible = show } // 4.过滤报警marker:alarmWells 如果没有找到符合要求的井,直接将全部查询结果隐藏,并将所有报警隐藏,否则按照查询结果筛选需要隐藏的报警 if (hideWellIds.length === this.alarmWells.length) { for (const alarmWell of this.alarmWells) { alarmWell.visible = false } } else { // 将报警隐藏 for (const alarmWell of this.alarmWells) { if (hideWellIds.indexOf(alarmWell.wellId) > -1) { alarmWell.visible = false } else { alarmWell.visible = true } } } // 5.过滤显示列表:alarmList this.alarmList = [] if (hideWellIds.length > 0) { // 如果有要隐藏的井,过滤 for (const alarm of this.alarmListOri) { const findFlag = hideWellIds.findIndex(code => code === alarm.wellId) if (findFlag === -1) { this.alarmList.push(alarm) } } } else { // 如果没有直接等于alarmListOri this.alarmList = this.alarmListOri } }, // 获取全部井列表 fetchDeviceList() { this.loading = false this.deviceTypeList.forEach(item => { const param = { deviceType: item.value } // getDeviceAllList(param).then(response => { // if (response.code === 200) { // if (response.data.length === 0) return // const graphicLayer = new mars3d.layer.GraphicLayer({ name: item.name }) // window.map.addLayer(graphicLayer) // dev_layer.push(graphicLayer) // const name = item.name.substr(0, 1) // response.data.forEach(data => { // if (wellLoc[data.wellCode] !== undefined && wellLoc[data.wellCode].length === 2) { // const primitive = new mars3d.graphic.ModelPrimitive({ // position: [wellLoc[data.wellCode][0], wellLoc[data.wellCode][1], -3], // style: { // url: '../static/model/' + 1 + '.glb', // scale: 1, // label: { // // 面中心点,显示文字的配置 // text: name, // 对应的属性名称 // opacity: 1, // font_size: 14, // color: '#ffffff', // font_weight: 'bold', // font_style: 'normal', // addHeight: 3, // // scaleByDistance: true, // // // // pixelOffsetY: -40, // // // // scaleByDistance_far: 300000, // // scaleByDistance_farValue: 0.4, // // scaleByDistance_near: 1, // // scaleByDistance_nearValue: 1.4, // visibleDepth: false // } // } // }) // graphicLayer.addGraphic(primitive) // } // }) // } // }) }) }, // 刷新报警列表 refreshAlarm() { console.log('refreshAlarm') this.count = this.baseConfig.refreshTime this.loading = true // 如果showAlarm为ture, 确保选中图层报警 if (this.showAlarm && this.checkedLayer.indexOf('alarm') == -1) { this.checkedLayer.push('alarm') } getAlarmsNow().then(response => { if (response.code === 200) { this.loading = false // 判断最新报警时间,若和旧的最新时间不一样,则判断是否需要产生声音 if (response.data.length > 0) { const latestTime = response.data[0].alarmTime console.log(latestTime, 'vs', this.latestAlarmTime) if (this.latestAlarmTime < latestTime) { // 如果不是初次加载并且声音开关开启状态 if ((!this.alarmFirstAmount) && this.baseConfig.alarmSound) { console.log('playAudio') this.playAudio() } this.latestAlarmTime = latestTime } } this.alarmFirstAmount = false // 初次加载完毕 // 获取当前报警列表 this.alarmListOri = response.data // 列表原始 this.alarmList = response.data // 要显示的报警列表 this.alarmWells = [] // 报警的井列表 for (const alarm of response.data) { if (this.alarmWells.findIndex(item => item.wellCode === alarm.wellCode) == -1) { this.alarmWells.push({ wellCode: alarm.wellCode, wellId: alarm.wellId, wellType: alarm.wellType, lngGaode: alarm.lngGaode, latGaode: alarm.latGaode, coordinates: [alarm.lngGaode, alarm.latGaode], position: alarm.position, visible: true }) } } console.log('alarmWells Length', this.alarmWells.length) } }) }, /** * 打开报警弹窗 * @param wellId 井id * @param coordinates 弹窗位置: [经度,纬度] * @param needCenter 是否需要将点居中 */ openAlarmWindow(wellId, coordinates, needCenter = false) { console.log('openAlarmWindow:' + wellId) // if (this.needCenter) { // 如果需要居中 // this.center = coordinates // } // 获取报警详情 getWellAlarms(wellId).then(response => { if (response.code === 200) { const wellInfo = response.data const alarmInfo = { wellCode: response.data.wellCode, position: response.data.position, deptName: response.data.deptName, wellTypeName: response.data.wellTypeName, alarms: response.data.alarmList, deep: response.data.deep } const AlarmWindow = Vue.extend({ render: h => h(AlarmInfoWindow, { props: { alarmInfo: alarmInfo }}) }) const alarmWindow = new AlarmWindow().$mount() const infoWindow = new window.AMap.InfoWindow({ content: alarmWindow.$el, // 显示内容 offset: [0, this.alarmOffset[1]], // 偏移 autoMove: true // 是否自动调整窗体到视野内 }) infoWindow.open(window.map, new toLngLat(coordinates)) } }) }, // 关闭所有弹窗 clearInfoWindow() { const { map } = this map.clearInfoWindow() }, // 点击报警列表 alarmRowClick(row) { console.log('alarmRowClick') const wellId = row.wellId for (const alarmWell of this.alarmWells) { if (alarmWell.wellId === wellId) { // this.center = alarmWell.coordinates if (this.zoom < 16) { this.zoom = 16 } this.openAlarmWindow(alarmWell.wellId, alarmWell.coordinates, true) } } }, // 点击工具箱菜单, menu:{menu:'xxx', name:''}, 建议菜单menu属性的命名与自定义弹窗的show属性名称保持同一规则 clickMenu(menu) { this.closeAllPopup() const key = menu.menu + 'WindowShow' const obj = {} obj[key] = true // 将该值置为false, 需要借助obj中转 Object.assign(this.menus, obj) }, // 关闭所有菜单点出的弹窗 closeAllPopup() { for (const key in this.menus) { if (key.indexOf('WindowShow') > -1) { // 将该值置为false, 需要借助obj中转 const obj = {} obj[key] = false Object.assign(this.menus, obj) } } }, // 关闭数据筛选弹窗 closePopupDataFilter() { Object.assign(this.menus, { dataFilterWindowShow: false }) }, // 坐标定位,居中,绘点 setCenter(position) { this.center = position var center = { lat: this.center[1], lng: this.center[0], alt: 10000, heading: 360, pitch: -45 } window.map.setCameraView(center) }, // 坐标拾取, 在地图上绘点 pickerPosition() { const { searchResultOffset, searchResultIcon, searchResultSize, center } = this const icon = new window.AMap.Icon({ size: toSize(searchResultSize), // 图标尺寸 image: searchResultIcon, // Icon的图像 imageSize: toSize(searchResultSize) // 根据所设置的大小拉伸或压缩图片 }) const marker = new window.AMap.Marker({ icon: icon, position: center, offset: toPixel(searchResultOffset), draggable: true }) marker.on('dragend', e => { const position = [e.lnglat.lng, e.lnglat.lat] this.$refs.popupLocation.setQuery(position) }) marker.setMap(window.map) this.tempMarker = marker }, // TODO: 关闭坐标定位窗口, 清除地图上的标注 closePopupLocation() { Object.assign(this.menus, { locationWindowShow: false }) }, // 获取当前deptid的所有下级id,仅最多支持3级 fetchDeptList(deptid) { console.log('fetchDeptList') const deptids = [deptid] // 储存了该pid和其子集 const deptlist = this.$refs.deptSelect.fetchDeptTree() for (const dept of deptlist) { if (dept.pid === deptid) { deptids.push(dept.id) } } const result = [] // 查找所有列表中有没有deptids里面的本人或子集 if (deptlist.length > 0) { for (const dept of deptlist) { if (deptids.indexOf(dept.id) !== -1) { result.push(dept.id) } else if (deptids.indexOf(dept.pid) !== -1) { result.push(dept.id) } } } console.log(result) return result } } } </script> <style rel="stylesheet/scss" lang="scss"> // 查询框 .map-search-div{ position: absolute; z-index: 100; padding: 5px 20px; background-color: rgba(244, 244, 244, 0.9); /*left: 90px;*/ .el-form-item{ margin-bottom: 0px; } } // 刷新框 .function-div{ position: absolute; right: 10px; top: 7px; z-index: 1100; padding: 10px; color: #ce8b74; font-size: 14px; /*background-color: rgba(244, 233, 230, 1.0);*/ .font-red{ color: red; font-weight: bold; } .el-icon-refresh:hover{ color: #ff7fe9; font-weight: bold; cursor: pointer; } } // 刷新框 .refresh-div{ position: absolute; right: 10px; top: 7px; z-index: 100; padding: 10px; color: #ce8b74; font-size: 14px; background-color: rgba(244, 233, 230, 1.0); .font-red{ color: red; font-weight: bold; } .el-icon-refresh:hover{ color: red; font-weight: bold; cursor: pointer; } } // 地图 .overview-map-container{ width: 100%; overflow-y: hidden; padding: 0px; .map-demo{ width: 100%; .svg-icon{ width: 20px; height: 20px; } .alarm-icon{ width: 29px; height: 30px; } .nomal-info-window{ background-color: pink; } } } .search-marker{ position: relative; .search-marker-image{ width: 100%; height: 100%; } .search-marker-label{ position:absolute; font-size: 14px; font-weight: 600; color:#FFF; z-index:50; top: 4px; left: 50%; transform: translateX(-50%) } } .cover{ position: absolute; bottom: 0px; left: 0px; display: flex; flex-wrap: wrap; background-color: #fcfbe8; width: 210px; height: 180px; padding: 6px; .cover-item{ width: 50%; padding: 1px; font-size: 13px; } } </style> <style rel="stylesheet/scss" lang="scss" scoped> .no-head-scrollbar .el-scrollbar__wrap, has-head-scrollbar .el-scrollbar__wrap { padding: 0px 10px; } </style>