Commit 75aae19c authored by ninglx's avatar ninglx

大屏页面逻辑完善,系统逻辑优化,模型加载逻辑修改

parent 5c162f1e
const map_config = {
SYS_ID: 'CAFC20296895433784C193457A870DFD',
MAP_CENTER: [112.96428650617997, 28.1871212850601],
MAP_CENTER: [112.96340509661252, 28.187408862647146],
MAP_ZOOM: 17.2,
......
......@@ -95,3 +95,8 @@ export default {
width: 100%;
}
</style>
<style>
.l7-popup .l7-popup-content{
background: transparent !important;
}
</style>
......@@ -119,7 +119,7 @@ export default {
right: 1px;
}
.cameraVideo {
//position: relative;
position: relative;
.videoControl {
position: absolute;
height: 100%;
......
......@@ -7,5 +7,6 @@ export default {
weather: require('../../assets/images/holo/qxjcy.png'),
camera: require('../../assets/images/holo/spxj.png'),
sign: require('../../assets/images/holo/xhj.png'),
homeCamera: require('../../assets/images/sc/crossCamera.png')
},
}
......@@ -131,16 +131,18 @@ export default {
})
},
initPageData(){
initPageData() {
},
initWebS() {
if (this.loading) this.loading = false
// 注册车辆实时ws
this.regisAndSendWs("callCar", {dataType: "6"});
this.regisAndSendWs("callCar", {dataType: "1"});
},
// 更新经纬度-角度-详细信息
// 更新经纬度-角度-详细信息-弹窗信息
setModel(model, options, setColor) {
if (setColor) {
model.traverse((child) => {
......@@ -177,7 +179,7 @@ export default {
if (this.vehicleModelsNum === 21) {
for (let item of allData) {
// 交通事故车辆popup标注&更新
if (item.eventType.length) { // todo: 参与交通事件的车辆 特殊字段
if (item.eventType?.length) { // todo: 参与交通事件的车辆 特殊字段
if (!popups[`${item.id}`]) {
popups[`${item.id}`] = new Popup({
offsets: [-100, 280],
......@@ -217,22 +219,12 @@ export default {
}
}
}
// console.log('count...', window.tb.world.children.length)
}
},
// 比较websocket车辆前后两次数据差异
diff(oldData, newData) {
// id 只在 newData 中存在且不在 oldData 中存在的即为 add
const add = newData.filter((e) => !oldData.find((c) => c.id === e.id));
// id 只在 oldData 中存在且不在 newData 中存在的即为 dele
const del = oldData.filter((e) => !newData.find((c) => c.id === e.id));
const com = newData.filter((e) => oldData.find((c) => c.id === e.id));
add.forEach((a) => (a.dill = "add"));
del.forEach((d) => (d.dill = "del"));
com.forEach((c) => (c.dill = "com"));
return [...add, ...del, ...com];
},
callCar(msg) {
let start = performance.now();
// 筛选可见区域
for (let i = 0; i < msg.length; i++) {
if (!msg[i].picLicense) {
msg[i].picLicense = ''
......@@ -245,39 +237,81 @@ export default {
}
}
if (msg.length > 0) {
// 第一帧 || 时间戳不相同放行
// 第一帧 || 时间戳不相同 => 放行
if (this.lastLocation.length === 0 || this.lastLocation[0].dateTime !== msg[0].dateTime) {
this.situationTimeVal = msg[0].dateTime
// 层级最大 展示3D & 车牌号
if (scene.getZoom() > 17) {
hide([layers.first.vehicle])
window.tb.world.visible = true;
this.currentLocation = msg;
let allData = this.diff(this.lastLocation, this.currentLocation);
let allData = this.diff(this.lastLocation, msg);
this.lastLocation = msg;
this.addDelUpdateVehicleModels(allData);
// 添加车牌号图层
if (!layers.first.license) {
layers.first.license = l7Tools.addLicenseLayer(scene, msg);
} else {
layers.first.license.setData(msg);
show(layers.first.license)
}
this.addOrUpdateLicense(msg)
} else {
this.lastLocation = [];
if (this.selectVehicle) {
this.selectVehicle = null;
}
if (window.tb) {
window.tb.clear()
this.lightShow = false
this.waitingShow = false
window.tb.world.visible = false;
}
hide(layers.first.license);
if (!layers.first.vehicle) {
layers.first.vehicle = l7Tools.addVehicleLayer(scene, msg);
} else {
layers.first.vehicle && layers.first.vehicle.setData(msg);
}
this.lastLocation = [];
hide([layers.first.license])
this.addOrUpdateVehicle(msg)
}
}
}
let end = performance.now();
// console.log('cost is', `${end - start}ms`)
},
addOrUpdateLicense(msg) {
if (!layers.first.license) {
layers.first.license = l7Tools.addLicenseLayer(scene, msg);
} else {
for (let msgItem of msg) {
for (let old of layers.first.license.encodedData) {
if (
msgItem.picLicense === old.shape &&
turf.distance(
[msgItem.longitude, msgItem.latitude],
old.coordinates,
{units: "kilometers"}
) < 0.0005
) {
msgItem.longitude = old.coordinates[0];
msgItem.latitude = old.coordinates[1];
}
}
}
layers.first.license.setData(msg);
show(layers.first.license);
}
},
addOrUpdateVehicle(msg) {
if (!layers.first.vehicle) {
layers.first.vehicle = l7Tools.addVehicleLayer(scene, msg);
} else {
layers.first.vehicle && layers.first.vehicle.setData(msg);
show(layers.first.vehicle);
}
},
// 比较websocket车辆前后两次数据差异
diff(oldData, newData) {
// id 只在 newData 中存在且不在 oldData 中存在的即为 add
const add = newData.filter((e) => !oldData.find((c) => c.id === e.id));
// id 只在 oldData 中存在且不在 newData 中存在的即为 dele
const del = oldData.filter((e) => !newData.find((c) => c.id === e.id));
const com = newData.filter((e) => oldData.find((c) => c.id === e.id));
add.forEach((a) => (a.dill = "add"));
del.forEach((d) => (d.dill = "del"));
com.forEach((c) => (c.dill = "com"));
return [...add, ...del, ...com];
},
// 根据 name 关闭 websocket 不传参则全部关闭
closeWs(name) {
if (name) {
......
......@@ -262,6 +262,7 @@ export default {
}
.home-left {
z-index: 11;
position: absolute;
left: 0;
top: 0;
......
<template>
<div class="home-right">
<msg-card title="事故现场监控">
<msg-card title="涉事车辆车内视角">
<div class="cardInner">
<div class="top">
<span class="top-left"></span>
......@@ -106,6 +106,7 @@ export default {
}
.home-right {
z-index: 11;
position: absolute;
right: 0;
top: 0;
......
......@@ -306,7 +306,7 @@ export default {
}
}
},
// 更新经纬度-角度-详细信息
// 更新经纬度-角度-详细信息-弹窗信息
setModel(model, options, setColor) {
if (setColor) {
model.traverse((child) => {
......@@ -342,6 +342,7 @@ export default {
addDelUpdateVehicleModels(allData) {
if (this.vehicleModelsNum === 21) {
for (let item of allData) {
// 新增
if (item.dill === "add") {
let model =
vehicleModelTypes[`car${item.originalType}`].duplicate();
......@@ -360,22 +361,12 @@ export default {
}
}
}
// console.log('count...', window.tb.world.children.length)
}
},
// 比较websocket车辆前后两次数据差异
diff(oldData, newData) {
// id 只在 newData 中存在且不在 oldData 中存在的即为 add
const add = newData.filter((e) => !oldData.find((c) => c.id === e.id));
// id 只在 oldData 中存在且不在 newData 中存在的即为 dele
const del = oldData.filter((e) => !newData.find((c) => c.id === e.id));
const com = newData.filter((e) => oldData.find((c) => c.id === e.id));
add.forEach((a) => (a.dill = "add"));
del.forEach((d) => (d.dill = "del"));
com.forEach((c) => (c.dill = "com"));
return [...add, ...del, ...com];
},
callCar(msg) {
let start = performance.now();
// 筛选可见区域
for (let i = 0; i < msg.length; i++) {
if (!msg[i].picLicense) {
msg[i].picLicense = ''
......@@ -388,39 +379,80 @@ export default {
}
}
if (msg.length > 0) {
// 第一帧 || 时间戳不相同放行
// 第一帧 || 时间戳不相同 => 放行
if (this.lastLocation.length === 0 || this.lastLocation[0].dateTime !== msg[0].dateTime) {
this.situationTimeVal = msg[0].dateTime
// 层级最大 展示3D & 车牌号
if (scene.getZoom() > 17) {
hide([layers.first.vehicle])
window.tb.world.visible = true;
this.currentLocation = msg;
let allData = this.diff(this.lastLocation, this.currentLocation);
let allData = this.diff(this.lastLocation, msg);
this.lastLocation = msg;
this.addDelUpdateVehicleModels(allData);
// 添加车牌号图层
if (!layers.first.license) {
layers.first.license = l7Tools.addLicenseLayer(scene, msg);
} else {
layers.first.license.setData(msg);
show(layers.first.license)
}
this.addOrUpdateLicense(msg)
} else {
this.lastLocation = [];
if (this.selectVehicle) {
this.selectVehicle = null;
}
if (window.tb) {
window.tb.clear()
this.lightShow = false
this.waitingShow = false
window.tb.world.visible = false;
}
hide(layers.first.license);
if (!layers.first.vehicle) {
layers.first.vehicle = l7Tools.addVehicleLayer(scene, msg);
} else {
layers.first.vehicle && layers.first.vehicle.setData(msg);
}
this.lastLocation = [];
hide([layers.first.license])
this.addOrUpdateVehicle(msg)
}
}
}
let end = performance.now();
// console.log('cost is', `${end - start}ms`)
},
addOrUpdateLicense(msg) {
if (!layers.first.license) {
layers.first.license = l7Tools.addLicenseLayer(scene, msg);
} else {
for (let msgItem of msg) {
for (let old of layers.first.license.encodedData) {
if (
msgItem.picLicense === old.shape &&
turf.distance(
[msgItem.longitude, msgItem.latitude],
old.coordinates,
{units: "kilometers"}
) < 0.0005
) {
msgItem.longitude = old.coordinates[0];
msgItem.latitude = old.coordinates[1];
}
}
}
layers.first.license.setData(msg);
show(layers.first.license);
}
},
addOrUpdateVehicle(msg) {
if (!layers.first.vehicle) {
layers.first.vehicle = l7Tools.addVehicleLayer(scene, msg);
} else {
layers.first.vehicle && layers.first.vehicle.setData(msg);
show(layers.first.vehicle);
}
},
// 比较websocket车辆前后两次数据差异
diff(oldData, newData) {
// id 只在 newData 中存在且不在 oldData 中存在的即为 add
const add = newData.filter((e) => !oldData.find((c) => c.id === e.id));
// id 只在 oldData 中存在且不在 newData 中存在的即为 dele
const del = oldData.filter((e) => !newData.find((c) => c.id === e.id));
const com = newData.filter((e) => oldData.find((c) => c.id === e.id));
add.forEach((a) => (a.dill = "add"));
del.forEach((d) => (d.dill = "del"));
com.forEach((c) => (c.dill = "com"));
return [...add, ...del, ...com];
},
refreshBounds() {
let bounds = map.getBounds();
let leftDownXy = [bounds._sw.lng, bounds._sw.lat];
......
<template>
<div class="home-left">
<div class="topI">
<msg-card title="事故现场监控">
<msg-card title="危险驾驶监控">
<div class="videos">
<camera-video class="videoItem" v-for="item of cameras" :video-data="item.videoUrl"/>
<span class="top-left"></span>
......@@ -13,7 +13,23 @@
</div>
<div class="bottomI">
<msg-card class="m-b-10" title="危险驾驶报警">
<div class="cardInner">
<div class="optionItem" v-for="item of dangerOptions">
<div class="leftIcon" :class="`danger${item.type}`"></div>
<div class="rightDetail">
<div class="rightInner">
<div class="license">车牌号:{{ item.picLicense }}</div>
<div>
<span>检测时间段:{{ item.timeBetween }}</span> 持续时长:{{ item.duration }}
</div>
<div>
地点:{{ item.location }}
</div>
</div>
</div>
</div>
</div>
</msg-card>
</div>
</div>
......@@ -30,14 +46,37 @@ export default {
computed: {},
data() {
return {
time:'09:10:00 - 09:12:30',
cameras:[],
time: '09:10:00 - 09:12:30',
cameras: [],
dangerOptions: [
{
type: 1,
picLicense: '湘A5740R',
timeBetween: '10:23:00 ~ 10:27:00',
duration: '4min',
location: '湘江中路与劳动西路交叉口南进口'
},
{
type: 2,
picLicense: '湘A5740R',
timeBetween: '10:23:00 ~ 10:27:00',
duration: '4min',
location: '湘江中路与劳动西路交叉口南进口'
},
{
type: 3,
picLicense: '湘A5740R',
timeBetween: '10:23:00 ~ 10:27:00',
duration: '4min',
location: '湘江中路与劳动西路交叉口南进口'
},
],
};
},
mounted() {
// 1事故场景 2相位空放 3直左冲突 4慢行交通 5危险驾驶
getCameraListByType({type:5}).then(res => {
console.log('cameraList',res)
// 1事故场景 2 相位空放 3直左冲突 4慢行交通 5危险驾驶
getCameraListByType({type: 5}).then(res => {
console.log('cameraList', res)
this.cameras = res.content
})
},
......@@ -186,6 +225,7 @@ export default {
}
.home-left {
z-index: 11;
position: absolute;
left: 0;
top: 0;
......@@ -222,37 +262,59 @@ export default {
.bottomI {
flex: 1;
.messages{
font-size: 18px;
.cardInner {
display: flex;
height: 100%;
flex-direction: column;
padding: 15px;
justify-content: space-around;
.message-title{
padding: 10px;
.optionItem {
display: flex;
justify-content: space-between;
span{
width: 40%
justify-content: space-around;
margin-bottom: 20px;
align-items: center;
/* 四个角 */
.leftIcon {
width: 83px;
height: 84px;
background-size: 100% 100%;
}
span:first-child{
display: inline-block;
width: 60%;
text-align: left;
.danger1 {
background-image: url("../../../assets/images/sc/danger_s.png");
}
}
.message-describe{
display: flex;
.label{
width: 100px;
.danger2 {
background-image: url("../../../assets/images/sc/danger_speedup.png");
}
.value-image{
width: 491px;
height: 373px;
background-image: url("../../../assets/images/xwPic.png");
background-size: 100% 100%;
border: 1px solid #0d7fd7;
.danger3 {
background-image: url("../../../assets/images/sc/danger_track.png");
}
.rightInner {
padding: 8px 23px;
font-size: 16px;
color: rgba(222, 234, 255, 1);
background-image: url("../../../assets/images/sc/textBorderBack.png");
background-size: 100% 100%;
}
span {
display: inline-block;
margin-right: 25px;
}
.license {
color: white;
font-size: 18px;
font-weight: 500;
margin-bottom: 8px;
}
}
}
}
......
<template>
<div class="home-right">
<msg-card title="当前方案">
<div class="cardInner">
<div class="comp">
<cross-control/>
<div class="home-right-inner">
<msg-card style="flex:0 0 50%" class="m-b-10" title="涉事车辆车内视角">
<div class="cardInner">
<span class="top-left"></span>
<span class="top-right"></span>
<span class="bottom-left"></span>
<span class="bottom-right"></span>
<camera-video :video-data="''"/>
</div>
</msg-card>
<msg-card class="m-b-10" title="车辆跟踪记录">
<el-table
:header-cell-style="{backgroundColor:'rgba(46, 119, 255, 0.15)',color:'rgba(217, 229, 255, 1)'}"
:header-cell-style="{backgroundColor:'rgba(1, 43, 83, 1)',color:'rgba(217, 237, 255, 1)'}"
:row-class-name="userTab"
:data="tableData"
border
style="background-color: transparent; width: 100%;">
style="background-color: transparent; width: 100%;margin-top: 10px">
<el-table-column
align="center"
prop="xy"
label="指标"
width="100">
prop="time"
label="时间">
</el-table-column>
<el-table-column
prop="type"
prop="location"
align="center"
label="A">
label="位置">
</el-table-column>
<el-table-column
prop="direction"
prop="behavior"
align="center"
label="B">
label="行为">
</el-table-column>
</el-table>
</msg-card>
<msg-card class="m-b-10" title="车辆历史危险驾驶行为">
<el-table
:header-cell-style="{backgroundColor:'rgba(1, 43, 83, 1)',color:'rgba(217, 237, 255, 1)'}"
:row-class-name="userTab"
:data="tableData1"
style="background-color: transparent; width: 100%;margin-top: 10px">
<el-table-column
prop="sat"
align="center"
label="C">
prop="time"
label="日期时间">
</el-table-column>
<el-table-column
prop="time"
prop="startTime"
align="center"
label="开始时间">
</el-table-column>
<el-table-column
prop="endTime"
align="center"
label="D">
label="结束时间">
</el-table-column>
<el-table-column
prop="behavior"
align="center"
label="危险驾驶行为">
</el-table-column>
</el-table>
</div>
</msg-card>
</msg-card>
</div>
</div>
</template>
......@@ -58,24 +81,28 @@ export default {
data() {
return {
tableData: [
{ xy: 'A', type: '机动车', direction: '234', sat: '3.2', time: 10 },
{ xy: 'A', type: '机动车', direction: '234', sat: '3.2', time: 10 },
{ xy: 'A', type: '非机动车', direction: '234', sat: '3.2', time: 10 },
{ xy: 'A', type: '非机动车', direction: '234', sat: '3.2', time: 10 },
]
{time: '09:00:12', location: '东进口车道1', behavior: '加速跑'},
{time: '09:00:12', location: '东进口车道2', behavior: '不走斑马线'},
{time: '09:00:12', location: '路口内部', behavior: '不走斑马线'},
],
tableData1:[
{time: '2023-03-26', startTime: '09:00:12', endTime: '09:20:12', behavior: 'S形驾驶'},
{time: '2023-03-26', startTime: '09:00:12', endTime: '09:20:12', behavior: 'S形驾驶'},
{time: '2023-03-26', startTime: '09:00:12', endTime: '09:20:12', behavior: 'S形驾驶'},
],
};
},
mounted() {
},
methods: {
userTab({ row, rowIndex }) {
userTab({row, rowIndex}) {
if (rowIndex % 2 === 0) {
return 'warning-row'
} else if (rowIndex % 2 !== 0) {
return 'pager-row'
}
},
objectSpanMethod({ row, column, rowIndex, columnIndex }) {
objectSpanMethod({row, column, rowIndex, columnIndex}) {
if (columnIndex === 0) {
if (rowIndex % 6 === 0) {
return {
......@@ -111,9 +138,15 @@ export default {
</script>
<style lang='less' scoped>
.full-h{
.cardInner{
height: 100%;
position: relative;
padding: 10px;
}
.full-h {
height: 100%;
}
::v-deep .content {
margin: 0
}
......@@ -173,65 +206,77 @@ export default {
background-color: rgba(3, 11, 25, 0.45);
background-image: linear-gradient(90deg, rgba(8, 20, 31, 0) 0%, rgba(6, 16, 26, 1) 100%);
.cardInner {
.comp{
height: 15%;
padding: 10px 0;
}
::v-deep .el-table{
height: 85%;
overflow-y: auto;
}
.home-right-inner {
position: relative;
display: flex;
flex-direction: column;
justify-content: space-between;
height: 100%;
::v-deep .el-table--small td, .el-table--small th{
padding: 4px 0;
}
::v-deep .el-table th{
padding: 4px 0;
}
::v-deep .el-table {
width: 440px;
color: rgba(217, 229, 255, 1);
font-size: 16px;
}
::v-deep .el-table tr{
background-color: unset;
}
::v-deep .el-table .warning-row {
background-color: transparent;
}
::v-deep .el-table tbody tr:hover > td {
background-color: transparent;
}
::v-deep .el-table__body tr.current-row > td {
background: transparent !important;
}
::v-deep .el-table .pager-row {
background-color: transparent;
}
::v-deep .el-table .cell .el-table th div {
padding-right: 0;
}
::v-deep .el-table--border td{
border-right: 1px solid rgba(62, 108, 150, 1);
border-bottom: 1px solid rgba(62, 108, 150, 1);
border-left: 1px solid rgba(62, 108, 150, 1);
}
::v-deep .el-table--border th{
border: 1px solid rgba(62, 108, 150, 1);
}
::v-deep .el-table--border{
border: none;
}
::v-deep .el-table--border::after{
width: 0;
}
::v-deep .el-table--border::before{
height: 0;
}
}
}
.m-b-10 {
margin-bottom: 10px;
}
::v-deep .cameraVideo{
height: 100%;
}
::v-deep .el-table{
height: 85%;
overflow-y: auto;
}
::v-deep .el-table--small td, .el-table--small th{
padding: 4px 0;
}
::v-deep .el-table th{
padding: 4px 0;
}
::v-deep .el-table {
width: 440px;
color: rgba(217, 229, 255, 1);
font-size: 16px;
}
::v-deep .el-table td, .el-table th.is-leaf{
border-bottom: none;
}
::v-deep .el-table th.is-leaf{
border-bottom: none;
}
::v-deep .el-table tr{
background-color: unset;
}
::v-deep .el-table .warning-row {
background-color: transparent;
}
::v-deep .el-table tbody tr:hover > td {
background-color: transparent;
}
::v-deep .el-table__body tr.current-row > td {
background: transparent !important;
}
::v-deep .el-table .pager-row {
background-color: rgba(53, 92, 166, 0.15);
}
::v-deep .el-table .cell .el-table th div {
padding-right: 0;
}
::v-deep .el-table--border td{
border-right: 1px solid rgba(62, 108, 150, 1);
border-bottom: 1px solid rgba(62, 108, 150, 1);
border-left: 1px solid rgba(62, 108, 150, 1);
}
::v-deep .el-table--border th{
border: 1px solid rgba(62, 108, 150, 1);
}
::v-deep .el-table--border{
border: none;
}
::v-deep .el-table--border::after{
width: 0;
}
::v-deep .el-table--border::before{
height: 0;
}
::v-deep .el-table::before{
height: 0;
}
</style>
\ No newline at end of file
......@@ -71,4 +71,12 @@ export default {
height: 100%;
width: 100%;
}
</style>
<style>
.home-left{
z-index: 11;
}
.home-right{
z-index: 11;
}
</style>
\ No newline at end of file
......@@ -2,12 +2,6 @@ import {PointLayer, RasterLayer, LineLayer, HeatmapLayer, PolygonLayer} from '@a
// home - camera图层
export function addCameraPoints(scene, msg, offset, callback) {
// for (let i = 0; i < msg.length; i++) {
// if (msg[i].isSignal === 0) continue;
// if (!msg[i].isSignal) {
// msg[i].isSignal = 1
// }
// }
const pointLayer = new PointLayer({zIndex: 2})
.source(msg, {
parser: {
......@@ -20,22 +14,14 @@ export function addCameraPoints(scene, msg, offset, callback) {
offsets: offset,
})
.shape('homeCamera')
// .shape('isSignal', function (level) {
// if (level === 1) {
// return 'cross'
// }
// if (level === 0) {
// return 'crossFalse'
// }
// })
.size(16)
.size(20)
.active({
color: '#ffffff',
mix: 0.6,
})
.on('click', (e) => {
callback(e)
})
pointLayer.on('click', (e) => {
callback(e)
})
scene.addLayer(pointLayer)
return pointLayer
}
......@@ -90,17 +76,17 @@ export function addLicenseLayer(scene, msg) {
halo: 1,
})
.color('#ffffff')
.on('contextmenu', (e) => {
const input = document.createElement('input')
input.setAttribute('readonly', 'readonly')
input.setAttribute('value', e.feature.id)
document.body.appendChild(input)
input.setSelectionRange(0, 9999)
input.select()
document.execCommand('copy')
document.body.removeChild(input)
ELEMENT.Message('复制ID成功!')
})
pointLayer.on('contextmenu', (e) => {
const input = document.createElement('input')
input.setAttribute('readonly', 'readonly')
input.setAttribute('value', e.feature.id)
document.body.appendChild(input)
input.setSelectionRange(0, 9999)
input.select()
document.execCommand('copy')
document.body.removeChild(input)
ELEMENT.Message('复制ID成功!')
})
scene.addLayer(pointLayer)
return pointLayer
}
......
<template>
<div id="e_popup">
<div class="equip_camera">
<div class="header">{{ 11111 }}</div>
<div class="header">{{ model.crossName }}</div>
<div class="main">
<camera-video style="height: 100%" :video-data="''"/>
<camera-video :auto-play="true" style="height: 100%" :video-data="model.videoUrl"/>
</div>
</div>
</div>
......@@ -31,13 +31,13 @@ export default {
<style lang='less' scoped>
#e_popup {
background: rgba(15, 38, 69, 1)
background: transparent;
}
.equip_camera {
width: 448px;
height: 328px;
background-image: url("../../../assets/images/holo/videobackgorund.png");
width: 314px;
height: 300px;
background-image: url("../../../assets/images/sc/cameraPopup.png");
background-repeat: no-repeat;
background-size: 100% 100%;
......@@ -51,6 +51,7 @@ export default {
}
.main {
position: relative;
padding: 2px;
height: calc(100% - 43px);
}
......
<template>
<div class="mepLegends"></div>
</template>
<script>
export default {
name: "mepLegends",
components: {},
computed: {},
data() {
return {};
},
mounted() {},
methods: {},
beforeDestroy() {},
};
</script>
<style lang='less' scoped>
.mepLegends{
height: 100px;
width: 400px;
background-color: rgba(13, 127, 215,0.7);
border-radius: 20px;
}
</style>
\ No newline at end of file
......@@ -22,6 +22,7 @@ function show(layer) {
item && !item.isVisible() && item.show();
}
}
import {getPhasePolygons} from "../../dao/api";
import {Popup} from "@antv/l7";
import mapAssets from "../../config/holo/mapAssets";
......@@ -82,48 +83,32 @@ export default {
setTimeout(() => {
this.initWebS()
}, 2000)
// todo
let timer = setInterval(() => {
let geo = {
type: 'FeatureCollection',
features: [
{
type: 'Feature',
properties: {
color: '#f00'
},
geometry: {
type: 'Polygon',
coordinates: [
[
[104.4140625, 35.460669951495305],
[98.7890625, 24.206889622398023],
[111.796875, 27.371767300523047],
[104.4140625, 35.460669951495305],
],
],
},
},
{
getPhasePolygons().then(res => {
let geo = {
type: 'FeatureCollection',
features: []
}
console.log('phase polygons', res.content)
for (let item of res.content) {
let wktarr = item.wkt.split(';')
for (let i = 0; i < wktarr.length; i++) {
wktarr[i] = wktarr[i].split(',')
for (let j = 0; j < wktarr[i].length; j++) {
wktarr[i][j] = Number(wktarr[i][j])
}
}
geo.features.push({
type: 'Feature',
properties: {
color: '#f00'
},
properties: item,
geometry: {
type: 'Polygon',
coordinates: [
[
[104.4140625, 35.460669951495305],
[99.7890625, 22.206889622398023],
[111.796875, 26.371767300523047],
[104.4140625, 35.460669951495305],
],
],
},
},
],
}
this.refreshGreenPolygon(geo)
coordinates: [wktarr]
}
})
}
this.refreshGreenPolygon(geo)
})
}, 5000)
this.timers.push(timer)
// map.addControl(new mapboxgl.NavigationControl(), 'bottom-right');
......@@ -164,9 +149,6 @@ export default {
})
},
refreshGreenPolygon(geo) {
getPhasePolygons().then(res => {
console.log('phase polygons',res.content)
})
// 更新
if (greenPolygonLayer) {
greenPolygonLayer.setData(geo)
......@@ -309,7 +291,9 @@ export default {
}
}
},
// 更新经纬度-角度-详细信息
// 更新经纬度-角度-详细信息-弹窗信息
setModel(model, options, setColor) {
if (setColor) {
model.traverse((child) => {
......@@ -345,6 +329,7 @@ export default {
addDelUpdateVehicleModels(allData) {
if (this.vehicleModelsNum === 21) {
for (let item of allData) {
// 新增
if (item.dill === "add") {
let model =
vehicleModelTypes[`car${item.originalType}`].duplicate();
......@@ -363,22 +348,12 @@ export default {
}
}
}
// console.log('count...', window.tb.world.children.length)
}
},
// 比较websocket车辆前后两次数据差异
diff(oldData, newData) {
// id 只在 newData 中存在且不在 oldData 中存在的即为 add
const add = newData.filter((e) => !oldData.find((c) => c.id === e.id));
// id 只在 oldData 中存在且不在 newData 中存在的即为 dele
const del = oldData.filter((e) => !newData.find((c) => c.id === e.id));
const com = newData.filter((e) => oldData.find((c) => c.id === e.id));
add.forEach((a) => (a.dill = "add"));
del.forEach((d) => (d.dill = "del"));
com.forEach((c) => (c.dill = "com"));
return [...add, ...del, ...com];
},
callCar(msg) {
let start = performance.now();
// 筛选可见区域
for (let i = 0; i < msg.length; i++) {
if (!msg[i].picLicense) {
msg[i].picLicense = ''
......@@ -391,39 +366,80 @@ export default {
}
}
if (msg.length > 0) {
// 第一帧 || 时间戳不相同放行
// 第一帧 || 时间戳不相同 => 放行
if (this.lastLocation.length === 0 || this.lastLocation[0].dateTime !== msg[0].dateTime) {
this.situationTimeVal = msg[0].dateTime
// 层级最大 展示3D & 车牌号
if (scene.getZoom() > 17) {
hide([layers.first.vehicle])
window.tb.world.visible = true;
this.currentLocation = msg;
let allData = this.diff(this.lastLocation, this.currentLocation);
let allData = this.diff(this.lastLocation, msg);
this.lastLocation = msg;
this.addDelUpdateVehicleModels(allData);
// 添加车牌号图层
if (!layers.first.license) {
layers.first.license = l7Tools.addLicenseLayer(scene, msg);
} else {
layers.first.license.setData(msg);
show(layers.first.license)
}
this.addOrUpdateLicense(msg)
} else {
this.lastLocation = [];
if (this.selectVehicle) {
this.selectVehicle = null;
}
if (window.tb) {
window.tb.clear()
this.lightShow = false
this.waitingShow = false
window.tb.world.visible = false;
}
hide(layers.first.license);
if (!layers.first.vehicle) {
layers.first.vehicle = l7Tools.addVehicleLayer(scene, msg);
} else {
layers.first.vehicle && layers.first.vehicle.setData(msg);
}
this.lastLocation = [];
hide([layers.first.license])
this.addOrUpdateVehicle(msg)
}
}
}
let end = performance.now();
// console.log('cost is', `${end - start}ms`)
},
addOrUpdateLicense(msg) {
if (!layers.first.license) {
layers.first.license = l7Tools.addLicenseLayer(scene, msg);
} else {
for (let msgItem of msg) {
for (let old of layers.first.license.encodedData) {
if (
msgItem.picLicense === old.shape &&
turf.distance(
[msgItem.longitude, msgItem.latitude],
old.coordinates,
{units: "kilometers"}
) < 0.0005
) {
msgItem.longitude = old.coordinates[0];
msgItem.latitude = old.coordinates[1];
}
}
}
layers.first.license.setData(msg);
show(layers.first.license);
}
},
addOrUpdateVehicle(msg) {
if (!layers.first.vehicle) {
layers.first.vehicle = l7Tools.addVehicleLayer(scene, msg);
} else {
layers.first.vehicle && layers.first.vehicle.setData(msg);
show(layers.first.vehicle);
}
},
// 比较websocket车辆前后两次数据差异
diff(oldData, newData) {
// id 只在 newData 中存在且不在 oldData 中存在的即为 add
const add = newData.filter((e) => !oldData.find((c) => c.id === e.id));
// id 只在 oldData 中存在且不在 newData 中存在的即为 dele
const del = oldData.filter((e) => !newData.find((c) => c.id === e.id));
const com = newData.filter((e) => oldData.find((c) => c.id === e.id));
add.forEach((a) => (a.dill = "add"));
del.forEach((d) => (d.dill = "del"));
com.forEach((c) => (c.dill = "com"));
return [...add, ...del, ...com];
},
refreshBounds() {
let bounds = map.getBounds();
let leftDownXy = [bounds._sw.lng, bounds._sw.lat];
......
......@@ -2,18 +2,14 @@ import {PointLayer, RasterLayer, LineLayer, HeatmapLayer, PolygonLayer} from '@a
// home3 - 绿灯空放polygon图层
export function addGreenPolygon(scene, msg){
export function addGreenPolygon(scene, msg) {
const polygonLayer = new PolygonLayer({zIndex: 2})
.source(msg)
.shape('fill')
// .color('color字段',(value) => {
// if(value === '') return 'red'
// if(value === '') return 'origin'
.color('rgba(0, 255, 60, 0.54)')
// .style({
// opacity: 0.6
// })
.color('#f00')
.style({
opacity: 0.6
})
scene.addLayer(polygonLayer)
return polygonLayer
}
......
<template>
<div class="home-left">
<div class="topI">
<msg-card title="事故现场监控">
<msg-card title="路口现场监控">
<div class="videos">
<camera-video class="videoItem" v-for="item of cameras" :video-data="item.videoUrl"/>
<span class="top-left"></span>
......
<template>
<div class="home-left">
<div class="topI">
<msg-card title="事故现场监控">
<msg-card title="慢行交通现场监控">
<div class="videos">
<camera-video :auto-play="true" class="videoItem" v-for="item of cameras" :video-data="item.videoUrl"/>
<camera-video class="videoItem" v-for="item of cameras" :video-data="item.videoUrl"/>
<span class="top-left"></span>
<span class="top-right"></span>
<span class="bottom-left"></span>
......@@ -12,8 +12,24 @@
</msg-card>
</div>
<div class="bottomI">
<msg-card class="m-b-10" title="事件辅助定责">
<msg-card class="m-b-10" title="慢行交通报警">
<div class="cardInner">
<div class="optionItem" v-for="item of dangerOptions">
<div class="leftIcon" :class="`danger${item.type}`"></div>
<div class="rightDetail">
<div class="rightInner">
<div class="license">{{ item.behavior }}</div>
<div>
<span>检测时间段:{{ item.timeBetween }}</span> 持续时长:{{ item.duration }}
</div>
<div>
地点:{{ item.location }}
</div>
</div>
</div>
</div>
</div>
</msg-card>
</div>
</div>
......@@ -30,31 +46,37 @@ export default {
computed: {},
data() {
return {
cameras:[],
location: ['路口', '路段', '高架桥'],
locationVal: 1,
isMulti: ['单车', '多车'],
isMultiVal: 1,
timeType: ['早高峰', '平峰', '晚高峰', '夜间'],
timeTypeVal: 1,
haveWalker: ['', ''],
haveWalkerVal: 1,
haveNoVehicle: ['', ''],
haveNoVehicleVal: 1,
arrowIndex: 2,
rows: [
{label: '事故时间', value: '2022-09-18 05:26:46'},
{label: '事故地点', value: '港东大街与迎春大街路口东向 直行车道'},
{label: '事故描述', value: '疑似多车事故:鲁YBZ796与鲁KF1F97,从不同方向进入路口,行驶路线发生冲突,导致事故。'},
{label: '定责建议', value: '港东大街与迎春大街路口东向 直行车道'},
{label: '辅助信息', value: '鲁YBZ796 疑似侧碰鲁 鲁KC1F97'},
time: '09:10:00 - 09:12:30',
cameras: [],
dangerOptions: [
{
type: 1,
behavior: '不走斑马线',
timeBetween: '10:23:00 ~ 10:27:00',
duration: '4min',
location: '湘江中路与劳动西路交叉口南进口'
},
{
type: 2,
behavior: '随意穿越路口',
timeBetween: '10:23:00 ~ 10:27:00',
duration: '4min',
location: '湘江中路与劳动西路交叉口南进口'
},
{
type: 1,
behavior: '信号配时不合理',
timeBetween: '10:23:00 ~ 10:27:00',
duration: '4min',
location: '湘江中路与劳动西路交叉口南进口'
},
],
};
},
mounted() {
// 1事故场景 2相位空放 3直左冲突 4慢行交通 5危险驾驶
getCameraListByType({type:4}).then(res => {
console.log('cameraList',res)
getCameraListByType({type: 6}).then(res => {
console.log('cameraList', res)
this.cameras = res.content
})
},
......@@ -70,7 +92,7 @@ export default {
font-size: 16px;
border-top: 1px solid rgba(62, 108, 150, 1);
border-left: 1px solid rgba(62, 108, 150, 1);
margin-bottom: 20px;
margin-bottom: 7px;
.row1 {
height: 30px;
......@@ -240,95 +262,57 @@ export default {
.bottomI {
flex: 1;
.analysis {
height: 100%;
.cardInner {
display: flex;
flex-direction: column;
justify-content: space-between;
padding: 10px;
.timeMsg {
height: 30px;
line-height: 30px;
width: 100%;
.optionItem {
display: flex;
justify-content: center;
justify-content: space-around;
margin-bottom: 20px;
align-items: center;
margin-bottom: 7px;
font-size: 18px;
/* 四个角 */
span {
font-weight: 700;
}
.el-icon-time {
margin-right: 5px;
}
}
.gradiantPoint {
display: flex;
margin-top: 30px;
padding: 0 20px;
justify-content: space-between;
overflow: visible;
.pointItem {
width: 10px;
height: 18px;
position: relative;
border-radius: 4px;
.arrow-down {
position: absolute;
left: 50%;
transform: translateX(-50%);
top: -28px;
width: 31px;
height: 33px;
background-image: url("../../../assets/images/acci/arrow-down.png");
background-position: center;
}
.leftIcon {
width: 83px;
height: 84px;
background-size: 100% 100%;
}
.point1 {
background-color: #1afd9c;
.danger1 {
background-image: url("../../../assets/images/sc/danger_bicycle.png");
}
.point2 {
background-color: #28fd28;
.danger2 {
background-image: url("../../../assets/images/sc/danger_passerby.png");
}
.point3 {
background-color: #f4fa01;
}
.point4 {
background-color: #fdc616;
}
.point5 {
background-color: #ff972a;
}
.point6 {
background-color: #ef7923;
.rightInner {
padding: 8px 23px;
font-size: 16px;
color: rgba(222, 234, 255, 1);
background-image: url("../../../assets/images/sc/textBorderBack.png");
background-size: 100% 100%;
}
.point7 {
background-color: #de5a1a;
span {
display: inline-block;
margin-right: 25px;
}
.point8 {
background-color: #cd3d12;
}
.license {
color: white;
font-size: 18px;
font-weight: 500;
margin-bottom: 8px;
.point9 {
background-color: #bd2009;
}
.point10 {
background-color: #ac0100;
}
}
}
}
......
<template>
<div class="home-right">
<msg-card title="事故现场监控">
<div class="cardInner">
<div class="top">
<span class="top-left"></span>
<span class="top-right"></span>
<span class="bottom-left"></span>
<span class="bottom-right"></span>
<!-- <cesium-map class="cesium-map" ref="homeRightTop" c-id="home-right-top"/>-->
<camera-video class="full-h" :video-data="''"/>
</div>
<div class="bottom">
<span class="top-left"></span>
<span class="top-right"></span>
<span class="bottom-left"></span>
<span class="bottom-right"></span>
<camera-video class="full-h" :video-data="''"/>
<!-- <cesium-map class="cesium-map" ref="homeRightBottom" c-id="home-right-bottom"/>-->
</div>
</div>
</msg-card>
<div class="home-right-inner">
<msg-card class="m-b-10" :title="`行人轨迹异常历史(${tableData.length}起)`">
<el-table
:header-cell-style="{backgroundColor:'rgba(1, 43, 83, 1)',color:'rgba(217, 237, 255, 1)'}"
:row-class-name="userTab"
:data="tableData"
style="background-color: transparent; width: 100%;margin-top: 10px">
<el-table-column
align="center"
prop="time"
label="时间">
</el-table-column>
<el-table-column
prop="location"
align="center"
label="位置">
</el-table-column>
<el-table-column
prop="behavior"
align="center"
label="行为">
</el-table-column>
</el-table>
</msg-card>
<msg-card class="m-b-10" title="非机动车危险驾驶行为">
<el-table
:header-cell-style="{backgroundColor:'rgba(1, 43, 83, 1)',color:'rgba(217, 237, 255, 1)'}"
:row-class-name="userTab"
:data="tableData1"
style="background-color: transparent; width: 100%;margin-top: 10px">
<el-table-column
align="center"
prop="time"
label="日期时间">
</el-table-column>
<el-table-column
prop="startTime"
align="center"
label="开始时间">
</el-table-column>
<el-table-column
prop="endTime"
align="center"
label="结束时间">
</el-table-column>
<el-table-column
prop="behavior"
align="center"
label="危险驾驶行为">
</el-table-column>
</el-table>
</msg-card>
</div>
</div>
</template>
......@@ -29,23 +61,66 @@
import CesiumMap from "../../../components/Standard/cesiumMap.vue";
import MsgCard from "../../../components/Standard/msg-card.vue";
import CameraVideo from "../../../components/Standard/cameraVideo.vue";
import CrossControl from "../../../components/CrossControl/crossControl.vue";
let topViewer, bottomViewer;
export default {
name: "homeRight",
components: {CameraVideo, MsgCard, CesiumMap},
components: {CrossControl, CameraVideo, MsgCard, CesiumMap},
computed: {},
data() {
return {};
return {
tableData: [
{time: '09:00:12', location: '东进口车道1', behavior: '加速跑'},
{time: '09:00:12', location: '东进口车道2', behavior: '不走斑马线'},
{time: '09:00:12', location: '路口内部', behavior: '不走斑马线'},
],
tableData1:[
{time: '2023-03-26', startTime: '09:00:12', endTime: '09:20:12', behavior: 'S形驾驶'},
{time: '2023-03-26', startTime: '09:00:12', endTime: '09:20:12', behavior: 'S形驾驶'},
{time: '2023-03-26', startTime: '09:00:12', endTime: '09:20:12', behavior: 'S形驾驶'},
],
};
},
mounted() {
// topViewer = this.$refs.homeRightTop.loadMap()
// bottomViewer = this.$refs.homeRightBottom.loadMap()
// topViewer.timeline.container.style.visibility = 'hidden'
// bottomViewer.timeline.container.style.visibility = 'hidden'
},
methods: {
userTab({row, rowIndex}) {
if (rowIndex % 2 === 0) {
return 'warning-row'
} else if (rowIndex % 2 !== 0) {
return 'pager-row'
}
},
objectSpanMethod({row, column, rowIndex, columnIndex}) {
if (columnIndex === 0) {
if (rowIndex % 6 === 0) {
return {
rowspan: 6,
colspan: 1
};
} else {
return {
rowspan: 0,
colspan: 0
};
}
}
if (columnIndex === 1) {
if (rowIndex % 2 === 0) {
return {
rowspan: 2,
colspan: 1
};
} else {
return {
rowspan: 0,
colspan: 0
};
}
}
}
},
beforeDestroy() {
......@@ -54,9 +129,15 @@ export default {
</script>
<style lang='less' scoped>
.full-h{
.cardInner{
height: 100%;
position: relative;
padding: 10px;
}
.full-h {
height: 100%;
}
::v-deep .content {
margin: 0
}
......@@ -116,30 +197,77 @@ export default {
background-color: rgba(3, 11, 25, 0.45);
background-image: linear-gradient(90deg, rgba(8, 20, 31, 0) 0%, rgba(6, 16, 26, 1) 100%);
.cardInner {
.home-right-inner {
position: relative;
display: flex;
flex-direction: column;
justify-content: space-between;
height: 100%
}
.top {
height: 49%;
padding: 13px;
position: relative;
border: 1px solid rgba(24, 144, 255, 0.4);
}
.bottom {
height: 49%;
padding: 13px;
border: 1px solid rgba(24, 144, 255, 0.4);
position: relative;
}
.cesium-map {
height: 100%;
}
}
.m-b-10 {
margin-bottom: 10px;
}
::v-deep .cameraVideo{
height: 100%;
}
::v-deep .el-table{
height: 85%;
overflow-y: auto;
}
::v-deep .el-table--small td, .el-table--small th{
padding: 4px 0;
}
::v-deep .el-table th{
padding: 4px 0;
}
::v-deep .el-table {
width: 440px;
color: rgba(217, 229, 255, 1);
font-size: 16px;
}
::v-deep .el-table td, .el-table th.is-leaf{
border-bottom: none;
}
::v-deep .el-table th.is-leaf{
border-bottom: none;
}
::v-deep .el-table tr{
background-color: unset;
}
::v-deep .el-table .warning-row {
background-color: transparent;
}
::v-deep .el-table tbody tr:hover > td {
background-color: transparent;
}
::v-deep .el-table__body tr.current-row > td {
background: transparent !important;
}
::v-deep .el-table .pager-row {
background-color: rgba(53, 92, 166, 0.15);
}
::v-deep .el-table .cell .el-table th div {
padding-right: 0;
}
::v-deep .el-table--border td{
border-right: 1px solid rgba(62, 108, 150, 1);
border-bottom: 1px solid rgba(62, 108, 150, 1);
border-left: 1px solid rgba(62, 108, 150, 1);
}
::v-deep .el-table--border th{
border: 1px solid rgba(62, 108, 150, 1);
}
::v-deep .el-table--border{
border: none;
}
::v-deep .el-table--border::after{
width: 0;
}
::v-deep .el-table--border::before{
height: 0;
}
::v-deep .el-table::before{
height: 0;
}
</style>
\ No newline at end of file
......@@ -9,6 +9,8 @@
</template>
<script>
import {addConflictPoint} from "./l7Tools";
function hide(layer) {
let arr = Array.isArray(layer) ? layer : [layer];
for (let item of arr) {
......@@ -32,6 +34,10 @@ import dict from "../../config/holo/dictionary";
import wsSource from "../../config/holo/wsSource";
import {initWs} from "../../config/holo/websocket";
import * as l7Tools from "./l7Tools";
import conflictDetail from "./mapPopup/conflictDetail.vue";
// import ConflictDetail from "./mapPopup/conflictDetail.vue";
const ConflictDetail = Vue.extend(conflictDetail)
let map,
scene,
......@@ -41,12 +47,12 @@ let map,
vehicle: null,
license: null,
}
},
greenPolygonLayer = null;
}
export default {
name: 'home4',
components: {
ConflictDetail,
HomeRight,
HomeLeft,
WMap
......@@ -82,50 +88,6 @@ export default {
setTimeout(() => {
this.initWebS()
}, 2000)
// todo
let timer = setInterval(() => {
let geo = {
type: 'FeatureCollection',
features: [
{
type: 'Feature',
properties: {
color: '#f00'
},
geometry: {
type: 'Polygon',
coordinates: [
[
[104.4140625, 35.460669951495305],
[98.7890625, 24.206889622398023],
[111.796875, 27.371767300523047],
[104.4140625, 35.460669951495305],
],
],
},
},
{
type: 'Feature',
properties: {
color: '#f00'
},
geometry: {
type: 'Polygon',
coordinates: [
[
[104.4140625, 35.460669951495305],
[99.7890625, 22.206889622398023],
[111.796875, 26.371767300523047],
[104.4140625, 35.460669951495305],
],
],
},
},
],
}
this.refreshGreenPolygon(geo)
}, 5000)
this.timers.push(timer)
// map.addControl(new mapboxgl.NavigationControl(), 'bottom-right');
});
scene.on("zoomend", (e) => {
......@@ -163,20 +125,35 @@ export default {
});
})
},
refreshGreenPolygon(geo) {
// 更新
if (greenPolygonLayer) {
greenPolygonLayer.setData(geo)
}
// 添加
else {
greenPolygonLayer = l7Tools.addGreenPolygon(scene, geo)
}
},
initWebS() {
if (this.loading) this.loading = false
this.regisAndSendWs("callCar", {dataType: "1"});
this.regisAndSendWs("callLight", {dataType: "4"});
this.getConflictPoint()
},
// 直左冲突点 & popup
getConflictPoint() {
let res = [{
longitude: 112.96290276,
latitude: 28.18286408,
type: '机动车冲突',
detail: '东口左转与南口直行冲突',
}]
l7Tools.addConflictPoint(scene, res)
let pop = new Popup({
// offsets: [-100, 280],
closeButton: false,
anchor:'bottom-left',
closeButtonOffsets: [-200, 17]
})
.setLngLat([112.96290276, 28.18286408])
.setHTML(`<div id="conflictPoint"></div>`)
scene.addPopup(pop);
new ConflictDetail({
propsData: {
model: res[0],
},
}).$mount(`#conflictPoint`);
},
callLight(msg) {
let lightArr = [];
......@@ -306,7 +283,9 @@ export default {
}
}
},
// 更新经纬度-角度-详细信息
// 更新经纬度-角度-详细信息-弹窗信息
setModel(model, options, setColor) {
if (setColor) {
model.traverse((child) => {
......@@ -342,6 +321,7 @@ export default {
addDelUpdateVehicleModels(allData) {
if (this.vehicleModelsNum === 21) {
for (let item of allData) {
// 新增
if (item.dill === "add") {
let model =
vehicleModelTypes[`car${item.originalType}`].duplicate();
......@@ -360,22 +340,12 @@ export default {
}
}
}
// console.log('count...', window.tb.world.children.length)
}
},
// 比较websocket车辆前后两次数据差异
diff(oldData, newData) {
// id 只在 newData 中存在且不在 oldData 中存在的即为 add
const add = newData.filter((e) => !oldData.find((c) => c.id === e.id));
// id 只在 oldData 中存在且不在 newData 中存在的即为 dele
const del = oldData.filter((e) => !newData.find((c) => c.id === e.id));
const com = newData.filter((e) => oldData.find((c) => c.id === e.id));
add.forEach((a) => (a.dill = "add"));
del.forEach((d) => (d.dill = "del"));
com.forEach((c) => (c.dill = "com"));
return [...add, ...del, ...com];
},
callCar(msg) {
let start = performance.now();
// 筛选可见区域
for (let i = 0; i < msg.length; i++) {
if (!msg[i].picLicense) {
msg[i].picLicense = ''
......@@ -388,39 +358,81 @@ export default {
}
}
if (msg.length > 0) {
// 第一帧 || 时间戳不相同放行
// 第一帧 || 时间戳不相同 => 放行
if (this.lastLocation.length === 0 || this.lastLocation[0].dateTime !== msg[0].dateTime) {
this.situationTimeVal = msg[0].dateTime
// 层级最大 展示3D & 车牌号
if (scene.getZoom() > 17) {
hide([layers.first.vehicle])
window.tb.world.visible = true;
this.currentLocation = msg;
let allData = this.diff(this.lastLocation, this.currentLocation);
let allData = this.diff(this.lastLocation, msg);
this.lastLocation = msg;
this.addDelUpdateVehicleModels(allData);
// 添加车牌号图层
if (!layers.first.license) {
layers.first.license = l7Tools.addLicenseLayer(scene, msg);
} else {
layers.first.license.setData(msg);
show(layers.first.license)
}
this.addOrUpdateLicense(msg)
} else {
this.lastLocation = [];
if (this.selectVehicle) {
this.selectVehicle = null;
}
if (window.tb) {
window.tb.clear()
this.lightShow = false
this.waitingShow = false
window.tb.world.visible = false;
}
hide(layers.first.license);
if (!layers.first.vehicle) {
layers.first.vehicle = l7Tools.addVehicleLayer(scene, msg);
} else {
layers.first.vehicle && layers.first.vehicle.setData(msg);
}
this.lastLocation = [];
hide([layers.first.license])
this.addOrUpdateVehicle(msg)
}
}
}
let end = performance.now();
// console.log('cost is', `${end - start}ms`)
},
addOrUpdateLicense(msg) {
if (!layers.first.license) {
layers.first.license = l7Tools.addLicenseLayer(scene, msg);
} else {
for (let msgItem of msg) {
for (let old of layers.first.license.encodedData) {
if (
msgItem.picLicense === old.shape &&
turf.distance(
[msgItem.longitude, msgItem.latitude],
old.coordinates,
{units: "kilometers"}
) < 0.0005
) {
msgItem.longitude = old.coordinates[0];
msgItem.latitude = old.coordinates[1];
}
}
}
layers.first.license.setData(msg);
show(layers.first.license);
}
},
addOrUpdateVehicle(msg) {
if (!layers.first.vehicle) {
layers.first.vehicle = l7Tools.addVehicleLayer(scene, msg);
} else {
layers.first.vehicle && layers.first.vehicle.setData(msg);
show(layers.first.vehicle);
}
},
// 比较websocket车辆前后两次数据差异
diff(oldData, newData) {
// id 只在 newData 中存在且不在 oldData 中存在的即为 add
const add = newData.filter((e) => !oldData.find((c) => c.id === e.id));
// id 只在 oldData 中存在且不在 newData 中存在的即为 dele
const del = oldData.filter((e) => !newData.find((c) => c.id === e.id));
const com = newData.filter((e) => oldData.find((c) => c.id === e.id));
add.forEach((a) => (a.dill = "add"));
del.forEach((d) => (d.dill = "del"));
com.forEach((c) => (c.dill = "com"));
return [...add, ...del, ...com];
},
refreshBounds() {
let bounds = map.getBounds();
let leftDownXy = [bounds._sw.lng, bounds._sw.lat];
......@@ -464,7 +476,8 @@ export default {
height: 100%;
position: relative;
}
::v-deep .el-table::before{
::v-deep .el-table::before {
height: 0;
}
</style>
......
......@@ -2,20 +2,23 @@ import {PointLayer, RasterLayer, LineLayer, HeatmapLayer, PolygonLayer} from '@a
// home3 - 绿灯空放polygon图层
export function addGreenPolygon(scene, msg){
const polygonLayer = new PolygonLayer({zIndex: 2})
.source(msg)
.shape('fill')
// .color('color字段',(value) => {
// if(value === '') return 'red'
// if(value === '') return 'origin'
// })
.color('#f00')
export function addConflictPoint(scene, msg){
const pointLayer = new PointLayer()
.source(msg, {
parser: {
type: 'json',
x: 'longitude',
y: 'latitude',
},
})
.shape('circle')
.style({
opacity: 0.6
blur: 1,
})
scene.addLayer(polygonLayer)
return polygonLayer
.size(20)
.color('#efba0a')
scene.addLayer(pointLayer)
return pointLayer
}
// 车辆圆点图层
......
<template>
<div class="home-left">
<div class="topI">
<msg-card title="事故现场监控">
<msg-card title="路口监控">
<div class="videos">
<camera-video class="videoItem" v-for="item of cameras" :video-data="item.videoUrl"/>
<span class="top-left"></span>
......
<template>
<div class="conflictDetail">
<div class="conflictDetail_head">
<span></span>机动车冲突
</div>
<div class="content">
<div class="detailItem">
<span>东口左转与南口直行冲突</span
>
</div>
</div>
</div>
</template>
<script>
export default {
name: "conflictDetail",
data() {
return {};
},
props: ["model"],
watch: {
model: {
handler(val) {
},
deep: true, // 深度监听
immediate: true, // 初次监听即执行
}
},
mounted() {
},
methods: {},
computed: {},
beforeDestroy() {
},
};
</script>
<style lang="less" scoped>
.conflictDetail {
font-size: 16px;
position: relative;
width: 291px;
height: 235px;
background-image: url("../../../assets/images/sc/popup_redback.png");
background-size: 100% 100%;
background-repeat: no-repeat;
.conflictDetail_head {
position: absolute;
top: -18px;
width: 50%;
background-image: linear-gradient(90deg, rgba(233, 75, 76, 1) 0%, rgba(233, 75, 76, 0) 100%);
height: 35px;
color: white;
display: flex;
align-items: center;
font-size: 20px;
font-weight: 700;
span {
display: inline-block;
width: 18px;
height: 18px;
margin: 0 5px;
line-height: 25px;
background-image: url('../../../assets/images/holo/vehicle_popup_icon.png');
background-position: center;
background-repeat: no-repeat;
}
}
.content {
height: calc(100% - 15px);
display: flex;
padding: 18px 24px;
flex-direction: column;
.detailItem {
height: 30px;
line-height: 30px;
white-space: nowrap;
color: white;
max-width: 200px;
overflow: hidden;
text-overflow: ellipsis;
span {
display: inline-block;
}
span.left {
text-align: left;
padding-left: 20px;
background-image: url("../../../assets/images/acci/arrow-origin.png");
background-size: auto;
background-repeat: no-repeat;
background-position: left;
color: rgba(207, 238, 255, 0.9);
}
span.right {
text-align: left;
color: white;
}
}
}
}
</style>
......@@ -176,14 +176,15 @@ export default {
height: 15%;
padding: 10px 0;
}
::v-deep .el-table{
height: 85%;
overflow-y: auto;
}
display: flex;
flex-direction: column;
justify-content: space-between;
height: 100%;
::v-deep .el-table{
height: 85%;
overflow-y: auto;
}
::v-deep .el-table--small td, .el-table--small th{
padding: 4px 0;
}
......
......@@ -31,8 +31,11 @@ const cesium_config = {
tile3dCenter: [112.929960602617,28.2186568459113], // Cesium 3D tile 三维路口模型坐标
tile3dURL: 'http://10.102.1.180:9090/1111/tileset.json', // 3D tile 三维路口模型
// tile3dURL: 'http://10.102.1.180:9090/1111/tileset.json', // 3D tile 三维路口模型
// tile3dURL: 'http://10.102.1.180:9090/cccc/tileset.json', // 3D tile 三维路口模型
// tile3dURL: 'http://192.168.2.78:9090/changsha2023/tileset.json', // 3D tile 三维路口模型
// tile3dURL: 'http://localhost:9003/model/scOjFHld/tileset.json', //李老八路径/
tile3dURL:'http://192.168.2.78:9090/changsha123/tileset.json',
zoomHeight: 1800, // 3D map 默认视角高度
baseMap: 'http://106.120.201.126:14722/styles/OSM%20OpenMapTiles/{z}/{x}/{y}@2x.png', // 3D map 标清底图
......
......@@ -15,7 +15,7 @@ export default {
computed: {},
methods: {
loadMap() {
// Cesium.Ion.defaultAccessToken = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiJkZWVjYmI0Mi0wMzk2LTQ2YjMtYjYwOC04MmMyNzEyYjJiOTMiLCJpZCI6MTA0MTAyLCJpYXQiOjE2NjAwMDQ5MjR9.YwCrjFrZrgYYxxxqAXlDWB_eQdmPh8kgj8ZRfLcEOT4';
Cesium.Ion.defaultAccessToken = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiJkZWVjYmI0Mi0wMzk2LTQ2YjMtYjYwOC04MmMyNzEyYjJiOTMiLCJpZCI6MTA0MTAyLCJpYXQiOjE2NjAwMDQ5MjR9.YwCrjFrZrgYYxxxqAXlDWB_eQdmPh8kgj8ZRfLcEOT4';
viewer = new Cesium.Viewer(this.cId, {
animation: false, // 隐藏动画控件
baseLayerPicker: false, // 隐藏图层选择控件
......@@ -35,12 +35,9 @@ export default {
// 如场景中的元素没有随仿真时间变化,请考虑将设置maximumRenderTimeChange为较高的值,例如Infinity
// maximumRenderTimeChange: Infinity,
shadows: false,
imageryProvider: new Cesium.UrlTemplateImageryProvider({
url: cesium_config.baseMap,
fileExtension: "png"
}),
// imageryProvider: new Cesium.ArcGisMapServerImageryProvider({
// url: "https://services.arcgisonline.com/ArcGIS/rest/services/NatGeo_World_Map/MapServer/",
// imageryProvider: new Cesium.UrlTemplateImageryProvider({
// url: cesium_config.baseMap,
// fileExtension: "png"
// }),
// terrainProvider: Cesium.createWorldTerrain(), // 地形
});
......@@ -49,22 +46,13 @@ export default {
const tileset = new Cesium.Cesium3DTileset({
url: cesium_config.tile3dURL
});
tileset.readyPromise.then(function (tileset) {
var boundingSphere = tileset.boundingSphere;
var cartographic = Cesium.Cartographic.fromCartesian(boundingSphere.center);
var surface = Cesium.Cartesian3.fromRadians(cartographic.longitude, cartographic.latitude, 0.0);
var offset = Cesium.Cartesian3.fromRadians(cartographic.longitude, cartographic.latitude, 10.0);
var translation = Cesium.Cartesian3.subtract(offset, surface, new Cesium.Cartesian3());
tileset.modelMatrix = Cesium.Matrix4.fromTranslation(translation);
});
tileset.readyPromise.then(() => {
const position = Cesium.Cartesian3.fromDegrees(cesium_config.tile3dCenter[0], cesium_config.tile3dCenter[1], -60)
tileset.root.transform = Cesium.Transforms.eastNorthUpToFixedFrame(position);
}
)
// tileset.readyPromise.then(() => {
// const position = Cesium.Cartesian3.fromDegrees(cesium_config.tile3dCenter[0], cesium_config.tile3dCenter[1], 0)
// tileset.root.transform = Cesium.Transforms.eastNorthUpToFixedFrame(position);
// })
viewer.scene.primitives.add(tileset)
// viewer.zoomTo(tileset);
viewer.zoomTo(tileset);
viewer.cesiumWidget.creditContainer.style.display = "none"
......@@ -86,14 +74,14 @@ export default {
Cesium.CameraEventType.LEFT_DRAG,
];
viewer.scene.globe.enableLighting = true
viewer.camera.flyTo({
destination: Cesium.Cartesian3.fromDegrees(...cesium_config.center, cesium_config.zoomHeight),
orientation: {
heading: Cesium.Math.toRadians(0), // 旋转角度
pitch: Cesium.Math.toRadians(-90.0), // 相机方向
},
duration: 0.5
});
// viewer.camera.flyTo({
// destination: Cesium.Cartesian3.fromDegrees(...cesium_config.center, cesium_config.zoomHeight),
// orientation: {
// heading: Cesium.Math.toRadians(0), // 旋转角度
// pitch: Cesium.Math.toRadians(-90.0), // 相机方向
// },
// duration: 0.5
// });
return viewer
},
},
......
......@@ -556,36 +556,33 @@ export default {
},
}).$mount("#equipment_popup");
},
// map 可视范围发生变化
refreshMap() {
if (this.$refs.switch) {
for (let item of this.$refs.switch.getOptions()) {
if (item.check) {
this[`switch${item.label}`]();
let zoom = scene.getZoom()
// 处理图层显隐
if (item.label === 'first') {
if (zoom > 18) {
show(layers.first.license)
hide([layers.first.vehiclePic])
}
if (zoom > 17 && zoom <= 18) {
show([layers.first.vehiclePic, layers.first.license])
hide([layers.first.vehicle])
}
if (zoom <= 17) {
show([layers.first.vehicle])
hide([layers.first.vehiclePic, layers.first.license])
}
}
// let zoom = scene.getZoom()
// // 处理图层显隐
// if (item.label === 'first') {
// if (zoom > 18) {
// show(layers.first.license)
// hide([layers.first.vehiclePic])
// }
// if (zoom > 17 && zoom <= 18) {
// show([layers.first.vehiclePic, layers.first.license])
// hide([layers.first.vehicle])
// }
// if (zoom <= 17) {
// show([layers.first.vehicle])
// hide([layers.first.vehiclePic, layers.first.license])
// }
//
// }
}
}
}
},
// 切换业务图层
changeCheck(item) {
if (item.check) {
......@@ -620,6 +617,9 @@ export default {
}
},
// 更新经纬度-角度-详细信息-弹窗信息
setModel(model, options, setColor) {
if (setColor) {
......@@ -657,7 +657,6 @@ export default {
model.setRotation({x: 90, y: 360 - options.courseAngle - 90, z: 0});
}
},
// 改变车辆详情弹窗内容
changeVehicleDetail(data) {
vehicleDetailPopup = new Popup({
......@@ -674,14 +673,12 @@ export default {
},
}).$mount("#vehicle_popup");
},
// 选中模型改变
onSelectedChangeVehicle(e) {
this.vehiclePopupVisible = true
this.selectVehicle = e.detail.userData.data;
this.changeVehicleDetail(this.selectVehicle)
},
// 根据处理后的数组新增-删除-更新模型
addDelUpdateVehicleModels(allData) {
if (this.vehicleModelsNum === 21) {
......@@ -713,34 +710,9 @@ export default {
console.log('count...', window.tb.world.children.length)
}
},
// 添加车牌号图层
addOrUpdateLicense(msg){
if (!layers.first.license) {
layers.first.license = l7Tools.addLicenseLayer(scene, msg);
} else {
for (let msgItem of msg) {
for (let old of layers.first.license.encodedData) {
if (
msgItem.picLicense === old.shape &&
turf.distance(
[msgItem.longitude, msgItem.latitude],
old.coordinates,
{units: "kilometers"}
) < 0.0005
) {
msgItem.longitude = old.coordinates[0];
msgItem.latitude = old.coordinates[1];
}
}
}
layers.first.license.setData(msg);
show(layers.first.license);
}
},
// websocket 回调
callCar(msg) {
let start = performance.now();
// 筛选可见区域
for (let i = 0; i < msg.length; i++) {
if (!msg[i].picLicense) {
msg[i].picLicense = ''
......@@ -753,19 +725,19 @@ export default {
}
}
if (this.sceneLoaded && msg.length > 0) {
// 第一帧 || 时间戳不相同放行
// 第一帧 || 时间戳不相同 => 放行
if (this.lastLocation.length === 0 || this.lastLocation[0].dateTime !== msg[0].dateTime) {
this.situationTimeVal = msg[0].dateTime
// 层级最大 展示3D & 车牌号
if (scene.getZoom() > 18) {
hide([layers.first.vehicle, layers.first.vehiclePic])
window.tb.world.visible = true;
this.currentLocation = msg;
let allData = this.diff(this.lastLocation, this.currentLocation);
this.lastLocation = msg;
this.addDelUpdateVehicleModels(allData);
this.addOrUpdateLicense(msg)
}
else {
} else {
this.lastLocation = [];
if (this.selectVehicle) {
this.selectVehicle = null;
......@@ -778,46 +750,88 @@ export default {
}
let zoom = scene.getZoom()
if (zoom > 17) {
// 层级中等 展示车牌号 & 图片
hide([layers.first.vehicle])
this.addOrUpdateVehiclePic(msg)
this.addOrUpdateLicense(msg)
if (!layers.first.vehiclePic) {
layers.first.vehiclePic = l7Tools.addVehiclePic(scene, msg);
} else {
for (let msgItem of msg) {
for (let old of layers.first.vehiclePic.encodedData) {
if (
msgItem.originalType === old.shape &&
turf.distance(
[msgItem.longitude, msgItem.latitude],
old.coordinates,
{units: "kilometers"}
) < 0.0005
) {
msgItem.longitude = old.coordinates[0];
msgItem.latitude = old.coordinates[1];
}
}
}
layers.first.vehiclePic.setData(msg);
}
}
if (zoom <= 17) {
if (!layers.first.vehicle) {
layers.first.vehicle = l7Tools.addVehicleLayer(scene, msg);
} else {
show(layers.first.vehicle);
layers.first.vehicle && layers.first.vehicle.setData(msg);
}
hide([layers.first.license,layers.first.vehiclePic])
this.addOrUpdateVehicle(msg)
}
}
}
}
let end = performance.now();
// console.log('cost is', `${end - start}ms`)
},
addOrUpdateLicense(msg) {
if (!layers.first.license) {
layers.first.license = l7Tools.addLicenseLayer(scene, msg);
} else {
for (let msgItem of msg) {
for (let old of layers.first.license.encodedData) {
if (
msgItem.picLicense === old.shape &&
turf.distance(
[msgItem.longitude, msgItem.latitude],
old.coordinates,
{units: "kilometers"}
) < 0.0005
) {
msgItem.longitude = old.coordinates[0];
msgItem.latitude = old.coordinates[1];
}
}
}
layers.first.license.setData(msg);
show(layers.first.license);
}
},
addOrUpdateVehicle(msg) {
if (!layers.first.vehicle) {
layers.first.vehicle = l7Tools.addVehicleLayer(scene, msg);
} else {
layers.first.vehicle && layers.first.vehicle.setData(msg);
show(layers.first.vehicle);
}
},
addOrUpdateVehiclePic(msg) {
if (!layers.first.vehiclePic) {
layers.first.vehiclePic = l7Tools.addVehiclePic(scene, msg);
} else {
for (let msgItem of msg) {
for (let old of layers.first.vehiclePic.encodedData) {
if (
msgItem.originalType === old.shape &&
turf.distance(
[msgItem.longitude, msgItem.latitude],
old.coordinates,
{units: "kilometers"}
) < 0.0005
) {
msgItem.longitude = old.coordinates[0];
msgItem.latitude = old.coordinates[1];
}
}
}
layers.first.vehiclePic.setData(msg);
show(layers.first.vehiclePic)
}
},
// 比较websocket车辆前后两次数据差异
diff(oldData, newData) {
// id 只在 newData 中存在且不在 oldData 中存在的即为 add
const add = newData.filter((e) => !oldData.find((c) => c.id === e.id));
// id 只在 oldData 中存在且不在 newData 中存在的即为 dele
const del = oldData.filter((e) => !newData.find((c) => c.id === e.id));
const com = newData.filter((e) => oldData.find((c) => c.id === e.id));
add.forEach((a) => (a.dill = "add"));
del.forEach((d) => (d.dill = "del"));
com.forEach((c) => (c.dill = "com"));
return [...add, ...del, ...com];
},
callPasserby(msg) {
let arr = [];
......@@ -1139,18 +1153,7 @@ export default {
if (success) {
}
},
// 比较websocket车辆前后两次数据差异
diff(oldData, newData) {
// id 只在 newData 中存在且不在 oldData 中存在的即为 add
const add = newData.filter((e) => !oldData.find((c) => c.id === e.id));
// id 只在 oldData 中存在且不在 newData 中存在的即为 dele
const del = oldData.filter((e) => !newData.find((c) => c.id === e.id));
const com = newData.filter((e) => oldData.find((c) => c.id === e.id));
add.forEach((a) => (a.dill = "add"));
del.forEach((d) => (d.dill = "del"));
com.forEach((c) => (c.dill = "com"));
return [...add, ...del, ...com];
},
// videoList 删除单个 video
deleteVideo(item) {
let index = this.videoListData.indexOf(item);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment