huweili-cesium 1.2.6 → 1.2.7
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 +142 -582
- 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,325 @@
|
|
|
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
|
-
if (DroneConfig) {
|
|
218
|
-
|
|
158
|
+
if (DroneConfig?.trailTime != null) {
|
|
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
|
|
|
195
|
+
// 6. 相机与首帧(须在容器尺寸稳定后 resize)
|
|
196
|
+
finalizeCameraAndRender(map, mapOptions, sceneMode)
|
|
475
197
|
|
|
476
|
-
|
|
198
|
+
// 7. 通知宿主(相机、工具栏已就绪)
|
|
199
|
+
emitMapReady(map, center)
|
|
477
200
|
console.log(`Cesium 地图加载成功,mapId: ${props.mapId}`)
|
|
478
201
|
|
|
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
|
-
|
|
524
|
-
|
|
202
|
+
// 8. 自管渲染循环(useDefaultRenderLoop: false)
|
|
525
203
|
startContinuousRendering(map)
|
|
526
|
-
|
|
527
204
|
} catch (error) {
|
|
528
|
-
|
|
529
205
|
mapStore.setMapLoadSta(MapLoadStatus.FAILED, props.mapId)
|
|
530
|
-
|
|
531
206
|
console.error('Cesium 地图加载失败:', error)
|
|
532
|
-
|
|
533
207
|
}
|
|
534
|
-
|
|
535
208
|
}
|
|
536
209
|
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
let lastActiveTime = Date.now()
|
|
542
|
-
|
|
543
|
-
const IDLE_TIMEOUT = 30000
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
210
|
+
// ---------------------------------------------------------------------------
|
|
211
|
+
// 6. 渲染循环
|
|
212
|
+
// ---------------------------------------------------------------------------
|
|
547
213
|
function startContinuousRendering(viewer) {
|
|
548
|
-
|
|
549
214
|
if (animationId) return
|
|
550
|
-
|
|
551
|
-
function animate() {
|
|
552
|
-
|
|
215
|
+
const tick = () => {
|
|
553
216
|
const now = Date.now()
|
|
554
|
-
|
|
555
217
|
if (
|
|
556
|
-
|
|
557
218
|
isMapActive &&
|
|
558
|
-
|
|
559
219
|
!document.hidden &&
|
|
560
|
-
|
|
561
220
|
map &&
|
|
562
|
-
|
|
563
221
|
!map.isDestroyed?.() &&
|
|
564
|
-
|
|
565
222
|
now - lastActiveTime < IDLE_TIMEOUT
|
|
566
|
-
|
|
567
223
|
) {
|
|
568
|
-
|
|
569
224
|
viewer.render()
|
|
570
|
-
|
|
571
225
|
}
|
|
572
|
-
|
|
573
|
-
animationId = requestAnimationFrame(animate)
|
|
574
|
-
|
|
226
|
+
animationId = requestAnimationFrame(tick)
|
|
575
227
|
}
|
|
576
|
-
|
|
577
|
-
animate()
|
|
578
|
-
|
|
228
|
+
tick()
|
|
579
229
|
}
|
|
580
230
|
|
|
581
|
-
|
|
582
|
-
|
|
583
231
|
function stopRenderLoop() {
|
|
584
|
-
|
|
585
232
|
if (animationId) {
|
|
586
|
-
|
|
587
233
|
cancelAnimationFrame(animationId)
|
|
588
|
-
|
|
589
234
|
animationId = null
|
|
590
|
-
|
|
591
235
|
}
|
|
592
|
-
|
|
593
236
|
}
|
|
594
237
|
|
|
595
|
-
|
|
596
|
-
|
|
597
238
|
function setupActivityListeners() {
|
|
598
|
-
|
|
599
|
-
const activities = ['mousemove', 'keydown', 'touchmove', 'wheel', 'click']
|
|
600
|
-
|
|
601
|
-
activities.forEach((event) => {
|
|
602
|
-
|
|
239
|
+
;['mousemove', 'keydown', 'touchmove', 'wheel', 'click'].forEach((event) => {
|
|
603
240
|
document.addEventListener(event, () => {
|
|
604
|
-
|
|
605
241
|
lastActiveTime = Date.now()
|
|
606
|
-
|
|
607
242
|
})
|
|
608
|
-
|
|
609
243
|
})
|
|
610
|
-
|
|
611
244
|
}
|
|
612
245
|
|
|
613
|
-
|
|
614
|
-
|
|
246
|
+
// ---------------------------------------------------------------------------
|
|
247
|
+
// 7. keep-alive 恢复
|
|
248
|
+
// ---------------------------------------------------------------------------
|
|
615
249
|
function resumeMapAfterCache() {
|
|
616
|
-
|
|
617
250
|
if (!map || map.isDestroyed?.()) return
|
|
618
|
-
|
|
619
251
|
mapStore.setCurrentMapId(props.mapId)
|
|
620
|
-
|
|
621
252
|
isMapActive = true
|
|
622
|
-
|
|
623
253
|
lastActiveTime = Date.now()
|
|
624
254
|
|
|
625
255
|
nextTick(() => {
|
|
626
|
-
|
|
627
256
|
if (!map || map.isDestroyed?.()) return
|
|
628
|
-
|
|
629
257
|
map.resize()
|
|
630
|
-
|
|
631
258
|
const mode = mapStore.getSceneMode(props.mapId)
|
|
632
|
-
|
|
633
259
|
syncCameraInteractionMode(map, props.mapId, mode === '2D' ? '2D' : '3D')
|
|
634
|
-
|
|
635
260
|
map.render()
|
|
636
|
-
|
|
637
261
|
if (!animationId) startContinuousRendering(map)
|
|
638
|
-
|
|
639
262
|
})
|
|
640
|
-
|
|
641
263
|
}
|
|
642
264
|
|
|
643
|
-
|
|
644
|
-
|
|
265
|
+
// ---------------------------------------------------------------------------
|
|
266
|
+
// 8. 生命周期
|
|
267
|
+
// ---------------------------------------------------------------------------
|
|
645
268
|
watch(
|
|
646
|
-
|
|
647
269
|
() => props.toolbarButtons,
|
|
648
|
-
|
|
649
270
|
() => {
|
|
650
|
-
|
|
651
|
-
if (map && !map.isDestroyed?.()) {
|
|
652
|
-
|
|
653
|
-
mountToolbarButtons(map)
|
|
654
|
-
|
|
655
|
-
}
|
|
656
|
-
|
|
271
|
+
if (map && !map.isDestroyed?.()) mountToolbarButtons(map)
|
|
657
272
|
},
|
|
658
|
-
|
|
659
273
|
{ deep: true },
|
|
660
|
-
|
|
661
274
|
)
|
|
662
275
|
|
|
663
|
-
|
|
664
|
-
|
|
665
276
|
onMounted(() => {
|
|
666
|
-
|
|
667
277
|
mapStore.setCurrentMapId(props.mapId)
|
|
668
|
-
|
|
669
278
|
setupActivityListeners()
|
|
670
|
-
|
|
671
279
|
onEvent('map-scene-mode-changed', handleSceneModeChange)
|
|
672
|
-
|
|
673
280
|
initCesium()
|
|
674
|
-
|
|
675
281
|
})
|
|
676
282
|
|
|
677
|
-
|
|
678
|
-
|
|
679
283
|
onActivated(() => {
|
|
680
|
-
|
|
681
284
|
mapStore.setCurrentMapId(props.mapId)
|
|
682
|
-
|
|
683
285
|
if (!map || map.isDestroyed?.()) {
|
|
684
|
-
|
|
685
286
|
isMapActive = true
|
|
686
|
-
|
|
687
287
|
initCesium()
|
|
688
|
-
|
|
689
288
|
return
|
|
690
|
-
|
|
691
289
|
}
|
|
692
|
-
|
|
693
290
|
resumeMapAfterCache()
|
|
694
|
-
|
|
695
291
|
})
|
|
696
292
|
|
|
697
|
-
|
|
698
|
-
|
|
699
293
|
onDeactivated(() => {
|
|
700
|
-
|
|
701
294
|
isMapActive = false
|
|
702
|
-
|
|
703
295
|
stopRenderLoop()
|
|
704
|
-
|
|
705
296
|
})
|
|
706
297
|
|
|
707
|
-
|
|
708
|
-
|
|
709
298
|
onUnmounted(() => {
|
|
710
|
-
|
|
711
299
|
isMapActive = false
|
|
712
|
-
|
|
713
300
|
stopRenderLoop()
|
|
714
|
-
|
|
715
301
|
offEvent('map-scene-mode-changed', handleSceneModeChange)
|
|
716
|
-
|
|
717
|
-
if (map) {
|
|
718
|
-
|
|
719
|
-
teardownOrthographicWheelZoom(map)
|
|
720
|
-
|
|
721
|
-
}
|
|
722
|
-
|
|
302
|
+
if (map) teardownOrthographicWheelZoom(map)
|
|
723
303
|
removeToolbarButtons(customButtons)
|
|
724
|
-
|
|
725
304
|
customButtons = []
|
|
726
|
-
|
|
727
305
|
if (map) {
|
|
728
|
-
|
|
729
306
|
map.destroy()
|
|
730
|
-
|
|
731
307
|
map = null
|
|
732
|
-
|
|
733
308
|
}
|
|
734
|
-
|
|
735
309
|
mapStore.removeMapInstance(props.mapId)
|
|
736
|
-
|
|
737
310
|
})
|
|
738
|
-
|
|
739
311
|
</script>
|
|
740
312
|
|
|
741
|
-
|
|
742
|
-
|
|
743
313
|
<style scoped lang="less">
|
|
744
314
|
.cesium-map-wrapper {
|
|
745
|
-
|
|
746
315
|
width: 100%;
|
|
747
|
-
|
|
748
316
|
height: 100%;
|
|
749
|
-
|
|
750
317
|
position: relative;
|
|
751
|
-
|
|
752
318
|
}
|
|
753
319
|
|
|
754
|
-
|
|
755
|
-
|
|
756
320
|
.cesium-container {
|
|
757
|
-
|
|
758
321
|
width: 100%;
|
|
759
|
-
|
|
760
322
|
height: 100%;
|
|
761
|
-
|
|
762
323
|
position: relative;
|
|
763
|
-
|
|
764
324
|
}
|
|
765
325
|
</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.7",
|
|
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",
|