zcloud-gbs-bi-react/src/pages/Container/Map/js/mapMethods.js

743 lines
23 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

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,
};
}