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

386 lines
14 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 portEntityBillboardImage from "~/assets/images/map_bi/point/dianwei.png";
import branchOfficeEntityBillboardImage from "~/assets/images/map_bi/point/gongsidianwei.png";
import { BranchOfficePoint } from "~/pages/Container/Map/js/mock";
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 Cesium = window.Cesium;
export default class MapMethods {
#viewer;
#defineCenterPoint = {
longitude: 119.6486945226887,
latitude: 39.93555616569192,
height: 900000,
}; // 默认中心点
#currentCenterPoint = {
longitude: 119.6486945226887,
latitude: 39.93555616569192,
height: 900000,
}; // 当前中心点
#previousCenterPoint = {
longitude: 119.6486945226887,
latitude: 39.93555616569192,
height: 900000,
}; // 上一次中心点
constructor(viewer) {
this.#viewer = viewer;
}
// 设置中心点
flyTo = ({ longitude, latitude, height } = this.#defineCenterPoint) => {
this.#viewer.camera.flyTo({ destination: getPosition(longitude, latitude, height), duration: 2 });
this.#previousCenterPoint = { ...this.#currentCenterPoint };
this.#currentCenterPoint = { longitude, latitude, height };
};
// 返回当前中心点
returnCurrentCenterPoint = () => {
const { longitude, latitude, height } = this.#currentCenterPoint;
this.#viewer.camera.flyTo({ destination: getPosition(longitude, latitude, height), duration: 2 });
};
// 返回上一次中心点
returnPreviousCenterPoint = () => {
const { longitude, latitude, height } = this.#previousCenterPoint;
this.#viewer.camera.flyTo({ destination: getPosition(longitude, latitude, height), duration: 2 });
this.#currentCenterPoint = { longitude, latitude, height };
};
// 切换场景模式
changeSceneMode = (type = "3d") => {
this.#viewer.scene.mode = { "2d": Cesium.SceneMode.COLUMBUS_VIEW, "3d": Cesium.SceneMode.SCENE3D }[type];
};
// 添加港口点
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) => {
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: "港口" } },
}),
);
this.#viewer.dataSources.add(entityCollection);
});
await addMergedEntityCollection(this.#viewer, "portEntityCollection");
};
// 移除港口点
removePortPoint = () => {
removeEntityCollection(this.#viewer, "portEntityCollectionMerged");
};
// 添加分公司点
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: "分公司" },
},
}),
);
this.#viewer.dataSources.add(entityCollection);
});
await addMergedEntityCollection(this.#viewer, "branchOfficeEntityCollection");
mitt.emit(changeCoverMaskVisibleMittKey, false);
};
// 删除分公司点
removeBranchOfficePoint = () => {
removeEntityCollection(this.#viewer, "branchOfficeEntityCollectionMerged");
};
// 添加四色图
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),
},
}),
);
});
this.#viewer.dataSources.add(entityCollection);
mitt.emit(changeCoverMaskVisibleMittKey, false);
};
// 删除四色图
removeFourColorDiagram = () => {
removeEntityCollection(this.#viewer, "fourColorDiagramEntityCollection");
};
// 添加墙
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(this.#viewer),
maximumHeights: Array.from({ length: pointCount }).fill(40),
minimumHeights: Array.from({ length: pointCount }).fill(0),
},
}),
);
});
this.#viewer.dataSources.add(entityCollection);
mitt.emit(changeCoverMaskVisibleMittKey, false);
};
// 删除墙
removeWall = () => {
removeEntityCollection(this.#viewer, "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) => {
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;
}
};
}