<template> <div id="devicePosition" style="width: 100vw; height: 91vh;"> <el-container v-if="onOff" style="height: 91vh;" v-loading="isLoging"> <el-aside width="auto" style="background-color: #ffffff"> <DeviceTree ref="deviceTree" :clickEvent="clickEvent" :contextMenuEvent="contextmenuEventHandler" ></DeviceTree> </el-aside> <el-main style="height: 91vh; padding: 0"> <MapComponent ref="map"></MapComponent> </el-main> </el-container> <div v-if="!onOff" style="width: 100%; height:100%; text-align: center; line-height: 5rem"> <p>地图功能已关闭</p> </div> <div ref="infobox" v-if="channel != null " > <div v-if="channel != null" class="infobox-content"> <el-descriptions class="margin-top" :title="channel.name" :column="1" :colon="true" size="mini" :labelStyle="labelStyle" > <el-descriptions-item label="编号" >{{channel.channelId}}</el-descriptions-item> <el-descriptions-item label="型号">{{channel.model}}</el-descriptions-item> <el-descriptions-item label="经度" >{{channel[longitudeStr]}}</el-descriptions-item> <el-descriptions-item label="纬度" >{{channel[latitudeStr]}}</el-descriptions-item> <el-descriptions-item label="生产厂商">{{channel.manufacture}}</el-descriptions-item> <el-descriptions-item label="行政区域" >{{channel.civilCode}}</el-descriptions-item> <el-descriptions-item label="设备归属" >{{channel.owner}}</el-descriptions-item> <el-descriptions-item label="安装地址" >{{channel.address == null?'未知': channel.address}}</el-descriptions-item> <el-descriptions-item label="云台类型" >{{channel.PTZTypeText}}</el-descriptions-item> <el-descriptions-item label="通道状态"> <el-tag size="small" v-if="channel.status === true">在线</el-tag> <el-tag size="small" type="info" v-if="channel.status === false">离线</el-tag> </el-descriptions-item> </el-descriptions> <div style="padding-top: 10px"> <el-button v-bind:disabled="device == null || device.online === 0" type="primary" size="small" title="播放" icon="el-icon-video-play" @click="play(channel)"></el-button> <el-button type="primary" size="small" title="编辑位置" icon="el-icon-edit" @click="edit(channel)"></el-button> <el-button type="primary" size="small" title="轨迹查询" icon="el-icon-map-location" @click="getTrace(channel)"></el-button> </div> <span class="infobox-close el-icon-close" @click="closeInfoBox()"></span> </div> </div> <devicePlayer ref="devicePlayer" ></devicePlayer> <queryTrace ref="queryTrace" ></queryTrace> </div> </template> <script> import MapComponent from "./common/MapComponent.vue"; import DeviceService from "./service/DeviceService"; import DeviceTree from "./common/DeviceTree"; import channelMapInfobox from "./dialog/channelMapInfobox"; import devicePlayer from './dialog/devicePlayer.vue' import queryTrace from './dialog/queryTrace.vue' export default { name: "map", components: { MapComponent, DeviceTree, channelMapInfobox, devicePlayer, queryTrace, }, data() { return { onOff: typeof window.mapParam !== "undefined" && window.mapParam.enable, deviceService: new DeviceService(), layer: null, lineLayer: null, channel: null, device: null, infoBoxId: null, labelStyle: { width: "56px" }, isLoging: false, longitudeStr: "longitude", latitudeStr: "latitude", }; }, created() { if (this.$route.query.deviceId) { console.log(this.$route.query.deviceId) // this.$refs.deviceTree.openByDeivceId(this.$route.query.deivceId) setTimeout(()=>{ // 延迟以等待地图加载完成 TODO 后续修改为通过是实际这;状态加回调完成 this.deviceService.getAllChannel(false, false, this.$route.query.deviceId, this.channelsHandler) }, 1000) } if (window.mapParam.coordinateSystem == "GCJ-02") { this.longitudeStr = "longitudeGcj02"; this.latitudeStr = "latitudeGcj02"; }else if (window.mapParam.coordinateSystem == "WGS84") { this.longitudeStr = "longitudeWgs84"; this.latitudeStr = "latitudeWgs84"; }else { this.longitudeStr = "longitude"; this.latitudeStr = "latitude"; } }, destroyed() { }, methods: { clickEvent: function (device, data, isCatalog) { this.device = device; if (data.channelId && !isCatalog) { // 点击通道 if (data[this.longitudeStr] * data[this.latitudeStr] === 0) { this.$message.error('未获取到位置信息'); } else { if (this.layer != null) { this.$refs.map.removeLayer(this.layer); } this.closeInfoBox() this.layer = this.$refs.map.addLayer([{ position: [data[this.longitudeStr], data[this.latitudeStr]], image: { src: this.getImageByChannel(data), anchor: [0.5, 1] }, data: data }], this.featureClickEvent) this.$refs.map.panTo([data[this.longitudeStr], data[this.latitudeStr]], mapParam.maxZoom) } } }, contextmenuEventHandler: function (device, event, data, isCatalog) { console.log(device) console.log(device.online) this.device = device; if (data.channelId && !isCatalog) { // 点击通道 this.$contextmenu({ items: [ { label: "播放", icon: "el-icon-video-play", disabled: device.online === 0, onClick: () => { this.play(data); } }, { label: "编辑位置", icon: "el-icon-edit", disabled: false, onClick: () => { this.edit(data) } }, { label: "轨迹查询", icon: "el-icon-map-location", disabled: false, onClick: () => { this.getTrace(data) } } ], event, // 鼠标事件信息 customClass: "custom-class", // 自定义菜单 class zIndex: 3000, // 菜单样式 z-index }); } else { if (typeof data.channelId === "undefined") { this.deviceOrSubChannelMenu(event, data) }else { // TODO 子目录暂时不支持查询他下面所有设备, 支持支持查询直属于这个目录的设备 this.deviceOrSubChannelMenu(event, data) } } }, deviceOrSubChannelMenu: function (event, data) { // 点击设备 this.$contextmenu({ items: [ { label: "定位", icon: "el-icon-s-promotion", disabled: false, onClick: () => { if (!data.channelId) { this.deviceService.getAllChannel(false, false, data.deviceId, this.channelsHandler) } if (data.channelId && data.subCount > 0) { // 点击子目录 this.deviceService.getAllSubChannel(false, data.deviceId, data.channelId, this.channelsHandler) } } }, { label: "查询轨迹", icon: "el-icon-map-location", disabled: false, onClick: () => { this.getTrace(data) } } ], event, // 鼠标事件信息 customClass: "custom-class", // 自定义菜单 class zIndex: 3000, // 菜单样式 z-index }); }, channelsHandler: function (channels) { console.log(2) if (channels.length > 0) { this.clean() this.closeInfoBox() let params = []; for (let i = 0; i < channels.length; i++) { let longitude = channels[i][this.longitudeStr]; let latitude = channels[i][this.latitudeStr]; if (longitude * latitude === 0) { continue; } let item = { position: [longitude, latitude], image: { src: this.getImageByChannel(channels[i]), anchor: [0.5, 1] }, data: channels[i] } params.push(item); } console.log(3) this.layer = this.$refs.map.addLayer(params, this.featureClickEvent) console.log(4) if (params.length === 1) { this.$refs.map.panTo([channels[0][this.longitudeStr], channels[0][this.latitudeStr]], mapParam.maxZoom) } else if (params.length > 1) { this.$refs.map.fit(this.layer) } else { this.$message.error('未获取到位置信息'); } } else { this.$message.error('未获取到位置信息'); } }, getImageByChannel: function (channel) { let src = "static/images/gis/camera.png" switch (channel.ptzType) { case 1: if (channel.status === 1) { src = "static/images/gis/camera1.png" } else { src = "static/images/gis/camera1-offline.png" } break; case 2: if (channel.status === 1) { src = "static/images/gis/camera2.png" } else { src = "static/images/gis/camera2-offline.png" } break; case 3: if (channel.status === 1) { src = "static/images/gis/camera3.png" } else { src = "static/images/gis/camera3-offline.png" } break; default: if (channel.status === 1) { src = "static/images/gis/camera.png" } else { src = "static/images/gis/camera-offline.png" } } return src; }, featureClickEvent: function (channels) { this.closeInfoBox() if (channels.length > 0) { this.channel = channels[0] } this.$nextTick(() => { let position = [this.channel[this.longitudeStr], this.channel[this.latitudeStr]]; this.infoBoxId = this.$refs.map.openInfoBox(position, this.$refs.infobox, [0, -50]) }) }, closeInfoBox: function () { if (this.infoBoxId != null) { this.$refs.map.closeInfoBox(this.infoBoxId) } }, play: function (channel) { let deviceId = channel.deviceId; this.isLoging = true; let channelId = channel.channelId; console.log("通知设备推流1:" + deviceId + " : " + channelId); let that = this; this.$axios({ method: 'get', url: '/api/play/start/' + deviceId + '/' + channelId }).then(function (res) { that.isLoging = false; if (res.data.code === 0) { that.$refs.devicePlayer.openDialog("media", deviceId, channelId, { streamInfo: res.data.data, hasAudio: channel.hasAudio }); } else { that.$message.error(res.data.msg); } }).catch(function (e) { }); }, edit: function (data) { this.$message.warning('暂不支持'); }, getTrace: function (data) { // this.$message.warning('暂不支持'); this.clean() this.$refs.queryTrace.openDialog(data, (channelPositions) => { console.log("getTrace") console.log(channelPositions) if (channelPositions.length === 0) { this.$message.success('未查询到轨迹信息'); } else { let positions = []; for (let i = 0; i < channelPositions.length; i++) { if (channelPositions[i][this.longitudeStr] * channelPositions[i][this.latitudeStr] > 0) { positions.push([channelPositions[i][this.longitudeStr], channelPositions[i][this.latitudeStr]]) } } if (positions.length === 0) { this.$message.success('未查询到轨迹信息'); return; } this.lineLayer = this.$refs.map.addLineLayer(positions) this.$refs.map.fit(this.lineLayer) } }) }, clean: function (){ if (this.lineLayer != null) { this.$refs.map.removeLayer(this.lineLayer) } if (this.infoBoxId != null) { this.$refs.map.closeInfoBox(this.infoBoxId) } if (this.layer != null) { this.$refs.map.removeLayer(this.layer) } } }, }; </script> <style> .infobox-content{ width: 260px; background-color: #FFFFFF; padding: 10px; border-radius: 10px; border: 1px solid #e2e2e2; } .infobox-content::after { position: absolute; bottom: -11px; left: 130px; display: block; content: ""; width: 16px; height: 16px; background: url('~@static/images/arrow.png') no-repeat center; } .infobox-close { position: absolute; right: 1rem; top: 1rem; color: #000000; cursor:pointer } .el-descriptions__title { font-size: 1rem; font-weight: 700; padding: 20px 20px 0px 23px; text-align: center; width: 100%; } </style>