Commit 9a0e0dac authored by xinzhedeai's avatar xinzhedeai

add:人员guiji

parent 3a3d83c5
......@@ -75,19 +75,19 @@ export const constantRoutes = [
}
]
},
{
path: '/zz',
component: Layout,
redirect: 'noredirect',
children: [
{
path: 'index',
component: () => import('@/views/index-zz'),
name: 'Index',
meta: { title: '首页2-zz', icon: 'dashboard', affix: true }
}
]
},
// {
// path: '/zz',
// component: Layout,
// redirect: 'noredirect',
// children: [
// {
// path: 'index',
// component: () => import('@/views/index-zz'),
// name: 'Index',
// meta: { title: '首页2-zz', icon: 'dashboard', affix: true }
// }
// ]
// },
{
path: '/guiji',
component: Layout,
......
......@@ -5,8 +5,6 @@
<!-- 人员实时追踪控制面板 -->
<div class="tracking-panel">
<div class="panel-header">
<h3>人员实时追踪</h3>
<select v-model="selectedPerson" @change="onPersonSelect">
<option value="">选择人员</option>
<option
......@@ -18,34 +16,6 @@
</option>
</select>
</div>
<!-- 时间轴组件 -->
<div class="timeline-container">
<div class="time-info">
<span>当前时间: {{ currentTimeDisplay }}</span>
</div>
<input
type="range"
v-model.number="currentTimeIndex"
:min="0"
:max="timePoints.length - 1"
@input="onTimelineChange"
class="timeline-slider"
/>
<div class="time-labels">
<span>{{ formatTime(timePoints[0]) }}</span>
<span>{{ formatTime(timePoints[timePoints.length - 1]) }}</span>
</div>
</div>
<!-- 控制面板按钮 -->
<div class="control-buttons">
<button @click="startTracking" :disabled="isTracking">开始追踪</button>
<button @click="stopTracking" :disabled="!isTracking">停止追踪</button>
<button @click="showFullPath">显示完整轨迹</button>
<button @click="clearTrails">清除轨迹</button>
</div>
</div>
</div>
</template>
......@@ -74,9 +44,9 @@ export default {
currentTimeDisplay: "", // 当前显示时间
// 添加轨迹相关配置
trajectoryConfig: {
pointCount: 10, // 每个人员的轨迹点数量
pointCount: 5, // 每个人员的轨迹点数量
maxRange: 0.001, // 约100米范围(1度约等于111公里,0.001度约等于111米)
heightOffset: 5, // 轨迹点高度偏移
heightOffset: 50, // 轨迹点高度偏移
},
};
},
......@@ -84,7 +54,10 @@ export default {
// 组件挂载后初始化地图
this.initCesium();
// 初始化时间点数据
this.initTimePoints();
// this.initTimePoints();
this.personCardList(() => {
console.log("人员数据", this.personnelList);
});
},
beforeDestroy() {
// 组件销毁前清理地图资源
......@@ -109,26 +82,8 @@ export default {
}
}
},
// 初始化时间点数据(生成过去1小时的时间点,每5分钟一个)
initTimePoints() {
const now = new Date();
const points = [];
// 只生成10个时间点,用于显示10个轨迹点
for (let i = 9; i >= 0; i--) {
const time = new Date(now.getTime() - i * 5 * 60 * 1000); // 每5分钟一个点
points.push(time);
}
this.timePoints = points;
this.currentTimeIndex = points.length - 1; // 默认显示最新时间
this.currentTimeDisplay = this.formatTime(points[points.length - 1]);
// 初始化人员轨迹数据
this.initPersonTrajectories();
},
// 初始化人员轨迹数据
// 为人员设置轨迹数据
initPersonTrajectories() {
// 将笛卡尔坐标转换为经纬度坐标作为基准点
const cartographic = Cesium.Cartographic.fromCartesian({
......@@ -164,9 +119,7 @@ export default {
time: this.timePoints[i],
lng: personBaseLng + lngOffset,
lat: personBaseLat + latOffset,
height:
baseHeight +
(Math.random() - 0.5) * this.trajectoryConfig.heightOffset,
height: baseHeight,
});
}
......@@ -185,118 +138,10 @@ export default {
onPersonSelect() {
this.clearTrails();
if (this.selectedPerson) {
this.updatePersonPositionByTimeIndex(this.currentTimeIndex);
this.showFullPath();
}
},
// 时间轴变化处理
onTimelineChange() {
this.currentTimeDisplay = this.formatTime(
this.timePoints[this.currentTimeIndex]
);
this.updatePersonPositionByTimeIndex(this.currentTimeIndex);
},
// 根据时间索引更新人员位置
updatePersonPositionByTimeIndex(index) {
if (
!this.selectedPerson ||
!this.personTrajectories[this.selectedPerson]
) {
return;
}
const trajectory = this.personTrajectories[this.selectedPerson][index];
if (!trajectory) return;
// 更新人员实体位置
const personEntity = this.bgEntities[this.selectedPerson];
if (personEntity) {
const position = Cesium.Cartesian3.fromDegrees(
trajectory.lng,
trajectory.lat,
trajectory.height
);
personEntity.position.setValue(position);
// 更新描述信息,包含时间
personEntity.description = `<div><h4>${
this.selectedPerson
}</h4><p>时间: ${this.formatTime(trajectory.time)}</p></div>`;
}
// 移动相机到人员位置
if (this.isTracking) {
this.viewer.camera.flyTo({
destination: Cesium.Cartesian3.fromDegrees(
trajectory.lng,
trajectory.lat,
trajectory.height + 100
),
duration: 0.5,
});
}
},
// 开始实时追踪
startTracking() {
if (!this.selectedPerson) {
alert("请先选择要追踪的人员");
return;
}
this.isTracking = true;
this.currentTimeIndex = this.timePoints.length - 1;
// 设置定时器模拟时间流逝
this.trackingInterval = setInterval(() => {
// 模拟新时间点的到来
const now = new Date();
this.timePoints.push(now);
// 为每个人员生成新的位置数据
this.personnelList.forEach((person) => {
if (!this.personTrajectories[person.perName]) {
this.personTrajectories[person.perName] = [];
}
const lastPos =
this.personTrajectories[person.perName][
this.personTrajectories[person.perName].length - 1
];
let newLng = lastPos.lng + (Math.random() - 0.5) * 0.00002;
let newLat = lastPos.lat + (Math.random() - 0.5) * 0.00002;
this.personTrajectories[person.perName].push({
time: now,
lng: newLng,
lat: newLat,
height: lastPos.height,
});
});
// 更新到最新时间
this.currentTimeIndex = this.timePoints.length - 1;
this.currentTimeDisplay = this.formatTime(now);
this.updatePersonPositionByTimeIndex(this.currentTimeIndex);
// 如果选择了当前人员,显示最新轨迹
if (this.selectedPerson) {
this.updateTrailDisplay();
}
}, 5000); // 每5秒更新一次
},
// 停止实时追踪
stopTracking() {
this.isTracking = false;
if (this.trackingInterval) {
clearInterval(this.trackingInterval);
this.trackingInterval = null;
}
},
// 显示完整轨迹
showFullPath() {
if (
......@@ -339,32 +184,6 @@ export default {
});
this.trailEntities[this.selectedPerson] = trailEntity;
// 添加所有轨迹点标记,因为只有10个点
trajectories.forEach((point, index) => {
const pointEntity = this.viewer.entities.add({
position: Cesium.Cartesian3.fromDegrees(
point.lng,
point.lat,
point.height + 5
),
point: {
pixelSize: 6,
color:
index === trajectories.length - 1
? Cesium.Color.RED
: Cesium.Color.GREEN,
outlineColor: Cesium.Color.WHITE,
outlineWidth: 2,
// 确保点在倾斜摄影上显示
heightReference: Cesium.HeightReference.CLAMP_TO_3D_TILE,
},
description: `<div><p>时间: ${this.formatTime(point.time)}</p></div>`,
});
this.trailEntities[`${this.selectedPerson}_point_${index}`] =
pointEntity;
});
},
// 清除轨迹
......@@ -374,200 +193,7 @@ export default {
}
this.trailEntities = {};
},
// 1. 提取通用实体创建函数
createEntity(item, type) {
const isPerson = type === "person";
const idField = isPerson ? "perName" : "vehicleName";
const labelColor = isPerson ? Cesium.Color.YELLOW : Cesium.Color.CYAN;
const iconPath = isPerson
? "/poi-marker-default.png"
: "/poi-marker-vehicle.png";
let lng = Number(item.lng);
let lat = Number(item.lat);
let height = Number(item.height);
let position = Cesium.Cartesian3.fromDegrees(lng, lat, height);
console.log(item[idField], position);
// 创建实体
let entity = this.viewer.entities.add({
position: position,
label: {
text: item[idField],
font: "16px",
backgroundColor: Cesium.Color.fromCssColorString("#173349"),
showBackground: true,
fillColor: labelColor,
depthTestAgainstTerrain: false,
pixelOffset: new Cesium.Cartesian2(0, -35),
},
billboard: {
image: iconPath,
scale: 0.5,
heightReference: Cesium.HeightReference.CLAMP_TO_3D_TILE,
},
description: `<div><h4>${item[idField]}${item.status}</h4></div>`,
// 确保实体固定在正确位置
position: new Cesium.CallbackProperty(() => {
return Cesium.Cartesian3.fromDegrees(lng, lat, height);
}, false),
// 为了在3D Tiles上正确显示,不使用fixedFrame
});
entity.info = item;
entity.type = type;
this.bgEntities[item[idField]] = entity;
return entity;
},
// 2. 提取实体更新函数
updateEntity(entity, item) {
let position = Cesium.Cartesian3.fromDegrees(
item.lng,
item.lat,
item.height
);
entity.position.setValue(position);
entity.fixedFrame = Cesium.Transforms.eastNorthUpToFixedFrame(position);
},
// 3. 提取批量创建实体的函数
createEntities(entityList, type) {
const isPerson = type === "person";
const idField = isPerson ? "perName" : "vehicleName";
for (let item of entityList) {
this.createEntity(item, type);
}
},
// 4. 提取批量更新实体的函数(增量更新模式)
updateEntities(entityList, type) {
const isPerson = type === "person";
const idField = isPerson ? "perName" : "vehicleName";
for (let item of entityList) {
let entity = this.bgEntities[item[idField]];
if (entity && entity.type === type) {
// 更新现有实体
this.updateEntity(entity, item);
} else {
// 创建新实体
this.createEntity(item, type);
}
}
},
// 5. 提取定时器逻辑为可重用函数
setupEntityUpdateInterval(type, dataGenerator, interval = 10000) {
// 清除现有定时器
if (this.intervaler) {
clearInterval(this.intervaler);
this.intervaler = null;
}
// 设置新的定时器
this.intervaler = setInterval(() => {
console.log(`开始获取实时${type === "person" ? "人员" : "车辆"}数据`);
// 生成或获取最新数据
if (typeof dataGenerator === "function") {
dataGenerator();
}
const entityList =
type === "person" ? this.personnelList : this.vehicleList;
// 更新实体(这里可以选择清除重建或增量更新)
// 方案1:清除所有实体后重建
this.clearEntities();
this.createEntities(entityList, type);
// 方案2:增量更新(推荐,性能更好)
// this.updateEntities(entityList, type);
}, interval);
},
createPersonModel() {
// 清除现有定时器
if (this.personModelInterval) {
clearInterval(this.personModelInterval);
this.personModelInterval = null;
}
// 清除现有实体
this.clearEntities();
// 立即生成并显示人员实体
console.log("立即创建人员实体");
this.personCardList((list) => {
console.log("人员数据", this.personnelList);
this.createEntities(this.personnelList, "person");
});
// 设置定时刷新
this.setupEntityUpdateInterval("person", () => {
this.personCardList(() => {
console.log("人员数据", this.personnelList);
});
});
// this.personModelInterval = setInterval(() => {
// console.log("开始获取实时数据");
// if (this.bgEntities) {
// for (let key in this.bgEntities) {
// if (isNaN(parseFloat(key))) {
// // 非数字键名的是人员实体
// this.viewer.entities.remove(this.bgEntities[key]);
// delete this.bgEntities[key];
// }
// }
// }
// // 从API获取最新的人员定位数据
// this.personCardList((list) => {
// console.log("人员数据", this.personnelList);
// // 创建新实体
// for (let item of this.personnelList) {
// let lng = Number(item.lng);
// let lat = Number(item.lat);
// let height = Number(item.height);
// let position = Cesium.Cartesian3.fromDegrees(lng, lat, height);
// console.log(item.perName, position);
// // 创建人员标记
// let entity = this.viewer.entities.add({
// position: position,
// label: {
// text: item.perName,
// font: "16px",
// backgroundColor: Cesium.Color.fromCssColorString("#173349"),
// showBackground: true,
// fillColor: Cesium.Color.YELLOW,
// depthTestAgainstTerrain: false, // 禁用地形深度测试
// pixelOffset: new Cesium.Cartesian2(0, -35),
// },
// billboard: {
// image: "/poi-marker-default.png",
// scale: 0.5,
// },
// description: `<div><h4>${item.perName}${item.status}</h4></div>`,
// fixedFrame: Cesium.Transforms.eastNorthUpToFixedFrame(position),
// });
// entity.info = item; // 添加 info 属性
// this.bgEntities[item.perName] = entity; // 存储新实体
// }
// // 如果已经选择了人员,更新其位置和轨迹
// if (this.selectedPerson) {
// this.updatePersonPositionByTimeIndex(this.currentTimeIndex);
// }
// });
// }, 10000); // 每10秒刷新一次
},
// 设置人员列表
personCardList(fn) {
// 将笛卡尔坐标转换为经纬度坐标
const cartographic = Cesium.Cartographic.fromCartesian({
......@@ -609,7 +235,7 @@ export default {
// 重新初始化轨迹数据
this.initPersonTrajectories();
fn(this.personnelList);
fn && fn(this.personnelList);
},
/**
......@@ -745,8 +371,7 @@ export default {
complete: () => {
console.log("相机已成功定位到模型上方");
// 先初始化时间点数据,再创建人员模型
this.initTimePoints();
this.createPersonModel(); // 定位后创建人员模型
this.personCardList(); // 定位后创建人员模型、
},
});
} catch (error) {
......@@ -794,10 +419,12 @@ export default {
// 追踪控制面板样式
.tracking-panel {
position: absolute;
bottom: 20px;
/* bottom: 20px; */
left: 50%;
top: 0;
-webkit-transform: translateX(-50%);
transform: translateX(-50%);
width: 80%;
width: 10%;
background: rgba(0, 0, 0, 0.8);
border-radius: 8px;
padding: 15px;
......
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