feat(map): 优化人员定位初始化点位闪烁问题

master
LiuJiaNan 2026-07-27 15:29:06 +08:00
parent cff14a1652
commit 273aa353ed
3 changed files with 39 additions and 17 deletions

View File

@ -189,6 +189,8 @@ function BottomUtils(props) {
}
if (item.type === "peoplePosition" && currentPort === "00003") {
// 连接 WebSocket 前初始化本次定位会话的统一时钟,首批人员共享同一采样基准。
mapMethods.current.initPeoplePositionClock();
peoplePositionConnect();
return;
}

View File

@ -92,6 +92,7 @@ export default function useMapMethods(viewerRef, request) {
});
const peopleId = useRef([]); // 人员定位 ID 列表
const peoplePositionStartTime = useRef(null); // 当前人员定位会话共用的采样起始时间
// 设置中心点
const flyTo = ({ longitude, latitude, height } = defineCenterPoint) => {
@ -120,6 +121,7 @@ export default function useMapMethods(viewerRef, request) {
// 添加港口点
const addPortPoint = async () => {
const viewer = getViewer();
await chunkedLoad(portPoint, 10, async (item) => {
const entityCollection = createEntityCollection("portEntityCollection");
entityCollection.entities.add(
@ -131,9 +133,9 @@ export default function useMapMethods(viewerRef, request) {
monitorItems: { data: { ...item, markType: "港口" } },
}),
);
getViewer().dataSources.add(entityCollection);
viewer.dataSources.add(entityCollection);
});
await addMergedEntityCollection(getViewer(), "portEntityCollection");
await addMergedEntityCollection(viewer, "portEntityCollection");
};
// 移除港口点
@ -143,6 +145,7 @@ export default function useMapMethods(viewerRef, request) {
// 添加分公司点
const addBranchOfficePoint = async (portArea = "", pointInfo = null) => {
const viewer = getViewer();
let requestData = [];
if (!pointInfo) {
const { data } = await request.getCorpInfoListAll({ eqPortArea: portArea, inType: [0, 1, 2, 6] });
@ -169,9 +172,9 @@ export default function useMapMethods(viewerRef, request) {
},
}),
);
getViewer().dataSources.add(entityCollection);
viewer.dataSources.add(entityCollection);
});
await addMergedEntityCollection(getViewer(), "branchOfficeEntityCollection");
await addMergedEntityCollection(viewer, "branchOfficeEntityCollection");
mitt.emit(changeCoverMaskVisibleMittKey, false);
};
@ -253,6 +256,7 @@ export default function useMapMethods(viewerRef, request) {
};
if (!edgeMap[id])
return;
const viewer = getViewer();
mitt.emit(changeCoverMaskVisibleMittKey, true);
const currentEdge = edgeMap[id]();
const entityCollection = createEntityCollection("wallEntityCollection");
@ -275,7 +279,7 @@ export default function useMapMethods(viewerRef, request) {
id: createId(),
wall: {
positions,
material: new Cesium.WallPolylineTrailLinkMaterialProperty(getViewer()),
material: new Cesium.WallPolylineTrailLinkMaterialProperty(viewer),
maximumHeights: Array.from({ length: pointCount }).fill(40),
minimumHeights: Array.from({ length: pointCount }).fill(0),
},
@ -283,7 +287,7 @@ export default function useMapMethods(viewerRef, request) {
);
});
getViewer().dataSources.add(entityCollection);
viewer.dataSources.add(entityCollection);
mitt.emit(changeCoverMaskVisibleMittKey, false);
};
@ -372,6 +376,7 @@ export default function useMapMethods(viewerRef, request) {
throw new Error("请传入markType扎点类型");
if (!options.markIcon)
throw new Error("请传入markIcon扎点图标");
const viewer = getViewer();
mitt.emit(changeCoverMaskVisibleMittKey, true);
await chunkedLoad(filterNull(pointList), 10, async (item) => {
const entityCollection = createEntityCollection(
@ -389,10 +394,10 @@ export default function useMapMethods(viewerRef, request) {
},
}),
);
getViewer().dataSources.add(entityCollection);
viewer.dataSources.add(entityCollection);
});
const dataSource = await addMergedEntityCollection(
getViewer(),
viewer,
"markEntityCollection",
options.markType,
);
@ -405,6 +410,18 @@ export default function useMapMethods(viewerRef, request) {
removeEntityCollection(getViewer(), `markEntityCollectionMerged${markType ? `_${markType}` : ""}`);
};
// 人员定位使用 Viewer 的全局时钟;每次开启定位仅初始化一次,避免首批点位互相重置时钟。
const initPeoplePositionClock = () => {
const start = Cesium.JulianDate.now();
const viewer = getViewer();
peoplePositionStartTime.current = start;
viewer.clock.startTime = start.clone();
viewer.clock.currentTime = start.clone();
viewer.clock.clockRange = Cesium.ClockRange.CLAMPED;
viewer.clock.shouldAnimate = false;
return start;
};
const addPeoplePoint = async (point, options) => {
const image = peopleImg[point.icon_type];
if (!image)
@ -413,7 +430,11 @@ export default function useMapMethods(viewerRef, request) {
throw new Error("请传入markType扎点类型");
const clonePoint = { ...point };
point.property = new Cesium.SampledPositionProperty();
const start = Cesium.JulianDate.now();
// 下一条实时定位到达前保持最后有效位置,避免全局时钟前进后点位短暂消失。
point.property.forwardExtrapolationType = Cesium.ExtrapolationType.HOLD;
point.property.forwardExtrapolationDuration = 0;
// 首批人员必须共用同一采样起点,后续实体创建不会影响已存在人员的播放时间。
const start = peoplePositionStartTime.current || initPeoplePositionClock();
const position = Cesium.Cartesian3.fromDegrees(point.x, point.y, 0);
point.property.addSample(start, position);
point.lastTime = start;
@ -431,18 +452,15 @@ export default function useMapMethods(viewerRef, request) {
data: { ...clonePoint, markType: `标记点_${options.markType}`, isShowModal: options.isShowModal ?? true },
},
});
getViewer().clock.startTime = start.clone();
getViewer().clock.currentTime = start.clone();
getViewer().clock.clockRange = Cesium.ClockRange.CLAMPED;
getViewer().clock.shouldAnimate = false;
};
const updatePeoplePoint = async (point) => {
if (getViewer().clock.shouldAnimate === false) {
getViewer().clock.shouldAnimate = true;
const viewer = getViewer();
if (viewer.clock.shouldAnimate === false) {
viewer.clock.shouldAnimate = true;
}
if (point.icon_type !== point.lastIconType) {
const entity = getViewer().entities.getById(point.id);
const entity = viewer.entities.getById(point.id);
if (!entity)
return;
entity.billboard.image = (
@ -473,6 +491,7 @@ export default function useMapMethods(viewerRef, request) {
getViewer().entities.removeById(id);
});
peopleId.current = [];
peoplePositionStartTime.current = null;
};
return {
@ -490,6 +509,7 @@ export default function useMapMethods(viewerRef, request) {
removeWall,
addMarkPoint,
removeMarkPoint,
initPeoplePositionClock,
addPeoplePoint,
updatePeoplePoint,
removePeoplePoint,

View File

@ -13,7 +13,7 @@ export default function usePeoplePosition(mapMethods, currentBranchOffice) {
const onMessage = async (message) => {
const data = JSON.parse(message.data);
const peopleList = filterNull([data]);
const peopleList = filterNull(Array.isArray(data) ? data : [data]);
for (let i = 0; i < peopleList.length; i++) {
const item = peopleList[i];
if (!item)