refactor(map): 将class重构成hook写法

master
LiuJiaNan 2026-07-15 09:26:35 +08:00
parent d16b6b2ee5
commit 42961e417c
4 changed files with 332 additions and 266 deletions

View File

@ -9,7 +9,7 @@ import Content from "./components/Content";
import Header from "./components/Header"; import Header from "./components/Header";
import RightUtils from "./components/RightUtils"; import RightUtils from "./components/RightUtils";
import { Context } from "./js/context"; import { Context } from "./js/context";
import InitMap from "./js/initMap"; import useInitMap from "./js/initMap";
import mitt from "./js/mitt"; import mitt from "./js/mitt";
import { import {
changeCoverMaskVisibleMittKey, changeCoverMaskVisibleMittKey,
@ -20,9 +20,8 @@ import "./index.less";
function Map(props) { function Map(props) {
const query = useGetUrlQuery(); const query = useGetUrlQuery();
const { viewer, mapMethods, initMap, externalEntryPort } = useInitMap();
const viewer = useRef(null); // cesium地图实例
const mapMethods = useRef(null); // cesium地图方法实例
const fullscreenRef = useRef(null); // 全屏容器的ref const fullscreenRef = useRef(null); // 全屏容器的ref
const [isFullscreen, { toggleFullscreen }] = useFullscreen(fullscreenRef); const [isFullscreen, { toggleFullscreen }] = useFullscreen(fullscreenRef);
@ -39,19 +38,17 @@ function Map(props) {
sessionStorage.removeItem("mapCurrentBranchOfficeId"); sessionStorage.removeItem("mapCurrentBranchOfficeId");
const initMap = new InitMap(); initMap();
const { viewer: viewerInstance, mapMethods: mapMethodsInstance }
= initMap.initMap();
viewer.current = viewerInstance;
mapMethods.current = mapMethodsInstance;
if (query.mapType === "港口") { if (query.mapType === "港口") {
initMap.externalEntryPort(query); const entered = externalEntryPort(query);
if (!entered)
message.warning("港口入口参数不完整,无法定位到对应港口");
} }
else { else {
setTimeout(() => { setTimeout(() => {
mapMethodsInstance.flyTo(); mapMethods.current.flyTo();
mapMethodsInstance.addPortPoint(); mapMethods.current.addPortPoint();
}, 500); }, 500);
} }

View File

@ -1,19 +1,74 @@
import { useRef } from "react";
import { createObliquePhotography } from "~/pages/Container/Map/js/mapUtils"; import { createObliquePhotography } from "~/pages/Container/Map/js/mapUtils";
import MapMethods from "./mapMethods"; import useMapMethods from "./mapMethods";
import PointClickEvent from "./pointClickEvent"; import usePointClickEvent from "./pointClickEvent";
const Cesium = window.Cesium; const Cesium = window.Cesium;
export default class InitMap { export default function useInitMap() {
#pointClickEvent; // 页面和地图工具共用同一个 Cesium 引用,避免内外各维护一份实例。
#viewer; const viewer = useRef(null);
#mapMethods; const mapMethodsValue = useMapMethods(viewer);
// Context 下游仍按 ref.current 调用地图方法,因此保留原有数据结构。
const mapMethods = useRef(mapMethodsValue);
mapMethods.current = mapMethodsValue;
// 点位点击处理集合:替代原 PointClickEvent class 实例,负责弹窗和层级进入。
const pointClickEvent = usePointClickEvent(viewer, mapMethodsValue);
// 获取当前 Cesium 实例,减少内部方法对 ref 结构的重复感知。
const getViewer = () => viewer.current;
// 倾斜摄影
const initObliquePhotography = () => {
getViewer().scene.globe.depthTestAgainstTerrain = true;
Cesium.ExperimentalFeatures.enableModelExperimental = true;
createObliquePhotography(
"http://192.168.192.215:8021/ware/upload/%E6%9B%B9%E5%A6%83%E7%94%B8%E6%B8%AF%E4%B8%9C/%E6%9B%B9%E5%A6%83%E7%94%B8%E6%B8%AF%E4%B8%9C/merge_tile.json",
getViewer(),
);
createObliquePhotography(
"http://192.168.192.215:8021/ware/upload/%E6%9B%B9%E5%A6%83%E7%94%B8%E6%B8%AF%E8%A5%BF/%E6%9B%B9%E5%A6%83%E7%94%B8%E6%B8%AF%E8%A5%BF/merge_tile.json",
getViewer(),
);
createObliquePhotography(
"http://192.168.192.215:8021/ware/upload/qhdxys/merge_tile.json",
getViewer(),
);
createObliquePhotography(
"http://192.168.192.215:8021/ware/upload/qhdgysh/merge_tile.json",
getViewer(),
);
createObliquePhotography(
"http://192.168.192.215:8021/ware/upload/%E6%B2%A7%E5%B7%9E%E6%B8%AF%E8%A5%BF/%E6%B2%A7%E5%B7%9E%E6%B8%AF%E8%A5%BF/merge_tile.json",
getViewer(),
);
createObliquePhotography(
"http://192.168.192.215:8021/ware/upload/%E6%B2%A7%E5%B7%9E%E6%B8%AF%E4%B8%9C/%E6%B2%A7%E5%B7%9E%E6%B8%AF%E4%B8%9C/merge_tile.json",
getViewer(),
);
};
// 注册点击事件
const registerClickEvent = () => {
getViewer().cesiumWidget.screenSpaceEventHandler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK);
getViewer().cesiumWidget.screenSpaceEventHandler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK);
const screenSpaceEventHandler = new Cesium.ScreenSpaceEventHandler(getViewer().scene.canvas);
screenSpaceEventHandler.setInputAction((movement) => {
const pick = getViewer().scene.pick(movement.position);
if (Cesium.defined(pick) && pick.id?.id) {
pointClickEvent.pointClickEvent(pick.id);
}
else {
pointClickEvent.closePopup();
}
}, Cesium.ScreenSpaceEventType.LEFT_CLICK);
};
// 初始化地图 // 初始化地图
initMap = () => { const initMap = () => {
const tianDiTuKey = "06494bcf2d4b66df7f3c586cc65af0cb"; const tianDiTuKey = "06494bcf2d4b66df7f3c586cc65af0cb";
const subdomains = ["0", "1", "2", "3", "4", "5", "6", "7"]; const subdomains = ["0", "1", "2", "3", "4", "5", "6", "7"];
this.#viewer = new Cesium.Viewer("cesiumContainer", { viewer.current = new Cesium.Viewer("cesiumContainer", {
// terrainProvider: Cesium.createWorldTerrain() // terrainProvider: Cesium.createWorldTerrain()
animation: false, // 动画 animation: false, // 动画
homeButton: true, // home键 homeButton: true, // home键
@ -39,8 +94,8 @@ export default class InitMap {
show: true, show: true,
}), }),
}); });
this.#viewer._cesiumWidget._creditContainer.style.display = "none"; // 隐藏cesium ion getViewer()._cesiumWidget._creditContainer.style.display = "none"; // 隐藏cesium ion
this.#viewer.imageryLayers.addImageryProvider( getViewer().imageryLayers.addImageryProvider(
new Cesium.WebMapTileServiceImageryProvider({ new Cesium.WebMapTileServiceImageryProvider({
// 影像注记 // 影像注记
url: url:
@ -54,56 +109,48 @@ export default class InitMap {
show: true, show: true,
}), }),
); );
this.#initObliquePhotography(); initObliquePhotography();
this.#registerClickEvent(); registerClickEvent();
this.#mapMethods = new MapMethods(this.#viewer); return { mapMethods: mapMethods.current, viewer: getViewer() };
this.#pointClickEvent = new PointClickEvent(this.#viewer, this.#mapMethods);
return { mapMethods: this.#mapMethods, viewer: this.#viewer };
}; };
// 倾斜摄影 // 外部入口进入港口:只有港口标识、名称和有效坐标齐全时才进入,避免 Cesium 接收到无效坐标。
#initObliquePhotography = () => { const externalEntryPort = (data) => {
this.#viewer.scene.globe.depthTestAgainstTerrain = true; const id = data.id || data.portId;
Cesium.ExperimentalFeatures.enableModelExperimental = true; const name = data.name || data.portName;
createObliquePhotography( const longitude = data.position?.x ?? data.longitude ?? data.lng ?? data.x;
"http://192.168.192.215:8021/ware/upload/%E6%9B%B9%E5%A6%83%E7%94%B8%E6%B8%AF%E4%B8%9C/%E6%9B%B9%E5%A6%83%E7%94%B8%E6%B8%AF%E4%B8%9C/merge_tile.json", const latitude = data.position?.y ?? data.latitude ?? data.lat ?? data.y;
this.#viewer, // 空字符串会被 Number 转成 0需要先排除空值再判断是否为有效数字。
); const hasCoordinate = value => value !== "" && value !== null && value !== undefined;
createObliquePhotography( const hasValidPosition
"http://192.168.192.215:8021/ware/upload/%E6%9B%B9%E5%A6%83%E7%94%B8%E6%B8%AF%E8%A5%BF/%E6%9B%B9%E5%A6%83%E7%94%B8%E6%B8%AF%E8%A5%BF/merge_tile.json", = hasCoordinate(longitude)
this.#viewer, && hasCoordinate(latitude)
); && Number.isFinite(Number(longitude))
createObliquePhotography( && Number.isFinite(Number(latitude));
"http://192.168.192.215:8021/ware/upload/qhdxys/merge_tile.json",
this.#viewer, if (!id || !name || !hasValidPosition)
); return false;
createObliquePhotography(
"http://192.168.192.215:8021/ware/upload/qhdgysh/merge_tile.json", pointClickEvent.pointClickEvent({
this.#viewer, monitorItems: {
); data: {
createObliquePhotography( ...data,
"http://192.168.192.215:8021/ware/upload/%E6%B2%A7%E5%B7%9E%E6%B8%AF%E8%A5%BF/%E6%B2%A7%E5%B7%9E%E6%B8%AF%E8%A5%BF/merge_tile.json", id,
this.#viewer, name,
); corpinfoId: data.corpinfoId,
createObliquePhotography( mapType: "港口",
"http://192.168.192.215:8021/ware/upload/%E6%B2%A7%E5%B7%9E%E6%B8%AF%E4%B8%9C/%E6%B2%A7%E5%B7%9E%E6%B8%AF%E4%B8%9C/merge_tile.json", isExternalEntry: "1",
this.#viewer, position: { x: Number(longitude), y: Number(latitude) },
); },
},
});
return true;
}; };
// 注册点击事件 return {
#registerClickEvent = () => { viewer,
this.#viewer.cesiumWidget.screenSpaceEventHandler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK); mapMethods,
this.#viewer.cesiumWidget.screenSpaceEventHandler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK); initMap,
const screenSpaceEventHandler = new Cesium.ScreenSpaceEventHandler(this.#viewer.scene.canvas); externalEntryPort,
screenSpaceEventHandler.setInputAction((movement) => {
const pick = this.#viewer.scene.pick(movement.position);
if (Cesium.defined(pick) && pick.id?.id) {
this.#pointClickEvent.pointClickEvent(pick.id);
}
else {
this.#pointClickEvent.closePopup();
}
}, Cesium.ScreenSpaceEventType.LEFT_CLICK);
}; };
} }

View File

@ -1,3 +1,4 @@
import { useRef } from "react";
import portEntityBillboardImage from "~/assets/images/map_bi/point/dianwei.png"; import portEntityBillboardImage from "~/assets/images/map_bi/point/dianwei.png";
import branchOfficeEntityBillboardImage from "~/assets/images/map_bi/point/gongsidianwei.png"; import branchOfficeEntityBillboardImage from "~/assets/images/map_bi/point/gongsidianwei.png";
import edgeCMT from "./edge/cmt.js"; import edgeCMT from "./edge/cmt.js";
@ -18,6 +19,40 @@ import { chunkedLoad, filterNull, formatPolygon } from "./utils";
import "./TrajectoryPolylineTrailLinkMaterialProperty.js"; import "./TrajectoryPolylineTrailLinkMaterialProperty.js";
import "./WallPolylineTrailLinkMaterialProperty"; import "./WallPolylineTrailLinkMaterialProperty";
const portPoint = [
{
id: "00002",
name: "沧州黄骅港矿石港务有限公司",
introduce:
"公司现共有10个泊位10-20万吨级设计年通过能力6400万吨。堆场面积176万平米堆存能力740万吨大型装卸设备44台套。",
position: { x: 117.91412, y: 38.35902 },
corpinfoId: "f8da1790b1034058ae2efefd69af3284",
},
{
id: "00003",
name: "秦皇岛港",
introduce:
"秦皇岛港分为东、西两个港区现有生产性泊位50个年设计通过能力2.26亿吨,经营货类主要包括煤炭、金属矿石、油品及液体化工、集装箱及其他杂货等。",
position: { x: 119.61254, y: 39.92572 },
},
{
id: "00004",
name: "曹妃甸实业港务",
introduce:
"公司现共有6个泊位(5-30万吨级)设计年通过能力6550万吨。堆场面积146万平米堆存能力1350万吨大型装卸设备23台套。",
position: { x: 118.51022, y: 38.93503 },
corpinfoId: "8854edee3aa94be496cee676b6d4845a",
},
{
id: "00005",
name: "曹妃甸煤炭港务",
introduce:
"公司现共有5个泊位5-10万吨级设计年通过能力5000万吨。堆场面积83万平米堆存能力373.5万吨大型装卸设备19台套。",
position: { x: 118.43701, y: 38.9866 },
corpinfoId: "6aa255d41602497fa0f934a822820df4",
},
];
const BranchOfficePoint = [ const BranchOfficePoint = [
{ {
corpName: "秦港股份有限公司", corpName: "秦港股份有限公司",
@ -357,91 +392,59 @@ const BranchOfficePoint = [
}, },
]; ];
const Cesium = window.Cesium; const Cesium = window.Cesium;
export default class MapMethods {
#viewer;
#defineCenterPoint = { export default function useMapMethods(viewerRef) {
// 获取当前 Cesium 实例:初始化前为空,地图方法会在 initMap 完成后被调用。
const getViewer = () => viewerRef.current;
// 默认中心点:初始化和回到首页视角时使用,保持全局港区俯视高度。
const defineCenterPoint = {
longitude: 119.6486945226887, longitude: 119.6486945226887,
latitude: 39.93555616569192, latitude: 39.93555616569192,
height: 900000, height: 900000,
}; // 默认中心点 };
#currentCenterPoint = { // 当前中心点:记录最近一次 flyTo 的视角,供外部按钮回到当前位置。
const currentCenterPointRef = useRef({
longitude: 119.6486945226887, longitude: 119.6486945226887,
latitude: 39.93555616569192, latitude: 39.93555616569192,
height: 900000, height: 900000,
}; // 当前中心点 });
#previousCenterPoint = { // 上一次中心点:从分公司返回港口层级时,需要回退到进入前的视角。
const previousCenterPointRef = useRef({
longitude: 119.6486945226887, longitude: 119.6486945226887,
latitude: 39.93555616569192, latitude: 39.93555616569192,
height: 900000, height: 900000,
}; // 上一次中心点 });
constructor(viewer) {
this.#viewer = viewer;
}
// 设置中心点 // 设置中心点
flyTo = ({ longitude, latitude, height } = this.#defineCenterPoint) => { const flyTo = ({ longitude, latitude, height } = defineCenterPoint) => {
this.#viewer.camera.flyTo({ destination: getPosition(longitude, latitude, height), duration: 2 }); getViewer().camera.flyTo({ destination: getPosition(longitude, latitude, height), duration: 2 });
this.#previousCenterPoint = { ...this.#currentCenterPoint }; previousCenterPointRef.current = { ...currentCenterPointRef.current };
this.#currentCenterPoint = { longitude, latitude, height }; currentCenterPointRef.current = { longitude, latitude, height };
}; };
// 返回当前中心点 // 返回当前中心点
returnCurrentCenterPoint = () => { const returnCurrentCenterPoint = () => {
const { longitude, latitude, height } = this.#currentCenterPoint; const { longitude, latitude, height } = currentCenterPointRef.current;
this.#viewer.camera.flyTo({ destination: getPosition(longitude, latitude, height), duration: 2 }); getViewer().camera.flyTo({ destination: getPosition(longitude, latitude, height), duration: 2 });
}; };
// 返回上一次中心点 // 返回上一次中心点
returnPreviousCenterPoint = () => { const returnPreviousCenterPoint = () => {
const { longitude, latitude, height } = this.#previousCenterPoint; const { longitude, latitude, height } = previousCenterPointRef.current;
this.#viewer.camera.flyTo({ destination: getPosition(longitude, latitude, height), duration: 2 }); getViewer().camera.flyTo({ destination: getPosition(longitude, latitude, height), duration: 2 });
this.#currentCenterPoint = { longitude, latitude, height }; currentCenterPointRef.current = { longitude, latitude, height };
}; };
// 切换场景模式 // 切换场景模式
changeSceneMode = (type = "3d") => { const changeSceneMode = (type = "3d") => {
this.#viewer.scene.mode = { "2d": Cesium.SceneMode.COLUMBUS_VIEW, "3d": Cesium.SceneMode.SCENE3D }[type]; getViewer().scene.mode = { "2d": Cesium.SceneMode.COLUMBUS_VIEW, "3d": Cesium.SceneMode.SCENE3D }[type];
}; };
// 添加港口点 // 添加港口点
addPortPoint = async () => { const addPortPoint = async () => {
const portPoint = [
{
id: "00002",
name: "沧州黄骅港矿石港务有限公司",
introduce:
"公司现共有10个泊位10-20万吨级设计年通过能力6400万吨。堆场面积176万平米堆存能力740万吨大型装卸设备44台套。",
position: { x: 117.91412, y: 38.35902 },
corpinfoId: "f8da1790b1034058ae2efefd69af3284",
},
{
id: "00003",
name: "秦皇岛港",
introduce:
"秦皇岛港分为东、西两个港区现有生产性泊位50个年设计通过能力2.26亿吨,经营货类主要包括煤炭、金属矿石、油品及液体化工、集装箱及其他杂货等。",
position: { x: 119.61254, y: 39.92572 },
},
{
id: "00004",
name: "曹妃甸实业港务",
introduce:
"公司现共有6个泊位(5-30万吨级)设计年通过能力6550万吨。堆场面积146万平米堆存能力1350万吨大型装卸设备23台套。",
position: { x: 118.51022, y: 38.93503 },
corpinfoId: "8854edee3aa94be496cee676b6d4845a",
},
{
id: "00005",
name: "曹妃甸煤炭港务",
introduce:
"公司现共有5个泊位5-10万吨级设计年通过能力5000万吨。堆场面积83万平米堆存能力373.5万吨大型装卸设备19台套。",
position: { x: 118.43701, y: 38.9866 },
corpinfoId: "6aa255d41602497fa0f934a822820df4",
},
];
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(
@ -453,18 +456,18 @@ export default class MapMethods {
monitorItems: { data: { ...item, mapType: "港口" } }, monitorItems: { data: { ...item, mapType: "港口" } },
}), }),
); );
this.#viewer.dataSources.add(entityCollection); getViewer().dataSources.add(entityCollection);
}); });
await addMergedEntityCollection(this.#viewer, "portEntityCollection"); await addMergedEntityCollection(getViewer(), "portEntityCollection");
}; };
// 移除港口点 // 移除港口点
removePortPoint = () => { const removePortPoint = () => {
removeEntityCollection(this.#viewer, "portEntityCollectionMerged"); removeEntityCollection(getViewer(), "portEntityCollectionMerged");
}; };
// 添加分公司点 // 添加分公司点
addBranchOfficePoint = async (area = "", pointInfo = null) => { const addBranchOfficePoint = async (area = "", pointInfo = null) => {
mitt.emit(changeCoverMaskVisibleMittKey, true); mitt.emit(changeCoverMaskVisibleMittKey, true);
let branchOfficePoint = []; let branchOfficePoint = [];
if (!pointInfo) { if (!pointInfo) {
@ -486,19 +489,19 @@ export default class MapMethods {
}, },
}), }),
); );
this.#viewer.dataSources.add(entityCollection); getViewer().dataSources.add(entityCollection);
}); });
await addMergedEntityCollection(this.#viewer, "branchOfficeEntityCollection"); await addMergedEntityCollection(getViewer(), "branchOfficeEntityCollection");
mitt.emit(changeCoverMaskVisibleMittKey, false); mitt.emit(changeCoverMaskVisibleMittKey, false);
}; };
// 删除分公司点 // 删除分公司点
removeBranchOfficePoint = () => { const removeBranchOfficePoint = () => {
removeEntityCollection(this.#viewer, "branchOfficeEntityCollectionMerged"); removeEntityCollection(getViewer(), "branchOfficeEntityCollectionMerged");
}; };
// 添加四色图 // 添加四色图
addFourColorDiagram = (id, corpionId) => { const addFourColorDiagram = (id, corpionId) => {
const edgeMap = { const edgeMap = {
"00003": edgeQHD, "00003": edgeQHD,
"00002": edgeCZKS, "00002": edgeCZKS,
@ -551,17 +554,17 @@ export default class MapMethods {
); );
}); });
this.#viewer.dataSources.add(entityCollection); getViewer().dataSources.add(entityCollection);
mitt.emit(changeCoverMaskVisibleMittKey, false); mitt.emit(changeCoverMaskVisibleMittKey, false);
}; };
// 删除四色图 // 删除四色图
removeFourColorDiagram = () => { const removeFourColorDiagram = () => {
removeEntityCollection(this.#viewer, "fourColorDiagramEntityCollection"); removeEntityCollection(getViewer(), "fourColorDiagramEntityCollection");
}; };
// 添加墙 // 添加墙
addWall = (id, corpionId) => { const addWall = (id, corpionId) => {
const edgeMap = { const edgeMap = {
"00003": edgeQHD, "00003": edgeQHD,
"00002": edgeCZKS, "00002": edgeCZKS,
@ -592,7 +595,7 @@ export default class MapMethods {
id: createId(), id: createId(),
wall: { wall: {
positions, positions,
material: new Cesium.WallPolylineTrailLinkMaterialProperty(this.#viewer), material: new Cesium.WallPolylineTrailLinkMaterialProperty(getViewer()),
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),
}, },
@ -600,63 +603,17 @@ export default class MapMethods {
); );
}); });
this.#viewer.dataSources.add(entityCollection); getViewer().dataSources.add(entityCollection);
mitt.emit(changeCoverMaskVisibleMittKey, false); mitt.emit(changeCoverMaskVisibleMittKey, false);
}; };
// 删除墙 // 删除墙
removeWall = () => { const removeWall = () => {
removeEntityCollection(this.#viewer, "wallEntityCollection"); removeEntityCollection(getViewer(), "wallEntityCollection");
};
/**
* desc: 添加点位
* @param {Array} pointList
* @param options {Object: {mapIcon, type, subLabel}} 配置项
* @param options.mapIcon {String} 扎点图标
* @param options.mapType {String} 扎点类型
* @param options.subLabel {String} 二级标题用于弹窗标题
*/
addMarkPoint = async (pointList, options) => {
if (!options.mapType)
throw new Error("请传入mapType扎点类型");
if (!options.mapIcon)
throw new Error("请传入mapIcon扎点图标");
mitt.emit(changeCoverMaskVisibleMittKey, true);
await chunkedLoad(pointList, 10, async (item) => {
const entityCollection = createEntityCollection(
`markEntityCollection_${options.mapType}`,
);
const name = item.MAP_POINT_NAME || item.AREA_NAME || "";
entityCollection.entities.add(
new Cesium.Entity({
id: createId(),
name,
position: getPosition(item.LONGITUDE, item.LATITUDE),
billboard: await getBillboard({ image: options.mapIcon, name }),
monitorItems: {
data: { ...item, mapType: `标记点_${options.mapType}`, subLabel: options.subLabel },
},
}),
);
this.#viewer.dataSources.add(entityCollection);
});
const dataSource = await addMergedEntityCollection(
this.#viewer,
"markEntityCollection",
options.mapType,
);
this.#enabledClustering(dataSource);
mitt.emit(changeCoverMaskVisibleMittKey, false);
};
// 删除点位
removeMarkPoint = (mapType) => {
removeEntityCollection(this.#viewer, `markEntityCollectionMerged${mapType ? `_${mapType}` : ""}`);
}; };
// 点位聚合 // 点位聚合
#enabledClustering = (dataSource) => { const enabledClustering = (dataSource) => {
dataSource.clustering.enabled = true; // 聚合开启 dataSource.clustering.enabled = true; // 聚合开启
dataSource.clustering.pixelRange = 50; // 设置像素范围,以扩展显示边框 dataSource.clustering.pixelRange = 50; // 设置像素范围,以扩展显示边框
dataSource.clustering.minimumClusterSize = 5; // 设置最小的聚合点数目,超过此数目才能聚合 dataSource.clustering.minimumClusterSize = 5; // 设置最小的聚合点数目,超过此数目才能聚合
@ -719,4 +676,67 @@ export default class MapMethods {
dataSource.clustering.pixelRange = pixelRange; dataSource.clustering.pixelRange = pixelRange;
} }
}; };
/**
* desc: 添加点位
* @param {Array} pointList
* @param options {Object: {mapIcon, type, subLabel}} 配置项
* @param options.mapIcon {String} 扎点图标
* @param options.mapType {String} 扎点类型
* @param options.subLabel {String} 二级标题用于弹窗标题
*/
const addMarkPoint = async (pointList, options) => {
if (!options.mapType)
throw new Error("请传入mapType扎点类型");
if (!options.mapIcon)
throw new Error("请传入mapIcon扎点图标");
mitt.emit(changeCoverMaskVisibleMittKey, true);
await chunkedLoad(pointList, 10, async (item) => {
const entityCollection = createEntityCollection(
`markEntityCollection_${options.mapType}`,
);
const name = item.MAP_POINT_NAME || item.AREA_NAME || "";
entityCollection.entities.add(
new Cesium.Entity({
id: createId(),
name,
position: getPosition(item.LONGITUDE, item.LATITUDE),
billboard: await getBillboard({ image: options.mapIcon, name }),
monitorItems: {
data: { ...item, mapType: `标记点_${options.mapType}`, subLabel: options.subLabel },
},
}),
);
getViewer().dataSources.add(entityCollection);
});
const dataSource = await addMergedEntityCollection(
getViewer(),
"markEntityCollection",
options.mapType,
);
enabledClustering(dataSource);
mitt.emit(changeCoverMaskVisibleMittKey, false);
};
// 删除点位
const removeMarkPoint = (mapType) => {
removeEntityCollection(getViewer(), `markEntityCollectionMerged${mapType ? `_${mapType}` : ""}`);
};
return {
flyTo,
returnCurrentCenterPoint,
returnPreviousCenterPoint,
changeSceneMode,
addPortPoint,
removePortPoint,
addBranchOfficePoint,
removeBranchOfficePoint,
addFourColorDiagram,
removeFourColorDiagram,
addWall,
removeWall,
addMarkPoint,
removeMarkPoint,
};
} }

