forked from integrated_whb/integrated_whb_vue
人员路径和绘制电子围栏
parent
626c1a4bb9
commit
97b43e070f
File diff suppressed because one or more lines are too long
|
@ -0,0 +1,79 @@
|
||||||
|
<template>
|
||||||
|
<div id="bi_container">
|
||||||
|
<div id="map" class="map_bg"></div>
|
||||||
|
<el-button type="primary" @click="confrim">完成绘制</el-button>
|
||||||
|
<el-button type="primary" @click="clear">清除绘制</el-button>
|
||||||
|
<el-button type="primary" @click="reduction">还原建筑</el-button>
|
||||||
|
<span>当前选中楼层id:{{ model_id }}</span>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { useVModels } from "@vueuse/core";
|
||||||
|
import { onBeforeUnmount, onMounted, ref } from "vue";
|
||||||
|
import {
|
||||||
|
clearEnclosure,
|
||||||
|
handleEnclosure,
|
||||||
|
handleMouseClick,
|
||||||
|
initMap,
|
||||||
|
reduction,
|
||||||
|
showEnclosure,
|
||||||
|
} from "./map";
|
||||||
|
import { useUserStore } from "@/pinia/user.js";
|
||||||
|
import { getEnterpriseInfo } from "@/request/enterprise_management.js";
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
positions: {
|
||||||
|
type: Array,
|
||||||
|
required: true,
|
||||||
|
default: () => [],
|
||||||
|
},
|
||||||
|
modUuid: {
|
||||||
|
type: String,
|
||||||
|
required: true,
|
||||||
|
default: "",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
const userStore = useUserStore();
|
||||||
|
const CORPINFO_ID = userStore.getUserInfo.CORPINFO_ID;
|
||||||
|
const data = [];
|
||||||
|
const model_id = ref(0);
|
||||||
|
const emits = defineEmits(["update:positions", "update:modUuid"]);
|
||||||
|
const { positions, modUuid } = useVModels(props, emits);
|
||||||
|
|
||||||
|
const confrim = () => {
|
||||||
|
showEnclosure(data);
|
||||||
|
positions.value = [...data];
|
||||||
|
modUuid.value = model_id.value;
|
||||||
|
};
|
||||||
|
const clear = () => {
|
||||||
|
clearEnclosure(data);
|
||||||
|
data.length = 0;
|
||||||
|
positions.value = [];
|
||||||
|
};
|
||||||
|
onMounted(async () => {
|
||||||
|
const corp = await getEnterpriseInfo({ CORPINFO_ID });
|
||||||
|
initMap(corp.pd);
|
||||||
|
handleMouseClick(model_id);
|
||||||
|
handleEnclosure(data);
|
||||||
|
});
|
||||||
|
onBeforeUnmount(() => {
|
||||||
|
window.$scene = null;
|
||||||
|
window.$icy = null;
|
||||||
|
window.$carmer = null;
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
<style scoped lang="scss">
|
||||||
|
#bi_container {
|
||||||
|
width: 100%;
|
||||||
|
height: 500px;
|
||||||
|
color: #ffffff;
|
||||||
|
position: relative;
|
||||||
|
font-size: 14px;
|
||||||
|
|
||||||
|
.map_bg {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -0,0 +1,167 @@
|
||||||
|
import axios from "axios";
|
||||||
|
import { useUserStore } from "@/pinia/user";
|
||||||
|
import pinia from "@/pinia";
|
||||||
|
|
||||||
|
const userStore = useUserStore(pinia);
|
||||||
|
const pls_ip = userStore.getUserInfo.POST_URL;
|
||||||
|
const url = pls_ip.replace("8084", "9000") + "/buildr/public/models/glb/";
|
||||||
|
export class Loadglb {
|
||||||
|
static modelMap = {};
|
||||||
|
constructor(icy) {
|
||||||
|
this.icy = icy;
|
||||||
|
this.model_def_group = null;
|
||||||
|
this.scene = null;
|
||||||
|
this.idList = [];
|
||||||
|
this.entityList = [];
|
||||||
|
this.number = 0;
|
||||||
|
this.building_group = null;
|
||||||
|
this.groundHeight = 0.2; // 设置地面的高度
|
||||||
|
}
|
||||||
|
|
||||||
|
async fetchData() {
|
||||||
|
try {
|
||||||
|
const response = await axios.get(
|
||||||
|
pls_ip.replace("8084", "9000") +
|
||||||
|
"/buildr/public/models/scene_000001.json"
|
||||||
|
);
|
||||||
|
// 将获取的数据保存到实例的属性中
|
||||||
|
this.scene = response.data.scene;
|
||||||
|
this.model_def_group = response.data.scene.model_def_group;
|
||||||
|
|
||||||
|
const map = new Map();
|
||||||
|
this.model_def_group.forEach((i) => {
|
||||||
|
map.set(i.guid.split("-")[3], { name: i.name, id: i.guid });
|
||||||
|
});
|
||||||
|
this.scene.building_group.forEach((i) => {
|
||||||
|
i.layer_group.forEach((a) => {
|
||||||
|
a.modelName = map.get(a.guid[0].split("-")[3]);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
this.building_group = this.scene.building_group;
|
||||||
|
// console.log(this.building_group);
|
||||||
|
} catch (error) {
|
||||||
|
// 处理可能错误
|
||||||
|
console.error(error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async model(Model) {
|
||||||
|
try {
|
||||||
|
// 执行 axios 请求并等待 fetchData 函数的异步操作完成
|
||||||
|
await this.fetchData();
|
||||||
|
const modelList = {};
|
||||||
|
this.scene.model_def_group.forEach((item) => {
|
||||||
|
modelList[item.guid] = item.name;
|
||||||
|
});
|
||||||
|
const modelTotal = this.scene.building_group.length;
|
||||||
|
this.createModel(Model, modelList, modelTotal);
|
||||||
|
this.scene.ground_group.forEach((ground) => {
|
||||||
|
const lon = ground.transform.translate.x;
|
||||||
|
const lat = ground.transform.translate.y;
|
||||||
|
const scale = ground.transform.scale;
|
||||||
|
ground.model_ref_group.forEach((layer) => {
|
||||||
|
// console.log(layer,'111');
|
||||||
|
const height = this.groundHeight;
|
||||||
|
const unit = {
|
||||||
|
lon,
|
||||||
|
lat,
|
||||||
|
scale,
|
||||||
|
id: layer.model_def_guid,
|
||||||
|
};
|
||||||
|
this.logNum([layer], height, unit, modelList, Model);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
// 处理可能的错误
|
||||||
|
console.error(error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
createModel(Model, modelList, modelTotal) {
|
||||||
|
this.scene.building_group.forEach((building, index) => {
|
||||||
|
if (
|
||||||
|
Number(this.number * 2) <= index &&
|
||||||
|
index < Number((this.number + 1) * 2)
|
||||||
|
) {
|
||||||
|
const lon = building.transform.translate.x;
|
||||||
|
const lat = building.transform.translate.y;
|
||||||
|
const scale = building.transform.scale;
|
||||||
|
building.layer_group.forEach((layer) => {
|
||||||
|
// console.log(layer,'111');
|
||||||
|
const height = Number(layer.height[0] + this.groundHeight);
|
||||||
|
const unit = {
|
||||||
|
lon,
|
||||||
|
lat,
|
||||||
|
scale,
|
||||||
|
id: layer.guid[0],
|
||||||
|
};
|
||||||
|
this.logNum(layer.model_ref_group, height, unit, modelList, Model);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (this.number * 2 < modelTotal) {
|
||||||
|
const throttle = setTimeout(() => {
|
||||||
|
this.number++;
|
||||||
|
this.createModel(Model, modelList, modelTotal);
|
||||||
|
sessionStorage.setItem("loading", (this.number * 2) / modelTotal);
|
||||||
|
clearTimeout(throttle);
|
||||||
|
}, 20);
|
||||||
|
if (
|
||||||
|
(this.number * 2) / modelTotal >= 0.5 &&
|
||||||
|
(this.number * 2) / modelTotal < 0.8
|
||||||
|
) {
|
||||||
|
sessionStorage.setItem("loadModel", "过半");
|
||||||
|
} else if ((this.number * 2) / modelTotal >= 0.8) {
|
||||||
|
sessionStorage.setItem("loadModel", "临底");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
console.log(
|
||||||
|
"加载完成 ,此次加载:" +
|
||||||
|
modelTotal +
|
||||||
|
"栋建筑,共:" +
|
||||||
|
this.model_def_group.length +
|
||||||
|
"个模型"
|
||||||
|
);
|
||||||
|
sessionStorage.setItem("loadModel", "完成");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
logNum(red, height, unit, modelList, Model) {
|
||||||
|
red.forEach((item) => {
|
||||||
|
if (this.idList.indexOf(item.model_def_guid) !== -1) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.idList.push(item.model_def_guid);
|
||||||
|
if (
|
||||||
|
Object.prototype.hasOwnProperty.call(
|
||||||
|
Loadglb.modelMap,
|
||||||
|
`${unit.id.split("-")[3].slice(0, unit.id.split("-")[3].length - 2)}`
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
Loadglb.modelMap[
|
||||||
|
`${unit.id.split("-")[3].slice(0, unit.id.split("-")[3].length - 2)}`
|
||||||
|
].push(item.model_def_guid);
|
||||||
|
} else {
|
||||||
|
Loadglb.modelMap[
|
||||||
|
`${unit.id.split("-")[3].slice(0, unit.id.split("-")[3].length - 2)}`
|
||||||
|
] = [item.model_def_guid];
|
||||||
|
}
|
||||||
|
const m = new Model(this.icy, {
|
||||||
|
id: item.model_def_guid,
|
||||||
|
name: "建筑",
|
||||||
|
url: `${url}${modelList[item.model_def_guid]}.gltf`,
|
||||||
|
height,
|
||||||
|
lon: unit.lon,
|
||||||
|
lat: unit.lat,
|
||||||
|
scale: unit.scale,
|
||||||
|
angle: [90, 0, 0],
|
||||||
|
// angle: [97.4843053, 0, 0]
|
||||||
|
});
|
||||||
|
this.entityList.push(m);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
getArr() {
|
||||||
|
return this.building_group;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,228 @@
|
||||||
|
import { Loadglb } from "./loadglb.js";
|
||||||
|
|
||||||
|
const loadMap = 3;
|
||||||
|
let $entityTransparent = [];
|
||||||
|
const clickModel = new Map();
|
||||||
|
|
||||||
|
let enclosure = null;
|
||||||
|
export const initMap = (corp) => {
|
||||||
|
window.$scene = new window.CustomCesium.Scene(
|
||||||
|
"map",
|
||||||
|
corp.CORP_NAME,
|
||||||
|
Number(loadMap)
|
||||||
|
);
|
||||||
|
window.$icy = window.$scene.getIcy();
|
||||||
|
window.$carmer = new window.CustomCesium.Carmer(window.$icy);
|
||||||
|
window.$icy.viewer.targetFrameRate = "30";
|
||||||
|
window.$icy.viewer.scene.light = new window.Cesium.DirectionalLight({
|
||||||
|
// 去除时间原因影响模型颜色
|
||||||
|
direction: new window.Cesium.Cartesian3(
|
||||||
|
0.35492591601301104,
|
||||||
|
-0.8909182691839401,
|
||||||
|
-0.2833588392420772
|
||||||
|
),
|
||||||
|
});
|
||||||
|
const [wgsLat, wgsLon] = bd09ToWgs84(corp.LATITUDE, corp.LONGITUDE);
|
||||||
|
console.log(corp.LATITUDE, corp.LONGITUDE);
|
||||||
|
flyTo(wgsLon, wgsLat);
|
||||||
|
// 亮度设置
|
||||||
|
const stages = window.$icy.viewer.scene.postProcessStages;
|
||||||
|
window.$icy.viewer.scene.brightness =
|
||||||
|
window.$icy.viewer.scene.brightness ||
|
||||||
|
stages.add(window.Cesium.PostProcessStageLibrary.createBrightnessStage());
|
||||||
|
window.$icy.viewer.scene.brightness.enabled = true;
|
||||||
|
window.$icy.viewer.scene.brightness.uniforms.brightness = Number(1.05); // 此处亮度值为倍数
|
||||||
|
createGlb(); // 加载glb
|
||||||
|
};
|
||||||
|
|
||||||
|
const bd09ToWgs84 = (bdLat, bdLon) => {
|
||||||
|
const pi = Math.PI;
|
||||||
|
const x_pi = (pi * 3000.0) / 180.0;
|
||||||
|
const x = bdLon - 0.0065;
|
||||||
|
const y = bdLat - 0.006;
|
||||||
|
const z = Math.sqrt(x * x + y * y) - 0.00002 * Math.sin(y * x_pi);
|
||||||
|
const theta = Math.atan2(y, x) - 0.000003 * Math.cos(x * x_pi);
|
||||||
|
const wgsLon = z * Math.cos(theta);
|
||||||
|
const wgsLat = z * Math.sin(theta);
|
||||||
|
return [wgsLat, wgsLon];
|
||||||
|
};
|
||||||
|
|
||||||
|
// eslint-disable-next-line no-unused-vars
|
||||||
|
const flyTo = (lng, lat) => {
|
||||||
|
window.$carmer.flyTo({
|
||||||
|
// 视角飞入
|
||||||
|
maxHeight: 1500,
|
||||||
|
time: 1,
|
||||||
|
position: [lng, lat, 200],
|
||||||
|
angle: [0, -60, 0],
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const createGlb = () => {
|
||||||
|
// 加载glb(建筑模型)
|
||||||
|
const loadGlb = new Loadglb(window.$icy);
|
||||||
|
loadGlb.model(window.CustomCesium.Model);
|
||||||
|
};
|
||||||
|
|
||||||
|
// eslint-disable-next-line no-unused-vars
|
||||||
|
export const handleMouseClick = (model_id) => {
|
||||||
|
// 加载鼠标拾取
|
||||||
|
const $mouse = new window.CustomCesium.Mouse(window.$icy);
|
||||||
|
// 隐藏逻辑
|
||||||
|
$mouse.mouseLeft((model) => {
|
||||||
|
if (model._name === "建筑") {
|
||||||
|
model_id.value = model._id;
|
||||||
|
console.log(model_id);
|
||||||
|
clickBuilding(model);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const clickBuilding = (model) => {
|
||||||
|
if (
|
||||||
|
Loadglb.modelMap[
|
||||||
|
`${model._id.split("-")[3].slice(0, model._id.split("-")[3].length - 2)}`
|
||||||
|
]
|
||||||
|
) {
|
||||||
|
if (
|
||||||
|
clickModel.get(
|
||||||
|
`${model._id
|
||||||
|
.split("-")[3]
|
||||||
|
.slice(0, model._id.split("-")[3].length - 2)}`
|
||||||
|
) === undefined
|
||||||
|
) {
|
||||||
|
// 如果这个模型是第一次点击
|
||||||
|
const m =
|
||||||
|
Loadglb.modelMap[
|
||||||
|
`${model._id
|
||||||
|
.split("-")[3]
|
||||||
|
.slice(0, model._id.split("-")[3].length - 2)}`
|
||||||
|
]; // 整栋楼的id集合
|
||||||
|
// console.log(m, '整栋楼id');
|
||||||
|
if (m.length > 1) {
|
||||||
|
// 当前点击这建筑是否有多层
|
||||||
|
m.forEach((id) => {
|
||||||
|
const entity = window.$icy.viewer.entities.getById(id);
|
||||||
|
if (model.id !== id) {
|
||||||
|
// 排除当前点击楼层
|
||||||
|
if (entity._icy.height > model._icy.height) {
|
||||||
|
if (
|
||||||
|
$entityTransparent.map((a) => a._id).indexOf(entity._id) === -1
|
||||||
|
) {
|
||||||
|
$entityTransparent.push(entity);
|
||||||
|
}
|
||||||
|
// console.log(this.$entityTransparent, '被隐藏的模型楼层集合');
|
||||||
|
entity.model.show = false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
clickModel.set(
|
||||||
|
`${model._id
|
||||||
|
.split("-")[3]
|
||||||
|
.slice(0, model._id.split("-")[3].length - 2)}`,
|
||||||
|
model._icy.height
|
||||||
|
); // 存储这个模型数据
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// 如果点击过这个模型
|
||||||
|
const m =
|
||||||
|
Loadglb.modelMap[
|
||||||
|
`${model._id
|
||||||
|
.split("-")[3]
|
||||||
|
.slice(0, model._id.split("-")[3].length - 2)}`
|
||||||
|
]; // 整栋楼的id集合
|
||||||
|
// console.log(m, '整栋楼id');
|
||||||
|
if (m.length > 1) {
|
||||||
|
// 当前点击这建筑是否有多层
|
||||||
|
if (
|
||||||
|
model._icy.height ===
|
||||||
|
clickModel.get(
|
||||||
|
`${model._id
|
||||||
|
.split("-")[3]
|
||||||
|
.slice(0, model._id.split("-")[3].length - 2)}`
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
m.forEach((id) => {
|
||||||
|
const entity = window.$icy.viewer.entities.getById(id);
|
||||||
|
entity.model.show = true;
|
||||||
|
clickModel.delete(
|
||||||
|
`${model._id
|
||||||
|
.split("-")[3]
|
||||||
|
.slice(0, model._id.split("-")[3].length - 2)}`
|
||||||
|
);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
m.forEach((id) => {
|
||||||
|
const entity = window.$icy.viewer.entities.getById(id);
|
||||||
|
if (model.id !== id) {
|
||||||
|
// 排除当前点击楼层
|
||||||
|
if (entity._icy.height > model._icy.height) {
|
||||||
|
if (
|
||||||
|
$entityTransparent.map((a) => a._id).indexOf(entity._id) ===
|
||||||
|
-1
|
||||||
|
) {
|
||||||
|
$entityTransparent.push(entity);
|
||||||
|
}
|
||||||
|
// console.log(this.$entityTransparent, '被隐藏的模型楼层集合');
|
||||||
|
entity.model.show = false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
clickModel.set(
|
||||||
|
`${model._id
|
||||||
|
.split("-")[3]
|
||||||
|
.slice(0, model._id.split("-")[3].length - 2)}`,
|
||||||
|
model._icy.height
|
||||||
|
); // 存储这个模型数据
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// model.model.color = new Cesium.Color(1, 1, 1, 0.6);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 还原建筑物
|
||||||
|
export const reduction = () => {
|
||||||
|
// 揭盖一键还原
|
||||||
|
if ($entityTransparent.length !== 0) {
|
||||||
|
$entityTransparent = $entityTransparent.forEach((item) => {
|
||||||
|
item.model.color = new window.Cesium.Color(1, 1, 1, 1);
|
||||||
|
item.model.show = true;
|
||||||
|
});
|
||||||
|
$entityTransparent = [];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export const handleEnclosure = (positions) => {
|
||||||
|
const $mouse = new window.CustomCesium.Mouse(window.$icy);
|
||||||
|
enclosure = new window.CustomCesium.Enclosure(window.$icy);
|
||||||
|
// 编辑围栏使用鼠标控件参照demo.html
|
||||||
|
enclosure.start();
|
||||||
|
$mouse.mouseRight((e) => {
|
||||||
|
enclosure.add(e.lng, e.lat, e.alt);
|
||||||
|
positions.push([e.lng, e.lat, e.alt]);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
export const clearEnclosure = () => {
|
||||||
|
if (enclosure) {
|
||||||
|
try {
|
||||||
|
enclosure.show(false);
|
||||||
|
} catch (e) {}
|
||||||
|
enclosure.clear();
|
||||||
|
enclosure = new window.CustomCesium.Enclosure(window.$icy);
|
||||||
|
enclosure.start();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export const showEnclosure = (positions) => {
|
||||||
|
enclosure.finish();
|
||||||
|
enclosure.showDataSource(
|
||||||
|
positions, // 数据
|
||||||
|
30, // 高度
|
||||||
|
"yellow" // 颜色默认黄色
|
||||||
|
);
|
||||||
|
enclosure.show(true);
|
||||||
|
};
|
|
@ -2,7 +2,11 @@ import { post } from "./axios";
|
||||||
|
|
||||||
export const getRealTimeList = (params) => post("/map/getRealTimeList", params); // 获取在线人员列表
|
export const getRealTimeList = (params) => post("/map/getRealTimeList", params); // 获取在线人员列表
|
||||||
export const getFenceList = (params) => post("/map/getFenceList", params); // 获取围栏列表
|
export const getFenceList = (params) => post("/map/getFenceList", params); // 获取围栏列表
|
||||||
|
export const getPersonnelTrajectories = (params) =>
|
||||||
|
post("/map/getPersonnelTrajectories", params); // 获取拥有历史轨迹的全部角色
|
||||||
|
|
||||||
|
export const getCharacterTrajectories = (params) =>
|
||||||
|
post("/map/getCharacterTrajectories", params); // 获取轨迹
|
||||||
export const getUserByCardNo = (params) =>
|
export const getUserByCardNo = (params) =>
|
||||||
post("/user/getUserByCardNo", params);
|
post("/user/getUserByCardNo", params);
|
||||||
|
|
||||||
|
|
|
@ -23,6 +23,8 @@ export const setAssignmentTicketAreaSettingsDeactivateOrEnable = (params) =>
|
||||||
post("/positAlarm/otherRegion/editStatus", params); // 作业票区域设置停用启用
|
post("/positAlarm/otherRegion/editStatus", params); // 作业票区域设置停用启用
|
||||||
export const setAssignmentTicketAreaSettingsDelete = (params) =>
|
export const setAssignmentTicketAreaSettingsDelete = (params) =>
|
||||||
post("/positAlarm/otherRegion/regionDelete", params); // 作业票区域设置删除
|
post("/positAlarm/otherRegion/regionDelete", params); // 作业票区域设置删除
|
||||||
|
export const setPosition = (params) =>
|
||||||
|
post("/positAlarm/otherRegion/redrawTheArea", params); // 区域选点
|
||||||
// TODO 接口不对
|
// TODO 接口不对
|
||||||
export const getPathPlanningList = (params) =>
|
export const getPathPlanningList = (params) =>
|
||||||
post("/positAlarm/coordinateLine/addCoordinateLine", params); // 路径规划列表
|
post("/positAlarm/coordinateLine/addCoordinateLine", params); // 路径规划列表
|
||||||
|
|
|
@ -17,5 +17,4 @@ export const setUnbindingDeployCardData = (params) =>
|
||||||
export const getNotBindTheCardData = (params) =>
|
export const getNotBindTheCardData = (params) =>
|
||||||
post("/deploy/card/thePersonWhoDidNotBindTheCard", params); // 批量解绑
|
post("/deploy/card/thePersonWhoDidNotBindTheCard", params); // 批量解绑
|
||||||
|
|
||||||
|
|
||||||
// 设备管理 ====
|
// 设备管理 ====
|
||||||
|
|
|
@ -102,17 +102,17 @@ const bottomOptionsList = [
|
||||||
check: false,
|
check: false,
|
||||||
action: handleTrajectory,
|
action: handleTrajectory,
|
||||||
},
|
},
|
||||||
{
|
// {
|
||||||
img: new URL("/src/assets/images/map/bottom/ico2.png", import.meta.url)
|
// img: new URL("/src/assets/images/map/bottom/ico2.png", import.meta.url)
|
||||||
.href,
|
// .href,
|
||||||
imgSelect: new URL(
|
// imgSelect: new URL(
|
||||||
"/src/assets/images/map/bottom/ico2_on.png",
|
// "/src/assets/images/map/bottom/ico2_on.png",
|
||||||
import.meta.url
|
// import.meta.url
|
||||||
).href,
|
// ).href,
|
||||||
title: "视频",
|
// title: "视频",
|
||||||
type: "video",
|
// type: "video",
|
||||||
check: false,
|
// check: false,
|
||||||
},
|
// },
|
||||||
{
|
{
|
||||||
img: new URL("/src/assets/images/map/bottom/ico3.png", import.meta.url)
|
img: new URL("/src/assets/images/map/bottom/ico3.png", import.meta.url)
|
||||||
.href,
|
.href,
|
||||||
|
|
|
@ -11,7 +11,12 @@
|
||||||
<el-col :span="6">
|
<el-col :span="6">
|
||||||
<el-form-item prop="personnel">
|
<el-form-item prop="personnel">
|
||||||
<el-select v-model="data.searchForm.personnel" filterable>
|
<el-select v-model="data.searchForm.personnel" filterable>
|
||||||
<el-option label="河北秦安" value="河北秦安" />
|
<el-option
|
||||||
|
v-for="item in data.personList"
|
||||||
|
:key="item.id"
|
||||||
|
:label="item.name ? `${item.name}(${item.id})` : item.id"
|
||||||
|
:value="item.id"
|
||||||
|
/>
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
|
@ -46,9 +51,6 @@
|
||||||
<el-slider v-model="currentSchedule" :max="data.maxSchedule" />
|
<el-slider v-model="currentSchedule" :max="data.maxSchedule" />
|
||||||
<div>
|
<div>
|
||||||
<span class="time">{{ data.time }}</span>
|
<span class="time">{{ data.time }}</span>
|
||||||
<span class="text-yellow ml-10">
|
|
||||||
当前所在图层:<el-tag size="small">{{ data.position }}</el-tag>
|
|
||||||
</span>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="speed ml-20">
|
<div class="speed ml-20">
|
||||||
|
@ -68,10 +70,21 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { reactive } from "vue";
|
import { reactive, onBeforeUnmount } from "vue";
|
||||||
import { ElMessage } from "element-plus";
|
import { ElMessage } from "element-plus";
|
||||||
import { VideoPause, VideoPlay } from "@element-plus/icons-vue";
|
import { VideoPause, VideoPlay } from "@element-plus/icons-vue";
|
||||||
|
import {
|
||||||
|
getPersonnelTrajectories,
|
||||||
|
getCharacterTrajectories,
|
||||||
|
} from "@/request/map.js";
|
||||||
|
import dayjs from "dayjs";
|
||||||
import { useInterval } from "@vueuse/core";
|
import { useInterval } from "@vueuse/core";
|
||||||
|
import {
|
||||||
|
addPerson,
|
||||||
|
hadleDestroy,
|
||||||
|
peoMovement,
|
||||||
|
showLine,
|
||||||
|
} from "@/views/BI/js/history_trajectory.js";
|
||||||
|
|
||||||
const data = reactive({
|
const data = reactive({
|
||||||
searchForm: {
|
searchForm: {
|
||||||
|
@ -79,21 +92,62 @@ const data = reactive({
|
||||||
dates: [],
|
dates: [],
|
||||||
},
|
},
|
||||||
isPlay: false,
|
isPlay: false,
|
||||||
maxSchedule: 100,
|
maxSchedule: 0,
|
||||||
time: "2021-08-01 12:00:00",
|
time: "0000-00-00 00:00:00",
|
||||||
position: "图层1",
|
position: "图层1",
|
||||||
speed: 1.0,
|
speed: 1.0,
|
||||||
|
personList: [],
|
||||||
|
positions: [],
|
||||||
});
|
});
|
||||||
const {
|
const {
|
||||||
counter: currentSchedule,
|
counter: currentSchedule,
|
||||||
pause,
|
pause,
|
||||||
resume,
|
resume,
|
||||||
|
reset,
|
||||||
} = useInterval(() => 1000 / data.speed, {
|
} = useInterval(() => 1000 / data.speed, {
|
||||||
immediate: false,
|
immediate: false,
|
||||||
controls: true,
|
controls: true,
|
||||||
callback: () => {},
|
callback: (count) => {
|
||||||
|
if (count >= data.maxSchedule) {
|
||||||
|
data.isPlay = false;
|
||||||
|
pause();
|
||||||
|
reset();
|
||||||
|
}
|
||||||
|
const currentData = data.positions[count].split(",");
|
||||||
|
const previousValue = count === 0 ? undefined : data.positions[count - 1];
|
||||||
|
const previousPosition = previousValue ? previousValue.split(",") : [];
|
||||||
|
data.time = dayjs(Number(currentData[3])).format("YYYY-MM-DD HH:mm:ss");
|
||||||
|
peoMovement(
|
||||||
|
data.searchForm.personnel,
|
||||||
|
currentData[0],
|
||||||
|
currentData[1],
|
||||||
|
currentData[2],
|
||||||
|
previousValue
|
||||||
|
? angleMath(
|
||||||
|
previousPosition[0],
|
||||||
|
previousPosition[1],
|
||||||
|
currentData[0],
|
||||||
|
currentData[1]
|
||||||
|
)
|
||||||
|
: undefined
|
||||||
|
);
|
||||||
|
},
|
||||||
});
|
});
|
||||||
const fnGetData = () => {
|
|
||||||
|
const angleMath = (lon, lat, lon1, lat1) => {
|
||||||
|
// 计算人物模型朝向角度
|
||||||
|
const radian = Math.atan2(lon - lon1, lat - lat1); // 返回来的是弧度
|
||||||
|
const angle = Number((180 / Math.PI) * radian - 180); // 根据弧度计算角度
|
||||||
|
return angle;
|
||||||
|
};
|
||||||
|
|
||||||
|
const getPersonList = async () => {
|
||||||
|
const res = await getPersonnelTrajectories();
|
||||||
|
data.personList = res.data.data;
|
||||||
|
};
|
||||||
|
|
||||||
|
getPersonList();
|
||||||
|
const fnGetData = async () => {
|
||||||
if (data.searchForm.personnel === "") {
|
if (data.searchForm.personnel === "") {
|
||||||
ElMessage.warning("请选择人员");
|
ElMessage.warning("请选择人员");
|
||||||
return;
|
return;
|
||||||
|
@ -102,8 +156,49 @@ const fnGetData = () => {
|
||||||
ElMessage.warning("请选择时间");
|
ElMessage.warning("请选择时间");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
hadleDestroy();
|
||||||
|
data.positions = [];
|
||||||
|
pause();
|
||||||
|
reset();
|
||||||
|
await getTrajectoriesData(
|
||||||
|
data.searchForm.personnel,
|
||||||
|
data.searchForm.dates[0],
|
||||||
|
data.searchForm.dates[1],
|
||||||
|
1
|
||||||
|
);
|
||||||
|
data.maxSchedule = data.positions.length;
|
||||||
|
const firstData = data.positions[0].split(",");
|
||||||
|
data.time = dayjs(Number(firstData[3])).format("YYYY-MM-DD HH:mm:ss");
|
||||||
|
const person = data.personList.filter(
|
||||||
|
(item) => item.id === data.searchForm.personnel
|
||||||
|
)[0];
|
||||||
|
addPerson(
|
||||||
|
data.searchForm.personnel,
|
||||||
|
person.name ? person.name : person.id,
|
||||||
|
firstData[0],
|
||||||
|
firstData[1],
|
||||||
|
firstData[2]
|
||||||
|
);
|
||||||
|
const positions = data.positions.map((item) => {
|
||||||
|
const position = item.split(",");
|
||||||
|
return [position[0], position[1], Number(position[2]) + 0.5];
|
||||||
|
});
|
||||||
|
showLine(positions);
|
||||||
ElMessage.success("搜索成功");
|
ElMessage.success("搜索成功");
|
||||||
};
|
};
|
||||||
|
const getTrajectoriesData = async (id, startTime, endTime, type) => {
|
||||||
|
const res = await getCharacterTrajectories({
|
||||||
|
id,
|
||||||
|
startTime,
|
||||||
|
endTime,
|
||||||
|
type,
|
||||||
|
});
|
||||||
|
data.positions = data.positions.concat(res.data.data);
|
||||||
|
if (res.data.msg !== "人物轨迹结束") {
|
||||||
|
type++;
|
||||||
|
await getTrajectoriesData(id, startTime, endTime, type);
|
||||||
|
}
|
||||||
|
};
|
||||||
const fnPlay = () => {
|
const fnPlay = () => {
|
||||||
data.isPlay = true;
|
data.isPlay = true;
|
||||||
resume();
|
resume();
|
||||||
|
@ -112,6 +207,11 @@ const fnPause = () => {
|
||||||
data.isPlay = false;
|
data.isPlay = false;
|
||||||
pause();
|
pause();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
onBeforeUnmount(() => {
|
||||||
|
console.log("onBeforeUnmount");
|
||||||
|
hadleDestroy();
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
|
|
|
@ -55,6 +55,8 @@ import BottomOptions from "./components/bottom_options.vue";
|
||||||
import HistoricalTrajectoryOptions from "./components/historical_trajectory_options.vue";
|
import HistoricalTrajectoryOptions from "./components/historical_trajectory_options.vue";
|
||||||
import { useRouter } from "vue-router";
|
import { useRouter } from "vue-router";
|
||||||
import { initMap } from "./js/map";
|
import { initMap } from "./js/map";
|
||||||
|
import { useUserStore } from "@/pinia/user.js";
|
||||||
|
import { getEnterpriseInfo } from "@/request/enterprise_management.js";
|
||||||
|
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const right_option = ref(true);
|
const right_option = ref(true);
|
||||||
|
@ -62,9 +64,10 @@ const transitionKey = ref(0);
|
||||||
const leftCurrentComponent = ref("");
|
const leftCurrentComponent = ref("");
|
||||||
const rightCurrentComponent = ref("");
|
const rightCurrentComponent = ref("");
|
||||||
const isHistoricalTrajectory = ref(false);
|
const isHistoricalTrajectory = ref(false);
|
||||||
const corp = { CORP_NAME: "河北秦安", lng: 119.44758654, lat: 39.91845908 };
|
const userStore = useUserStore();
|
||||||
|
const CORPINFO_ID = userStore.getUserInfo.CORPINFO_ID;
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(async () => {
|
||||||
autofit.init({
|
autofit.init({
|
||||||
dh: document.querySelector(".map_bg").offsetHeight,
|
dh: document.querySelector(".map_bg").offsetHeight,
|
||||||
dw: 1920,
|
dw: 1920,
|
||||||
|
@ -72,9 +75,13 @@ onMounted(() => {
|
||||||
resize: true,
|
resize: true,
|
||||||
});
|
});
|
||||||
transitionKey.value = Math.random();
|
transitionKey.value = Math.random();
|
||||||
initMap(corp);
|
const corp = await getEnterpriseInfo({ CORPINFO_ID });
|
||||||
|
initMap(corp.pd);
|
||||||
});
|
});
|
||||||
onBeforeUnmount(() => {
|
onBeforeUnmount(() => {
|
||||||
|
window.$scene = null;
|
||||||
|
window.$icy = null;
|
||||||
|
window.$carmer = null;
|
||||||
autofit.off();
|
autofit.off();
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -0,0 +1,133 @@
|
||||||
|
let entityArr = [];
|
||||||
|
let billboardArr = [];
|
||||||
|
let line = [];
|
||||||
|
export const addPerson = (id, name, lon, lat, height) => {
|
||||||
|
entityArr = new window.CustomCesium.GroupModel("人物模型");
|
||||||
|
billboardArr = new window.CustomCesium.GroupModel("人物姓名");
|
||||||
|
addEntity(id, name, lon, lat, height);
|
||||||
|
addBillboard(id, name, lon, lat, height);
|
||||||
|
};
|
||||||
|
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: Number(height) + 2.05,
|
||||||
|
});
|
||||||
|
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;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 显示轨迹线
|
||||||
|
*/
|
||||||
|
export const showLine = (positions) => {
|
||||||
|
line = new window.CustomCesium.Line(window.$icy, {
|
||||||
|
width: 10,
|
||||||
|
positions,
|
||||||
|
color: "#00ff00",
|
||||||
|
});
|
||||||
|
line.show(true);
|
||||||
|
// line.destroy();
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* id, lon, lat, height,alt 接收人物移动数据
|
||||||
|
* entityArr 接收人物模型分组
|
||||||
|
* billboardArr 接收人物铭牌分组
|
||||||
|
*/
|
||||||
|
export const peoMovement = (id, lon, lat, height, alt) => {
|
||||||
|
entityArr.children.forEach((b, m) => {
|
||||||
|
if (b.entity._id === id) {
|
||||||
|
b.updateAngle([alt, 0, 0]); // 改变人物朝向
|
||||||
|
b.animationMove(lon, lat, height, 1000, () => {}); // 人物平滑移动
|
||||||
|
billboardArr.children[m].animationMove(
|
||||||
|
lon,
|
||||||
|
lat,
|
||||||
|
Number(Number(height) + 2.05),
|
||||||
|
1000
|
||||||
|
); // 人物铭牌平滑移动
|
||||||
|
} else {
|
||||||
|
console.log(`人物移动数据错误`);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
export const hadleDestroy = () => {
|
||||||
|
if (entityArr && entityArr.children) {
|
||||||
|
entityArr.children.forEach((e) => {
|
||||||
|
e.destroy();
|
||||||
|
});
|
||||||
|
billboardArr.children.forEach((e) => {
|
||||||
|
e.destroy();
|
||||||
|
});
|
||||||
|
line.destroy();
|
||||||
|
entityArr = [];
|
||||||
|
billboardArr = [];
|
||||||
|
line = [];
|
||||||
|
}
|
||||||
|
};
|
|
@ -35,7 +35,8 @@ export const initMap = (corp) => {
|
||||||
-0.2833588392420772
|
-0.2833588392420772
|
||||||
),
|
),
|
||||||
});
|
});
|
||||||
flyTo(corp.lng, corp.lat);
|
const [wgsLat, wgsLon] = bd09ToWgs84(corp.LATITUDE, corp.LONGITUDE);
|
||||||
|
flyTo(wgsLon, wgsLat);
|
||||||
// 亮度设置
|
// 亮度设置
|
||||||
const stages = window.$icy.viewer.scene.postProcessStages;
|
const stages = window.$icy.viewer.scene.postProcessStages;
|
||||||
window.$icy.viewer.scene.brightness =
|
window.$icy.viewer.scene.brightness =
|
||||||
|
@ -47,6 +48,18 @@ export const initMap = (corp) => {
|
||||||
handleMouseClick(); // 加载鼠标拾取
|
handleMouseClick(); // 加载鼠标拾取
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const bd09ToWgs84 = (bdLat, bdLon) => {
|
||||||
|
const pi = Math.PI;
|
||||||
|
const x_pi = (pi * 3000.0) / 180.0;
|
||||||
|
const x = bdLon - 0.0065;
|
||||||
|
const y = bdLat - 0.006;
|
||||||
|
const z = Math.sqrt(x * x + y * y) - 0.00002 * Math.sin(y * x_pi);
|
||||||
|
const theta = Math.atan2(y, x) - 0.000003 * Math.cos(x * x_pi);
|
||||||
|
const wgsLon = z * Math.cos(theta);
|
||||||
|
const wgsLat = z * Math.sin(theta);
|
||||||
|
return [wgsLat, wgsLon];
|
||||||
|
};
|
||||||
|
|
||||||
// eslint-disable-next-line no-unused-vars
|
// eslint-disable-next-line no-unused-vars
|
||||||
const flyTo = (lng, lat) => {
|
const flyTo = (lng, lat) => {
|
||||||
window.$carmer.flyTo({
|
window.$carmer.flyTo({
|
||||||
|
|
|
@ -2,7 +2,7 @@ import pako from "pako"; // 解密gzip插件
|
||||||
import { useWebSocket } from "@vueuse/core";
|
import { useWebSocket } from "@vueuse/core";
|
||||||
import { useUserStore } from "@/pinia/user";
|
import { useUserStore } from "@/pinia/user";
|
||||||
import pinia from "@/pinia";
|
import pinia from "@/pinia";
|
||||||
import { getRealTimeList, getFenceList } from "@/request/map";
|
import { getFenceList } from "@/request/map";
|
||||||
|
|
||||||
const userStore = useUserStore(pinia);
|
const userStore = useUserStore(pinia);
|
||||||
const pls_ip = userStore.getUserInfo.POST_URL;
|
const pls_ip = userStore.getUserInfo.POST_URL;
|
||||||
|
@ -39,50 +39,20 @@ const { open, close } = useWebSocket(
|
||||||
billboardArr.children.forEach((e) => {
|
billboardArr.children.forEach((e) => {
|
||||||
e.destroy();
|
e.destroy();
|
||||||
});
|
});
|
||||||
|
entityArr = [];
|
||||||
|
billboardArr = [];
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
export const handleTrajectory = (b) => {
|
export const handleTrajectory = (b) => {
|
||||||
if (b) {
|
if (b) {
|
||||||
getOnlineUser();
|
|
||||||
open();
|
open();
|
||||||
} else {
|
} else {
|
||||||
close();
|
close();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const getOnlineUser = async () => {
|
|
||||||
entityArr = new window.CustomCesium.GroupModel("人物模型");
|
|
||||||
billboardArr = new window.CustomCesium.GroupModel("人物姓名");
|
|
||||||
// await getRealTimeList();
|
|
||||||
const { data } = await getRealTimeList();
|
|
||||||
let userList = data.data;
|
|
||||||
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 addEntity = (id, name, lon, lat, height) => {
|
||||||
const obj = new window.CustomCesium.Model(window.$icy, {
|
const obj = new window.CustomCesium.Model(window.$icy, {
|
||||||
url: "/src/assets/glb/person_000002_blue.gltf",
|
url: "/src/assets/glb/person_000002_blue.gltf",
|
||||||
|
@ -119,7 +89,7 @@ const addBillboard = (id, name, lon, lat, height) => {
|
||||||
id: id + "_name",
|
id: id + "_name",
|
||||||
lon,
|
lon,
|
||||||
lat,
|
lat,
|
||||||
height,
|
height: height + 2.05,
|
||||||
});
|
});
|
||||||
billboardArr.add(bulletinBoard);
|
billboardArr.add(bulletinBoard);
|
||||||
};
|
};
|
||||||
|
@ -190,31 +160,49 @@ function peoMovement(moveData) {
|
||||||
const map = new Map();
|
const map = new Map();
|
||||||
moveData.forEach((i, n) => {
|
moveData.forEach((i, n) => {
|
||||||
map.set(i.split(",")[0], n);
|
map.set(i.split(",")[0], n);
|
||||||
});
|
if (!entityArr || !entityArr.children) {
|
||||||
entityArr.children.forEach((b, m) => {
|
entityArr = new window.CustomCesium.GroupModel("人物模型");
|
||||||
const index = map.get(b.entity._id);
|
billboardArr = new window.CustomCesium.GroupModel("人物姓名");
|
||||||
const item = moveData[index];
|
const entity = i.split(",");
|
||||||
if (index !== undefined) {
|
addEntity(entity[0], entity[8], entity[1], entity[2], entity[4]);
|
||||||
const itData = item.split(","); // itData下标:0=【卡号】,(1,2,4)=【lon,lat,alt】,3=【人物朝向角度】,5=【工号】,6=【当前楼层】
|
addBillboard(entity[0], entity[8], entity[1], entity[2], entity[4]);
|
||||||
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}'`);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
entityArr.children.forEach((b, m) => {
|
||||||
|
if (!b.entity) {
|
||||||
|
const entity = i.split(",");
|
||||||
|
addEntity(entity[0], entity[8], entity[1], entity[2], entity[4]);
|
||||||
|
addBillboard(entity[0], entity[8], entity[1], entity[2], entity[4]);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
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}'`);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
const entity = i.split(",");
|
||||||
|
addEntity(entity[0], entity[8], entity[1], entity[2], entity[4]);
|
||||||
|
addBillboard(entity[0], entity[8], entity[1], entity[2], entity[4]);
|
||||||
|
}
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -13,12 +13,7 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="video">
|
<div class="video">
|
||||||
<ali-player
|
<ali-player
|
||||||
v-if="tabsIndex === 0 && ptVideoSrc"
|
v-if="tabsIndex === 0 && cpVideoSrc"
|
||||||
:source="VITE_FILE_URL + ptVideoSrc"
|
|
||||||
height="182px"
|
|
||||||
/>
|
|
||||||
<ali-player
|
|
||||||
v-if="tabsIndex === 1 && cpVideoSrc"
|
|
||||||
:source="VITE_FILE_URL + cpVideoSrc"
|
:source="VITE_FILE_URL + cpVideoSrc"
|
||||||
height="182px"
|
height="182px"
|
||||||
/>
|
/>
|
||||||
|
@ -32,7 +27,7 @@ import { getVideo } from "@/request/large_screen_data_display.js";
|
||||||
import AliPlayer from "@/components/ali-player/index.vue";
|
import AliPlayer from "@/components/ali-player/index.vue";
|
||||||
|
|
||||||
const VITE_FILE_URL = import.meta.env.VITE_FILE_URL;
|
const VITE_FILE_URL = import.meta.env.VITE_FILE_URL;
|
||||||
const tabsList = ["平台视频", "企业视频"];
|
const tabsList = ["企业视频"];
|
||||||
const tabsIndex = ref(0);
|
const tabsIndex = ref(0);
|
||||||
const ptVideoSrc = ref("");
|
const ptVideoSrc = ref("");
|
||||||
const cpVideoSrc = ref("");
|
const cpVideoSrc = ref("");
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
<template>
|
<template>
|
||||||
<el-dialog v-model="visible" title="选点" :on-close="fnClose">
|
<el-dialog v-model="visible" title="选点" :on-close="fnClose">
|
||||||
|
<map-tools v-if="visible" ref="mapToolsRef" v-model:positions="positions" />
|
||||||
<template #footer>
|
<template #footer>
|
||||||
<el-button @click="fnClose">关闭</el-button>
|
<el-button @click="fnClose">关闭</el-button>
|
||||||
<el-button type="primary" @click="fnSubmit">保存</el-button>
|
<el-button type="primary" @click="fnSubmit">保存</el-button>
|
||||||
|
@ -8,9 +9,12 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
|
import { ref } from "vue";
|
||||||
import { useVModels } from "@vueuse/core";
|
import { useVModels } from "@vueuse/core";
|
||||||
import { debounce } from "throttle-debounce";
|
import { debounce } from "throttle-debounce";
|
||||||
import { ElMessage } from "element-plus";
|
import { ElMessage } from "element-plus";
|
||||||
|
import MapTools from "@/components/map_tools";
|
||||||
|
import { setPosition } from "@/request/map_settings.js";
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
visible: {
|
visible: {
|
||||||
|
@ -18,15 +22,26 @@ const props = defineProps({
|
||||||
required: true,
|
required: true,
|
||||||
default: false,
|
default: false,
|
||||||
},
|
},
|
||||||
|
id: {
|
||||||
|
type: Number,
|
||||||
|
required: true,
|
||||||
|
default: 0,
|
||||||
|
},
|
||||||
});
|
});
|
||||||
const emits = defineEmits(["update:visible", "get-data"]);
|
const emits = defineEmits(["update:visible", "get-data"]);
|
||||||
const { visible } = useVModels(props, emits);
|
const { visible } = useVModels(props, emits);
|
||||||
|
const positions = ref([]);
|
||||||
const fnClose = () => {
|
const fnClose = () => {
|
||||||
visible.value = false;
|
visible.value = false;
|
||||||
};
|
};
|
||||||
const fnSubmit = debounce(
|
const fnSubmit = debounce(
|
||||||
1000,
|
1000,
|
||||||
async () => {
|
async () => {
|
||||||
|
if (positions.value.length < 3) {
|
||||||
|
ElMessage.warning("请选择至少3个点");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
await setPosition({ id: props.id, list: JSON.stringify(positions.value) });
|
||||||
ElMessage.success("保存成功");
|
ElMessage.success("保存成功");
|
||||||
fnClose();
|
fnClose();
|
||||||
emits("get-data");
|
emits("get-data");
|
||||||
|
|
|
@ -104,6 +104,7 @@
|
||||||
@get-data="fnResetPagination"
|
@get-data="fnResetPagination"
|
||||||
/>
|
/>
|
||||||
<selecting-points
|
<selecting-points
|
||||||
|
:id="data.selectingPointsDialog.id"
|
||||||
v-model:visible="data.selectingPointsDialog.visible"
|
v-model:visible="data.selectingPointsDialog.visible"
|
||||||
@get-data="fnResetPagination"
|
@get-data="fnResetPagination"
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -59,24 +59,24 @@
|
||||||
<el-button type="primary" text link @click="fnQrCode(row)">
|
<el-button type="primary" text link @click="fnQrCode(row)">
|
||||||
二维码
|
二维码
|
||||||
</el-button>
|
</el-button>
|
||||||
<el-button
|
<!-- <el-button-->
|
||||||
v-if="buttonJurisdiction.edit"
|
<!-- v-if="buttonJurisdiction.edit"-->
|
||||||
type="primary"
|
<!-- type="primary"-->
|
||||||
text
|
<!-- text-->
|
||||||
link
|
<!-- link-->
|
||||||
@click="
|
<!-- @click="-->
|
||||||
router.push({
|
<!-- router.push({-->
|
||||||
path: '/risk_control/identifying_parts/resources_risk',
|
<!-- path: '/risk_control/identifying_parts/resources_risk',-->
|
||||||
query: {
|
<!-- query: {-->
|
||||||
IDENTIFICATIONPARTS_ID: row.IDENTIFICATIONPARTS_ID,
|
<!-- IDENTIFICATIONPARTS_ID: row.IDENTIFICATIONPARTS_ID,-->
|
||||||
PARTSNAME: row.PARTSNAME,
|
<!-- PARTSNAME: row.PARTSNAME,-->
|
||||||
RISKUNITNAME: row.RISKUNITNAME,
|
<!-- RISKUNITNAME: row.RISKUNITNAME,-->
|
||||||
},
|
<!-- },-->
|
||||||
})
|
<!-- })-->
|
||||||
"
|
<!-- "-->
|
||||||
>
|
<!-- >-->
|
||||||
匹配资源存在风险
|
<!-- 匹配资源存在风险-->
|
||||||
</el-button>
|
<!-- </el-button>-->
|
||||||
<el-button
|
<el-button
|
||||||
v-if="buttonJurisdiction.edit"
|
v-if="buttonJurisdiction.edit"
|
||||||
type="primary"
|
type="primary"
|
||||||
|
@ -148,12 +148,11 @@ import { ElMessage, ElMessageBox } from "element-plus";
|
||||||
import { nextTick, reactive } from "vue";
|
import { nextTick, reactive } from "vue";
|
||||||
import LayoutImportFile from "@/components/import_file/index.vue";
|
import LayoutImportFile from "@/components/import_file/index.vue";
|
||||||
import Add from "./components/add.vue";
|
import Add from "./components/add.vue";
|
||||||
import { useRouter } from "vue-router";
|
// import { useRouter } from "vue-router";
|
||||||
import QrCode from "./components/qr_code.vue";
|
import QrCode from "./components/qr_code.vue";
|
||||||
import LayoutTooltipImg from "@/components/tooltip_img/index.vue";
|
import LayoutTooltipImg from "@/components/tooltip_img/index.vue";
|
||||||
import useButtonJurisdiction from "@/assets/js/useButtonJurisdiction.js";
|
import useButtonJurisdiction from "@/assets/js/useButtonJurisdiction.js";
|
||||||
|
// const router = useRouter();
|
||||||
const router = useRouter();
|
|
||||||
const { list, pagination, searchForm, fnGetData, fnResetPagination, tableRef } =
|
const { list, pagination, searchForm, fnGetData, fnResetPagination, tableRef } =
|
||||||
useListData(getIdentifyingPartsList);
|
useListData(getIdentifyingPartsList);
|
||||||
const data = reactive({
|
const data = reactive({
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="6">
|
<el-col :span="6">
|
||||||
<el-form-item label="风险分级">
|
<el-form-item label="风险分级" prop="LEVELID">
|
||||||
<el-select v-model="searchForm.LEVELID">
|
<el-select v-model="searchForm.LEVELID">
|
||||||
<el-option
|
<el-option
|
||||||
v-for="item in riskClassificationList"
|
v-for="item in riskClassificationList"
|
||||||
|
@ -43,7 +43,7 @@
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="6">
|
<el-col :span="6">
|
||||||
<el-form-item label="事故类型">
|
<el-form-item label="事故类型" prop="BIANMA">
|
||||||
<el-select v-model="searchForm.BIANMA">
|
<el-select v-model="searchForm.BIANMA">
|
||||||
<el-option
|
<el-option
|
||||||
v-for="item in accidentTypeList"
|
v-for="item in accidentTypeList"
|
||||||
|
|
Loading…
Reference in New Issue