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

172 lines
7.1 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 { createObliquePhotography } from "~/pages/Container/Map/js/mapUtils";
import useMapMethods from "./mapMethods";
import usePointClickEvent from "./pointClickEvent";
const Cesium = window.Cesium;
export default function useInitMap(options) {
// 页面和地图工具共用同一个 Cesium 引用,避免内外各维护一份实例。
const viewer = useRef(null);
const mapMethodsValue = useMapMethods(viewer, options.request);
// Context 下游仍按 ref.current 调用地图方法,因此保留原有数据结构。
const mapMethods = useRef(mapMethodsValue);
mapMethods.current = mapMethodsValue;
// 点位点击处理集合:替代原 PointClickEvent class 实例,负责弹窗和层级进入。
const pointClickEvent = usePointClickEvent(viewer, mapMethodsValue);
// Cesium 点击事件只在初始化时注册,必须始终使用首次创建的处理器,才能关闭其维护的 Popup 实例。
const pointClickEventRef = useRef(pointClickEvent);
// 获取当前 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) {
pointClickEventRef.current.pointClickEvent(pick.id);
}
else {
pointClickEventRef.current.closePopup();
}
}, Cesium.ScreenSpaceEventType.LEFT_CLICK);
};
// 初始化地图
const initMap = () => {
const tianDiTuKey = "06494bcf2d4b66df7f3c586cc65af0cb";
const subdomains = ["0", "1", "2", "3", "4", "5", "6", "7"];
viewer.current = new Cesium.Viewer("cesiumContainer", {
// terrainProvider: Cesium.createWorldTerrain()
animation: false, // 动画
homeButton: true, // home键
geocoder: true, // 地址编码
baseLayerPicker: false, // 图层选择控件
timeline: false, // 时间轴
fullscreenButton: true, // 全屏显示
infoBox: true, // 点击要素之后浮窗
sceneModePicker: true, // 投影方式 三维/二维
navigationInstructionsInitiallyVisible: false, // 导航指令
navigationHelpButton: false, // 帮助信息
selectionIndicator: false, // 选择
imageryProvider: new Cesium.WebMapTileServiceImageryProvider({
// 影像底图
url:
`https://t{s}.tianditu.gov.cn/img_w/wmts?service=wmts&request=GetTile&version=1.0.0&LAYER=img&tileMatrixSet=w&TileMatrix={TileMatrix}&TileRow={TileRow}&TileCol={TileCol}&style=default&format=tiles&tk=${
tianDiTuKey}`,
subdomains,
layer: "tdtImgLayer",
style: "default",
format: "image/jpeg",
tileMatrixSetID: "GoogleMapsCompatible", // 使用谷歌的瓦片切片方式
show: true,
}),
});
// 调整 Cesium 默认相机操作:左键旋转地图,右键调整俯仰角,实现从平面俯视到立体视角的切换。
const cameraController = getViewer().scene.screenSpaceCameraController;
cameraController.rotateEventTypes = Cesium.CameraEventType.LEFT_DRAG;
cameraController.tiltEventTypes = [
Cesium.CameraEventType.RIGHT_DRAG,
Cesium.CameraEventType.MIDDLE_DRAG,
Cesium.CameraEventType.PINCH,
];
cameraController.zoomEventTypes = [
Cesium.CameraEventType.WHEEL,
Cesium.CameraEventType.PINCH,
];
getViewer()._cesiumWidget._creditContainer.style.display = "none"; // 隐藏cesium ion
getViewer().imageryLayers.addImageryProvider(
new Cesium.WebMapTileServiceImageryProvider({
// 影像注记
url:
`https://t{s}.tianditu.gov.cn/cia_w/wmts?service=wmts&request=GetTile&version=1.0.0&LAYER=cia&tileMatrixSet=w&TileMatrix={TileMatrix}&TileRow={TileRow}&TileCol={TileCol}&style=default.jpg&tk=${
tianDiTuKey}`,
subdomains,
layer: "tdtCiaLayer",
style: "default",
format: "image/jpeg",
tileMatrixSetID: "GoogleMapsCompatible",
show: true,
}),
);
initObliquePhotography();
registerClickEvent();
return { mapMethods: mapMethods.current, viewer: getViewer() };
};
// 外部入口进入港口:只有港口标识、名称和有效坐标齐全时才进入,避免 Cesium 接收到无效坐标。
const externalEntryPort = (data) => {
const id = data.id || data.portId;
const name = data.name || data.portName;
const longitude = data.position?.x ?? data.longitude ?? data.lng ?? data.x;
const latitude = data.position?.y ?? data.latitude ?? data.lat ?? data.y;
// 空字符串会被 Number 转成 0需要先排除空值再判断是否为有效数字。
const hasCoordinate = value => value !== "" && value !== null && value !== undefined;
const hasValidPosition
= hasCoordinate(longitude)
&& hasCoordinate(latitude)
&& Number.isFinite(Number(longitude))
&& Number.isFinite(Number(latitude));
if (!id || !name || !hasValidPosition)
return false;
pointClickEventRef.current.pointClickEvent({
monitorItems: {
data: {
...data,
id,
name,
corpinfoId: data.corpinfoId,
markType: "港口",
isExternalEntry: "1",
position: { x: Number(longitude), y: Number(latitude) },
},
},
});
return true;
};
return {
viewer,
mapMethods,
initMap,
externalEntryPort,
closePopup: () => pointClickEventRef.current.closePopup(),
};
}