import { useRef } from "react"; import portEntityBillboardImage from "~/assets/images/map_bi/point/dianwei.png"; import branchOfficeEntityBillboardImage from "~/assets/images/map_bi/point/gongsidianwei.png"; import edgeCMT from "./edge/cmt.js"; import edgeCSY from "./edge/csy.js"; import edgeCZKS from "./edge/czks.js"; import edgeQHD from "./edge/qhd.js"; import { addMergedEntityCollection, createEntityCollection, createId, getBillboard, getPosition, removeEntityCollection, } from "./mapUtils"; import mitt from "./mitt"; import { changeCoverMaskVisibleMittKey } from "./mittKey"; import { chunkedLoad, filterNull, formatPolygon } from "./utils"; import "./TrajectoryPolylineTrailLinkMaterialProperty.js"; 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 = [ { corpName: "秦港股份有限公司", longitude: "", corpinfoId: "1", latitude: "", mapPointName: "秦港股份有限公司", }, { corpName: "秦皇岛港新益港务有限公司12", longitude: "117.81722012173059", corpinfoId: "035958e685cf4850bc40151c5e0617a6", latitude: "40.16437937435123", mapPointName: "秦皇岛港新益港务有限公司12", }, { corpName: "测试测试0527-1", longitude: "118.95108477670387", corpinfoId: "8ab3328e42974f338942d0506b58d8f3", latitude: "40.69968157498669", mapPointName: "测试测试0527-1", }, { corpName: "1122公司测试隐患考评", longitude: "", corpinfoId: "805c21b0fccb49aba0c409e4eccbfd59", latitude: "", mapPointName: "1122公司测试隐患考评", }, { corpName: "秦港股份二公司", longitude: "119.63521", corpinfoId: "17973964c87346e7a4a737cf252557d9", latitude: "39.92944", mapPointName: "秦港股份二公司", }, { corpName: "55555", longitude: "", corpinfoId: "cdadd26e8fb74ce6a683bc0e5aa69e99", latitude: "", mapPointName: "55555", }, { corpName: "秦港股份六公司", longitude: "119.67186", corpinfoId: "97b87eba9f9c49a0a917c1f412016fb1", latitude: "39.94193", mapPointName: "秦港股份六公司", }, { corpName: "测试企业信息", longitude: "", corpinfoId: "e43c5aeaf9694df3aeddef71654c8cf2", latitude: "", mapPointName: "测试企业信息", }, { corpName: "秦港股份七公司", longitude: "119.67172", corpinfoId: "286dcae730aa43ba82c97a676f9d8ee2", latitude: "39.94342", mapPointName: "秦港股份七公司", }, { corpName: "秦港股份九公司", longitude: "119.67623", corpinfoId: "21590a00ea5e462e9ee44dd332dddc26", latitude: "39.93108", mapPointName: "秦港股份九公司", }, { corpName: "秦港股份杂货公司", longitude: "119.58103", corpinfoId: "033549ed3bd648e49c8a65eb4993ec2f", latitude: "39.91532", mapPointName: "秦港股份杂货公司", }, { corpName: "秦港股份铁运公司", longitude: "119.63189", corpinfoId: "66131d4e5c8f4c8893b80975dca39ac3", latitude: "39.94252", mapPointName: "秦港股份铁运公司", }, { corpName: "秦港股份流机公司", longitude: "119.587", corpinfoId: "f1478d64109445948d819beb6c1b52ee", latitude: "39.91472", mapPointName: "秦港股份流机公司", }, { corpName: "秦港股份电力公司", longitude: "119.5996970027171", corpinfoId: "f21cf733f1354503865af705ecc8dba2", latitude: "39.919168362236874", mapPointName: "秦港股份电力公司", }, { corpName: "秦港股份船舶公司", longitude: "119.61417", corpinfoId: "d7e15394923740bf979efd8c0105063b", latitude: "39.92033", mapPointName: "秦港股份船舶公司", }, { corpName: "0507-1", longitude: "119.65480053930092", corpinfoId: "a29620da401b4f05a73d9f7d629030c5", latitude: "39.922427338021684", mapPointName: "0507-1", }, { corpName: "秦港股份综服中心", longitude: "119.62629", corpinfoId: "c4e000a8245843ad82f8e172ce063671", latitude: "39.9319", mapPointName: "秦港股份综服中心", }, { corpName: "秦港物资中心", longitude: "119.66925", corpinfoId: "9595235dfa334b2898a0e75d160418fa", latitude: "39.93953", mapPointName: "秦港物资中心", }, { corpName: "秦港教培中心", longitude: "119.58357", corpinfoId: "0407e689f75746358326f040e59d1e32", latitude: "39.92007", mapPointName: "秦港教培中心", }, { corpName: "秦港行政中心", longitude: "119.59925", corpinfoId: "bca641ac9978474987b3f0377f82359e", latitude: "39.91755", mapPointName: "秦港行政中心", }, { corpName: "秦港餐饮中心", longitude: "119.60255", corpinfoId: "4e1b8e11c2a94d9eac8cfa07145f9f69", latitude: "39.91895", mapPointName: "秦港餐饮中心", }, { corpName: "工程项目中心", longitude: "", corpinfoId: "7b00458c903a4460aeeb3c189dde7ebb", latitude: "", mapPointName: "工程项目中心", }, { corpName: "秦港技术中心", longitude: "119.58399", corpinfoId: "6692f5f1f14c4544b9f7ca7a59d065db", latitude: "39.91774", mapPointName: "秦港技术中心", }, { corpName: "河北港口集团数联科技(雄安)有限公司", longitude: "", corpinfoId: "5cee11f6152d42e0a08ae38dc6abcfdf", latitude: "", mapPointName: "河北港口集团数联科技(雄安)有限公司", }, { corpName: "秦港新闻中心", longitude: "", corpinfoId: "8d97ef3051724e968024be1e6e6779ba", latitude: "", mapPointName: "秦港新闻中心", }, { corpName: "秦港财务中心", longitude: "", corpinfoId: "7abd8156caa14229bcabc382309e2e94", latitude: "", mapPointName: "秦港财务中心", }, { corpName: "秦港审计中心", longitude: "", corpinfoId: "e2a121b54b8a44569726b12b47f6c2ed", latitude: "", mapPointName: "秦港审计中心", }, { corpName: "沧州黄骅港矿石港务有限公司", longitude: "117.8291", corpinfoId: "f8da1790b1034058ae2efefd69af3284", latitude: "38.3223", mapPointName: "沧州黄骅港矿石港务有限公司", }, { corpName: "唐山曹妃甸煤炭港务有限公司", longitude: "118.44159", corpinfoId: "6aa255d41602497fa0f934a822820df4", latitude: "38.98158", mapPointName: "唐山曹妃甸煤炭港务有限公司", }, { corpName: "唐山曹妃甸实业港务有限公司", longitude: "118.53903", corpinfoId: "8854edee3aa94be496cee676b6d4845a", latitude: "38.94306", mapPointName: "唐山曹妃甸实业港务有限公司", }, { corpName: "秦皇岛中理", longitude: "119.61138", corpinfoId: "e52f138ca0444c55bdae2a429e3cdbfe", latitude: "39.91428", mapPointName: "秦皇岛中理", }, { corpName: "沧州黄骅港散货港务有限公司", longitude: "", corpinfoId: "84a6206738ac4703b277d6245ec111ec", latitude: "", mapPointName: "沧州黄骅港散货港务有限公司", }, { corpName: "秦山港务", longitude: "119.69864", corpinfoId: "1fc6f50705de4fd6a76e80f2fc6e4720", latitude: "39.93794", mapPointName: "秦山港务", }, { corpName: "唐曹铁路有限公司(小集物流)", longitude: "", corpinfoId: "fb6c1a78bc414f109269a677e19a8a80", latitude: "", mapPointName: "唐曹铁路有限公司(小集物流)", }, { corpName: "新港湾(托管)", longitude: "119.57749", corpinfoId: "3baaa68e74514a649338baf8c88b565b", latitude: "39.90205", mapPointName: "新港湾(托管)", }, { corpName: "沧州黄骅港原油港务有限公司", longitude: "", corpinfoId: "fa88fb8186f74c7b995c4f4622379d3b", latitude: "", mapPointName: "沧州黄骅港原油港务有限公司", }, { corpName: "河北唐山曹妃甸冀同港口有限公司", longitude: "", corpinfoId: "5818906b74714c86b697abc8ca23e1a7", latitude: "", mapPointName: "河北唐山曹妃甸冀同港口有限公司", }, { corpName: "河港港工", longitude: "119.60725", corpinfoId: "3a854eefa7894e06aaa1a2611bca80f6", latitude: "39.92514", mapPointName: "河港港工", }, { corpName: "河港机械", longitude: "119.65135983055092", corpinfoId: "1e6dbbe16004402f8d2c0e52afd9a676", latitude: "39.93524462021923", mapPointName: "河港机械", }, { corpName: "河港城发", longitude: "", corpinfoId: "f42d930a7e694123a2d6ad3e546ba695", latitude: "", mapPointName: "河港城发", }, { corpName: "方宇物业", longitude: "", corpinfoId: "90966974de3c4b83aca6f8fd6432d5c2", latitude: "", mapPointName: "方宇物业", }, { corpName: "河港检测", longitude: "119.58435", corpinfoId: "020578a4c1f04bc692ee25145c2efbe5", latitude: "39.91774", mapPointName: "河港检测", }, { corpName: "测试分公司22354", longitude: "119.59401996313625", corpinfoId: "8ac5c5fb138e4828a81ada5849246c80", latitude: "39.95368714225534", mapPointName: "测试分公司22354", }, { corpName: "测试分公司26201", longitude: "119.24647177465056", corpinfoId: "1c3794fa9ae048288585d7a9fafd44d3", latitude: "39.928680261541466", mapPointName: "测试分公司26201", }, { corpName: "0508-11", longitude: "", corpinfoId: "23b0759ebefe413dbc439dc978ed8506", latitude: "", mapPointName: "0508-11", }, { corpName: "卓云企业", longitude: "119.44612949064937", corpinfoId: "13cf0f4ec77e4d98ae8cdd9c3386ae0c", latitude: "39.91957983420952", mapPointName: "卓云企业", }, { corpName: "0620-1", longitude: "", corpinfoId: "f32a6ef1b45e42278dfecd3a5327cdf5", latitude: "", mapPointName: "0620-1", }, { corpName: "0508-12", longitude: "", corpinfoId: "d4be61ffb6554e4085c1dd419d264331", latitude: "", mapPointName: "0508-12", }, ]; const Cesium = window.Cesium; export default function useMapMethods(viewerRef) { // 获取当前 Cesium 实例:初始化前为空,地图方法会在 initMap 完成后被调用。 const getViewer = () => viewerRef.current; // 默认中心点:初始化和回到首页视角时使用,保持全局港区俯视高度。 const defineCenterPoint = { longitude: 119.6486945226887, latitude: 39.93555616569192, height: 900000, }; // 当前中心点:记录最近一次 flyTo 的视角,供外部按钮回到当前位置。 const currentCenterPointRef = useRef({ longitude: 119.6486945226887, latitude: 39.93555616569192, height: 900000, }); // 上一次中心点:从分公司返回港口层级时,需要回退到进入前的视角。 const previousCenterPointRef = useRef({ longitude: 119.6486945226887, latitude: 39.93555616569192, height: 900000, }); // 设置中心点 const flyTo = ({ longitude, latitude, height } = defineCenterPoint) => { getViewer().camera.flyTo({ destination: getPosition(longitude, latitude, height), duration: 2 }); previousCenterPointRef.current = { ...currentCenterPointRef.current }; currentCenterPointRef.current = { longitude, latitude, height }; }; // 返回当前中心点 const returnCurrentCenterPoint = () => { const { longitude, latitude, height } = currentCenterPointRef.current; getViewer().camera.flyTo({ destination: getPosition(longitude, latitude, height), duration: 2 }); }; // 返回上一次中心点 const returnPreviousCenterPoint = () => { const { longitude, latitude, height } = previousCenterPointRef.current; getViewer().camera.flyTo({ destination: getPosition(longitude, latitude, height), duration: 2 }); currentCenterPointRef.current = { longitude, latitude, height }; }; // 切换场景模式 const changeSceneMode = (type = "3d") => { getViewer().scene.mode = { "2d": Cesium.SceneMode.COLUMBUS_VIEW, "3d": Cesium.SceneMode.SCENE3D }[type]; }; // 添加港口点 const addPortPoint = async () => { await chunkedLoad(portPoint, 10, async (item) => { const entityCollection = createEntityCollection("portEntityCollection"); entityCollection.entities.add( new Cesium.Entity({ id: item.id, name: item.name, position: getPosition(item.position.x, item.position.y), billboard: await getBillboard({ image: portEntityBillboardImage, name: item.name }), monitorItems: { data: { ...item, mapType: "港口" } }, }), ); getViewer().dataSources.add(entityCollection); }); await addMergedEntityCollection(getViewer(), "portEntityCollection"); }; // 移除港口点 const removePortPoint = () => { removeEntityCollection(getViewer(), "portEntityCollectionMerged"); }; // 添加分公司点 const addBranchOfficePoint = async (area = "", pointInfo = null) => { mitt.emit(changeCoverMaskVisibleMittKey, true); let branchOfficePoint = []; if (!pointInfo) { branchOfficePoint = filterNull(BranchOfficePoint); } else { branchOfficePoint = filterNull([pointInfo]); } await chunkedLoad(branchOfficePoint, 10, async (item) => { const entityCollection = createEntityCollection("branchOfficeEntityCollection"); entityCollection.entities.add( new Cesium.Entity({ id: item.corpinfoId, name: item.corpName, position: getPosition(item.longitude, item.latitude), billboard: await getBillboard({ image: branchOfficeEntityBillboardImage, name: item.corpName }), monitorItems: { data: { ...item, id: item.corpinfoId, mapType: "分公司" }, }, }), ); getViewer().dataSources.add(entityCollection); }); await addMergedEntityCollection(getViewer(), "branchOfficeEntityCollection"); mitt.emit(changeCoverMaskVisibleMittKey, false); }; // 删除分公司点 const removeBranchOfficePoint = () => { removeEntityCollection(getViewer(), "branchOfficeEntityCollectionMerged"); }; // 添加四色图 const addFourColorDiagram = (id, corpionId) => { const edgeMap = { "00003": edgeQHD, "00002": edgeCZKS, "00005": edgeCMT, "00004": edgeCSY, }; if (!edgeMap[id]) return; mitt.emit(changeCoverMaskVisibleMittKey, true); const currentEdge = edgeMap[id](); const entityCollection = createEntityCollection( "fourColorDiagramEntityCollection", ); // 先收集需要渲染的数据 const itemsToRender = []; for (const currentEdgeKey in currentEdge) { const currentEdgeItem = currentEdge[currentEdgeKey]; if (currentEdgeKey === "wallList") continue; for (let i = 0; i < currentEdgeItem.length; i++) { const item = currentEdgeItem[i]; // 如果有 corpionId,则只添加匹配的;否则全部添加 if (!corpionId || item.corpinfoId === corpionId) { itemsToRender.push(item); } if (!item.corpinfoId) { itemsToRender.push(item); } } } // 统一渲染 itemsToRender.forEach((item) => { const latitudeAndLongitude = formatPolygon(item); entityCollection.entities.add( new Cesium.Entity({ id: createId(), polygon: { hierarchy: Cesium.Cartesian3.fromDegreesArray(latitudeAndLongitude), extrudedHeight: item.stretchHeight, height: item.height, material: Cesium.Color.fromCssColorString(item.color), outline: !!item.strokeColor, outlineColor: Cesium.Color.fromCssColorString(item.strokeColor), }, }), ); }); getViewer().dataSources.add(entityCollection); mitt.emit(changeCoverMaskVisibleMittKey, false); }; // 删除四色图 const removeFourColorDiagram = () => { removeEntityCollection(getViewer(), "fourColorDiagramEntityCollection"); }; // 添加墙 const addWall = (id, corpionId) => { const edgeMap = { "00003": edgeQHD, "00002": edgeCZKS, "00005": edgeCMT, "00004": edgeCSY, }; if (!edgeMap[id]) return; mitt.emit(changeCoverMaskVisibleMittKey, true); const currentEdge = edgeMap[id](); const entityCollection = createEntityCollection("wallEntityCollection"); const wallList = currentEdge.wallList; if (!Array.isArray(wallList)) return; // 筛选需要渲染的边界墙 const itemsToRender = wallList.filter(item => !corpionId || item.corpinfoId === corpionId); // 统一渲染 itemsToRender.forEach((item) => { const latitudeAndLongitude = formatPolygon(item); const positions = Cesium.Cartesian3.fromDegreesArray(latitudeAndLongitude); const pointCount = latitudeAndLongitude.length / 2; entityCollection.entities.add( new Cesium.Entity({ id: createId(), wall: { positions, material: new Cesium.WallPolylineTrailLinkMaterialProperty(getViewer()), maximumHeights: Array.from({ length: pointCount }).fill(40), minimumHeights: Array.from({ length: pointCount }).fill(0), }, }), ); }); getViewer().dataSources.add(entityCollection); mitt.emit(changeCoverMaskVisibleMittKey, false); }; // 删除墙 const removeWall = () => { removeEntityCollection(getViewer(), "wallEntityCollection"); }; // 点位聚合 const enabledClustering = (dataSource) => { dataSource.clustering.enabled = true; // 聚合开启 dataSource.clustering.pixelRange = 50; // 设置像素范围,以扩展显示边框 dataSource.clustering.minimumClusterSize = 5; // 设置最小的聚合点数目,超过此数目才能聚合 let removeListener; // 按聚合层级创建对应图标 const pinBuilder = new Cesium.PinBuilder(); const pin100 = pinBuilder .fromText("100+", Cesium.Color.BLUE, 48) .toDataURL(); const pin50 = pinBuilder.fromText("50+", Cesium.Color.BLUE, 48).toDataURL(); const pin40 = pinBuilder.fromText("40+", Cesium.Color.RED, 48).toDataURL(); const pin30 = pinBuilder.fromText("30+", Cesium.Color.RED, 48).toDataURL(); const pin20 = pinBuilder.fromText("20+", Cesium.Color.RED, 48).toDataURL(); const pin10 = pinBuilder.fromText("10+", Cesium.Color.RED, 48).toDataURL(); // 10以内聚合图标 const singleDigitPins = Array.from({ length: 8 }); for (let i = 0; i < singleDigitPins.length; ++i) { singleDigitPins[i] = pinBuilder .fromText(`${i + 2}`, Cesium.Color.VIOLET, 48) .toDataURL(); } customStyle(); function customStyle() { if (Cesium.defined(removeListener)) { removeListener(); removeListener = undefined; } else { removeListener = dataSource.clustering.clusterEvent.addEventListener( (clusteredEntities, cluster) => { cluster.label.show = false; cluster.billboard.show = true; cluster.billboard.id = cluster.label.id; cluster.billboard.verticalOrigin = Cesium.VerticalOrigin.BOTTOM; cluster.billboard.horizontalOrigin = Cesium.HorizontalOrigin.CENTER; cluster.billboard.heightReference = Cesium.HeightReference.CLAMP_TO_GROUND; cluster.billboard.disableDepthTestDistance = Number.POSITIVE_INFINITY; const thresholdMap = [ { threshold: 100, image: pin100 }, { threshold: 50, image: pin50 }, { threshold: 40, image: pin40 }, { threshold: 30, image: pin30 }, { threshold: 20, image: pin20 }, { threshold: 10, image: pin10 }, ]; const matched = thresholdMap.find( ({ threshold }) => clusteredEntities.length >= threshold, ); cluster.billboard.image = matched ? matched.image : singleDigitPins[clusteredEntities.length - 2]; }, ); } const pixelRange = dataSource.clustering.pixelRange; dataSource.clustering.pixelRange = 0; 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, }; }