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") { if (item.type === "peoplePosition" && currentPort === "00003") {
// 连接 WebSocket 前初始化本次定位会话的统一时钟,首批人员共享同一采样基准。
mapMethods.current.initPeoplePositionClock();
peoplePositionConnect(); peoplePositionConnect();
return; return;
} }

View File

@ -92,6 +92,7 @@ export default function useMapMethods(viewerRef, request) {
}); });
const peopleId = useRef([]); // 人员定位 ID 列表 const peopleId = useRef([]); // 人员定位 ID 列表
const peoplePositionStartTime = useRef(null); // 当前人员定位会话共用的采样起始时间
// 设置中心点 // 设置中心点
const flyTo = ({ longitude, latitude, height } = defineCenterPoint) => { const flyTo = ({ longitude, latitude, height } = defineCenterPoint) => {
@ -120,6 +121,7 @@ export default function useMapMethods(viewerRef, request) {
// 添加港口点 // 添加港口点
const addPortPoint = async () => { const addPortPoint = async () => {
const viewer = getViewer();
await chunkedLoad(portPoint, 10, async (item) => { await chunkedLoad(portPoint, 10, async (item) => {
const entityCollection = createEntityCollection("portEntityCollection"); const entityCollection = createEntityCollection("portEntityCollection");
entityCollection.entities.add( entityCollection.entities.add(
@ -131,9 +133,9 @@ export default function useMapMethods(viewerRef, request) {
monitorItems: { data: { ...item, markType: "港口" } }, 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 addBranchOfficePoint = async (portArea = "", pointInfo = null) => {
const viewer = getViewer();
let requestData = []; let requestData = [];
if (!pointInfo) { if (!pointInfo) {
const { data } = await request.getCorpInfoListAll({ eqPortArea: portArea, inType: [0, 1, 2, 6] }); 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); mitt.emit(changeCoverMaskVisibleMittKey, false);
}; };
@ -253,6 +256,7 @@ export default function useMapMethods(viewerRef, request) {
}; };
if (!edgeMap[id]) if (!edgeMap[id])
return; return;
const viewer = getViewer();
mitt.emit(changeCoverMaskVisibleMittKey, true); mitt.emit(changeCoverMaskVisibleMittKey, true);
const currentEdge = edgeMap[id](); const currentEdge = edgeMap[id]();
const entityCollection = createEntityCollection("wallEntityCollection"); const entityCollection = createEntityCollection("wallEntityCollection");
@ -275,7 +279,7 @@ export default function useMapMethods(viewerRef, request) {
id: createId(), id: createId(),
wall: { wall: {
positions, positions,
material: new Cesium.WallPolylineTrailLinkMaterialProperty(getViewer()), material: new Cesium.WallPolylineTrailLinkMaterialProperty(viewer),
maximumHeights: Array.from({ length: pointCount }).fill(40), maximumHeights: Array.from({ length: pointCount }).fill(40),
minimumHeights: Array.from({ length: pointCount }).fill(0), 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); mitt.emit(changeCoverMaskVisibleMittKey, false);
}; };
@ -372,6 +376,7 @@ export default function useMapMethods(viewerRef, request) {
throw new Error("请传入markType扎点类型"); throw new Error("请传入markType扎点类型");
if (!options.markIcon) if (!options.markIcon)
throw new Error("请传入markIcon扎点图标"); throw new Error("请传入markIcon扎点图标");
const viewer = getViewer();
mitt.emit(changeCoverMaskVisibleMittKey, true); mitt.emit(changeCoverMaskVisibleMittKey, true);
await chunkedLoad(filterNull(pointList), 10, async (item) => { await chunkedLoad(filterNull(pointList), 10, async (item) => {
const entityCollection = createEntityCollection( 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( const dataSource = await addMergedEntityCollection(
getViewer(), viewer,
"markEntityCollection", "markEntityCollection",
options.markType, options.markType,
); );
@ -405,6 +410,18 @@ export default function useMapMethods(viewerRef, request) {
removeEntityCollection(getViewer(), `markEntityCollectionMerged${markType ? `_${markType}` : ""}`); 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 addPeoplePoint = async (point, options) => {
const image = peopleImg[point.icon_type]; const image = peopleImg[point.icon_type];
if (!image) if (!image)
@ -413,7 +430,11 @@ export default function useMapMethods(viewerRef, request) {
throw new Error("请传入markType扎点类型"); throw new Error("请传入markType扎点类型");
const clonePoint = { ...point }; const clonePoint = { ...point };
point.property = new Cesium.SampledPositionProperty(); 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); const position = Cesium.Cartesian3.fromDegrees(point.x, point.y, 0);
point.property.addSample(start, position); point.property.addSample(start, position);
point.lastTime = start; point.lastTime = start;
@ -431,18 +452,15 @@ export default function useMapMethods(viewerRef, request) {
data: { ...clonePoint, markType: `标记点_${options.markType}`, isShowModal: options.isShowModal ?? true }, 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) => { const updatePeoplePoint = async (point) => {
if (getViewer().clock.shouldAnimate === false) { const viewer = getViewer();
getViewer().clock.shouldAnimate = true; if (viewer.clock.shouldAnimate === false) {
viewer.clock.shouldAnimate = true;
} }
if (point.icon_type !== point.lastIconType) { if (point.icon_type !== point.lastIconType) {
const entity = getViewer().entities.getById(point.id); const entity = viewer.entities.getById(point.id);
if (!entity) if (!entity)
return; return;
entity.billboard.image = ( entity.billboard.image = (
@ -473,6 +491,7 @@ export default function useMapMethods(viewerRef, request) {
getViewer().entities.removeById(id); getViewer().entities.removeById(id);
}); });
peopleId.current = []; peopleId.current = [];
peoplePositionStartTime.current = null;
}; };
return { return {
@ -490,6 +509,7 @@ export default function useMapMethods(viewerRef, request) {
removeWall, removeWall,
addMarkPoint, addMarkPoint,
removeMarkPoint, removeMarkPoint,
initPeoplePositionClock,
addPeoplePoint, addPeoplePoint,
updatePeoplePoint, updatePeoplePoint,
removePeoplePoint, removePeoplePoint,

View File

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