| | |
| | | import * as Cesium from 'cesium' |
| | | import { Cartesian3, Terrain, Viewer } from 'cesium' |
| | | import store from '@/store/index' |
| | | import jaGeojsonRaw from '@/assets/geojson/ja.geojson?raw' |
| | | |
| | | import getBaseConfig from '@/buildConfig/config' |
| | | |
| | |
| | | /** |
| | | * 公共的Cesium (蓝色,2d) |
| | | */ |
| | | |
| | | const DEFAULT_VIEW_RECTANGLE = (() => { |
| | | try { |
| | | const geojson = JSON.parse(jaGeojsonRaw) |
| | | let west = Infinity |
| | | let east = -Infinity |
| | | let south = Infinity |
| | | let north = -Infinity |
| | | const walk = coords => { |
| | | if (!Array.isArray(coords)) return |
| | | if (typeof coords[0] === 'number' && typeof coords[1] === 'number') { |
| | | const lng = coords[0] |
| | | const lat = coords[1] |
| | | if (!Number.isFinite(lng) || !Number.isFinite(lat)) return |
| | | west = Math.min(west, lng) |
| | | east = Math.max(east, lng) |
| | | south = Math.min(south, lat) |
| | | north = Math.max(north, lat) |
| | | return |
| | | } |
| | | coords.forEach(walk) |
| | | } |
| | | geojson?.features?.forEach(feature => walk(feature?.geometry?.coordinates)) |
| | | if ([west, east, south, north].every(Number.isFinite)) { |
| | | return Cesium.Rectangle.fromDegrees(west, south, east, north) |
| | | } |
| | | } catch (error) {} |
| | | return Cesium.Rectangle.fromDegrees(66, 4, 135, 53.55) |
| | | })() |
| | | |
| | | |
| | | // 封装的不用管 |
| | | let cn = { |
| | |
| | | this.handlerRightEvents = { handler: null } |
| | | this.handlerMouseMoveEvents = { handler: null } |
| | | this.viewer = null |
| | | this.terrainProvider = null |
| | | this.terrainLoading = null |
| | | this.terrainEnabled = false |
| | | this.globalBaseMapLayers = [] |
| | | this.boundary = null |
| | | this.init(options) |
| | |
| | | dockOptions = {}, |
| | | boundaryChange, |
| | | terrainLoadCallback, |
| | | boundaryColor = '#7FFFD4', |
| | | boundaryColor = '#00F9EC', |
| | | dockRangeType = 1, |
| | | useDockHeight = false |
| | | } = options |
| | | Cesium.Camera.DEFAULT_VIEW_FACTOR = -0.45 |
| | | // 西南东北,默认显示中国 |
| | | Cesium.Camera.DEFAULT_VIEW_RECTANGLE = Cesium.Rectangle.fromDegrees(66, 4, 135, 53.55) |
| | | Cesium.Camera.DEFAULT_VIEW_RECTANGLE = DEFAULT_VIEW_RECTANGLE |
| | | const viewerOptions = { |
| | | infoBox: false, // 禁用沙箱,解决控制台报错 |
| | | animation: false, // 左下角的动画仪表盘 |
| | |
| | | |
| | | this.viewer?.cesiumWidget.screenSpaceEventHandler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK) // 禁用双击 |
| | | |
| | | if (terrain) { |
| | | try { |
| | | const noTerrainMechanism = ['1962779164650135554'] |
| | | if (noTerrainMechanism.includes(store.state.user.userInfo?.deptId)) { |
| | | // 使用Cesium World Terrain |
| | | Cesium.createWorldTerrainAsync({ |
| | | requestWaterMask: false, // 请求水域效果 |
| | | requestVertexNormals: true // 请求光照和地形法线 |
| | | }).then(terrainProvider => { |
| | | this.viewer.terrainProvider = terrainProvider |
| | | terrainLoadCallback?.() |
| | | }) |
| | | } else { |
| | | /*// 正则:第一位非0,第二位任意数字,后10位都是0 |
| | | const re = /^[1-9]\d0{10}$/ |
| | | |
| | | let result = null |
| | | |
| | | // 1️⃣先判断 areaCode |
| | | if (re.test(store.state.user.userInfo.detail.areaCode)) { |
| | | result = store.state.user.userInfo.detail.areaCode.slice(0, 6) |
| | | } else { |
| | | // 2️⃣如果不满足,从 ancestors 里找 |
| | | const matchedItems = store.state.user.userInfo.detail.ancestors |
| | | .split(',') |
| | | .filter(item => re.test(item)) // 过滤出符合条件的 |
| | | |
| | | // 取第一个符合条件的前6位(可以改成 last one 看需求) |
| | | if (matchedItems.length > 0) { |
| | | result = matchedItems[0].slice(0, 6) |
| | | } |
| | | } |
| | | |
| | | // 使用公司地形 |
| | | Cesium.CesiumTerrainProvider.fromUrl(`${import.meta.env.VITE_APP_TERRAIN_URL}${result}`, { |
| | | requestVertexNormals: true, // 启用地形法线增强立体感 |
| | | requestWaterMask: true, // 启用水体遮罩效果 |
| | | }).then(terrainProvider => { |
| | | this.viewer.terrainProvider = terrainProvider |
| | | terrainLoadCallback?.() |
| | | })*/ |
| | | } |
| | | } catch (error) { |
| | | console.error('地形加载失败:', error) |
| | | } |
| | | } |
| | | this.setTerrainVisible(terrain, terrainLoadCallback) |
| | | |
| | | this.viewer.scene.screenSpaceCameraController.maximumZoomDistance = 4500000 |
| | | this.switchLayers(layerMode) |
| | |
| | | return this.viewer |
| | | } |
| | | |
| | | async ensureTerrainProvider () { |
| | | if (this.terrainProvider) return this.terrainProvider |
| | | if (this.terrainLoading) return this.terrainLoading |
| | | this.terrainLoading = Cesium.CesiumTerrainProvider.fromUrl( |
| | | `${import.meta.env.VITE_APP_TERRAIN_URL}ja_terrain`, |
| | | { |
| | | requestVertexNormals: true, // 启用地形法线增强立体感 |
| | | requestWaterMask: true, // 启用水体遮罩效果 |
| | | } |
| | | ).then(provider => { |
| | | this.terrainProvider = provider |
| | | return provider |
| | | }) |
| | | return this.terrainLoading |
| | | } |
| | | |
| | | async setTerrainVisible (visible, terrainLoadCallback) { |
| | | if (!this.viewer) return |
| | | if (!visible) { |
| | | this.viewer.terrainProvider = new Cesium.EllipsoidTerrainProvider() |
| | | this.terrainEnabled = false |
| | | return |
| | | } |
| | | try { |
| | | const provider = await this.ensureTerrainProvider() |
| | | if (!this.viewer) return |
| | | this.viewer.terrainProvider = provider |
| | | this.terrainEnabled = true |
| | | terrainLoadCallback?.() |
| | | } catch (error) { |
| | | this.terrainEnabled = false |
| | | } |
| | | } |
| | | |
| | | // 销毁viewer |
| | | viewerDestroy (removeDom = true) { |
| | | if (!this.viewer) return |