import * as Cesium from 'cesium'; import AmapMercatorTilingScheme from './cesium/AmapMercatorTilingScheme/index'; import store from '@/store'; import { Terrain } from 'cesium'; // vite env const { VITE_APP_BASE } = import.meta.env; window.CESIUM_BASE_URL = `${VITE_APP_BASE}cesiumPu`; // 定义全局的viewer变量防止重复生成 let viewer = null; let globalBaseMapLayers = []; window.globalCesium = Cesium; window.$viewer = null; let customEntityDataSources = {}; let customMapLayer = {}; let handlerEvents = { handler: null, }; export default function cesiumOperation() { const TDT_Token = 'c6eea7dad4fa1e2d1e32ec0e7c9735db'; // 天地图地图 const TDT_IMG_C = 'https://{s}.tianditu.gov.cn/img_c/wmts?service=wmts&request=GetTile&version=1.0.0' + '&LAYER=img&tileMatrixSet=c&TileMatrix={TileMatrix}&TileRow={TileRow}&TileCol={TileCol}' + '&style=default&format=tiles&tk=' + TDT_Token; // 天地图注记 const TDT_ZJ = 'https://{s}.tianditu.gov.cn/cia_c/wmts?service=wmts&request=GetTile&version=1.0.0' + '&LAYER=cia&tileMatrixSet=c&TileMatrix={TileMatrix}&TileRow={TileRow}&TileCol={TileCol}' + '&style=default&format=tiles&tk=' + TDT_Token; // 标准地图注记 const TID_STAND = 'https://{s}.tianditu.gov.cn/vec_w/wmts?service=wmts&request=GetTile&version=1.0.0' + '&LAYER=img&tileMatrixSet=c&TileMatrix={TileMatrix}&TileRow={TileRow}&TileCol={TileCol}' + '&style=default&format=tiles&tk=' + TDT_Token; // 天地图图层变量 const imageryProvider_tdt = new Cesium.WebMapTileServiceImageryProvider({ url: TDT_IMG_C, layer: 'tdtImg_c', style: 'default', format: 'tiles', tileMatrixSetID: 'c', subdomains: ['t0', 't1', 't2', 't3', 't4', 't5', 't6', 't7'], tilingScheme: new Cesium.GeographicTilingScheme(), tileMatrixLabels: [ '1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15', '16', '17', '18', '19', ], maximumLevel: 17, }); // 标准地图图层变量 const imageryProvider_stand = new Cesium.UrlTemplateImageryProvider({ url: 'https://t{s}.tianditu.gov.cn/DataServer?T=vec_w&x={x}&y={y}&l={z}&tk=e45274b0235bb913eceb393aabbf9c9c', subdomains: ['0', '1', '2', '3', '4', '5', '6', '7'], // format: 'image/jpeg', // show: true, maximumLevel: 18, credit: 'stand_tc', }); // 标准地图图层注解 const imageryProvider_standZh = new Cesium.UrlTemplateImageryProvider({ url: 'https://t{s}.tianditu.gov.cn/DataServer?T=cva_w&x={x}&y={y}&l={z}&tk=e45274b0235bb913eceb393aabbf9c9c', subdomains: ['0', '1', '2', '3', '4', '5', '6', '7'], maximumLevel: 18, credit: 'stand_zj', }); // 天地图中文注记加载 const annotation = new Cesium.WebMapTileServiceImageryProvider({ url: TDT_ZJ, layer: 'tdtZwImg_c', style: 'default', format: 'tiles', tileMatrixSetID: 'c', subdomains: ['t0', 't1', 't2', 't3', 't4', 't5', 't6', 't7'], tilingScheme: new Cesium.GeographicTilingScheme(), tileMatrixLabels: [ '1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15', '16', '17', '18', '19', ], maximumLevel: 50, }); // 高德地图图层变量 //高德矢量地图数据图层,自带注记 const imageryProvider_ammapSL = new Cesium.UrlTemplateImageryProvider({ url: 'https://webrd02.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=8&x={x}&y={y}&z={z}', layer: 'tdtVecBasicLayer', style: 'default', format: 'image/png', tileMatrixSetID: 'GoogleMapsCompatible', subdomains: ['0', '1', '2', '3', '4', '5', '6', '7'], maximumLevel: 18, tilingScheme: new AmapMercatorTilingScheme(), credit: 'amap_SL', }); //高德影像地图数据图层,自带注记 const imageryProvider_ammap = new Cesium.UrlTemplateImageryProvider({ url: 'https://webst02.is.autonavi.com/appmaptile?style=6&x={x}&y={y}&z={z}', layer: 'tdtVecBasicLayer', style: 'default', format: 'image/png', tileMatrixSetID: 'GoogleMapsCompatible', subdomains: ['0', '1', '2', '3', '4', '5', '6', '7'], maximumLevel: 18, tilingScheme: new AmapMercatorTilingScheme(), credit: 'amap_stand', }); // 高德影像地图数据图层,注记 const imageryProvider_ammapBz = new Cesium.UrlTemplateImageryProvider({ url: 'https://webst02.is.autonavi.com/appmaptile?x={x}&y={y}&z={z}&lang=zh_cn&size=1&scale=1&style=8', tilingScheme: new AmapMercatorTilingScheme(), minimumLevel: 3, }); Cesium.Ion.defaultAccessToken = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiJkMzg4MDk5YS05MWEzLTQ3NTYtOTYzNS04Yzk4MjU2MjI5N2YiLCJpZCI6MjE3OTM4LCJpYXQiOjE3MTY3NzIzOTR9.q1rzR7SRtIulQKTtJuv5HPUbp1av5E9RaOe-6voPDGc'; const _init = async id => { const cesiumToken = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiJkYTZlNGNlYS01NTU1LTQ1MGEtYmNlZS0yNTE2NDk5YWM2MjEiLCJpZCI6MTc5Njk2LCJpYXQiOjE3MDA1NDcwMjV9.qcl4AH2731cfFd0-I1ZLUINPXqvglLkDFD-UGR2zU5M'; Cesium.Ion.defaultAccessToken = cesiumToken; Cesium.Camera.DEFAULT_VIEW_FACTOR = -0.45; // 西南东北,默认显示中国 Cesium.Camera.DEFAULT_VIEW_RECTANGLE = Cesium.Rectangle.fromDegrees(66, 4, 135, 53.55); viewer = new Cesium.Viewer(id, { terrain: Terrain.fromWorldTerrain(), infoBox: false, // 禁用沙箱,解决控制台报错 animation: false, // 左下角的动画仪表盘 baseLayerPicker: false, // 右上角的图层选择按钮 geocoder: false, // 搜索框 homeButton: false, // home按钮 sceneModePicker: false, // 模式切换按钮 timeline: false, // 底部的时间轴 navigationHelpButton: false, // 右上角的帮助按钮, selectionIndicator: false, // 是否显示选择指示器 baseLayer: false, fullscreenButton: false, }); // viewer.scene.globe.depthTestAgainstTerrain = true; viewer.imageryLayers.removeAll(); globalBaseMapLayers = []; viewer.cesiumWidget.screenSpaceEventHandler.removeInputAction( Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK ); // 禁用双击 viewer.scene.screenSpaceCameraController.minimumZoomDistance = 100; viewer.scene.screenSpaceCameraController.maximumZoomDistance = 4500000; // viewer.scene.camera.setView({ // destination: Cesium.Cartesian3.fromDegrees(115.856725497,28.624514734, 8000) // }); // // 添加地形数据 // viewer.terrainProvider = new Cesium.CesiumTerrainProvider({ // url: 'https://data.marsgis.cn/terrain', // }); // viewer.terrainProvider = new Cesium.CesiumTerrainProvider({ // url: Cesium.IonResource.fromAssetId(1), // requestWaterMask: false, // requestVertexNormals: true, // }) window.$viewer = viewer; loadLAYER(); }; const loadLAYER = () => { let mapLayers = []; globalBaseMapLayers.length && globalBaseMapLayers.forEach(item => { if (item.mapLayer) item.mapLayer.show = false; }); // 高德影像地图数据图层 if (store.state.common.mapSetting.mode === 3) { mapLayers.push( ...[ { key: 'imageryProvider_ammap', layer: imageryProvider_ammap }, { key: 'imageryProvider_ammapBz', layer: imageryProvider_ammapBz }, ] ); } // 高德地图矢量图层加载 if (store.state.common.mapSetting.mode === 2) { mapLayers.push({ key: 'imageryProvider_ammapSL', layer: imageryProvider_ammapSL, }); } // 标准地图加载 if (store.state.common.mapSetting.mode === 0) { mapLayers.push( ...[ { key: 'imageryProvider_standZh', layer: imageryProvider_standZh }, { key: 'imageryProvider_stand', layer: imageryProvider_stand }, ] ); } // 路线图加载 if ( store.state.common.mapSetting.roadLine === true && store.state.common.mapSetting.mode === 1 ) { mapLayers.push({ key: 'annotation', layer: annotation }); } // 天地图图层加载 if (store.state.common.mapSetting.mode === 1) { mapLayers.push({ key: 'imageryProvider_tdt', layer: imageryProvider_tdt, }); } // 创建一个Set来快速查找array2中的id let keyBaseMap = new Set(globalBaseMapLayers.map(item => item.key)); let keyMapLayers = new Set(mapLayers.map(item => item.key)); let keyExistBaseMap = mapLayers.filter(item => !keyBaseMap.has(item.key)); let keyNoExistBaseMap = globalBaseMapLayers.filter(item => keyMapLayers.has(item.key)); keyExistBaseMap.length && keyExistBaseMap.forEach(item => { let curLayer = { key: item.key, mapLayer: viewer?.imageryLayers.addImageryProvider(item.layer), }; if (curLayer.mapLayer) curLayer.mapLayer.show = true; viewer?.imageryLayers.lowerToBottom(curLayer.mapLayer); globalBaseMapLayers.push(curLayer); }); keyNoExistBaseMap.length && keyNoExistBaseMap.forEach(item => { if (item.mapLayer) item.mapLayer.show = true; viewer?.imageryLayers.lowerToBottom(item.mapLayer); }); // 2D/3D切换 switchModel(store.state.common.mapSetting.visual); }; const addCustomLayers = (layerName, options) => { if (options.type == 'arcgis') { var imageryProvider = new Cesium.WebMapTileServiceImageryProvider({ url: options.src, layer: options.title, style: 'default', format: 'image/png', tileMatrixSetID: 'default', tilingScheme: new Cesium.GeographicTilingScheme(), tileMatrixLabels: [ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15', '16', '17', '18', '19', ], }); customMapLayer[layerName] = viewer?.imageryLayers.addImageryProvider(imageryProvider); // const layerProvider = new Cesium.ArcGisMapServerImageryProvider({ // url: options.src, // tilingScheme: new Cesium.GeographicTilingScheme() // }) // customMapLayer[layerName] = viewer?.imageryLayers.addImageryProvider(layerProvider) } }; const removeCustomLayers = (layerName = '') => { if (layerName) { if (customMapLayer[layerName]) { viewer?.imageryLayers.remove(customMapLayer[layerName]); delete customMapLayer[layerName]; } } else { for (let k in customMapLayer) { viewer?.imageryLayers.remove(customMapLayer[k]); } customMapLayer = {}; } }; // 切换不同背景图层 const patternMap = () => { const imageryLayers = viewer?.scene.imageryLayers; // 切换为标准图层 if (store.state.common.mapSetting.mode === 0) { const tdtImg_c = imageryLayers?._layers.find(v => v.imageryProvider._layer === 'tdtImg_c'); const tdtZwImg_c = imageryLayers?._layers.find( v => v.imageryProvider._layer === 'tdtZwImg_c' ); viewer?.imageryLayers.remove(tdtImg_c); viewer?.imageryLayers.remove(tdtZwImg_c); } else { const tdtStand_c = imageryLayers?._layers.find( v => v.imageryProvider.credit?.html === 'stand_tc' ); const tdtStand_zj = imageryLayers?._layers.find( v => v.imageryProvider.credit?.html === 'stand_zj' ); viewer?.imageryLayers.remove(tdtStand_c); viewer?.imageryLayers.remove(tdtStand_zj); } loadLAYER(); }; // 生成或删除路网图层 const roadPattern = flag => { if (store.state.common.mapSetting.mode === 0) return; const imageryLayers = viewer?.scene.imageryLayers; const tdtZwImg_c = imageryLayers?._layers.find(v => v.imageryProvider._layer === 'tdtZwImg_c'); if (!flag) { viewer?.imageryLayers.remove(tdtZwImg_c); } else { viewer?.imageryLayers.addImageryProvider(annotation); } }; // 二维三维切换 // 切换为二三维模式 const switchModel = type => { switch (type) { case '2D': viewer?.scene.morphTo2D(0); // viewer?.scene.camera.setView({ // orientation: { // pitch: Cesium.Math.toRadians(-60), // heading: Cesium.Math.toRadians(0), // }, // }); break; case '3D': viewer?.scene.morphTo3D(0); // viewer?.scene.camera.setView({ // orientation: { // pitch: Cesium.Math.toRadians(-90), // heading: Cesium.Math.toRadians(0), // }, // }); break; default: break; } }; /** * @description: 地图暗黑模式切换 * @param {*} viewer 地图实例 * @param {*} options 配置项 * @return {*} */ const darkMap = (viewer, isDark = false, options) => { const defaultOptions = { brightness: 1, contrast: 1, gamma: 1, hue: 0, saturation: 1, }; !isDark && Object.assign(options, defaultOptions); const baseLayer = viewer.imageryLayers.get(0); baseLayer.brightness = options.brightness || 0; baseLayer.contrast = options.contrast || 0; baseLayer.gamma = options.gamma || 2; baseLayer.hue = options.hue || 0; baseLayer.saturation = options.saturation || 0; const baseFragShader = viewer.scene.globe._surfaceShaderSet.baseFragmentShaderSource.sources; for (let i = 0; i < baseFragShader.length; i++) { const strS = 'color = czm_saturation(color, textureSaturation);\n#endif\n'; let strT = 'color = czm_saturation(color, textureSaturation);\n#endif\n'; if (options.invertColor) { strT += ` color.r = 1.0 - color.r; color.g = 1.0 - color.g; color.b = 1.0 - color.b; `; } if (options.filterRGB.length > 0) { strT += ` color.r = color.r * ${options.filterRGB[0]}.0/255.0; color.g = color.g * ${options.filterRGB[1]}.0/255.0; color.b = color.b * ${options.filterRGB[2]}.0/255.0; `; } if (!isDark) { //恢复默认 baseFragShader[i] = baseFragShader[i].replace(strT, strS); } else { // 替换为暗黑模式 baseFragShader[i] = baseFragShader[i].replace(strS, strT); } } }; const switchDarkModel = () => { const isDark = store.state.common.mapSetting.isDark; darkMap(viewer, isDark, { //反色 invertColor: true, //滤色值 [176, 224, 230] filterRGB: [60, 145, 172], }); }; //移除DataSource中所有实体 const removeAllDataSource = () => { viewer?.dataSources.removeAll(); }; // 清除所有标记点 const removeAllPoint = () => { if (viewer) { viewer?.entities?.removeAll(); // viewer?.scene?.primitives?.removeAll(); } }; // 通过点ID删除 const removeById = id => { viewer?.entities.removeById(id); const pointEntity = viewer?.entities.getById(id); if (pointEntity && pointEntity !== undefined) { viewer?.entities.remove(pointEntity); } }; // 通过点ID获取实体 const getEntityById = id => { const pointEntity = viewer?.entities.getById(id); return pointEntity; }; // 添加标记点 const addPoint = pointOption => { if (!pointOption.longitude && !pointOption.latitude) return; const position = Cesium.Cartesian3.fromDegrees( pointOption.longitude, pointOption.latitude, pointOption?.altitude || 0 ); viewer?.entities.add({ position, billboard: pointOption.billboard, point: pointOption.point, label: pointOption.label, id: pointOption.id, }); }; const addPolyline = pointOption => { return viewer?.entities.add({ polyline: pointOption.polyline, id: pointOption.id, }); }; // 更新图片实体位置 function updateEntityPosition(longitude, latitude, id, params) { const entity = getEntityById(id); const position = Cesium.Cartesian3.fromDegrees(longitude, latitude); const heading = Cesium.Math.toRadians(-params.heading); if (Cesium.defined(entity)) { entity.position = position; entity.billboard.rotation = heading; } } // 飞行 flyto const flyTo = (pointOption, time = 4, height = 3000, orientation = {}) => { if (!pointOption.longitude && !pointOption.latitude) return; const destination = Cesium.Cartesian3.fromDegrees( pointOption.longitude, pointOption.latitude, height ); const duration = time; viewer?.camera.flyTo({ destination, duration, orientation, }); }; // 鼠标点击事件 const addLeftClickEvent = (sid, cb, eventKey = 'handler') => { if (handlerEvents.handler) removeLeftClickEvent(); if (handlerEvents[eventKey]) removeLeftClickEvent(eventKey); handlerEvents[eventKey] = new Cesium.ScreenSpaceEventHandler(viewer?.scene.canvas); handlerEvents[eventKey].setInputAction(function (click) { const pick = viewer?.scene.pick(click.position); if (pick && pick.primitive && pick.primitive?.customParams?.type == '3DTileset') { return cb(click, pick, viewer, handlerEvents[eventKey]); } if (pick && pick.id && (pick.id._id === sid || pick.id._id.includes(sid))) { cb(click, pick, viewer, handlerEvents[eventKey]); } if (sid === null) { cb(click, pick, viewer, handlerEvents[eventKey]); } }, Cesium.ScreenSpaceEventType.LEFT_CLICK); }; // 移除鼠标点击事件 const removeLeftClickEvent = (eventKey = 'handler') => { if (handlerEvents[eventKey] == null) return; handlerEvents[eventKey].removeInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK); handlerEvents[eventKey] = null; }; // 鼠标左键按下事件 let leftDownClickHandler = { handler: null }; const addLeftDownClickEvent = (sid, cb, eventKey = 'handler') => { if (leftDownClickHandler.handler) removeLeftDownClickEvent(); if (leftDownClickHandler[eventKey]) removeLeftDownClickEvent(eventKey); leftDownClickHandler[eventKey] = new Cesium.ScreenSpaceEventHandler(viewer?.scene.canvas); leftDownClickHandler[eventKey].setInputAction(function (click) { const pick = viewer?.scene.pick(click.position); cb(click, pick, viewer); }, Cesium.ScreenSpaceEventType.LEFT_DOWN); }; // 移除鼠标左键按下事件 const removeLeftDownClickEvent = (eventKey = 'handler') => { if (leftDownClickHandler[eventKey] == null) return; leftDownClickHandler[eventKey].removeInputAction(Cesium.ScreenSpaceEventType.LEFT_DOWN); leftDownClickHandler[eventKey] = null; }; // 鼠标右击事件 let leftUpClickHandler = { handler: null }; const addLeftUpClickEvent = (sid, cb, eventKey = 'handler') => { if (leftUpClickHandler.handler) removeLeftUpClickEvent(); if (leftUpClickHandler[eventKey]) removeLeftUpClickEvent(eventKey); leftUpClickHandler[eventKey] = new Cesium.ScreenSpaceEventHandler(viewer?.scene.canvas); leftUpClickHandler[eventKey].setInputAction(function (click) { const pick = viewer?.scene.pick(click.position); cb(click, pick, viewer); }, Cesium.ScreenSpaceEventType.LEFT_UP); }; // 移除鼠标右键事件 const removeLeftUpClickEvent = (eventKey = 'handler') => { if (leftUpClickHandler[eventKey] == null) return; leftUpClickHandler[eventKey].removeInputAction(Cesium.ScreenSpaceEventType.LEFT_UP); leftUpClickHandler[eventKey] = null; }; // 鼠标右击事件 let rightClickHandler; const addRightClickEvent = (sid, cb) => { if (rightClickHandler) removeRightClickEvent(); rightClickHandler = new Cesium.ScreenSpaceEventHandler(viewer?.scene.canvas); rightClickHandler.setInputAction(function (click) { const pick = viewer?.scene.pick(click.position); cb(click, pick, viewer); }, Cesium.ScreenSpaceEventType.RIGHT_CLICK); }; // 移除鼠标右键事件 const removeRightClickEvent = () => { if (!rightClickHandler) return; rightClickHandler.removeInputAction(Cesium.ScreenSpaceEventType.RIGHT_CLICK); rightClickHandler = null; }; // 鼠标移动事件 let LeftMounseHandler; const addLeftmounseEvent = (sid, cb) => { if (LeftMounseHandler) removeLeftmounseEvent(); LeftMounseHandler = new Cesium.ScreenSpaceEventHandler(viewer?.scene.canvas); LeftMounseHandler.setInputAction(function (event) { const cartesian3 = viewer?.scene.globe.pick( viewer?.camera.getPickRay(event.startPosition), viewer?.scene ); cb(cartesian3, viewer); }, Cesium.ScreenSpaceEventType.MOUSE_MOVE); }; // 移除鼠标移动事件 const removeLeftmounseEvent = () => { if (LeftMounseHandler == null) return; LeftMounseHandler.removeInputAction(Cesium.ScreenSpaceEventType.MOUSE_MOVE); LeftMounseHandler = null; }; let MounseHandler; const addMounseHandler = (sid, cb) => { if (MounseHandler == null) removeMounseEvent(); MounseHandler = new Cesium.ScreenSpaceEventHandler(viewer?.scene.canvas); MounseHandler.setInputAction(function (movement) { let mouseInfo = _getMouseInfo(movement.endPosition); cb(mouseInfo, viewer); }, Cesium.ScreenSpaceEventType.MOUSE_MOVE); }; const _getMouseInfo = position => { let scene = viewer.scene; let target = scene.pick(position); let cartesian = undefined; let surfaceCartesian = undefined; let wgs84Position = undefined; let wgs84SurfacePosition = undefined; if (scene.pickPositionSupported) { cartesian = scene.pickPosition(position); } if (cartesian) { let c = Cesium.Ellipsoid.WGS84.cartesianToCartographic(cartesian); if (c) { wgs84Position = { lng: Cesium.Math.toDegrees(c.longitude), lat: Cesium.Math.toDegrees(c.latitude), alt: c.height, }; } } if ( scene.mode === Cesium.SceneMode.SCENE3D && !(viewer.terrainProvider instanceof Cesium.EllipsoidTerrainProvider) ) { let ray = scene.camera.getPickRay(position); surfaceCartesian = scene.globe.pick(ray, scene); } else { surfaceCartesian = scene.camera.pickEllipsoid(position, Cesium.Ellipsoid.WGS84); } if (surfaceCartesian) { let c = Cesium.Ellipsoid.WGS84.cartesianToCartographic(surfaceCartesian); if (c) { wgs84SurfacePosition = { lng: Cesium.Math.toDegrees(c.longitude), lat: Cesium.Math.toDegrees(c.latitude), alt: c.height, }; } } return { target: target, windowPosition: position, position: cartesian, wgs84Position: wgs84Position, surfacePosition: surfaceCartesian, wgs84SurfacePosition: wgs84SurfacePosition, }; }; // 移除鼠标移动事件 const removeMounseEvent = () => { if (MounseHandler == null) return; MounseHandler.removeInputAction(Cesium.ScreenSpaceEventType.MOUSE_MOVE); MounseHandler = null; }; // 视角变化时间 let mapViewHandler = null; const addCameraMoveEvent = cb => { if (mapViewHandler) removeCameraMoveEvent(); mapViewHandler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas); mapViewHandler.setInputAction(event => { cb(event); }, Cesium.ScreenSpaceEventType.WHEEL); }; const removeCameraMoveEvent = () => { if (mapViewHandler == null) return; mapViewHandler.removeInputAction(Cesium.ScreenSpaceEventType.WHEEL); mapViewHandler = null; }; // 添加entity const addCustomEntityDataSource = (sourceName, entities) => { if (!customEntityDataSources[sourceName]) { customEntityDataSources[sourceName] = new Cesium.CustomDataSource(); window.$viewer?.dataSources.add(customEntityDataSources[sourceName]); } let entity = customEntityDataSources[sourceName].entities.add(entities); return entity; }; const clearCustomEntityDataSource = sourceName => { if (customEntityDataSources[sourceName]) { customEntityDataSources[sourceName]?.entities.removeAll(); } }; const removeAllCustomEntityDataSource = sourceName => { if (customEntityDataSources[sourceName]) { customEntityDataSources[sourceName]?.entities.removeAll(); window.$viewer.dataSources.remove(customEntityDataSources[sourceName]); delete customEntityDataSources[sourceName]; } }; // 添加entity const addCustomImageryProviderDataSource = imageryLayers => { return viewer?.imageryLayers.addImageryProvider(imageryLayers); }; const showCustomImageryProviderDataSource = (imageryLayers, show) => { if (imageryLayers) { imageryLayers.show = show; } }; const removeAllCustomImageryProviderDataSource = imageryLayers => { if (imageryLayers) { viewer?.imageryLayers.remove(imageryLayers); } }; // 添加范围的圆 const addEllipse = ({ longitude, latitude, dist = 7000 }) => { if (!longitude && !latitude) return; // 定义起点位置 const position = Cesium.Cartesian3.fromDegrees(longitude, latitude); // 画圆 viewer?.entities.add({ position, id: 'rangeEllipse', name: 'rangeEllipse', ellipse: { semiMinorAxis: dist, semiMajorAxis: dist, outline: true, material: Cesium.Color.CORNFLOWERBLUE.withAlpha(0.3), }, }); // 添加距离虚线 // addDistLine({ longitude, latitude, dist }); }; const addDistLine = ({ longitude, latitude, dist = 7 }) => { // 定义起点位置 const startPosition = Cesium.Cartesian3.fromDegrees(longitude, latitude); // 计算目标位置(7公里处) const offsetCartesian = Cesium.Cartesian3.fromDegrees( longitude, latitude + Cesium.Math.toDegrees( dist / (Cesium.Ellipsoid.WGS84.maximumRadius * Math.cos(Cesium.Math.toRadians(latitude))) ) // 7公里的偏移 ); // 将目标位置转换为经纬度 // const offsetCartographic = Cesium.Cartographic.fromCartesian(offsetCartesian); // const offsetLongitude = Cesium.Math.toDegrees(offsetCartographic.longitude); // const offsetLatitude = Cesium.Math.toDegrees(offsetCartographic.latitude); addPolyline({ id: 'dist_line', polyline: { width: 5, positions: [startPosition, offsetCartesian], material: new Cesium.PolylineGlowMaterialProperty({ glowPower: 0.2, taperPower: 0.5, color: Cesium.Color.CORNFLOWERBLUE, }), }, }); }; // 添加圆 const addCircle = option => { if (!option.longitude && !option.latitude) return; // 定义起点位置 const { longitude, latitude } = option; const position = Cesium.Cartesian3.fromDegrees(longitude, latitude); viewer.entities.add({ position, id: option.id, ellipse: { semiMinorAxis: option.radius, semiMajorAxis: option.radius, height: option.height || 120, material: Cesium.Color.fromCssColorString(option.color).withAlpha(0.1), outline: true, outlineColor: Cesium.Color.fromCssColorString(option.color), outlineWidth: 3, }, }); }; // /** * @description: 添加矩形 * @param {*} option { id: string, color: string, positions: array[ lng,lat,height ] } * @return {*} void 0 */ const addPolygon = option => { if (option.positions.length === 0) return; let zIndex = {}; if (option.zIndex) { zIndex = { zIndex: option.zIndex, }; } // 定义起点位置 viewer.entities.add({ id: option.id, polygon: { hierarchy: Cesium.Cartesian3.fromDegreesArrayHeights(option.positions), material: Cesium.Color.fromCssColorString(option.color).withAlpha(0.1), extrudedHeight: 0, outline: true, outlineColor: Cesium.Color.fromCssColorString(option.color), outlineWidth: 3, }, ...zIndex, }); }; // Cesium矢量切片是否加载完成 const isLoadingCompleted = () => { return new Promise((resolve, reject) => { const helper = new Cesium.EventHelper(); helper.add(viewer?.scene.globe.tileLoadProgressEvent, function (e) { if (e === 0) { resolve(true); } }); }); }; // 获取屏幕四个角经纬度 const getScreenCorner = () => { const camera = viewer.scene.camera; const canvas = viewer.canvas; // 获取屏幕左下角和右上角的世界坐标 const leftBottom = new Cesium.Cartesian2(0, canvas.clientHeight); const rightTop = new Cesium.Cartesian2(canvas.clientWidth, 0); // 将屏幕坐标转为世界坐标 const leftBottomWorld = camera.pickEllipsoid(leftBottom, viewer.scene.globe.ellipsoid); const rightTopWorld = camera.pickEllipsoid(rightTop, viewer.scene.globe.ellipsoid); // 将世界坐标转为经纬度 const leftBottomCartographic = viewer.scene.globe.ellipsoid.cartesianToCartographic(leftBottomWorld); const rightTopCartographic = viewer.scene.globe.ellipsoid.cartesianToCartographic(rightTopWorld); // 获取经纬度 const leftBottomLonLat = [ Cesium.Math.toDegrees(leftBottomCartographic.longitude), Cesium.Math.toDegrees(leftBottomCartographic.latitude), ]; const rightTopLonLat = [ Cesium.Math.toDegrees(rightTopCartographic.longitude), Cesium.Math.toDegrees(rightTopCartographic.latitude), ]; // 返回四个角的经纬度 return { lb: leftBottomLonLat, rb: [rightTopLonLat[0], leftBottomLonLat[1]], // 右下角 rt: rightTopLonLat, lt: [leftBottomLonLat[0], rightTopLonLat[1]], // 左上角 }; }; // 加载3D建筑模型 let tileset = null; function setBuilding3dModel() { try { const resource = Cesium.IonResource.fromAssetId(96188); tileset = new Cesium.Cesium3DTileset({ url: resource, }); tileset.customParams = { type: '3DTileset', }; viewer.scene.primitives.add(tileset); } catch (error) { console.log(`Error loading tileset: ${error}`); } } function removeBuilding3dModel() { if (tileset) { viewer.scene.primitives.remove(tileset); } } const viewerDestory = () => { viewer && viewer.destroy(); viewer = null; window.$viewer = null }; let tilesetArr = []; const add3Dtileset = () => { let url = '/3Dtile/kjds/tileset.json'; let tileset = new Cesium.Cesium3DTileset({ url: url, }); tileset.customParams = { type: '3DTileset', }; tilesetArr.push(tileset); tilesetArr.forEach(i => viewer?.scene.primitives.add(i)); }; const remove3Dtileset = () => { if (tilesetArr.length > 0) { tilesetArr.forEach(i => viewer.scene.primitives.remove(i)); } tilesetArr = []; }; let pointEditHandler; // 航点航线编辑相关事件 const pointInitEvent = (lefet_down, mouse_move, left_up) => { if (!pointEditHandler) { pointEditHandler = new Cesium.ScreenSpaceEventHandler(viewer?.scene.canvas); } const events = { lefet_down, mouse_move, left_up, }; pointEditBindEvent(events); pointEditBindEvent(events, Cesium.KeyboardEventModifier.CTRL); pointEditBindEvent(events, Cesium.KeyboardEventModifier.ALT); pointEditBindEvent(events, Cesium.KeyboardEventModifier.SHIFT); pointEditBindEvent(events, Cesium.KeyboardEventModifier.META); }; const pointEditBindEvent = (events, e) => { if (pointEditHandler) { pointEditHandler.setInputAction( events.lefet_down(e), Cesium.ScreenSpaceEventType.LEFT_DOWN, e ); pointEditHandler.setInputAction( events.mouse_move(e), Cesium.ScreenSpaceEventType.MOUSE_MOVE, e ); pointEditHandler.setInputAction(events.left_up(e), Cesium.ScreenSpaceEventType.LEFT_UP, e); } }; const pointUnInitEvent = () => { pointEditUnBindEvent(); pointEditUnBindEvent(Cesium.KeyboardEventModifier.CTRL); pointEditUnBindEvent(Cesium.KeyboardEventModifier.ALT); pointEditUnBindEvent(Cesium.KeyboardEventModifier.SHIFT); pointEditUnBindEvent(Cesium.KeyboardEventModifier.META); pointEditHandler = null; }; const pointEditUnBindEvent = e => { pointEditHandler?.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_DOWN, e); pointEditHandler?.removeInputAction(Cesium.ScreenSpaceEventType.MOUSE_MOVE, e); pointEditHandler?.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_UP, e); }; return { _init, patternMap, loadLAYER, roadPattern, switchModel, switchDarkModel, removeAllDataSource, removeAllPoint, removeById, getEntityById, addPoint, addPolyline, updateEntityPosition, flyTo, addLeftClickEvent, removeLeftClickEvent, addRightClickEvent, removeRightClickEvent, addLeftmounseEvent, removeLeftmounseEvent, addLeftUpClickEvent, removeLeftUpClickEvent, addLeftDownClickEvent, removeLeftDownClickEvent, addMounseHandler, removeMounseEvent, addCameraMoveEvent, removeCameraMoveEvent, addCircle, addPolygon, addEllipse, isLoadingCompleted, getScreenCorner, setBuilding3dModel, removeBuilding3dModel, viewerDestory, globalCesium: window.globalCesium || Cesium, addCustomEntityDataSource, clearCustomEntityDataSource, removeAllCustomEntityDataSource, _getMouseInfo, addCustomImageryProviderDataSource, showCustomImageryProviderDataSource, removeAllCustomImageryProviderDataSource, addCustomLayers, removeCustomLayers, add3Dtileset, remove3Dtileset, // 航线规划---航点航线 pointInitEvent, pointUnInitEvent, }; }