refactor(map): 将class重构成hook写法
parent
d16b6b2ee5
commit
42961e417c
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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);
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue