<template>
|
<div class="trace-plot">
|
<div class="filter-bar">
|
<el-date-picker
|
size="small"
|
v-model="searchTime"
|
@change="checkTime"
|
type="datetimerange"
|
:picker-options="pickerOptions"
|
start-placeholder="开始日期"
|
end-placeholder="结束日期"
|
value-format="yyyy-MM-dd HH:mm:ss"
|
:default-time="['00:00:00','23:59:59']"
|
></el-date-picker>
|
<el-button @click="checkTime" size="small" type="primary" class="btn-search">查 询</el-button>
|
</div>
|
<div class="check-target" :style="{height:fixedH+'px'}">
|
<div class="controller">
|
<!-- <el-checkbox v-model="isHideAll" @change="hideAllChange">隐藏全部</el-checkbox> -->
|
<el-checkbox v-model="isInvert" @change="invertChange">反选</el-checkbox>
|
</div>
|
<div class="target-list">
|
<div
|
class="list-item"
|
v-for="item in actObjs"
|
:key="item.id"
|
:class="{'deact':item.isHide}"
|
:style="{borderColor:item.isHide?'#ccc':item.color}"
|
@click="checkTarget(item)"
|
>
|
<!-- <img src alt :style="{backgroundColor:item.color}"/> -->
|
<img :src="'/httpImage/'+item.picSmUrl" />
|
</div>
|
</div>
|
</div>
|
<!-- <canvas
|
ref="trackArea"
|
:width="cW"
|
:height="cH"
|
:style="{backgroundImage:`url(${panoramaPath})`}"
|
></canvas>-->
|
<canvas
|
ref="trackArea"
|
:width="fixedW"
|
:height="fixedH"
|
:style="{backgroundImage:`url(${panoramaPath})`,backgroundSize:`${bgW}px ${bgH}px`}"
|
></canvas>
|
</div>
|
</template>
|
|
<script>
|
import { getSearchList } from '@/api/search';
|
import { getPanoramaPic } from "@/api/panorama";
|
export default {
|
data() {
|
return {
|
cW: 0,
|
cH: 0,
|
panoramaPath: '',
|
trackData: [],
|
activeObjHashMap: {},
|
actObj: {},
|
actObjs: [],
|
searchTime: [
|
this.$moment().format("YYYY-MM-DD 00:00:00"),
|
this.$moment().format("YYYY-MM-DD 23:59:59")
|
//this.$moment().format("YYYY-MM-DD HH:mm:ss")
|
],
|
pickerOptions: {
|
shortcuts: [{
|
text: '近一小时',
|
onClick(picker) {
|
const end = new Date();
|
const start = new Date();
|
start.setTime(start.getTime() - 60 * 60 * 1000);
|
picker.$emit('pick', [start, end])
|
}
|
}, {
|
text: '近三小时',
|
onClick(picker) {
|
const end = new Date();
|
const start = new Date();
|
start.setTime(start.getTime() - 60 * 60 * 1000 * 3);
|
picker.$emit('pick', [start, end])
|
}
|
}, {
|
text: '近六小时',
|
onClick(picker) {
|
const end = new Date();
|
const start = new Date();
|
start.setTime(start.getTime() - 60 * 60 * 1000 * 6);
|
picker.$emit('pick', [start, end])
|
}
|
}]
|
},
|
timer: null,
|
intervalTime: 5000,
|
colorArr: ['#F4DA40', '#0092BC', '#97D700', '#D0006F', '#D86018', '#653279', '#A45A2A', '#004B87', '#008C95', '#AA0061'],
|
searchStartTimeStamp: 0,
|
searchEndTimeStamp: 0,
|
fixedW: 960,
|
fixedH: 700,
|
bgW: 0,
|
bgH: 0,
|
targetChecked: [],
|
isHideAll: false,
|
isInvert: false,
|
}
|
},
|
mounted() {
|
this.searchData();
|
//this.filterData();
|
this.getPanorama();
|
|
},
|
beforeDestroy() {
|
clearInterval(this.timer);
|
},
|
methods: {
|
checkTime() {
|
if (!this.searchTime) {
|
this.$notify({
|
type: 'warning',
|
message: '请选择时间!'
|
});
|
return;
|
}
|
clearInterval(this.timer);
|
//判断是否是查历史数据
|
if (Date.parse(this.searchTime[1]) < Date.now()) {
|
this.filterData()
|
} else {
|
this.activeObjHashMap = {};
|
//实时查
|
this.searchData();
|
}
|
},
|
filterData() {
|
let _this = this;
|
var param = {
|
page: 1,
|
size: 5000,
|
searchTime: this.searchTime,
|
timeMark: null,
|
alarmlevel: [],
|
inputValue: '',
|
tabs: [],
|
tasks: [],
|
treeNodes: [],
|
isAll: false
|
};
|
//clearInterval(this.timer);
|
getSearchList(param).then(res => {
|
_this.actObjs = [];
|
if (!res.data.datalist) {
|
this.$notify({
|
type: 'info',
|
message: '此时间段内无人员轨迹,请选择其他时间段查看!'
|
});
|
_this.drawTracePath();
|
|
return;
|
}
|
res.data.datalist.forEach(obj => {
|
obj.activeObject.targetInfo.forEach(target => {
|
if (target.targetType == 'UniquelID') {
|
let attribute = JSON.parse(target.attribute);
|
let someone = _this.actObjs.find(actObj => actObj.id == target.targetId);
|
if (someone) {
|
someone.posInfo.unshift({ globalCoordX: attribute.globalCoordX, globalCoordY: attribute.globalCoordY, timeStamp: Date.parse(obj.activeObject.picDate) });
|
} else {
|
_this.actObjs.push({ id: target.targetId, picSmUrl: target.picSmUrl, posInfo: [{ globalCoordX: attribute.globalCoordX, globalCoordY: attribute.globalCoordY, timeStamp: Date.parse(obj.activeObject.picDate) }] });
|
}
|
}
|
})
|
});
|
for (var i = 0; i < _this.actObjs.length; i++) {
|
this.$set(_this.actObjs[i], 'color', _this.colorArr[i % 10]);
|
this.$set(_this.actObjs[i], 'isHide', _this.actObjs[i].isHide);
|
}
|
_this.drawTracePath();
|
})
|
},
|
hideAllChange() {
|
this.actObjs.forEach(target => {
|
target.isHide = this.isHideAll;
|
});
|
this.drawTracePath();
|
},
|
invertChange() {
|
console.log(this.isInvert)
|
this.actObjs.forEach(target => {
|
target.isHide = !target.isHide;
|
});
|
let showOne = this.actObjs.find(target => !target.isHide);
|
if (!showOne) {
|
this.isHideAll = true;
|
} else {
|
this.isHideAll = false;
|
}
|
this.drawTracePath();
|
},
|
checkTarget(item) {
|
item.isHide = !item.isHide;
|
this.isHideAll = item.isHide;
|
this.drawTracePath();
|
},
|
getPanorama() {
|
let _this = this;
|
getPanoramaPic().then(res => {
|
let { panoramaPath, width, height } = res.data;
|
_this.panoramaPath = panoramaPath + '?' + Math.random();
|
_this.cW = width;
|
_this.cH = height;
|
//判断长宽比
|
let ratio = res.data.width / res.data.height;
|
if (ratio > (_this.fixedW / _this.fixedH)) {
|
_this.bgW = _this.fixedW;
|
_this.bgH = _this.bgW * res.data.height / res.data.width;
|
} else {
|
_this.bgH = _this.fixedH;
|
_this.bgW = res.data.width * _this.bgH / res.data.height;
|
}
|
})
|
},
|
drawTracePath() {
|
let canvas = this.$refs['trackArea'];
|
let ctx = canvas.getContext('2d');
|
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
ctx.lineWidth = 3;
|
ctx.lineCap = 'round';
|
this.actObjs.forEach(target => {
|
if (!target.isHide) {
|
ctx.beginPath();
|
ctx.fillStyle = target.color;
|
ctx.arc(target.posInfo[0].globalCoordX, target.posInfo[0].globalCoordY, 3, 0, Math.PI * 2);
|
ctx.fill();
|
for (var i = 1; i < target.posInfo.length; i++) {
|
ctx.beginPath();
|
ctx.arc(target.posInfo[i].globalCoordX, target.posInfo[i].globalCoordY, 3, 0, Math.PI * 2);
|
ctx.fill();
|
}
|
}
|
|
});
|
this.actObjs.forEach(target => {
|
if (!target.isHide) {
|
ctx.beginPath();
|
ctx.strokeStyle = target.color;
|
ctx.moveTo(target.posInfo[0].globalCoordX, target.posInfo[0].globalCoordY);
|
for (var i = 1; i < target.posInfo.length; i++) {
|
ctx.lineTo(target.posInfo[i].globalCoordX, target.posInfo[i].globalCoordY)
|
}
|
ctx.stroke();
|
}
|
})
|
},
|
searchData() {
|
let _this = this;
|
var param = {
|
page: 1,
|
size: 5000,
|
searchTime: this.searchTime,
|
alarmlevel: [],
|
inputValue: '',
|
tabs: [],
|
tasks: [],
|
treeNodes: [],
|
isAll: false
|
};
|
if ((new Date() - _this.timeMark) < _this.intervalTime) {
|
return
|
}
|
getSearchList(param).then(res => {
|
_this.activeObjHashMap = {};
|
_this.actObjs = [];
|
if (!res.data.datalist) {
|
//_this.activeObjHashMap = {};
|
//_this.actObj = {};
|
_this.actObjs = [];
|
this.$notify({
|
type: 'info',
|
message: '此时间段内无人员轨迹,请选择其他时间段查看!'
|
});
|
_this.drawTracePath();
|
clearInterval(this.timer);
|
return;
|
}
|
for (var key in _this.activeObjHashMap) {
|
let innerKey = res.data.datalist && res.data.datalist.find(obj => obj.activeObject.id == key);
|
if (!innerKey) {
|
delete _this.activeObjHashMap[key];
|
//delete _this.actObj[key];
|
let index = _this.actObjs.findIndex(one => one.id == innerKey);
|
_this.actObjs.splice(index, 1)
|
}
|
}
|
|
let filterArr = [];
|
res.data.datalist && res.data.datalist.forEach(obj => {
|
if (_this.activeObjHashMap[obj.activeObject.id] !== 1) {
|
_this.activeObjHashMap[obj.activeObject.id] = 1
|
filterArr.push(obj)
|
}
|
//filterArr.push(obj)
|
});
|
|
//filterArr.forEach(item => {
|
res.data.datalist.forEach(item => {
|
item.activeObject.targetInfo.forEach(target => {
|
if (target.targetType == 'UniquelID') {
|
let attribute = JSON.parse(target.attribute);
|
let someone = _this.actObjs.find(obj => obj.id == target.targetId);
|
if (someone) {
|
someone.posInfo.unshift({ globalCoordX: attribute.globalCoordX, globalCoordY: attribute.globalCoordY, timeStamp: Date.parse(item.activeObject.picDate) });
|
} else {
|
_this.actObjs.push({ id: target.targetId, picSmUrl: target.picSmUrl, posInfo: [{ globalCoordX: attribute.globalCoordX, globalCoordY: attribute.globalCoordY, timeStamp: Date.parse(item.activeObject.picDate) }] });
|
}
|
|
if (_this.actObj[target.targetId]) {
|
_this.actObj[target.targetId].unshift({ picSmUrl: target.picSmUrl, globalCoordX: attribute.globalCoordX, globalCoordY: attribute.globalCoordY, timeStamp: Date.parse(item.activeObject.picDate) });
|
|
} else {
|
_this.actObj[target.targetId] = [{ picSmUrl: target.picSmUrl, globalCoordX: attribute.globalCoordX, globalCoordY: attribute.globalCoordY, timeStamp: Date.parse(item.activeObject.picDate) }];
|
|
}
|
}
|
})
|
});
|
|
_this.searchStartTimeStamp = Date.parse(_this.searchTime[0]);
|
_this.searchEndTimeStamp = Date.parse(_this.searchTime[1]);
|
|
for (var i = 0; i < _this.actObjs.length; i++) {
|
_this.actObjs[i].posInfo = _this.actObjs[i].posInfo.filter(item => item.timeStamp >= _this.searchStartTimeStamp && item.timeStamp <= _this.searchEndTimeStamp)
|
|
if (!_this.actObjs[i].posInfo.length) {
|
_this.actObjs.splice(i, 1);
|
}
|
|
this.$set(_this.actObjs[i], 'color', _this.colorArr[i % 10]);
|
this.$set(_this.actObjs[i], 'isHide', _this.actObjs[i].isHide);
|
}
|
|
// console.log(_this.actObjs)
|
|
_this.drawTracePath();
|
_this.timeMark = new Date();
|
_this.timer = setTimeout(() => {
|
_this.searchData()
|
}, _this.intervalTime)
|
|
|
})
|
}
|
}
|
}
|
</script>
|
|
<style lang="scss">
|
.trace-plot {
|
.filter-bar {
|
width: 960px;
|
margin: 20px 10px;
|
display: flex;
|
align-items: center;
|
flex-direction: end;
|
.btn-search {
|
margin-left: 20px;
|
}
|
}
|
.check-target {
|
padding: 30px;
|
box-sizing: border-box;
|
overflow: auto;
|
background: #f1f4f9;
|
float: left;
|
.target-list {
|
display: flex;
|
flex-wrap: wrap;
|
justify-content: space-between;
|
width: 300px;
|
|
.list-item {
|
width: 80px;
|
height: 80px;
|
margin-bottom: 10px;
|
border: 3px solid yellow;
|
border-radius: 50%;
|
img {
|
width: 100%;
|
height: 100%;
|
display: block;
|
border-radius: 50%;
|
}
|
&.deact {
|
opacity: 0.5;
|
background: rgba(0, 0, 0, 0.3);
|
}
|
}
|
}
|
}
|
canvas {
|
//background: lightsteelblue;
|
background-repeat: no-repeat;
|
}
|
}
|
</style>
|