huweili-cesium 1.2.6 → 1.2.8
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 +12 -1
- package/index.vue +143 -581
- package/js/index.js +10 -0
- package/js/utils/cesiumMapBootstrap.js +164 -0
- package/package.json +3 -1
package/README.md
CHANGED
|
@@ -86,7 +86,18 @@ export default defineConfig({
|
|
|
86
86
|
|
|
87
87
|
事件:`@onload`,参数 `{ map, center, mapId, toolbar }`(`map` 为 Cesium `Viewer` 实例;`toolbar` 可在加载后动态增删按钮)。
|
|
88
88
|
|
|
89
|
-
|
|
89
|
+
### 为何不用 Cesium 内置 2D 模式
|
|
90
|
+
|
|
91
|
+
Viewer 固定为 `SCENE3D`,业务上的「2D」是 **正交相机 + 俯视**(`basis.js` / `cameraInteraction.js`),不切换 `SCENE2D` / `COLUMBUS_VIEW`。简要优点:
|
|
92
|
+
|
|
93
|
+
- **2D/3D 切换更顺**:无场景变形(morph),透视与正交互换,缩放与锚点更易对齐(含工具栏切换、RTK 跟飞)。
|
|
94
|
+
- **渲染一致**:无人机、轨迹、围栏等与 3D 同一套规则,少踩 2D 投影下的显示差异。
|
|
95
|
+
- **交互可控**:2D 可锁定俯视、自定义滚轮缩放(正交宽度),避免与内置 2D 控制器行为不一致。
|
|
96
|
+
- **语义清晰**:`mapStore` 的 `2D`/`3D` 表示业务视角,不与 Cesium `SceneMode` 枚举混用。
|
|
97
|
+
|
|
98
|
+
配置里 `scene.sceneMode: '2D'` 表示初始化俯视正交,而非启用 Cesium 平面地图模式。
|
|
99
|
+
|
|
100
|
+
### 各项目自定义工具栏
|
|
90
101
|
|
|
91
102
|
**方式 1:组件 props(推荐)**
|
|
92
103
|
|
package/index.vue
CHANGED
|
@@ -1,765 +1,327 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
|
|
3
|
-
<div class="cesium-map-wrapper" @pointerdown="handleMapPointerDown">
|
|
4
|
-
|
|
2
|
+
<div class="cesium-map-wrapper">
|
|
5
3
|
<div class="cesium-container" ref="cesiumContainer" />
|
|
6
|
-
|
|
7
4
|
<WsIndicator />
|
|
8
|
-
|
|
9
5
|
</div>
|
|
10
|
-
|
|
11
6
|
</template>
|
|
12
7
|
|
|
13
|
-
|
|
14
|
-
|
|
15
8
|
<script setup>
|
|
16
|
-
|
|
9
|
+
/**
|
|
10
|
+
* CesiumMap 组件 — 编排层
|
|
11
|
+
*
|
|
12
|
+
* 职责边界:
|
|
13
|
+
* - 本文件:Vue 生命周期、Pinia 注册、渲染循环、工具栏、onload 事件
|
|
14
|
+
* - cesiumMapBootstrap.js:Viewer / Scene / Imagery / Input 分层配置
|
|
15
|
+
* - basis.js + cameraInteraction.js:2D 正交 / 3D 透视相机与交互
|
|
16
|
+
*/
|
|
17
17
|
import * as Cesium from 'cesium'
|
|
18
|
-
|
|
19
18
|
import { ref, watch, onMounted, onUnmounted, onActivated, onDeactivated, nextTick, toRaw } from 'vue'
|
|
20
|
-
|
|
21
19
|
import { MapConfig, DroneConfig } from './js/config/index.js'
|
|
22
|
-
|
|
23
20
|
import WsIndicator from './components/wsIndicator/wsIndicator.vue'
|
|
24
|
-
|
|
25
21
|
import { objectUtils } from './js/utils/cesium/object.js'
|
|
26
|
-
|
|
27
22
|
import { basicConfig, teardownOrthographicWheelZoom } from './js/basis.js'
|
|
28
|
-
|
|
29
23
|
import { useMapStore, MapLoadStatus } from './js/stores/mapStore.js'
|
|
30
|
-
|
|
31
24
|
import { useEventBus } from './js/utils/useEventBus.js'
|
|
32
|
-
|
|
33
|
-
import { processMapConfigColors } from './js/tileProviders.js'
|
|
34
|
-
|
|
35
|
-
import { applyImageryLayers, resolveOnlineBasemap } from './js/utils/mapImagery.js'
|
|
36
|
-
|
|
37
25
|
import { createCustomToolbarButtons } from './js/customToolbarButtons.js'
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
26
|
+
import {
|
|
27
|
+
resolveMapOptions,
|
|
28
|
+
buildViewerOptions,
|
|
29
|
+
buildContextOptions,
|
|
30
|
+
buildSceneRenderOptions,
|
|
31
|
+
applySceneRenderOptions,
|
|
32
|
+
applyConfiguredImagery,
|
|
33
|
+
applyViewerInputPolicy,
|
|
34
|
+
createMapViewer,
|
|
35
|
+
} from './js/utils/cesiumMapBootstrap.js'
|
|
36
|
+
|
|
37
|
+
// ---------------------------------------------------------------------------
|
|
38
|
+
// 0. 依赖注入(包内模块能力)
|
|
39
|
+
// ---------------------------------------------------------------------------
|
|
43
40
|
const { merge } = objectUtils()
|
|
44
|
-
|
|
45
41
|
const { mouseController, setInitialCameraView, syncCameraInteractionMode } = basicConfig()
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
42
|
const {
|
|
50
|
-
|
|
51
43
|
addToolbarButton,
|
|
52
|
-
|
|
53
44
|
addToolbarButtons,
|
|
54
|
-
|
|
55
45
|
removeToolbarButtons,
|
|
56
|
-
|
|
57
46
|
createDefaultToolbarButtons,
|
|
58
|
-
|
|
59
47
|
} = createCustomToolbarButtons()
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
48
|
const mapStore = useMapStore()
|
|
64
|
-
|
|
65
49
|
const { on: onEvent, off: offEvent } = useEventBus()
|
|
66
50
|
|
|
67
|
-
|
|
68
|
-
|
|
51
|
+
// ---------------------------------------------------------------------------
|
|
52
|
+
// 1. 组件接口
|
|
53
|
+
// ---------------------------------------------------------------------------
|
|
69
54
|
const emit = defineEmits(['onload'])
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
55
|
const props = defineProps({
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
default: undefined,
|
|
80
|
-
|
|
81
|
-
},
|
|
82
|
-
|
|
83
|
-
mapId: {
|
|
84
|
-
|
|
85
|
-
type: String,
|
|
86
|
-
|
|
87
|
-
default: 'default',
|
|
88
|
-
|
|
89
|
-
},
|
|
90
|
-
|
|
91
|
-
showDefaultToolbar: {
|
|
92
|
-
|
|
93
|
-
type: Boolean,
|
|
94
|
-
|
|
95
|
-
default: true,
|
|
96
|
-
|
|
97
|
-
},
|
|
98
|
-
|
|
99
|
-
toolbarButtons: {
|
|
100
|
-
|
|
101
|
-
type: Array,
|
|
102
|
-
|
|
103
|
-
default: undefined,
|
|
104
|
-
|
|
105
|
-
},
|
|
106
|
-
|
|
107
|
-
extraToolbarButtons: {
|
|
108
|
-
|
|
109
|
-
type: Array,
|
|
110
|
-
|
|
111
|
-
default: () => [],
|
|
112
|
-
|
|
113
|
-
},
|
|
114
|
-
|
|
56
|
+
options: { type: Object, default: undefined },
|
|
57
|
+
mapId: { type: String, default: 'default' },
|
|
58
|
+
showDefaultToolbar: { type: Boolean, default: true },
|
|
59
|
+
toolbarButtons: { type: Array, default: undefined },
|
|
60
|
+
extraToolbarButtons: { type: Array, default: () => [] },
|
|
115
61
|
})
|
|
116
62
|
|
|
63
|
+
// ---------------------------------------------------------------------------
|
|
64
|
+
// 2. 运行时状态
|
|
65
|
+
// ---------------------------------------------------------------------------
|
|
66
|
+
const cesiumContainer = ref(null)
|
|
67
|
+
/** @type {import('cesium').Viewer|null} */
|
|
68
|
+
let map = null
|
|
69
|
+
let customButtons = []
|
|
70
|
+
let isMapActive = true
|
|
71
|
+
let animationId = null
|
|
72
|
+
let lastActiveTime = Date.now()
|
|
73
|
+
const IDLE_TIMEOUT = 30000
|
|
117
74
|
|
|
118
|
-
|
|
75
|
+
// ---------------------------------------------------------------------------
|
|
76
|
+
// 3. 工具栏
|
|
77
|
+
// ---------------------------------------------------------------------------
|
|
119
78
|
function resolveToolbarButtonConfigs() {
|
|
120
|
-
|
|
121
|
-
if (props.toolbarButtons?.length) {
|
|
122
|
-
|
|
123
|
-
return props.toolbarButtons
|
|
124
|
-
|
|
125
|
-
}
|
|
126
|
-
|
|
79
|
+
if (props.toolbarButtons?.length) return props.toolbarButtons
|
|
127
80
|
const configs = []
|
|
128
|
-
|
|
129
81
|
if (props.showDefaultToolbar) {
|
|
130
|
-
|
|
131
82
|
configs.push(...createDefaultToolbarButtons({ mapId: props.mapId }))
|
|
132
|
-
|
|
133
83
|
}
|
|
134
|
-
|
|
135
84
|
if (props.extraToolbarButtons?.length) {
|
|
136
|
-
|
|
137
85
|
configs.push(...props.extraToolbarButtons)
|
|
138
|
-
|
|
139
86
|
}
|
|
140
|
-
|
|
141
87
|
return configs
|
|
142
|
-
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
const handleSceneModeChange = ({ mapId, sceneMode }) => {
|
|
148
|
-
|
|
149
|
-
if (mapId !== props.mapId || !map || map.isDestroyed?.()) return
|
|
150
|
-
|
|
151
|
-
syncCameraInteractionMode(map, mapId, sceneMode)
|
|
152
|
-
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
const handleMapPointerDown = () => {
|
|
158
|
-
|
|
159
|
-
if (map && !map.isDestroyed?.()) {
|
|
160
|
-
|
|
161
|
-
ensureMapFocus(map)
|
|
162
|
-
|
|
163
|
-
}
|
|
164
|
-
|
|
165
88
|
}
|
|
166
89
|
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
const cesiumContainer = ref(null)
|
|
170
|
-
|
|
171
|
-
let map = null
|
|
172
|
-
|
|
173
|
-
let customButtons = []
|
|
174
|
-
|
|
175
|
-
let isMapActive = true
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
90
|
function mountToolbarButtons(viewer) {
|
|
180
|
-
|
|
181
91
|
if (!viewer || viewer.isDestroyed?.()) return
|
|
182
|
-
|
|
183
92
|
removeToolbarButtons(customButtons)
|
|
184
|
-
|
|
185
93
|
customButtons = []
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
if (toolbarConfigs.length) {
|
|
190
|
-
|
|
191
|
-
customButtons = addToolbarButtons(viewer, toolbarConfigs)
|
|
192
|
-
|
|
94
|
+
const configs = resolveToolbarButtonConfigs()
|
|
95
|
+
if (configs.length) {
|
|
96
|
+
customButtons = addToolbarButtons(viewer, configs)
|
|
193
97
|
}
|
|
98
|
+
}
|
|
194
99
|
|
|
100
|
+
// ---------------------------------------------------------------------------
|
|
101
|
+
// 4. 场景模式事件(工具栏 2D/3D 切换 → 同步相机交互)
|
|
102
|
+
// ---------------------------------------------------------------------------
|
|
103
|
+
function handleSceneModeChange({ mapId, sceneMode }) {
|
|
104
|
+
if (mapId !== props.mapId || !map || map.isDestroyed?.()) return
|
|
105
|
+
syncCameraInteractionMode(map, mapId, sceneMode)
|
|
195
106
|
}
|
|
196
107
|
|
|
108
|
+
function registerMapContext(viewer, mapOptions) {
|
|
109
|
+
const center = mapOptions.scene.center || {}
|
|
110
|
+
const sceneMode = mapOptions.scene.sceneMode || '3D'
|
|
111
|
+
|
|
112
|
+
mapStore.setMapInfo(
|
|
113
|
+
'center',
|
|
114
|
+
{
|
|
115
|
+
lng: center.lng,
|
|
116
|
+
lat: center.lat,
|
|
117
|
+
heading: center.heading,
|
|
118
|
+
pitch: center.pitch,
|
|
119
|
+
roll: center.roll,
|
|
120
|
+
duration: center.duration,
|
|
121
|
+
alt: center.alt,
|
|
122
|
+
},
|
|
123
|
+
props.mapId,
|
|
124
|
+
)
|
|
125
|
+
mapStore.setMap(viewer, props.mapId)
|
|
126
|
+
mapStore.setSceneMode(sceneMode, props.mapId)
|
|
127
|
+
|
|
128
|
+
return { center, sceneMode }
|
|
129
|
+
}
|
|
197
130
|
|
|
131
|
+
function emitMapReady(viewer, center) {
|
|
132
|
+
emit('onload', {
|
|
133
|
+
map: viewer,
|
|
134
|
+
center,
|
|
135
|
+
mapId: props.mapId,
|
|
136
|
+
toolbar: {
|
|
137
|
+
addToolbarButton: (opt) => addToolbarButton(viewer, opt),
|
|
138
|
+
addToolbarButtons: (opts) => addToolbarButtons(viewer, opts),
|
|
139
|
+
removeToolbarButtons,
|
|
140
|
+
},
|
|
141
|
+
syncCameraInteractionMode: (mode) => syncCameraInteractionMode(viewer, props.mapId, mode),
|
|
142
|
+
})
|
|
143
|
+
}
|
|
198
144
|
|
|
199
|
-
|
|
145
|
+
function finalizeCameraAndRender(viewer, mapOptions, sceneMode) {
|
|
146
|
+
viewer.resize()
|
|
147
|
+
setInitialCameraView(viewer, mapOptions.scene.center, sceneMode, props.mapId)
|
|
148
|
+
viewer.render()
|
|
149
|
+
}
|
|
200
150
|
|
|
151
|
+
// ---------------------------------------------------------------------------
|
|
152
|
+
// 5. 地图初始化主流程
|
|
153
|
+
// ---------------------------------------------------------------------------
|
|
154
|
+
async function initCesium() {
|
|
201
155
|
if (!cesiumContainer.value) return
|
|
202
156
|
|
|
203
157
|
mapStore.setMapLoadSta(MapLoadStatus.LOADING, props.mapId)
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
let mapOptions
|
|
208
|
-
|
|
209
|
-
if (MapConfig) {
|
|
210
|
-
|
|
211
|
-
mapOptions = MapConfig
|
|
212
|
-
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
158
|
if (DroneConfig) {
|
|
218
|
-
|
|
219
159
|
mapStore.setTrailTime(DroneConfig.trailTime, props.mapId)
|
|
220
|
-
|
|
221
|
-
}
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
if (props.options) {
|
|
226
|
-
|
|
227
|
-
let exOptions
|
|
228
|
-
|
|
229
|
-
if (props.options.then) {
|
|
230
|
-
|
|
231
|
-
exOptions = toRaw(await props.options)
|
|
232
|
-
|
|
233
|
-
} else {
|
|
234
|
-
|
|
235
|
-
exOptions = toRaw(props.options)
|
|
236
|
-
|
|
237
|
-
}
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
if (mapOptions) {
|
|
242
|
-
|
|
243
|
-
mapOptions = merge(mapOptions, exOptions)
|
|
244
|
-
|
|
245
|
-
} else {
|
|
246
|
-
|
|
247
|
-
mapOptions = exOptions
|
|
248
|
-
|
|
249
|
-
}
|
|
250
|
-
|
|
251
160
|
}
|
|
252
161
|
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
if (mapOptions) {
|
|
256
|
-
|
|
257
|
-
mapOptions = processMapConfigColors(mapOptions)
|
|
258
|
-
|
|
259
|
-
}
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
162
|
+
let mapOptions
|
|
263
163
|
try {
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
useDefaultRenderLoop: false,
|
|
270
|
-
|
|
271
|
-
baseLayer: mapOptions.control.imageryProvider === false ? false : undefined,
|
|
272
|
-
|
|
273
|
-
baseLayerPicker: mapOptions.control.baseLayerPicker,
|
|
274
|
-
|
|
275
|
-
geocoder: mapOptions.control.geocoder,
|
|
276
|
-
|
|
277
|
-
homeButton: mapOptions.control.homeButton,
|
|
278
|
-
|
|
279
|
-
sceneModePicker: mapOptions.control.sceneModePicker,
|
|
280
|
-
|
|
281
|
-
navigationHelpButton: mapOptions.control.navigationHelpButton,
|
|
282
|
-
|
|
283
|
-
animation: mapOptions.control.animation,
|
|
284
|
-
|
|
285
|
-
timeline: mapOptions.control.timeline,
|
|
286
|
-
|
|
287
|
-
infoBox: mapOptions.control.infoBox,
|
|
288
|
-
|
|
289
|
-
fullscreenButton: mapOptions.control.fullscreenButton,
|
|
290
|
-
|
|
291
|
-
vrButton: mapOptions.control.vrButton,
|
|
292
|
-
|
|
293
|
-
terrainProvider: mapOptions.terrain.show
|
|
294
|
-
|
|
295
|
-
? await Cesium.CesiumTerrainProvider.fromUrl(mapOptions.terrain.url, {
|
|
296
|
-
|
|
297
|
-
requestWaterMask: mapOptions.terrain.coastlineData,
|
|
298
|
-
|
|
299
|
-
requestVertexNormals: mapOptions.terrain.lightingData,
|
|
300
|
-
|
|
301
|
-
})
|
|
302
|
-
|
|
303
|
-
: undefined,
|
|
304
|
-
|
|
305
|
-
terrainShadows: Cesium.ShadowMode.RECEIVE_ONLY,
|
|
306
|
-
|
|
307
|
-
creditContainer: document.createElement('div'),
|
|
308
|
-
|
|
309
|
-
}
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
const contextOptions = {
|
|
314
|
-
|
|
315
|
-
webgl: {
|
|
316
|
-
|
|
317
|
-
alpha: false,
|
|
318
|
-
|
|
319
|
-
depth: true,
|
|
320
|
-
|
|
321
|
-
stencil: false,
|
|
322
|
-
|
|
323
|
-
antialias: true,
|
|
324
|
-
|
|
325
|
-
premultipliedAlpha: true,
|
|
326
|
-
|
|
327
|
-
preserveDrawingBuffer: false,
|
|
328
|
-
|
|
329
|
-
failIfMajorPerformanceCaveat: false,
|
|
330
|
-
|
|
331
|
-
},
|
|
332
|
-
|
|
333
|
-
requestWebGl2: true,
|
|
334
|
-
|
|
335
|
-
powerPreference: 'high-performance',
|
|
336
|
-
|
|
337
|
-
}
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
const sceneRenderOptions = {
|
|
342
|
-
|
|
343
|
-
debugShowFramesPerSecond: mapOptions.scene.debugShowFramesPerSecond,
|
|
344
|
-
|
|
345
|
-
enableLighting: mapOptions.scene.globe.enableLighting,
|
|
346
|
-
|
|
347
|
-
depthTestAgainstTerrain: mapOptions.scene.globe.depthTestAgainstTerrain,
|
|
348
|
-
|
|
349
|
-
fogEnabled: mapOptions.scene.fog.enabled,
|
|
350
|
-
|
|
351
|
-
skyAtmosphereShow: mapOptions.scene.skyAtmosphere.show,
|
|
352
|
-
|
|
353
|
-
dynamicAtmosphereLighting: mapOptions.scene.globe.dynamicAtmosphereLighting,
|
|
354
|
-
|
|
355
|
-
dynamicAtmosphereLightingFromSun: mapOptions.scene.globe.dynamicAtmosphereLightingFromSun,
|
|
356
|
-
|
|
357
|
-
}
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
map = new Cesium.Viewer(cesiumContainer.value, {
|
|
362
|
-
|
|
363
|
-
...viewerOptions,
|
|
364
|
-
|
|
365
|
-
contextOptions,
|
|
366
|
-
|
|
164
|
+
mapOptions = await resolveMapOptions({
|
|
165
|
+
mapConfig: MapConfig,
|
|
166
|
+
propsOptions: props.options,
|
|
167
|
+
merge,
|
|
168
|
+
toRaw,
|
|
367
169
|
})
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
map.scene.debugShowFramesPerSecond = sceneRenderOptions.debugShowFramesPerSecond
|
|
372
|
-
|
|
373
|
-
map.scene.globe.enableLighting = sceneRenderOptions.enableLighting
|
|
374
|
-
|
|
375
|
-
map.scene.globe.depthTestAgainstTerrain = sceneRenderOptions.depthTestAgainstTerrain
|
|
376
|
-
|
|
377
|
-
map.scene.fog.enabled = sceneRenderOptions.fogEnabled
|
|
378
|
-
|
|
379
|
-
map.scene.skyAtmosphere.show = sceneRenderOptions.skyAtmosphereShow
|
|
380
|
-
|
|
381
|
-
map.scene.globe.dynamicAtmosphereLighting = sceneRenderOptions.dynamicAtmosphereLighting
|
|
382
|
-
|
|
383
|
-
map.scene.globe.dynamicAtmosphereLightingFromSun =
|
|
384
|
-
|
|
385
|
-
sceneRenderOptions.dynamicAtmosphereLightingFromSun
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
const sceneMode = mapOptions.scene.sceneMode || '3D'
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
const activeBasemap = resolveOnlineBasemap(mapOptions)
|
|
394
|
-
|
|
395
|
-
if (activeBasemap) {
|
|
396
|
-
|
|
397
|
-
applyImageryLayers(map, mapOptions, activeBasemap)
|
|
398
|
-
|
|
399
|
-
console.log(`加载在线底图:${activeBasemap.name},URL:${activeBasemap.url}`)
|
|
400
|
-
|
|
401
|
-
window._currentBasemapId = activeBasemap.id
|
|
402
|
-
|
|
403
|
-
} else {
|
|
404
|
-
|
|
405
|
-
console.warn('未找到可用底图,Cesium 将使用默认底图或空底图显示')
|
|
406
|
-
|
|
407
|
-
}
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
if (map.screenSpaceEventHandler && mapOptions.control.disableDoubleClick) {
|
|
412
|
-
|
|
413
|
-
map.screenSpaceEventHandler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK)
|
|
414
|
-
|
|
170
|
+
if (!mapOptions) {
|
|
171
|
+
throw new Error('缺少地图配置 MapConfig / options')
|
|
415
172
|
}
|
|
416
173
|
|
|
174
|
+
// 1. Viewer:控件、地形、渲染循环策略
|
|
175
|
+
const viewerOptions = await buildViewerOptions(mapOptions)
|
|
176
|
+
const contextOptions = buildContextOptions()
|
|
177
|
+
map = createMapViewer(cesiumContainer.value, viewerOptions, contextOptions)
|
|
417
178
|
|
|
179
|
+
// 2. Scene / Globe:光照、雾、大气
|
|
180
|
+
const sceneRenderOptions = buildSceneRenderOptions(mapOptions)
|
|
181
|
+
applySceneRenderOptions(map, sceneRenderOptions)
|
|
418
182
|
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
map.selectedEntityChanged.addEventListener(() => {
|
|
422
|
-
|
|
423
|
-
map.selectedEntity = undefined
|
|
424
|
-
|
|
425
|
-
})
|
|
426
|
-
|
|
427
|
-
}
|
|
428
|
-
|
|
429
|
-
|
|
183
|
+
// 3. Imagery:在线底图
|
|
184
|
+
applyConfiguredImagery(map, mapOptions)
|
|
430
185
|
|
|
186
|
+
// 4. Input:双击、选中、鼠标扩展
|
|
187
|
+
applyViewerInputPolicy(map, mapOptions)
|
|
431
188
|
mouseController(map, props.mapId)
|
|
432
189
|
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
mapStore.setMapInfo(
|
|
436
|
-
|
|
437
|
-
'center',
|
|
438
|
-
|
|
439
|
-
{
|
|
440
|
-
|
|
441
|
-
lng: mapOptions.scene.center.lng,
|
|
442
|
-
|
|
443
|
-
lat: mapOptions.scene.center.lat,
|
|
444
|
-
|
|
445
|
-
heading: mapOptions.scene.center.heading,
|
|
446
|
-
|
|
447
|
-
pitch: mapOptions.scene.center.pitch,
|
|
448
|
-
|
|
449
|
-
roll: mapOptions.scene.center.roll,
|
|
450
|
-
|
|
451
|
-
duration: mapOptions.scene.center.duration,
|
|
452
|
-
|
|
453
|
-
alt: mapOptions.scene.center.alt,
|
|
454
|
-
|
|
455
|
-
},
|
|
456
|
-
|
|
457
|
-
props.mapId,
|
|
458
|
-
|
|
459
|
-
)
|
|
460
|
-
|
|
461
|
-
mapStore.setMap(map, props.mapId)
|
|
462
|
-
|
|
463
|
-
mapStore.setSceneMode(sceneMode, props.mapId)
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
const center = mapOptions.scene.center || {}
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
190
|
+
// 5. 业务上下文:Pinia + 工具栏 + 加载态
|
|
191
|
+
const { center, sceneMode } = registerMapContext(map, mapOptions)
|
|
471
192
|
mountToolbarButtons(map)
|
|
472
|
-
|
|
473
193
|
mapStore.setMapLoadSta(MapLoadStatus.LOADED, props.mapId)
|
|
474
194
|
|
|
475
|
-
|
|
476
|
-
|
|
195
|
+
// 6. 通知宿主(必须在相机 finalize 之前,与历史行为一致)
|
|
196
|
+
// 宿主在 mapOnLoad 内同步添加半球、航迹、无人机等 Entity/Primitive;
|
|
197
|
+
// 若先 setInitialCameraView 再 onload,首帧已绘制且部分场景下实体不刷新。
|
|
198
|
+
emitMapReady(map, center)
|
|
477
199
|
console.log(`Cesium 地图加载成功,mapId: ${props.mapId}`)
|
|
478
200
|
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
map,
|
|
482
|
-
|
|
483
|
-
center,
|
|
484
|
-
|
|
485
|
-
mapId: props.mapId,
|
|
486
|
-
|
|
487
|
-
toolbar: {
|
|
488
|
-
|
|
489
|
-
addToolbarButton: (opt) => addToolbarButton(map, opt),
|
|
490
|
-
|
|
491
|
-
addToolbarButtons: (opts) => addToolbarButtons(map, opts),
|
|
492
|
-
|
|
493
|
-
removeToolbarButtons,
|
|
494
|
-
|
|
495
|
-
},
|
|
496
|
-
|
|
497
|
-
syncCameraInteractionMode: (mode) => syncCameraInteractionMode(map, props.mapId, mode),
|
|
498
|
-
|
|
499
|
-
})
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
map.resize()
|
|
504
|
-
|
|
505
|
-
setInitialCameraView(map, mapOptions.scene.center, sceneMode, props.mapId)
|
|
506
|
-
|
|
507
|
-
map.render()
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
if (sceneMode === '2D') {
|
|
512
|
-
|
|
513
|
-
nextTick(() => {
|
|
514
|
-
|
|
515
|
-
if (!map || map.isDestroyed?.()) return
|
|
516
|
-
|
|
517
|
-
syncCameraInteractionMode(map, props.mapId, '2D')
|
|
518
|
-
|
|
519
|
-
})
|
|
520
|
-
|
|
521
|
-
}
|
|
522
|
-
|
|
523
|
-
|
|
201
|
+
// 7. 相机与首帧(须在容器尺寸稳定后 resize)
|
|
202
|
+
finalizeCameraAndRender(map, mapOptions, sceneMode)
|
|
524
203
|
|
|
204
|
+
// 8. 自管渲染循环(useDefaultRenderLoop: false)
|
|
525
205
|
startContinuousRendering(map)
|
|
526
|
-
|
|
527
206
|
} catch (error) {
|
|
528
|
-
|
|
529
207
|
mapStore.setMapLoadSta(MapLoadStatus.FAILED, props.mapId)
|
|
530
|
-
|
|
531
208
|
console.error('Cesium 地图加载失败:', error)
|
|
532
|
-
|
|
533
209
|
}
|
|
534
|
-
|
|
535
210
|
}
|
|
536
211
|
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
let lastActiveTime = Date.now()
|
|
542
|
-
|
|
543
|
-
const IDLE_TIMEOUT = 30000
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
212
|
+
// ---------------------------------------------------------------------------
|
|
213
|
+
// 6. 渲染循环
|
|
214
|
+
// ---------------------------------------------------------------------------
|
|
547
215
|
function startContinuousRendering(viewer) {
|
|
548
|
-
|
|
549
216
|
if (animationId) return
|
|
550
|
-
|
|
551
|
-
function animate() {
|
|
552
|
-
|
|
217
|
+
const tick = () => {
|
|
553
218
|
const now = Date.now()
|
|
554
|
-
|
|
555
219
|
if (
|
|
556
|
-
|
|
557
220
|
isMapActive &&
|
|
558
|
-
|
|
559
221
|
!document.hidden &&
|
|
560
|
-
|
|
561
222
|
map &&
|
|
562
|
-
|
|
563
223
|
!map.isDestroyed?.() &&
|
|
564
|
-
|
|
565
224
|
now - lastActiveTime < IDLE_TIMEOUT
|
|
566
|
-
|
|
567
225
|
) {
|
|
568
|
-
|
|
569
226
|
viewer.render()
|
|
570
|
-
|
|
571
227
|
}
|
|
572
|
-
|
|
573
|
-
animationId = requestAnimationFrame(animate)
|
|
574
|
-
|
|
228
|
+
animationId = requestAnimationFrame(tick)
|
|
575
229
|
}
|
|
576
|
-
|
|
577
|
-
animate()
|
|
578
|
-
|
|
230
|
+
tick()
|
|
579
231
|
}
|
|
580
232
|
|
|
581
|
-
|
|
582
|
-
|
|
583
233
|
function stopRenderLoop() {
|
|
584
|
-
|
|
585
234
|
if (animationId) {
|
|
586
|
-
|
|
587
235
|
cancelAnimationFrame(animationId)
|
|
588
|
-
|
|
589
236
|
animationId = null
|
|
590
|
-
|
|
591
237
|
}
|
|
592
|
-
|
|
593
238
|
}
|
|
594
239
|
|
|
595
|
-
|
|
596
|
-
|
|
597
240
|
function setupActivityListeners() {
|
|
598
|
-
|
|
599
|
-
const activities = ['mousemove', 'keydown', 'touchmove', 'wheel', 'click']
|
|
600
|
-
|
|
601
|
-
activities.forEach((event) => {
|
|
602
|
-
|
|
241
|
+
;['mousemove', 'keydown', 'touchmove', 'wheel', 'click'].forEach((event) => {
|
|
603
242
|
document.addEventListener(event, () => {
|
|
604
|
-
|
|
605
243
|
lastActiveTime = Date.now()
|
|
606
|
-
|
|
607
244
|
})
|
|
608
|
-
|
|
609
245
|
})
|
|
610
|
-
|
|
611
246
|
}
|
|
612
247
|
|
|
613
|
-
|
|
614
|
-
|
|
248
|
+
// ---------------------------------------------------------------------------
|
|
249
|
+
// 7. keep-alive 恢复
|
|
250
|
+
// ---------------------------------------------------------------------------
|
|
615
251
|
function resumeMapAfterCache() {
|
|
616
|
-
|
|
617
252
|
if (!map || map.isDestroyed?.()) return
|
|
618
|
-
|
|
619
253
|
mapStore.setCurrentMapId(props.mapId)
|
|
620
|
-
|
|
621
254
|
isMapActive = true
|
|
622
|
-
|
|
623
255
|
lastActiveTime = Date.now()
|
|
624
256
|
|
|
625
257
|
nextTick(() => {
|
|
626
|
-
|
|
627
258
|
if (!map || map.isDestroyed?.()) return
|
|
628
|
-
|
|
629
259
|
map.resize()
|
|
630
|
-
|
|
631
260
|
const mode = mapStore.getSceneMode(props.mapId)
|
|
632
|
-
|
|
633
261
|
syncCameraInteractionMode(map, props.mapId, mode === '2D' ? '2D' : '3D')
|
|
634
|
-
|
|
635
262
|
map.render()
|
|
636
|
-
|
|
637
263
|
if (!animationId) startContinuousRendering(map)
|
|
638
|
-
|
|
639
264
|
})
|
|
640
|
-
|
|
641
265
|
}
|
|
642
266
|
|
|
643
|
-
|
|
644
|
-
|
|
267
|
+
// ---------------------------------------------------------------------------
|
|
268
|
+
// 8. 生命周期
|
|
269
|
+
// ---------------------------------------------------------------------------
|
|
645
270
|
watch(
|
|
646
|
-
|
|
647
271
|
() => props.toolbarButtons,
|
|
648
|
-
|
|
649
272
|
() => {
|
|
650
|
-
|
|
651
|
-
if (map && !map.isDestroyed?.()) {
|
|
652
|
-
|
|
653
|
-
mountToolbarButtons(map)
|
|
654
|
-
|
|
655
|
-
}
|
|
656
|
-
|
|
273
|
+
if (map && !map.isDestroyed?.()) mountToolbarButtons(map)
|
|
657
274
|
},
|
|
658
|
-
|
|
659
275
|
{ deep: true },
|
|
660
|
-
|
|
661
276
|
)
|
|
662
277
|
|
|
663
|
-
|
|
664
|
-
|
|
665
278
|
onMounted(() => {
|
|
666
|
-
|
|
667
279
|
mapStore.setCurrentMapId(props.mapId)
|
|
668
|
-
|
|
669
280
|
setupActivityListeners()
|
|
670
|
-
|
|
671
281
|
onEvent('map-scene-mode-changed', handleSceneModeChange)
|
|
672
|
-
|
|
673
282
|
initCesium()
|
|
674
|
-
|
|
675
283
|
})
|
|
676
284
|
|
|
677
|
-
|
|
678
|
-
|
|
679
285
|
onActivated(() => {
|
|
680
|
-
|
|
681
286
|
mapStore.setCurrentMapId(props.mapId)
|
|
682
|
-
|
|
683
287
|
if (!map || map.isDestroyed?.()) {
|
|
684
|
-
|
|
685
288
|
isMapActive = true
|
|
686
|
-
|
|
687
289
|
initCesium()
|
|
688
|
-
|
|
689
290
|
return
|
|
690
|
-
|
|
691
291
|
}
|
|
692
|
-
|
|
693
292
|
resumeMapAfterCache()
|
|
694
|
-
|
|
695
293
|
})
|
|
696
294
|
|
|
697
|
-
|
|
698
|
-
|
|
699
295
|
onDeactivated(() => {
|
|
700
|
-
|
|
701
296
|
isMapActive = false
|
|
702
|
-
|
|
703
297
|
stopRenderLoop()
|
|
704
|
-
|
|
705
298
|
})
|
|
706
299
|
|
|
707
|
-
|
|
708
|
-
|
|
709
300
|
onUnmounted(() => {
|
|
710
|
-
|
|
711
301
|
isMapActive = false
|
|
712
|
-
|
|
713
302
|
stopRenderLoop()
|
|
714
|
-
|
|
715
303
|
offEvent('map-scene-mode-changed', handleSceneModeChange)
|
|
716
|
-
|
|
717
|
-
if (map) {
|
|
718
|
-
|
|
719
|
-
teardownOrthographicWheelZoom(map)
|
|
720
|
-
|
|
721
|
-
}
|
|
722
|
-
|
|
304
|
+
if (map) teardownOrthographicWheelZoom(map)
|
|
723
305
|
removeToolbarButtons(customButtons)
|
|
724
|
-
|
|
725
306
|
customButtons = []
|
|
726
|
-
|
|
727
307
|
if (map) {
|
|
728
|
-
|
|
729
308
|
map.destroy()
|
|
730
|
-
|
|
731
309
|
map = null
|
|
732
|
-
|
|
733
310
|
}
|
|
734
|
-
|
|
735
311
|
mapStore.removeMapInstance(props.mapId)
|
|
736
|
-
|
|
737
312
|
})
|
|
738
|
-
|
|
739
313
|
</script>
|
|
740
314
|
|
|
741
|
-
|
|
742
|
-
|
|
743
315
|
<style scoped lang="less">
|
|
744
316
|
.cesium-map-wrapper {
|
|
745
|
-
|
|
746
317
|
width: 100%;
|
|
747
|
-
|
|
748
318
|
height: 100%;
|
|
749
|
-
|
|
750
319
|
position: relative;
|
|
751
|
-
|
|
752
320
|
}
|
|
753
321
|
|
|
754
|
-
|
|
755
|
-
|
|
756
322
|
.cesium-container {
|
|
757
|
-
|
|
758
323
|
width: 100%;
|
|
759
|
-
|
|
760
324
|
height: 100%;
|
|
761
|
-
|
|
762
325
|
position: relative;
|
|
763
|
-
|
|
764
326
|
}
|
|
765
327
|
</style>
|
package/js/index.js
CHANGED
|
@@ -36,6 +36,16 @@ export {
|
|
|
36
36
|
teardownOrthographicWheelZoom,
|
|
37
37
|
syncCameraInteractionMode,
|
|
38
38
|
} from './utils/cameraInteraction.js'
|
|
39
|
+
export {
|
|
40
|
+
resolveMapOptions,
|
|
41
|
+
buildViewerOptions,
|
|
42
|
+
buildContextOptions,
|
|
43
|
+
buildSceneRenderOptions,
|
|
44
|
+
applySceneRenderOptions,
|
|
45
|
+
applyConfiguredImagery,
|
|
46
|
+
applyViewerInputPolicy,
|
|
47
|
+
createMapViewer,
|
|
48
|
+
} from './utils/cesiumMapBootstrap.js'
|
|
39
49
|
|
|
40
50
|
export {
|
|
41
51
|
BaseConfig,
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cesium Viewer 启动配置(按 Cesium 架构分层)
|
|
3
|
+
*
|
|
4
|
+
* 1. Viewer — 控件、地形、底图策略、渲染循环开关
|
|
5
|
+
* 2. Context — WebGL 上下文
|
|
6
|
+
* 3. Scene — 光照、雾、大气、调试项
|
|
7
|
+
* 4. Imagery — 在线底图(业务配置驱动)
|
|
8
|
+
* 5. Input — 双击、实体选中、鼠标扩展
|
|
9
|
+
*/
|
|
10
|
+
import * as Cesium from 'cesium'
|
|
11
|
+
import { processMapConfigColors } from '../tileProviders.js'
|
|
12
|
+
import { applyImageryLayers, resolveOnlineBasemap } from './mapImagery.js'
|
|
13
|
+
|
|
14
|
+
// ---------------------------------------------------------------------------
|
|
15
|
+
// 阶段 0:合并业务配置
|
|
16
|
+
// ---------------------------------------------------------------------------
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* @param {object} params
|
|
20
|
+
* @param {object} [params.mapConfig] MapConfig
|
|
21
|
+
* @param {object} [params.propsOptions] 组件 props.options(支持 Promise)
|
|
22
|
+
* @param {Function} params.merge objectUtils().merge
|
|
23
|
+
* @param {Function} params.toRaw vue toRaw
|
|
24
|
+
*/
|
|
25
|
+
export async function resolveMapOptions({ mapConfig, propsOptions, merge, toRaw }) {
|
|
26
|
+
let mapOptions = mapConfig || undefined
|
|
27
|
+
|
|
28
|
+
if (propsOptions) {
|
|
29
|
+
const exOptions = propsOptions.then
|
|
30
|
+
? toRaw(await propsOptions)
|
|
31
|
+
: toRaw(propsOptions)
|
|
32
|
+
mapOptions = mapOptions ? merge(mapOptions, exOptions) : exOptions
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
if (mapOptions) {
|
|
36
|
+
mapOptions = processMapConfigColors(mapOptions)
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
return mapOptions
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// ---------------------------------------------------------------------------
|
|
43
|
+
// 阶段 1:Viewer 构造参数
|
|
44
|
+
// ---------------------------------------------------------------------------
|
|
45
|
+
|
|
46
|
+
export async function buildViewerOptions(mapOptions) {
|
|
47
|
+
return {
|
|
48
|
+
sceneMode: Cesium.SceneMode.SCENE3D,
|
|
49
|
+
useDefaultRenderLoop: false,
|
|
50
|
+
baseLayer: mapOptions.control.imageryProvider === false ? false : undefined,
|
|
51
|
+
baseLayerPicker: mapOptions.control.baseLayerPicker,
|
|
52
|
+
geocoder: mapOptions.control.geocoder,
|
|
53
|
+
homeButton: mapOptions.control.homeButton,
|
|
54
|
+
sceneModePicker: mapOptions.control.sceneModePicker,
|
|
55
|
+
navigationHelpButton: mapOptions.control.navigationHelpButton,
|
|
56
|
+
animation: mapOptions.control.animation,
|
|
57
|
+
timeline: mapOptions.control.timeline,
|
|
58
|
+
infoBox: mapOptions.control.infoBox,
|
|
59
|
+
fullscreenButton: mapOptions.control.fullscreenButton,
|
|
60
|
+
vrButton: mapOptions.control.vrButton,
|
|
61
|
+
terrainProvider: mapOptions.terrain.show
|
|
62
|
+
? await Cesium.CesiumTerrainProvider.fromUrl(mapOptions.terrain.url, {
|
|
63
|
+
requestWaterMask: mapOptions.terrain.coastlineData,
|
|
64
|
+
requestVertexNormals: mapOptions.terrain.lightingData,
|
|
65
|
+
})
|
|
66
|
+
: undefined,
|
|
67
|
+
terrainShadows: Cesium.ShadowMode.RECEIVE_ONLY,
|
|
68
|
+
creditContainer: document.createElement('div'),
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// ---------------------------------------------------------------------------
|
|
73
|
+
// 阶段 2:WebGL Context
|
|
74
|
+
// ---------------------------------------------------------------------------
|
|
75
|
+
|
|
76
|
+
export function buildContextOptions() {
|
|
77
|
+
return {
|
|
78
|
+
webgl: {
|
|
79
|
+
alpha: false,
|
|
80
|
+
depth: true,
|
|
81
|
+
stencil: false,
|
|
82
|
+
antialias: true,
|
|
83
|
+
premultipliedAlpha: true,
|
|
84
|
+
preserveDrawingBuffer: false,
|
|
85
|
+
failIfMajorPerformanceCaveat: false,
|
|
86
|
+
},
|
|
87
|
+
requestWebGl2: true,
|
|
88
|
+
powerPreference: 'high-performance',
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// ---------------------------------------------------------------------------
|
|
93
|
+
// 阶段 3:Scene / Globe 渲染环境
|
|
94
|
+
// ---------------------------------------------------------------------------
|
|
95
|
+
|
|
96
|
+
export function buildSceneRenderOptions(mapOptions) {
|
|
97
|
+
return {
|
|
98
|
+
debugShowFramesPerSecond: mapOptions.scene.debugShowFramesPerSecond,
|
|
99
|
+
enableLighting: mapOptions.scene.globe.enableLighting,
|
|
100
|
+
depthTestAgainstTerrain: mapOptions.scene.globe.depthTestAgainstTerrain,
|
|
101
|
+
fogEnabled: mapOptions.scene.fog.enabled,
|
|
102
|
+
skyAtmosphereShow: mapOptions.scene.skyAtmosphere.show,
|
|
103
|
+
dynamicAtmosphereLighting: mapOptions.scene.globe.dynamicAtmosphereLighting,
|
|
104
|
+
dynamicAtmosphereLightingFromSun: mapOptions.scene.globe.dynamicAtmosphereLightingFromSun,
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
export function applySceneRenderOptions(viewer, options) {
|
|
109
|
+
viewer.scene.debugShowFramesPerSecond = options.debugShowFramesPerSecond
|
|
110
|
+
viewer.scene.globe.enableLighting = options.enableLighting
|
|
111
|
+
viewer.scene.globe.depthTestAgainstTerrain = options.depthTestAgainstTerrain
|
|
112
|
+
viewer.scene.fog.enabled = options.fogEnabled
|
|
113
|
+
viewer.scene.skyAtmosphere.show = options.skyAtmosphereShow
|
|
114
|
+
viewer.scene.globe.dynamicAtmosphereLighting = options.dynamicAtmosphereLighting
|
|
115
|
+
viewer.scene.globe.dynamicAtmosphereLightingFromSun = options.dynamicAtmosphereLightingFromSun
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
// ---------------------------------------------------------------------------
|
|
119
|
+
// 阶段 4:Imagery 底图
|
|
120
|
+
// ---------------------------------------------------------------------------
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* @returns {string|undefined} 当前底图 id(写入 window._currentBasemapId)
|
|
124
|
+
*/
|
|
125
|
+
export function applyConfiguredImagery(viewer, mapOptions) {
|
|
126
|
+
const activeBasemap = resolveOnlineBasemap(mapOptions)
|
|
127
|
+
if (activeBasemap) {
|
|
128
|
+
applyImageryLayers(viewer, mapOptions, activeBasemap)
|
|
129
|
+
console.log(`加载在线底图:${activeBasemap.name},URL:${activeBasemap.url}`)
|
|
130
|
+
if (typeof window !== 'undefined') {
|
|
131
|
+
window._currentBasemapId = activeBasemap.id
|
|
132
|
+
}
|
|
133
|
+
return activeBasemap.id
|
|
134
|
+
}
|
|
135
|
+
console.warn('未找到可用底图,Cesium 将使用默认底图或空底图显示')
|
|
136
|
+
return undefined
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
// ---------------------------------------------------------------------------
|
|
140
|
+
// 阶段 5:输入与交互策略
|
|
141
|
+
// ---------------------------------------------------------------------------
|
|
142
|
+
|
|
143
|
+
export function applyViewerInputPolicy(viewer, mapOptions) {
|
|
144
|
+
if (viewer.screenSpaceEventHandler && mapOptions.control.disableDoubleClick) {
|
|
145
|
+
viewer.screenSpaceEventHandler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK)
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
if (mapOptions.control.disableEntityClick) {
|
|
149
|
+
viewer.selectedEntityChanged.addEventListener(() => {
|
|
150
|
+
viewer.selectedEntity = undefined
|
|
151
|
+
})
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
// ---------------------------------------------------------------------------
|
|
156
|
+
// 阶段 6:创建 Viewer
|
|
157
|
+
// ---------------------------------------------------------------------------
|
|
158
|
+
|
|
159
|
+
export function createMapViewer(container, viewerOptions, contextOptions) {
|
|
160
|
+
return new Cesium.Viewer(container, {
|
|
161
|
+
...viewerOptions,
|
|
162
|
+
contextOptions,
|
|
163
|
+
})
|
|
164
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "huweili-cesium",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.8",
|
|
4
4
|
"description": "基于 Cesium 的地图工具库(无人机态势、轨迹、围栏、工具栏等)",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./index.js",
|
|
@@ -93,6 +93,8 @@
|
|
|
93
93
|
"./utils/orthographicCameraZoom.js": "./js/utils/orthographicCameraZoom.js",
|
|
94
94
|
"./utils/cameraInteraction": "./js/utils/cameraInteraction.js",
|
|
95
95
|
"./utils/cameraInteraction.js": "./js/utils/cameraInteraction.js",
|
|
96
|
+
"./utils/cesiumMapBootstrap": "./js/utils/cesiumMapBootstrap.js",
|
|
97
|
+
"./utils/cesiumMapBootstrap.js": "./js/utils/cesiumMapBootstrap.js",
|
|
96
98
|
"./js/utils/orthographicCameraZoom": "./js/utils/orthographicCameraZoom.js",
|
|
97
99
|
"./js/utils/orthographicCameraZoom.js": "./js/utils/orthographicCameraZoom.js",
|
|
98
100
|
"./utils/cesium/object": "./js/utils/cesium/object.js",
|