huweili-cesium 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +88 -0
- package/api/gaode.js +16 -0
- package/basis.js +335 -0
- package/cardPool.js +315 -0
- package/clickHandler.js +298 -0
- package/config/hooks.js +21 -0
- package/config/index.js +15 -0
- package/customToolbarButtons.js +160 -0
- package/drawFence.js +336 -0
- package/drawFenceNew.js +1454 -0
- package/droneRipple.js +198 -0
- package/geometry.js +300 -0
- package/groundLink.js +192 -0
- package/hemisphere.js +310 -0
- package/index.js +51 -0
- package/labelDiv.js +427 -0
- package/movePath.js +96 -0
- package/movePoint.js +517 -0
- package/package.json +99 -0
- package/qrCodeGenerator.js +369 -0
- package/setPath.js +126 -0
- package/setPoint.js +356 -0
- package/stores/mapStore.js +375 -0
- package/tileProviders.js +141 -0
- package/toolbar/basemapSwitcher.js +360 -0
- package/toolbar/compass.js +84 -0
- package/toolbar/fullscreenController.js +94 -0
- package/toolbar/zoomController.js +164 -0
- package/utils/droneSelection.js +136 -0
- package/utils/eventBus.js +6 -0
- package/utils/getMapCenterPosition.js +32 -0
- package/utils/useEventBus.js +52 -0
package/README.md
ADDED
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
# huweili-cesium
|
|
2
|
+
|
|
3
|
+
基于 Cesium 的地图工具库,从 `tzr` 项目 `src/components/cesiumMap/js` 提取,包含 **21 个** 核心 JS 模块(含 `toolbar` 子目录 4 个文件)。
|
|
4
|
+
|
|
5
|
+
## 安装
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install huweili-cesium
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
### 对等依赖(需在项目中已安装)
|
|
12
|
+
|
|
13
|
+
- `cesium`
|
|
14
|
+
- `vue` ^3.3
|
|
15
|
+
- `pinia` ^2 或 ^3
|
|
16
|
+
- `mitt` ^3
|
|
17
|
+
- `qrcode` ^1.5
|
|
18
|
+
|
|
19
|
+
## 使用前准备
|
|
20
|
+
|
|
21
|
+
1. 在 HTML 中加载与宿主项目一致的 `constants.js`(定义 `window.DroneStatus`、`window.MapInstanceIds` 等),或自行赋值这些全局变量。
|
|
22
|
+
2. 在 Vue 应用中 `app.use(pinia)`,地图组件初始化后调用各 `*Config()` 工厂函数。
|
|
23
|
+
|
|
24
|
+
## 引入示例
|
|
25
|
+
|
|
26
|
+
```js
|
|
27
|
+
// 统一入口
|
|
28
|
+
import { basicConfig, setPoint, movePointConfig } from 'huweili-cesium'
|
|
29
|
+
|
|
30
|
+
// 或按文件引入
|
|
31
|
+
import { basicConfig } from 'huweili-cesium/basis'
|
|
32
|
+
import { hemisphereConfig } from 'huweili-cesium/hemisphere'
|
|
33
|
+
import { createCustomToolbarButtons } from 'huweili-cesium/customToolbarButtons'
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## 可选业务钩子
|
|
37
|
+
|
|
38
|
+
若需光电引导、轨迹列表等业务能力,在应用启动时注入:
|
|
39
|
+
|
|
40
|
+
```js
|
|
41
|
+
import { setDroneMapProvider, setOptGuideHandler } from 'huweili-cesium/config/hooks'
|
|
42
|
+
|
|
43
|
+
setDroneMapProvider(() => myDroneMap)
|
|
44
|
+
setOptGuideHandler((payload) => api.toOptGuide(payload))
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
## 发布到 npm(维护者)
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
cd huweili-cesium
|
|
51
|
+
npm login
|
|
52
|
+
npm publish
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
首次发布前可在本地打包预览:
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
npm pack
|
|
59
|
+
# 会生成 huweili-cesium-1.0.0.tgz,解压检查是否包含全部 js
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
## 从 tzr 源目录同步更新
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
cd huweili-cesium
|
|
66
|
+
npm run sync
|
|
67
|
+
# 同步后需重新修复 @/ 别名为包内相对路径(见 scripts)
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
## 包含的文件清单
|
|
71
|
+
|
|
72
|
+
| 文件 | 说明 |
|
|
73
|
+
|------|------|
|
|
74
|
+
| basis.js | 地图基础操作 |
|
|
75
|
+
| setPoint.js / movePoint.js | 点位与移动 |
|
|
76
|
+
| setPath.js / movePath.js | 路径与轨迹 |
|
|
77
|
+
| groundLink.js | 地面连接线 |
|
|
78
|
+
| hemisphere.js | 半球区域 |
|
|
79
|
+
| geometry.js | 几何图形 |
|
|
80
|
+
| drawFence.js / drawFenceNew.js | 电子围栏 |
|
|
81
|
+
| cardPool.js / labelDiv.js | 信息牌 |
|
|
82
|
+
| clickHandler.js | 点击交互 |
|
|
83
|
+
| tileProviders.js | 底图瓦片 |
|
|
84
|
+
| customToolbarButtons.js | 工具栏 |
|
|
85
|
+
| toolbar/* | 指南针、底图切换、缩放、全屏 |
|
|
86
|
+
| droneRipple.js / qrCodeGenerator.js | 涟漪、二维码 |
|
|
87
|
+
|
|
88
|
+
另含 `stores/mapStore.js`、`utils/*`、`config/*` 等运行依赖。
|
package/api/gaode.js
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 逆地理编码(可选)
|
|
3
|
+
* 宿主项目可覆盖:import { setGeocodeProvider } from 'huweili-cesium/api/gaode'
|
|
4
|
+
*/
|
|
5
|
+
let geocodeProvider = null
|
|
6
|
+
|
|
7
|
+
export function setGeocodeProvider(fn) {
|
|
8
|
+
geocodeProvider = fn
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export function getAddressByLocation(lng, lat) {
|
|
12
|
+
if (geocodeProvider) {
|
|
13
|
+
return geocodeProvider(lng, lat)
|
|
14
|
+
}
|
|
15
|
+
return Promise.resolve('')
|
|
16
|
+
}
|
package/basis.js
ADDED
|
@@ -0,0 +1,335 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 地图基本操作模块
|
|
3
|
+
*
|
|
4
|
+
* 提供在Cesium地图上基本操作的功能,如设置地图中心点、添加鼠标事件控制器等
|
|
5
|
+
* 支持在地图上添加鼠标事件控制器,如点击、拖动、缩放等
|
|
6
|
+
*
|
|
7
|
+
* @author huweili
|
|
8
|
+
* @email czxyhuweili@163.com
|
|
9
|
+
* @version 1.0.0
|
|
10
|
+
*/
|
|
11
|
+
import * as Cesium from 'cesium'
|
|
12
|
+
import { useMapStore } from '../stores/mapStore.js'
|
|
13
|
+
|
|
14
|
+
export function basicConfig() {
|
|
15
|
+
|
|
16
|
+
// 获取地图store实例
|
|
17
|
+
const mapStore = useMapStore()
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* 检查坐标是否在中国境内
|
|
21
|
+
* @param {*} longitude - 经度
|
|
22
|
+
* @param {*} latitude - 纬度
|
|
23
|
+
* @returns - 是否在中国境内
|
|
24
|
+
*/
|
|
25
|
+
const isInChina = (longitude, latitude) => {
|
|
26
|
+
// 中国大致经纬度范围
|
|
27
|
+
// 经度: 73°33′E 至 135°05′E
|
|
28
|
+
// 纬度: 3°51′N 至 53°33′N
|
|
29
|
+
return longitude >= 73.55 && longitude <= 135.08 && latitude >= 3.85 && latitude <= 53.55
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* 设置Cesium地图时间为当前北京时间
|
|
34
|
+
* @param mapId - 地图实例ID,可选,不传则使用当前实例
|
|
35
|
+
*/
|
|
36
|
+
const setBeiJingTime = (mapId) => {
|
|
37
|
+
const map = mapStore.getMap(mapId)
|
|
38
|
+
if (!map) return
|
|
39
|
+
// 强制设置时间为当前北京时间
|
|
40
|
+
const now = new Date()
|
|
41
|
+
const chinaTime = new Date(now.getTime() + 8 * 60 * 60 * 1000)
|
|
42
|
+
map.clock.currentTime = Cesium.JulianDate.fromDate(chinaTime)
|
|
43
|
+
// 如果你不想动画效果,可以暂停时钟
|
|
44
|
+
map.clock.shouldAnimate = true
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* 鼠标事件控制器
|
|
49
|
+
*
|
|
50
|
+
* 处理地图上的鼠标事件,包括点击、拖动、缩放等、
|
|
51
|
+
* @param map - 地图实例
|
|
52
|
+
*/
|
|
53
|
+
const mouseController = (map) => {
|
|
54
|
+
// 添加右键点击事件监听
|
|
55
|
+
map.screenSpaceEventHandler.setInputAction((click) => {
|
|
56
|
+
// 获取点击位置的笛卡尔坐标
|
|
57
|
+
const cartesian = map.camera.pickEllipsoid(click.position, map.scene.globe.ellipsoid);
|
|
58
|
+
|
|
59
|
+
if (cartesian) {
|
|
60
|
+
// 转换为经纬度
|
|
61
|
+
const cartographic = Cesium.Cartographic.fromCartesian(cartesian);
|
|
62
|
+
const lng = Cesium.Math.toDegrees(cartographic.longitude);
|
|
63
|
+
const lat = Cesium.Math.toDegrees(cartographic.latitude);
|
|
64
|
+
const height = cartographic.height;
|
|
65
|
+
|
|
66
|
+
console.log('点击位置:', {
|
|
67
|
+
lng: Number(lng),
|
|
68
|
+
lat: Number(lat),
|
|
69
|
+
height: Number(height)
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
// 弹出alert显示坐标信息
|
|
73
|
+
// alert(`点击位置坐标:\n经度:${Number(lng).toFixed(6)}\n纬度:${Number(lat).toFixed(6)}\n高度:${Number(height).toFixed(2)}米`);
|
|
74
|
+
}
|
|
75
|
+
}, Cesium.ScreenSpaceEventType.RIGHT_CLICK);
|
|
76
|
+
|
|
77
|
+
// 添加左键点击事件,用于隐藏弹窗
|
|
78
|
+
map.screenSpaceEventHandler.setInputAction(() => {
|
|
79
|
+
console.log('左键点击事件触发')
|
|
80
|
+
}, Cesium.ScreenSpaceEventType.LEFT_CLICK);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* 设置地图中心点
|
|
85
|
+
*
|
|
86
|
+
* @param options - 包含地图中心点经纬度和高度的对象
|
|
87
|
+
* @param options.lng - 地图中心点经度
|
|
88
|
+
* @param options.lat - 地图中心点纬度
|
|
89
|
+
* @param options.alt - 可选,镜头高度/相机距离,默认 10000
|
|
90
|
+
* @param options.targetAlt - 可选,看向目标点的高度,例如飞机高度,默认 0
|
|
91
|
+
* @param options.map - 地图实例,可选,默认从store中获取
|
|
92
|
+
* @param options.mapId - 地图实例ID,可选,不传则使用当前实例
|
|
93
|
+
*/
|
|
94
|
+
const setCesiumCenter = (options) => {
|
|
95
|
+
const { lng, lat, alt: altitude, targetAlt, map: mapInstance, mapId } = options
|
|
96
|
+
|
|
97
|
+
const map = mapInstance || mapStore.getMap(mapId)
|
|
98
|
+
if (!map) {
|
|
99
|
+
console.error('地图实例不存在')
|
|
100
|
+
return null
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
const centerInfo = mapStore.getMapInfo('center', mapId) || {}
|
|
104
|
+
// 优先级:传入的 altitude > 配置文件中的 centerInfo.alt > 默认值 10000
|
|
105
|
+
const finalAltitude = altitude !== undefined ? altitude : (centerInfo.alt || 10000)
|
|
106
|
+
// targetAlt 是看向目标点的高度,例如飞机高度;不要和视角高度 alt 混用
|
|
107
|
+
const finalTargetAlt = targetAlt !== undefined ? targetAlt : (centerInfo.targetAlt || 0)
|
|
108
|
+
|
|
109
|
+
// 检查当前是正交投影(2D)还是透视投影(3D)
|
|
110
|
+
const isOrthographic = map.camera.frustum instanceof Cesium.OrthographicFrustum
|
|
111
|
+
|
|
112
|
+
if (isOrthographic) {
|
|
113
|
+
// 2D 俯视视角
|
|
114
|
+
set2DView(map, lng, lat, finalAltitude)
|
|
115
|
+
} else {
|
|
116
|
+
// 3D 斜视视角
|
|
117
|
+
set3DView(map, lng, lat, centerInfo, finalAltitude, finalTargetAlt)
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
/******************************************************2、3维视角切换**************************************************************************** */
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* 获取当前RTK经纬度
|
|
127
|
+
* @param {string=} mapId 地图实例ID
|
|
128
|
+
* @returns {{lng: number, lat: number}|null}
|
|
129
|
+
*/
|
|
130
|
+
const getCurrentRtkPosition = (mapId) => {
|
|
131
|
+
const rtkData = mapStore.getRtkData(mapId)
|
|
132
|
+
const lng = Number(rtkData?.longitude)
|
|
133
|
+
const lat = Number(rtkData?.latitude)
|
|
134
|
+
|
|
135
|
+
if (!Number.isFinite(lng) || !Number.isFinite(lat)) {
|
|
136
|
+
return null
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
return { lng, lat }
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* 恢复 3D 透视投影
|
|
144
|
+
* @param {object} map Cesium 地图实例
|
|
145
|
+
*/
|
|
146
|
+
const restorePerspectiveFrustum = (map) => {
|
|
147
|
+
if (!map) return
|
|
148
|
+
|
|
149
|
+
const currentFrustum = map.camera.frustum
|
|
150
|
+
const perspectiveFrustum = new Cesium.PerspectiveFrustum()
|
|
151
|
+
perspectiveFrustum.fov = Cesium.Math.toRadians(60)
|
|
152
|
+
perspectiveFrustum.aspectRatio = map.canvas.clientWidth / map.canvas.clientHeight
|
|
153
|
+
perspectiveFrustum.near = currentFrustum.near || 1.0
|
|
154
|
+
perspectiveFrustum.far = currentFrustum.far || 10000000.0
|
|
155
|
+
map.camera.frustum = perspectiveFrustum
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* 设置 2D 俯视用的正交投影
|
|
160
|
+
* @param {object} map Cesium 地图实例
|
|
161
|
+
*/
|
|
162
|
+
const applyOrthographicFrustum = (map) => {
|
|
163
|
+
if (!map) return
|
|
164
|
+
|
|
165
|
+
const canvas = map.canvas
|
|
166
|
+
const frustum = new Cesium.OrthographicFrustum()
|
|
167
|
+
const width = canvas.clientWidth
|
|
168
|
+
const height = canvas.clientHeight
|
|
169
|
+
|
|
170
|
+
// 检查当前是否是透视投影,只有透视投影才有 fovy
|
|
171
|
+
let widthValue
|
|
172
|
+
if (map.scene.camera.frustum instanceof Cesium.PerspectiveFrustum) {
|
|
173
|
+
widthValue = width * map.scene.camera.frustum.fovy * map.scene.camera.positionCartographic.height / 1000
|
|
174
|
+
} else {
|
|
175
|
+
// 如果已经是正交投影,保留当前宽度或使用默认值
|
|
176
|
+
widthValue = map.scene.camera.frustum.width || 20000
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
frustum.width = widthValue
|
|
180
|
+
frustum.aspectRatio = width / height
|
|
181
|
+
frustum.near = 0.1
|
|
182
|
+
frustum.far = 10000000.0
|
|
183
|
+
map.scene.camera.frustum = frustum
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
/**
|
|
187
|
+
* 设置并锁定2D俯视视角(禁止通过中键拖动进入3D姿态)
|
|
188
|
+
* @param {object} map Cesium 地图实例
|
|
189
|
+
* @param {number} lng 经度
|
|
190
|
+
* @param {number} lat 纬度
|
|
191
|
+
* @param {number=} height 相机高度
|
|
192
|
+
*/
|
|
193
|
+
const set2DView = (map, lng, lat, height = 10000) => {
|
|
194
|
+
if (!map) return
|
|
195
|
+
applyOrthographicFrustum(map)
|
|
196
|
+
const cameraController = map.scene?.screenSpaceCameraController
|
|
197
|
+
if (cameraController) {
|
|
198
|
+
cameraController.enableTilt = false
|
|
199
|
+
cameraController.enableLook = false
|
|
200
|
+
}
|
|
201
|
+
map.camera.setView({
|
|
202
|
+
destination: Cesium.Cartesian3.fromDegrees(lng, lat, height),
|
|
203
|
+
orientation: {
|
|
204
|
+
heading: Cesium.Math.toRadians(0),
|
|
205
|
+
pitch: Cesium.Math.toRadians(-90),
|
|
206
|
+
roll: Cesium.Math.toRadians(0)
|
|
207
|
+
}
|
|
208
|
+
})
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
/**
|
|
212
|
+
* 设置3D斜视视角(恢复透视投影,让相机看向指定目标点)
|
|
213
|
+
*
|
|
214
|
+
* 简单理解:就像你站在高楼上看地面上的目标
|
|
215
|
+
* - 你站的位置高度 = altitude
|
|
216
|
+
* - 你看向的目标点 = (lng, lat, targetAlt)
|
|
217
|
+
* - 你的视线角度 = heading(朝向) + pitch(俯仰)
|
|
218
|
+
*
|
|
219
|
+
* @param {object} map Cesium 地图实例(必须传)
|
|
220
|
+
* @param {number} lng 目标点的经度(比如无人机所在位置)
|
|
221
|
+
* @param {number} lat 目标点的纬度
|
|
222
|
+
* @param {Object=} centerInfo 视角配置(可选)
|
|
223
|
+
* @param {number} [centerInfo.heading=0] 水平朝向角度(0=正北,90=正东)
|
|
224
|
+
* @param {number} [centerInfo.pitch=-35] 俯仰角度(负数=向下看,-90=正俯视)
|
|
225
|
+
* @param {number=} altitude 相机高度(单位:米,默认10000米)
|
|
226
|
+
* @param {number=} targetAlt 目标点的高度(比如无人机的飞行高度,默认0)
|
|
227
|
+
*/
|
|
228
|
+
const set3DView = (map, lng, lat, centerInfo = {}, altitude = 10000, targetAlt = 0) => {
|
|
229
|
+
// 1. 检查地图实例是否存在,不存在就直接返回
|
|
230
|
+
if (!map) return
|
|
231
|
+
|
|
232
|
+
// 2. 恢复3D透视投影(让地图可以有立体感)
|
|
233
|
+
restorePerspectiveFrustum(map)
|
|
234
|
+
|
|
235
|
+
// 3. 获取相机控制器,允许用户之后可以倾斜和旋转视角
|
|
236
|
+
const cameraController = map.scene?.screenSpaceCameraController
|
|
237
|
+
if (cameraController) {
|
|
238
|
+
cameraController.enableTilt = true // 允许倾斜(上下看)
|
|
239
|
+
cameraController.enableLook = true // 允许旋转(左右看)
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
// 4. 处理俯仰角度(视线上下倾斜的角度)
|
|
243
|
+
// pitch范围:0度=水平向前看,-90度=正俯视,-35度=稍微向下看
|
|
244
|
+
// 这里防止配置的角度太极端(<= -80度几乎就是俯视了,强制改成-35度)
|
|
245
|
+
const configuredPitch = centerInfo.pitch ?? -35 // 用配置的值,没有就用默认-35度
|
|
246
|
+
const targetPitch = configuredPitch <= -80 ? -35 : configuredPitch // 防止角度太极端
|
|
247
|
+
const pitchRadians = Cesium.Math.toRadians(targetPitch) // 角度转弧度(Cesium用弧度计算)
|
|
248
|
+
|
|
249
|
+
// 5. 处理目标点高度(比如无人机的飞行高度)
|
|
250
|
+
const targetAltNumber = Number(targetAlt) // 转成数字
|
|
251
|
+
const finalTargetAlt = Number.isFinite(targetAltNumber) ? targetAltNumber : 0 // 确保是有效数字
|
|
252
|
+
// 把经纬度+高度转成Cesium能识别的三维坐标(笛卡尔坐标)
|
|
253
|
+
const targetPosition = Cesium.Cartesian3.fromDegrees(lng, lat, finalTargetAlt)
|
|
254
|
+
|
|
255
|
+
// 6. 处理相机高度(我们想让相机飞多高)
|
|
256
|
+
const altitudeNumber = Number(altitude)
|
|
257
|
+
const finalAltitude = Number.isFinite(altitudeNumber) ? altitudeNumber : 10000
|
|
258
|
+
|
|
259
|
+
// 7. 计算相机到目标点的直线距离(重点!)
|
|
260
|
+
// HeadingPitchRange的range是"直线距离",不是高度
|
|
261
|
+
// 想象一下:你站在100米高的地方,视线向下30度看地面
|
|
262
|
+
// 你到目标点的直线距离 = 高度 / sin(俯仰角)
|
|
263
|
+
// 用Math.max(..., 0.1)防止sin值太小导致距离过大
|
|
264
|
+
const range = finalAltitude / Math.max(Math.sin(Math.abs(pitchRadians)), 0.1)
|
|
265
|
+
|
|
266
|
+
// 8. 设置相机看向目标点
|
|
267
|
+
// HeadingPitchRange:一种描述相机位置的方式
|
|
268
|
+
// - heading: 水平朝向(比如0=正北看)
|
|
269
|
+
// - pitch: 俯仰角度(向下为负)
|
|
270
|
+
// - range: 相机到目标点的直线距离
|
|
271
|
+
map.camera.lookAt(
|
|
272
|
+
targetPosition, // 看向的目标点
|
|
273
|
+
new Cesium.HeadingPitchRange(
|
|
274
|
+
Cesium.Math.toRadians(centerInfo.heading ?? 0), // 朝向转弧度
|
|
275
|
+
pitchRadians, // 俯仰角(弧度)
|
|
276
|
+
range // 直线距离
|
|
277
|
+
)
|
|
278
|
+
)
|
|
279
|
+
|
|
280
|
+
// 9. 重置相机变换(确保lookAt生效后恢复正常状态)
|
|
281
|
+
map.camera.lookAtTransform(Cesium.Matrix4.IDENTITY)
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
/**
|
|
285
|
+
* 在两种俯仰视角之间切换
|
|
286
|
+
* 注意:这里只切换相机视角,不切换 Cesium 的 2D/3D 模式
|
|
287
|
+
* @param {string=} mapId 地图实例ID
|
|
288
|
+
*/
|
|
289
|
+
const toggleViewToRtk = (mapId) => {
|
|
290
|
+
const map = mapStore.getMap(mapId)
|
|
291
|
+
const rtkPosition = getCurrentRtkPosition(mapId)
|
|
292
|
+
|
|
293
|
+
if (!map || !rtkPosition) {
|
|
294
|
+
return { success: false, currentMode: null }
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
const centerInfo = mapStore.getMapInfo('center', mapId) || {}
|
|
298
|
+
let { lng, lat } = rtkPosition
|
|
299
|
+
|
|
300
|
+
if (lng === 0 && lat === 0) {
|
|
301
|
+
lng = centerInfo.lng ?? lng
|
|
302
|
+
lat = centerInfo.lat ?? lat
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
const camera = map.camera
|
|
306
|
+
const isOrthographic = camera.frustum instanceof Cesium.OrthographicFrustum
|
|
307
|
+
const nextAlt = centerInfo.alt ?? 10000
|
|
308
|
+
|
|
309
|
+
let currentMode
|
|
310
|
+
// 切换视角
|
|
311
|
+
if (isOrthographic) {
|
|
312
|
+
// 当前是正交投影(俯视),切换到透视投影(斜视)
|
|
313
|
+
set3DView(map, lng, lat, centerInfo, 10000)
|
|
314
|
+
currentMode = '3D'
|
|
315
|
+
} else {
|
|
316
|
+
// 当前是透视投影,切换到正交投影(俯视)
|
|
317
|
+
set2DView(map, lng, lat, nextAlt)
|
|
318
|
+
currentMode = '2D'
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
return { success: true, currentMode }
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
return {
|
|
325
|
+
isInChina,
|
|
326
|
+
mouseController,
|
|
327
|
+
setCesiumCenter,
|
|
328
|
+
setBeiJingTime,
|
|
329
|
+
toggleViewToRtk,
|
|
330
|
+
set2DView,
|
|
331
|
+
set3DView,
|
|
332
|
+
applyOrthographicFrustum,
|
|
333
|
+
restorePerspectiveFrustum
|
|
334
|
+
}
|
|
335
|
+
}
|