import pako from "pako"; // 解密gzip插件 import { useWebSocket } from "@vueuse/core"; import { useUserStore } from "@/pinia/user"; import pinia from "@/pinia"; import { getRealTimeList } 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 { open, close } = useWebSocket( encodeURI("ws://" + pls_ip.replace("http://", "") + "/netty/test.io?u=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); } }, onDisconnected: () => { if (entityArr) { entityArr.children.forEach((e) => { e.destroy(); }); billboardArr.children.forEach((e) => { e.destroy(); }); } }, } ); 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(); // let userList = data.data; const userList = [ { cardNo: "8379", name: "大大", longitude: 119.44768654, latitude: 39.91745908, altitude: 0, }, { cardNo: "9979", name: "小小小小", longitude: 119.44758754, latitude: 39.91745908, altitude: 0, }, ]; userList.forEach(({ cardNo, name, longitude, latitude, altitude }) => { addEntity(cardNo, name, longitude, latitude, altitude); addBillboard(cardNo, name, longitude, latitude, altitude + 2); }); entityArr.show(true); billboardArr.show(true); }; const addEntity = (id, name, lon, lat, height) => { const obj = new window.CustomCesium.Model(window.$icy, { url: "/src/assets/glb/person_000002_blue.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: "人物", 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) => { // 创建广告牌 const bulletinBoard = new window.CustomCesium.BulletinBoard(window.$icy); bulletinBoard.loadCanvas(drawCanvas(name), { name: "人物铭牌", id: id + "_name", lon, lat, height, }); billboardArr.add(bulletinBoard); }; // eslint-disable-next-line no-unused-vars const drawCanvas = (name) => { const canvas = document.createElement("canvas"); const width = 70; const height = 20; 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 12px 'Microsoft YaHei'"; ctx.textAlign = "center"; ctx.textBaseline = "middle"; ctx.fillText(name, width / 2, height / 2); return canvas; }; const addNewPerson = (data) => { data.forEach((item) => { const entity = item.split(","); addEntity(entity[0], entity[5], entity[1], entity[2], entity[4]); addBillboard(entity[0], entity[5], entity[1], entity[2], entity[4]); }); }; 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,2,4)=【lon,lat,alt】,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 ); // 人物铭牌平滑移动 } else { console.log(`人物移动数据错误,错误参数:'${item}'`); } } }); } export const handleFence = () => { };