| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423 |
- <template>
- <div id="devicePosition" style="width: 100vw; height: 91vh;">
- <el-container v-if="onOff" style="height: 91vh;" v-loading="isLoging">
- <el-aside width="400px" 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 (channelId) {
- this.$axios({
- method: 'get',
- url: `/api/common/channel/one`,
- params: {
- id: channelId,
- }
- }).then((res) => {
- if (res.data.code === 0) {
- console.log(res.data.data)
- console.log(res.data.data.gbLongitude)
- console.log(res.data.data.gbLatitude)
- if (!res.data.data.gbLongitude || !res.data.data.gbLatitude) {
- this.$message.error({
- showClose: true,
- message: "位置信息不存在"
- })
- }else {
- if (this.layer != null) {
- this.$refs.map.removeLayer(this.layer);
- }
- this.closeInfoBox()
- this.layer = this.$refs.map.addLayer([{
- position: [res.data.data.gbLongitude, res.data.data.gbLatitude],
- image: {
- src: this.getImageByChannel(res.data.data),
- anchor: [0.5, 1]
- },
- data: res.data.data
- }], this.featureClickEvent)
- this.$refs.map.panTo([res.data.data.gbLongitude, res.data.data.gbLatitude], mapParam.maxZoom)
- }
- }
- }).catch(function (error) {
- console.log(error);
- });
- },
- 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({
- showClose: true,
- message: "未获取到位置信息"
- })
- }
- } else {
- this.$message.error({
- showClose: true,
- message: "未获取到位置信息"
- })
- }
- },
- getImageByChannel: function (channel) {
- let src = "static/images/gis/camera.png"
- switch (channel.gbPtzType) {
- case 1:
- if (channel.gbStatus === "ON") {
- src = "static/images/gis/camera1.png"
- } else {
- src = "static/images/gis/camera1-offline.png"
- }
- break;
- case 2:
- if (channel.gbStatus === "ON") {
- src = "static/images/gis/camera2.png"
- } else {
- src = "static/images/gis/camera2-offline.png"
- }
- break;
- case 3:
- if (channel.gbStatus === "ON") {
- src = "static/images/gis/camera3.png"
- } else {
- src = "static/images/gis/camera3-offline.png"
- }
- break;
- default:
- if (channel.gbStatus === "ON") {
- 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({
- showClose: true,
- message: "暂不支持"
- })
- },
- 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.info({
- showClose: true,
- message: "未查询到轨迹信息"
- })
- } 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.info({
- showClose: true,
- message: "未查询到轨迹信息"
- })
- 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>
|