wvp-GB28181-pro/web_src/src/components/map.vue

387 lines
13 KiB
Vue
Raw Normal View History

2021-01-27 15:24:28 +08:00
<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>
2022-07-03 07:40:54 +08:00
<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 === 1">线</el-tag>
<el-tag size="small" type="info" v-if="channel.status === 0">线</el-tag>
</el-descriptions-item>
</el-descriptions>
<div style="padding-top: 10px">
2022-07-03 07:40:54 +08:00
<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>
2021-01-27 15:24:28 +08:00
</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'
2021-01-27 15:24:28 +08:00
export default {
name: "map",
components: {
MapComponent,
DeviceTree,
channelMapInfobox,
devicePlayer,
queryTrace,
},
data() {
return {
2022-05-06 16:01:36 +08:00
onOff: typeof window.mapParam !== "undefined" && window.mapParam.enable,
deviceService: new DeviceService(),
layer: null,
lineLayer: null,
channel: null,
2022-07-03 07:40:54 +08:00
device: null,
infoBoxId: null,
labelStyle: {
width: "56px"
},
isLoging: false,
2022-07-03 07:40:54 +08:00
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)
2022-07-03 07:40:54 +08:00
}
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: {
2022-07-03 07:40:54 +08:00
clickEvent: function (device, data, isCatalog) {
this.device = device;
if (data.channelId && !isCatalog) {
// 点击通道
2022-07-03 07:40:54 +08:00
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([{
2022-07-03 07:40:54 +08:00
position: [data[this.longitudeStr], data[this.latitudeStr]],
image: {
src: this.getImageByChannel(data),
anchor: [0.5, 1]
},
data: data
}], this.featureClickEvent)
2022-07-03 07:40:54 +08:00
this.$refs.map.panTo([data[this.longitudeStr], data[this.latitudeStr]], mapParam.maxZoom)
}
}
},
2022-07-03 07:40:54 +08:00
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",
2022-07-03 07:40:54 +08:00
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)
}
2021-01-27 15:24:28 +08:00
}
],
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)
}
2021-01-27 15:24:28 +08:00
}
}
],
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 = [];
2022-07-03 07:40:54 +08:00
for (let i = 0; i < channels.length; i++) {
2022-07-03 07:40:54 +08:00
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) {
2022-07-03 07:40:54 +08:00
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(() => {
2022-07-03 07:40:54 +08:00
let position = [this.channel[this.longitudeStr], this.channel[this.latitudeStr]];
2022-06-15 16:04:36 +08:00
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].cnLng * channelPositions[i].cnLat > 0) {
positions.push([channelPositions[i].cnLng, channelPositions[i].cnLat])
}
}
if (positions.length === 0) {
this.$message.success('未查询到轨迹信息');
return;
}
this.lineLayer = this.$refs.map.addLineLayer(positions)
this.$refs.map.fit(this.lineLayer)
}
})
2021-01-27 15:24:28 +08:00
},
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)
}
}
},
2021-01-27 15:24:28 +08:00
};
</script>
<style>
.infobox-content{
width: 260px;
background-color: #FFFFFF;
padding: 10px;
border-radius: 10px;
border: 1px solid #e2e2e2;
}
2021-01-27 15:24:28 +08:00
.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%;
}
2021-01-27 15:24:28 +08:00
</style>