integrated_traffic_vue/src/views/BI/js/trajectory.js

318 lines
8.3 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

import pako from "pako"; // 解密gzip插件
import { useWebSocket } from "@vueuse/core";
import { useUserStore } from "@/pinia/user";
import pinia from "@/pinia";
import { getRealTimeList, getFenceList } from "@/request/map";
const userStore = useUserStore(pinia);
const pls_ip = userStore.getUserInfo.POST_URL;
// const pls_ip = "http://121.22.38.202:8084";
let entityArr = [];
let billboardArr = [];
const fencesArr = [];
const leftObj = {
perDataList: [],
armDataList: [],
regPerDataList: [], // 区域人员统计
deptDataList: [], // 部门统计
};
const { open, close } = useWebSocket(
encodeURI("ws://" + pls_ip.replace("http://", "") + "/netty/test.io?u=1"),
// encodeURI("ws://58.58.162.14:8084/netty/test.io?userid=1"),
{
immediate: false,
heartbeat: {
message: "ping",
interval: 5000,
pongTimeout: 1000,
},
delay: 1000,
onMessage: (ws, event) => {
const msg = unzip(event.data);
const decodedMsg = JSON.parse(decodeURIComponent(msg));
if (decodedMsg.msg === "000") {
peoMovement(decodedMsg.data);
}
if (decodedMsg.msg === "006") {
addNewPerson(decodedMsg.data);
}
if (decodedMsg.msg === "008") {
removePerson(decodedMsg.data);
}
changeLeftObjData(decodedMsg);
},
onDisconnected: () => {
if (entityArr && entityArr.children) {
entityArr.children.forEach((e) => {
e.destroy();
});
billboardArr.children.forEach((e) => {
e.destroy();
});
entityArr = [];
billboardArr = [];
}
},
}
);
export const handleGetPerList = async () => {
return leftObj;
};
export const handleInit = async () => {
getOnlineUser();
open();
};
export const handleTrajectory = (b) => {
if (b) {
getOnlineUser();
open();
} else {
close();
}
};
const getOnlineUser = async () => {
entityArr = new window.CustomCesium.GroupModel("人物模型");
billboardArr = new window.CustomCesium.GroupModel("人物姓名");
await getRealTimeList();
const { data } = await getRealTimeList();
const userList = data.data.list;
userList.forEach((item) => {
const user = item.split(",");
addEntity(user[0], user[5], user[1], user[2], user[3], user[8], user[6]);
addBillboard(user[0], user[5], user[1], user[2], user[3], user[8], user[7]);
});
entityArr.show(true);
billboardArr.show(true);
};
const addEntity = (id, name, lon, lat, height, floor, gltf) => {
const obj = new window.CustomCesium.Model(window.$icy, {
url: "/src/assets/glb/" + gltf + ".gltf",
height: 0,
scale: 1,
angle: [-90, 0, 0],
});
let e;
// eslint-disable-next-line prefer-const
e = obj.clone(e);
const enModule = new window.CustomCesium.Model(
window.$icy,
{
name: "人物",
floor,
peoName: name,
height,
id,
lon,
lat, // 位置
scale: 1, // 大小
angle: [-90, 0, 0],
},
e
);
// 修改模型方向 第一个参数是航向角
// enModule.updateAngle([-90,20,20]);
entityArr.add(enModule);
};
const addBillboard = (id, name, lon, lat, height, floor, type) => {
// 创建广告牌
const bulletinBoard = new window.CustomCesium.BulletinBoard(window.$icy);
bulletinBoard.loadCanvas(drawCanvas(name, floor), {
name: "人物铭牌",
floor,
peoName: name,
id: id + "_name",
lon,
lat,
height: Number(height) + 2.05,
url: "/src/assets/glb/" + type + ".png",
});
billboardArr.add(bulletinBoard);
};
// eslint-disable-next-line no-unused-vars
const drawCanvas = (name, floor) => {
const canvas = document.createElement("canvas");
const width = 160;
const height = 46;
canvas.width = width;
canvas.height = height;
const borderRadius = 5; // 圆角半径
const ctx = canvas.getContext("2d");
ctx.beginPath();
ctx.moveTo(borderRadius, 0);
ctx.lineTo(width - borderRadius, 0);
ctx.arcTo(width, 0, width, borderRadius, borderRadius);
ctx.lineTo(width, height - borderRadius);
ctx.arcTo(width, height, width - borderRadius, height, borderRadius);
ctx.lineTo(borderRadius, height);
ctx.arcTo(0, height, 0, height - borderRadius, borderRadius);
ctx.lineTo(0, borderRadius);
ctx.arcTo(0, 0, borderRadius, 0, borderRadius);
ctx.closePath();
ctx.fillStyle = "rgba(42, 86, 158, 1)";
ctx.fill();
ctx.fillStyle = "#fff";
ctx.font = "normal 28px 'Microsoft YaHei'";
ctx.textAlign = "center";
ctx.textBaseline = "middle";
ctx.fillText((name || "未知人员") + `(${floor}F)`, width / 2, height / 2);
return canvas;
};
const changeLeftObjData = (decodedMsg) => {
if (decodedMsg.msg === "005") {
leftObj.perDataList = decodedMsg.data;
}
if (decodedMsg.msg === "003") {
leftObj.armDataList = decodedMsg.data;
}
if (decodedMsg.msg === "002") {
leftObj.regPerDataList = decodedMsg.data;
}
if (decodedMsg.msg === "008") {
leftObj.deptDataList = decodedMsg.data;
}
};
const addNewPerson = (data) => {
data.forEach((item) => {
const entity = item.split(",");
addEntity(
entity[0],
entity[5],
entity[1],
entity[2],
entity[4],
1,
entity[6]
);
addBillboard(
entity[0],
entity[5],
entity[1],
entity[2],
entity[4],
1,
entity[7]
);
});
};
const removePerson = (data) => {
data.forEach((item) => {
entityArr.children.forEach((e) => {
if (e.entity._id === item) {
e.destroy();
}
});
billboardArr.children.forEach((e) => {
if (e.entity._id === item + "_name") {
e.destroy();
}
});
});
};
const unzip = (b64Data) => {
let strData = atob(b64Data);
const charData = strData.split("").map(function (x) {
return x.charCodeAt(0);
});
const binData = new Uint8Array(charData);
const data = pako.inflate(binData);
strData = String.fromCharCode.apply(null, new Uint16Array(data));
return strData;
};
/**
* moveData 接收webscoket人物移动数据
* entityArr 接收人物模型分组
* billboardArr 接收人物铭牌分组
*/
function peoMovement(moveData) {
const map = new Map();
moveData.forEach((i, n) => {
map.set(i.split(",")[0], n);
});
entityArr.children.forEach((b, m) => {
const index = map.get(b.entity._id);
const item = moveData[index];
if (index !== undefined) {
const itData = item.split(","); // itData下标0=【卡号】1,24=【lonlatalt】3=【人物朝向角度】5=【工号】6=【当前楼层】
if (itData[4] != null && itData.length >= 6) {
b.updateAngle([itData[3], 0, 0]); // 改变人物朝向
b.animationMove(
itData[1],
itData[2],
Number(itData[4]),
2000,
() => {}
); // 人物平滑移动
billboardArr.children[m].animationMove(
itData[1],
itData[2],
Number(Number(itData[4]) + 2.05),
2000
); // 人物铭牌平滑移动
if (Number(itData[6]) !== Number(b.entity.floor)) {
b.entity.floor = itData[6];
billboardArr.children[m].uopdateImg(
drawCanvas(b.entity.peoName, itData[6]),
!0
);
}
} else {
console.log(`人物移动数据错误,错误参数:'${item}'`);
}
}
});
}
export const trackUser = (id, b) => {
if (b) {
const t = window.$icy.viewer.entities.getById(id);
window.$icy.viewer.trackedEntity = t;
window.$icy.viewer._selectedEntity = t;
t.viewFrom = new window.Cesium.Cartesian3(-30, 60, 30);
} else {
window.$icy.viewer._selectedEntity = undefined;
window.$icy.viewer.trackedEntity = undefined;
window.$icy.viewer.camera.lookAtTransform(window.Cesium.Matrix4.IDENTITY);
}
};
export const handleFence = async (b) => {
if (b) {
const { data } = await getFenceList();
const fences = data.rows;
fences.forEach((fence) => {
if (fence.list.length > 0) {
const enclosure = new window.CustomCesium.Enclosure(window.$icy);
enclosure.showDataSource(
fence.list, // 数据
30, // 高度
"yellow" // 颜色默认黄色
);
fencesArr.push(enclosure);
}
});
} else {
if (fencesArr) {
fencesArr.forEach((fence) => {
fence.clear();
fence.destroy();
});
}
}
};