View File

@ -1,3 +1,4 @@
import { useRef } from "react";
import BranchOffice from "../components/popup/components/BranchOffice"; import BranchOffice from "../components/popup/components/BranchOffice";
import Port from "../components/popup/components/Port"; import Port from "../components/popup/components/Port";
import PopupInfo from "../components/popup/js/PopupInfo"; import PopupInfo from "../components/popup/js/PopupInfo";
@ -12,71 +13,35 @@ import {
resetBottomCurrentIndexMittKey, resetBottomCurrentIndexMittKey,
} from "./mittKey"; } from "./mittKey";
export default class PointClickEvent { export default function usePointClickEvent(viewerRef, mapMethods) {
#viewer; const popupRef = useRef(null);
#popup;
#mapMethods;
constructor(viewer, mapMethods) { // 获取当前 Cesium 实例:点击事件触发时地图已经完成初始化。
this.#viewer = viewer; const getViewer = () => viewerRef.current;
this.#mapMethods = mapMethods;
}
// 关闭弹窗 // 关闭弹窗
closePopup = () => { const closePopup = () => {
if (this.#popup) { if (popupRef.current) {
this.#popup.remove(); popupRef.current.remove();
this.#popup = null; popupRef.current = null;
} }
}; };
// 点位点击
pointClickEvent = (pick) => {
const data = pick.monitorItems.data;
this.closePopup();
if (data.isExternalEntry === "1" && data.mapType === "港口") {
this.#clickPortPointEnter(data);
return;
}
if (data.mapType === "港口")
this.#clickPortPoint(data);
if (data.mapType === "分公司")
this.#clickBranchOfficePoint(data);
if (data.mapType.includes("标记点"))
this.#clickMarkPoint(data);
};
// 港口点位点击
#clickPortPoint = (data) => {
const position = getPosition(data.position.x, data.position.y);
this.#popup = new PopupInfo(this.#viewer, {
component: Port,
position,
props: {
info: data,
close: this.closePopup,
enter: () => {
this.#clickPortPointEnter(data);
},
},
});
};
// 港口点位点击进入 // 港口点位点击进入
#clickPortPointEnter = (data) => { const clickPortPointEnter = (data) => {
this.closePopup(); closePopup();
this.#mapMethods.removePortPoint(); mapMethods.removePortPoint();
// setTimeout(() => { // setTimeout(() => {
if (data.id === "00003") { if (data.id === "00003") {
this.#mapMethods.flyTo({ longitude: data.position.x, latitude: data.position.y, height: 10000 }); mapMethods.flyTo({ longitude: data.position.x, latitude: data.position.y, height: 10000 });
this.#mapMethods.addBranchOfficePoint(); mapMethods.addBranchOfficePoint();
mitt.emit(clickPortPointMittKey, data); mitt.emit(clickPortPointMittKey, data);
} }
else { else {
this.#mapMethods.removeFourColorDiagram(); mapMethods.removeFourColorDiagram();
this.#mapMethods.removeWall(); mapMethods.removeWall();
this.#mapMethods.flyTo({ longitude: data.position.x, latitude: data.position.y, height: 2000 }); mapMethods.flyTo({ longitude: data.position.x, latitude: data.position.y, height: 2000 });
this.#mapMethods.addBranchOfficePoint("", { mapMethods.addBranchOfficePoint("", {
corpName: data.name, corpName: data.name,
corpinfoId: data.corpinfoId, corpinfoId: data.corpinfoId,
longitude: data.position.x, longitude: data.position.x,
@ -91,35 +56,31 @@ export default class PointClickEvent {
mitt.emit(resetAllBottomUtilsCheckMittKey); mitt.emit(resetAllBottomUtilsCheckMittKey);
}; };
// 分公司点位点击 // 港口点位点击
#clickBranchOfficePoint = async (data) => { const clickPortPoint = (data) => {
if (data.id === sessionStorage.getItem("mapCurrentBranchOfficeId")) const position = getPosition(data.position.x, data.position.y);
return; popupRef.current = new PopupInfo(getViewer(), {
// const { info } = await getCorpInfo({ id: data.id }); component: Port,
const info = {};
const position = getPosition(data.longitude, data.latitude);
this.#popup = new PopupInfo(this.#viewer, {
component: BranchOffice,
position, position,
props: { props: {
info, info: data,
close: this.closePopup, close: closePopup,
enter: () => { enter: () => {
this.#clickBranchOfficePointEnter(data); clickPortPointEnter(data);
}, },
}, },
}); });
}; };
// 分公司点位点击进入 // 分公司点位点击进入
#clickBranchOfficePointEnter = (data) => { const clickBranchOfficePointEnter = (data) => {
this.closePopup(); closePopup();
this.#mapMethods.removeBranchOfficePoint(); mapMethods.removeBranchOfficePoint();
this.#mapMethods.removeMarkPoint(); mapMethods.removeMarkPoint();
this.#mapMethods.addBranchOfficePoint("", data); mapMethods.addBranchOfficePoint("", data);
this.#mapMethods.removeFourColorDiagram(); mapMethods.removeFourColorDiagram();
this.#mapMethods.removeWall(); mapMethods.removeWall();
this.#mapMethods.flyTo({ longitude: data.longitude, latitude: data.latitude, height: 2000 }); mapMethods.flyTo({ longitude: data.longitude, latitude: data.latitude, height: 2000 });
mitt.emit(deletePeoplePositionPointMittKey); mitt.emit(deletePeoplePositionPointMittKey);
mitt.emit(clickBranchOfficePointMittKey, data); mitt.emit(clickBranchOfficePointMittKey, data);
sessionStorage.setItem("mapCurrentBranchOfficeId", data.corpinfoId); sessionStorage.setItem("mapCurrentBranchOfficeId", data.corpinfoId);
@ -127,8 +88,49 @@ export default class PointClickEvent {
mitt.emit(resetAllBottomUtilsCheckMittKey); mitt.emit(resetAllBottomUtilsCheckMittKey);
}; };
// 分公司点位点击
const clickBranchOfficePoint = async (data) => {
if (data.id === sessionStorage.getItem("mapCurrentBranchOfficeId"))
return;
// const { info } = await getCorpInfo({ id: data.id });
const info = {};
const position = getPosition(data.longitude, data.latitude);
popupRef.current = new PopupInfo(getViewer(), {
component: BranchOffice,
position,
props: {
info,
close: closePopup,
enter: () => {
clickBranchOfficePointEnter(data);
},
},
});
};
// 标记点位点击 // 标记点位点击
#clickMarkPoint = (data) => { const clickMarkPoint = (data) => {
mitt.emit(clickMarkPointMittKey, data); mitt.emit(clickMarkPointMittKey, data);
}; };
// 点位点击
const pointClickEvent = (pick) => {
const data = pick.monitorItems.data;
closePopup();
if (data.isExternalEntry === "1" && data.mapType === "港口") {
clickPortPointEnter(data);
return;
}
if (data.mapType === "港口")
clickPortPoint(data);
if (data.mapType === "分公司")
clickBranchOfficePoint(data);
if (data.mapType.includes("标记点"))
clickMarkPoint(data);
};
return {
closePopup,
pointClickEvent,
};
} }