huweili-cesium 1.3.0 → 1.3.2

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 CHANGED
@@ -1,315 +1,315 @@
1
- # huweili-cesium
2
-
3
- 基于 Cesium 的地图工具库。所有 **JS 模块** 位于包内 `js/` 目录(含 `toolbar`、`stores`、`utils`、`config`、`api` 子目录);根目录保留 `index.js`(npm 主入口)与 `index.vue`(地图组件)。
4
-
5
- ## 安装
6
-
7
- ```bash
8
- npm install huweili-cesium
9
- ```
10
-
11
- ### 对等依赖(需在项目中已安装)
12
-
13
- - `cesium` 1.136.0
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
- ```js
29
- // 主入口同时支持:默认导出组件 + 命名导出 JS 模块
30
- import CesiumMap, { basicConfig, setPoint, movePointConfig } from 'huweili-cesium'
31
-
32
- // 仅 JS 模块(不含 Vue 组件)可用子路径
33
- import { basicConfig } from 'huweili-cesium/js'
34
-
35
- // 或按文件引入
36
- import { basicConfig } from 'huweili-cesium/basis'
37
- import { hemisphereConfig } from 'huweili-cesium/hemisphere'
38
- import { createCustomToolbarButtons } from 'huweili-cesium/customToolbarButtons'
39
- ```
40
-
41
- ### Vue 地图组件(开箱即用)
42
-
43
- ```vue
44
- <template>
45
- <div class="map-page">
46
- <CesiumMap map-id="default" @onload="onMapLoad" />
47
- </div>
48
- </template>
49
-
50
- <script setup>
51
- // 推荐:包主入口默认导出组件
52
- import CesiumMap from 'huweili-cesium'
53
- // 等价写法:
54
- // import CesiumMap from 'huweili-cesium/index.vue'
55
- // import CesiumMap from 'huweili-cesium/CesiumMap'
56
-
57
- function onMapLoad({ map, center }) {
58
- console.log('地图已加载', map, center)
59
- }
60
- </script>
61
-
62
- <style scoped>
63
- .map-page {
64
- width: 100%;
65
- height: 100vh;
66
- }
67
- </style>
68
- ```
69
-
70
- **Vite 宿主项目**需在 `vite.config` 中允许编译该依赖(否则 `.vue` 可能无法处理):
71
-
72
- ```js
73
- export default defineConfig({
74
- optimizeDeps: {
75
- include: ['huweili-cesium'],
76
- },
77
- })
78
- ```
79
-
80
- 组件 props:
81
-
82
- | prop | 类型 | 默认 | 说明 |
83
- |------|------|------|------|
84
- | `mapId` | `string` | `'default'` | 多地图实例 ID,与 `mapStore` 对应 |
85
- | `options` | `object` | — | 覆盖/合并 `MapConfig` 的配置 |
86
-
87
- 事件:`@onload`,参数 `{ map, center, mapId, toolbar }`(`map` 为 Cesium `Viewer` 实例;`toolbar` 可在加载后动态增删按钮)。
88
-
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
- ### 各项目自定义工具栏
101
-
102
- **方式 1:组件 props(推荐)**
103
-
104
- ```vue
105
- <CesiumMap
106
- map-id="default"
107
- :show-default-toolbar="true"
108
- :extra-toolbar-buttons="myExtraButtons"
109
- />
110
- ```
111
-
112
- ```js
113
- import { useEventBus } from 'huweili-cesium/utils/useEventBus'
114
-
115
- const { emit } = useEventBus()
116
-
117
- const myExtraButtons = [
118
- {
119
- title: '导出',
120
- text: '导',
121
- onClick: () => emit('exportMap', {}),
122
- },
123
- ]
124
- ```
125
-
126
- 完全不用内置默认按钮、自己定义一整组:
127
-
128
- ```vue
129
- <CesiumMap :toolbar-buttons="myToolbarButtons" />
130
- ```
131
-
132
- 内置默认按钮里的图标路径使用宿主项目的 `import.meta.env.BASE_URL`(如 `/images/new/tj.svg`),请在宿主 `public/images/new/` 放置对应资源;业务按钮(如「机型统计」)通过 `useEventBus` 发事件,宿主需自行 `on('toggleBarChartControl', ...)` 监听。
133
-
134
- ## 可选业务钩子
135
-
136
- 若需光电引导、轨迹列表等业务能力,在应用启动时注入:
137
-
138
- ```js
139
- import { setDroneMapProvider, setOptGuideHandler } from 'huweili-cesium/config/hooks'
140
-
141
- setDroneMapProvider(() => myDroneMap)
142
- setOptGuideHandler((payload) => api.toOptGuide(payload))
143
- ```
144
-
145
- ## 发布到 npm(维护者)
146
-
147
- 项目根目录已配置 `.npmrc`(Token 授权,见 `.npmrc.example`),**无需执行 `npm login`**。安装依赖走 npmmirror 镜像,发布通过 `package.json` 中的 `publishConfig` 固定到 npm 官方源。
148
-
149
- ### 发布步骤
150
-
151
- 1. 修改 `package.json` 中的 `version`(须高于 npm 上已有版本)
152
- 2. 在项目根目录执行:
153
-
154
- ```bash
155
- npm publish
156
- ```
157
-
158
- ### 仅验证打包内容(不上传)
159
-
160
- ```bash
161
- npm publish --dry-run
162
- ```
163
-
164
- ### 本地打包预览
165
-
166
- ```bash
167
- npm pack
168
- # 会生成 huweili-cesium-x.y.z.tgz,解压检查是否包含全部 js
169
- ```
170
-
171
- ### 验证登录与最新版本
172
-
173
- ```bash
174
- npm whoami --registry=https://registry.npmjs.org/
175
- npm view huweili-cesium version --registry=https://registry.npmjs.org/
176
- ```
177
-
178
- ## 从 tzr 源目录同步更新
179
-
180
- ```bash
181
- cd huweili-cesium
182
- npm run sync
183
- # 同步后需重新修复 @/ 别名为包内相对路径(见 scripts)
184
- ```
185
-
186
- ## 地图与自定义工具栏
187
-
188
- 地图组件来自 npm 包 **`huweili-cesium`**,工具栏按钮在业务侧配置,不写在 `mapConfig.js` 里。
189
-
190
- ### 1. 前置配置(`constants.js` / `mapConfig.js`)
191
-
192
- `index.html` 中已按顺序引入:
193
-
194
- ```html
195
- <script src="/config/constants.js"></script>
196
- <script src="/config/mapConfig.js"></script>
197
- ```
198
-
199
- | 文件 | 作用 | 与地图组件的关系 |
200
- |------|------|------------------|
201
- | `public/config/constants.js` | `window.MapInstanceIds` 定义多地图 ID(如 `HOME: 'home-main-map'`) | `:map-id` 须与之一致,工具栏回调里的 `mapId` 也要传同一个值 |
202
- | `public/config/mapConfig.js` | `window.MapConfig`(中心点、2D/3D、底图列表、是否显示 Cesium 自带控件等) | 控制地图初始化;`control.homeButton: false` 时由自定义工具栏替代 |
203
-
204
- 在页面中引用常量(从 `runtimeConfig` 导入):
205
-
206
- ```js
207
- import { MapInstanceIds } from '@/config/runtimeConfig'
208
-
209
- const HOME_MAP_ID = MapInstanceIds?.HOME || 'home-main-map'
210
- ```
211
-
212
- ### 2. 页面引用 `CesiumMap`(首页示例)
213
-
214
- `src/views/home/indexnew.vue`:
215
-
216
- ```vue
217
- <template>
218
- <CesiumMap
219
- :map-id="HOME_MAP_ID"
220
- :toolbar-buttons="getHomeToolbarButtons({ mapId: HOME_MAP_ID })"
221
- @onload="mapOnLoad"
222
- />
223
- </template>
224
-
225
- <script setup>
226
- import CesiumMap from 'huweili-cesium'
227
- import { MapInstanceIds } from '@/config/runtimeConfig'
228
- import { getHomeToolbarButtons } from '@/utils/homeToolbarButtons'
229
-
230
- const HOME_MAP_ID = MapInstanceIds?.HOME || 'home-main-map'
231
- </script>
232
- ```
233
-
234
- - **`toolbar-buttons`**:传入整组按钮(首页不用包内默认按钮,因此不必再写 `show-default-toolbar`)
235
- - **`map-id`**:与 `constants.js` 里 `MapInstanceIds.HOME` 保持一致
236
-
237
- ### 3. 工具栏按钮配置(`src/utils/homeToolbarButtons.js`)
238
-
239
- 通用按钮(指北针、机型统计、回中心、2D/3D、缩放、底图、全屏)集中在此文件维护。
240
-
241
- 页面只需追加自己的按钮时,使用 `extra`:
242
-
243
- ```js
244
- import { useEventBus } from 'huweili-cesium/utils/useEventBus'
245
- import { getHomeToolbarButtons } from '@/utils/homeToolbarButtons'
246
-
247
- const { emit } = useEventBus()
248
-
249
- getHomeToolbarButtons({
250
- mapId: HOME_MAP_ID,
251
- extra: [
252
- {
253
- title: '导出',
254
- text: '导',
255
- onClick: () => emit('exportMap', {}),
256
- },
257
- ],
258
- })
259
- ```
260
-
261
- 按钮项字段说明:
262
-
263
- | 字段 | 说明 |
264
- |------|------|
265
- | `title` | 悬停提示 |
266
- | `text` / `iconSrc` | 文字或图标(二选一,图标放 `public/images/new/`) |
267
- | `isCompass: true` | 指北针专用 |
268
- | `onClick(viewer, button)` | 点击回调 |
269
-
270
- 「机型统计」等通过 `useEventBus` 发事件,页面需 `on('toggleBarChartControl', ...)` 监听。
271
-
272
- ### 4. 其他页面
273
-
274
- - 复用首页整套按钮:`getHomeToolbarButtons({ mapId: '你的 mapId' })`
275
- - 完全自定义:直接传数组给 `:toolbar-buttons="[...]"`
276
- - 地图加载后动态增删:在 `@onload` 回调里使用返回的 `toolbar.addToolbarButton(...)`
277
-
278
- 图标资源路径使用 `import.meta.env.BASE_URL`(如 `/jlap/images/new/xxx.svg`),请放在 `public/images/new/`。
279
-
280
- ## 目录结构
281
-
282
- ```
283
- huweili-cesium/
284
- ├── index.js # npm 主入口(默认导出 CesiumMap + 转发 js 模块)
285
- ├── index.vue # 地图 Vue 组件
286
- ├── components/ # 组件(如 wsIndicator)
287
- ├── js/ # 全部 JS 模块
288
- │ ├── basis.js
289
- │ ├── toolbar/
290
- │ ├── stores/
291
- │ ├── utils/
292
- │ ├── config/
293
- │ └── api/
294
- └── package.json
295
- ```
296
-
297
- ## 包含的文件清单(均在 `js/` 下)
298
-
299
- | 文件 | 说明 |
300
- |------|------|
301
- | js/basis.js | 地图基础操作 |
302
- | js/setPoint.js / js/movePoint.js | 点位与移动 |
303
- | js/setPath.js / js/movePath.js | 路径与轨迹 |
304
- | js/groundLink.js | 地面连接线 |
305
- | js/hemisphere.js | 半球区域 |
306
- | js/geometry.js | 几何图形 |
307
- | js/drawFence.js / js/drawFenceNew.js | 电子围栏 |
308
- | js/cardPool.js / js/labelDiv.js | 信息牌 |
309
- | js/clickHandler.js | 点击交互 |
310
- | js/tileProviders.js | 底图瓦片 |
311
- | js/customToolbarButtons.js | 工具栏 |
312
- | js/toolbar/* | 指南针、底图切换、缩放、全屏 |
313
- | js/droneRipple.js / js/qrCodeGenerator.js | 涟漪、二维码 |
314
-
315
- 另含 `js/stores/mapStore.js`、`js/utils/*`、`js/config/*`、`js/api/*` 等运行依赖。
1
+ # huweili-cesium
2
+
3
+ 基于 Cesium 的地图工具库。所有 **JS 模块** 位于包内 `js/` 目录(含 `toolbar`、`stores`、`utils`、`config`、`api` 子目录);根目录保留 `index.js`(npm 主入口)与 `index.vue`(地图组件)。
4
+
5
+ ## 安装
6
+
7
+ ```bash
8
+ npm install huweili-cesium
9
+ ```
10
+
11
+ ### 对等依赖(需在项目中已安装)
12
+
13
+ - `cesium` 1.136.0
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
+ ```js
29
+ // 主入口同时支持:默认导出组件 + 命名导出 JS 模块
30
+ import CesiumMap, { basicConfig, setPoint, movePointConfig } from 'huweili-cesium'
31
+
32
+ // 仅 JS 模块(不含 Vue 组件)可用子路径
33
+ import { basicConfig } from 'huweili-cesium/js'
34
+
35
+ // 或按文件引入
36
+ import { basicConfig } from 'huweili-cesium/basis'
37
+ import { hemisphereConfig } from 'huweili-cesium/hemisphere'
38
+ import { createCustomToolbarButtons } from 'huweili-cesium/customToolbarButtons'
39
+ ```
40
+
41
+ ### Vue 地图组件(开箱即用)
42
+
43
+ ```vue
44
+ <template>
45
+ <div class="map-page">
46
+ <CesiumMap map-id="default" @onload="onMapLoad" />
47
+ </div>
48
+ </template>
49
+
50
+ <script setup>
51
+ // 推荐:包主入口默认导出组件
52
+ import CesiumMap from 'huweili-cesium'
53
+ // 等价写法:
54
+ // import CesiumMap from 'huweili-cesium/index.vue'
55
+ // import CesiumMap from 'huweili-cesium/CesiumMap'
56
+
57
+ function onMapLoad({ map, center }) {
58
+ console.log('地图已加载', map, center)
59
+ }
60
+ </script>
61
+
62
+ <style scoped>
63
+ .map-page {
64
+ width: 100%;
65
+ height: 100vh;
66
+ }
67
+ </style>
68
+ ```
69
+
70
+ **Vite 宿主项目**需在 `vite.config` 中允许编译该依赖(否则 `.vue` 可能无法处理):
71
+
72
+ ```js
73
+ export default defineConfig({
74
+ optimizeDeps: {
75
+ include: ['huweili-cesium'],
76
+ },
77
+ })
78
+ ```
79
+
80
+ 组件 props:
81
+
82
+ | prop | 类型 | 默认 | 说明 |
83
+ |------|------|------|------|
84
+ | `mapId` | `string` | `'default'` | 多地图实例 ID,与 `mapStore` 对应 |
85
+ | `options` | `object` | — | 覆盖/合并 `MapConfig` 的配置 |
86
+
87
+ 事件:`@onload`,参数 `{ map, center, mapId, toolbar }`(`map` 为 Cesium `Viewer` 实例;`toolbar` 可在加载后动态增删按钮)。
88
+
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
+ ### 各项目自定义工具栏
101
+
102
+ **方式 1:组件 props(推荐)**
103
+
104
+ ```vue
105
+ <CesiumMap
106
+ map-id="default"
107
+ :show-default-toolbar="true"
108
+ :extra-toolbar-buttons="myExtraButtons"
109
+ />
110
+ ```
111
+
112
+ ```js
113
+ import { useEventBus } from 'huweili-cesium/utils/useEventBus'
114
+
115
+ const { emit } = useEventBus()
116
+
117
+ const myExtraButtons = [
118
+ {
119
+ title: '导出',
120
+ text: '导',
121
+ onClick: () => emit('exportMap', {}),
122
+ },
123
+ ]
124
+ ```
125
+
126
+ 完全不用内置默认按钮、自己定义一整组:
127
+
128
+ ```vue
129
+ <CesiumMap :toolbar-buttons="myToolbarButtons" />
130
+ ```
131
+
132
+ 内置默认按钮里的图标路径使用宿主项目的 `import.meta.env.BASE_URL`(如 `/images/new/tj.svg`),请在宿主 `public/images/new/` 放置对应资源;业务按钮(如「机型统计」)通过 `useEventBus` 发事件,宿主需自行 `on('toggleBarChartControl', ...)` 监听。
133
+
134
+ ## 可选业务钩子
135
+
136
+ 若需光电引导、轨迹列表等业务能力,在应用启动时注入:
137
+
138
+ ```js
139
+ import { setDroneMapProvider, setOptGuideHandler } from 'huweili-cesium/config/hooks'
140
+
141
+ setDroneMapProvider(() => myDroneMap)
142
+ setOptGuideHandler((payload) => api.toOptGuide(payload))
143
+ ```
144
+
145
+ ## 发布到 npm(维护者)
146
+
147
+ 项目根目录已配置 `.npmrc`(Token 授权,见 `.npmrc.example`),**无需执行 `npm login`**。安装依赖走 npmmirror 镜像,发布通过 `package.json` 中的 `publishConfig` 固定到 npm 官方源。
148
+
149
+ ### 发布步骤
150
+
151
+ 1. 修改 `package.json` 中的 `version`(须高于 npm 上已有版本)
152
+ 2. 在项目根目录执行:
153
+
154
+ ```bash
155
+ npm publish
156
+ ```
157
+
158
+ ### 仅验证打包内容(不上传)
159
+
160
+ ```bash
161
+ npm publish --dry-run
162
+ ```
163
+
164
+ ### 本地打包预览
165
+
166
+ ```bash
167
+ npm pack
168
+ # 会生成 huweili-cesium-x.y.z.tgz,解压检查是否包含全部 js
169
+ ```
170
+
171
+ ### 验证登录与最新版本
172
+
173
+ ```bash
174
+ npm whoami --registry=https://registry.npmjs.org/
175
+ npm view huweili-cesium version --registry=https://registry.npmjs.org/
176
+ ```
177
+
178
+ ## 从 tzr 源目录同步更新
179
+
180
+ ```bash
181
+ cd huweili-cesium
182
+ npm run sync
183
+ # 同步后需重新修复 @/ 别名为包内相对路径(见 scripts)
184
+ ```
185
+
186
+ ## 地图与自定义工具栏
187
+
188
+ 地图组件来自 npm 包 **`huweili-cesium`**,工具栏按钮在业务侧配置,不写在 `mapConfig.js` 里。
189
+
190
+ ### 1. 前置配置(`constants.js` / `mapConfig.js`)
191
+
192
+ `index.html` 中已按顺序引入:
193
+
194
+ ```html
195
+ <script src="/config/constants.js"></script>
196
+ <script src="/config/mapConfig.js"></script>
197
+ ```
198
+
199
+ | 文件 | 作用 | 与地图组件的关系 |
200
+ |------|------|------------------|
201
+ | `public/config/constants.js` | `window.MapInstanceIds` 定义多地图 ID(如 `HOME: 'home-main-map'`) | `:map-id` 须与之一致,工具栏回调里的 `mapId` 也要传同一个值 |
202
+ | `public/config/mapConfig.js` | `window.MapConfig`(中心点、2D/3D、底图列表、是否显示 Cesium 自带控件等) | 控制地图初始化;`control.homeButton: false` 时由自定义工具栏替代 |
203
+
204
+ 在页面中引用常量(从 `runtimeConfig` 导入):
205
+
206
+ ```js
207
+ import { MapInstanceIds } from '@/config/runtimeConfig'
208
+
209
+ const HOME_MAP_ID = MapInstanceIds?.HOME || 'home-main-map'
210
+ ```
211
+
212
+ ### 2. 页面引用 `CesiumMap`(首页示例)
213
+
214
+ `src/views/home/indexnew.vue`:
215
+
216
+ ```vue
217
+ <template>
218
+ <CesiumMap
219
+ :map-id="HOME_MAP_ID"
220
+ :toolbar-buttons="getHomeToolbarButtons({ mapId: HOME_MAP_ID })"
221
+ @onload="mapOnLoad"
222
+ />
223
+ </template>
224
+
225
+ <script setup>
226
+ import CesiumMap from 'huweili-cesium'
227
+ import { MapInstanceIds } from '@/config/runtimeConfig'
228
+ import { getHomeToolbarButtons } from '@/utils/homeToolbarButtons'
229
+
230
+ const HOME_MAP_ID = MapInstanceIds?.HOME || 'home-main-map'
231
+ </script>
232
+ ```
233
+
234
+ - **`toolbar-buttons`**:传入整组按钮(首页不用包内默认按钮,因此不必再写 `show-default-toolbar`)
235
+ - **`map-id`**:与 `constants.js` 里 `MapInstanceIds.HOME` 保持一致
236
+
237
+ ### 3. 工具栏按钮配置(`src/utils/homeToolbarButtons.js`)
238
+
239
+ 通用按钮(指北针、机型统计、回中心、2D/3D、缩放、底图、全屏)集中在此文件维护。
240
+
241
+ 页面只需追加自己的按钮时,使用 `extra`:
242
+
243
+ ```js
244
+ import { useEventBus } from 'huweili-cesium/utils/useEventBus'
245
+ import { getHomeToolbarButtons } from '@/utils/homeToolbarButtons'
246
+
247
+ const { emit } = useEventBus()
248
+
249
+ getHomeToolbarButtons({
250
+ mapId: HOME_MAP_ID,
251
+ extra: [
252
+ {
253
+ title: '导出',
254
+ text: '导',
255
+ onClick: () => emit('exportMap', {}),
256
+ },
257
+ ],
258
+ })
259
+ ```
260
+
261
+ 按钮项字段说明:
262
+
263
+ | 字段 | 说明 |
264
+ |------|------|
265
+ | `title` | 悬停提示 |
266
+ | `text` / `iconSrc` | 文字或图标(二选一,图标放 `public/images/new/`) |
267
+ | `isCompass: true` | 指北针专用 |
268
+ | `onClick(viewer, button)` | 点击回调 |
269
+
270
+ 「机型统计」等通过 `useEventBus` 发事件,页面需 `on('toggleBarChartControl', ...)` 监听。
271
+
272
+ ### 4. 其他页面
273
+
274
+ - 复用首页整套按钮:`getHomeToolbarButtons({ mapId: '你的 mapId' })`
275
+ - 完全自定义:直接传数组给 `:toolbar-buttons="[...]"`
276
+ - 地图加载后动态增删:在 `@onload` 回调里使用返回的 `toolbar.addToolbarButton(...)`
277
+
278
+ 图标资源路径使用 `import.meta.env.BASE_URL`(如 `/jlap/images/new/xxx.svg`),请放在 `public/images/new/`。
279
+
280
+ ## 目录结构
281
+
282
+ ```
283
+ huweili-cesium/
284
+ ├── index.js # npm 主入口(默认导出 CesiumMap + 转发 js 模块)
285
+ ├── index.vue # 地图 Vue 组件
286
+ ├── components/ # 组件(如 wsIndicator)
287
+ ├── js/ # 全部 JS 模块
288
+ │ ├── basis.js
289
+ │ ├── toolbar/
290
+ │ ├── stores/
291
+ │ ├── utils/
292
+ │ ├── config/
293
+ │ └── api/
294
+ └── package.json
295
+ ```
296
+
297
+ ## 包含的文件清单(均在 `js/` 下)
298
+
299
+ | 文件 | 说明 |
300
+ |------|------|
301
+ | js/basis.js | 地图基础操作 |
302
+ | js/setPoint.js / js/movePoint.js | 点位与移动 |
303
+ | js/setPath.js / js/movePath.js | 路径与轨迹 |
304
+ | js/groundLink.js | 地面连接线 |
305
+ | js/hemisphere.js | 半球区域 |
306
+ | js/geometry.js | 几何图形 |
307
+ | js/drawFence.js / js/drawFenceNew.js | 电子围栏 |
308
+ | js/cardPool.js / js/labelDiv.js | 信息牌 |
309
+ | js/clickHandler.js | 点击交互 |
310
+ | js/tileProviders.js | 底图瓦片 |
311
+ | js/customToolbarButtons.js | 工具栏 |
312
+ | js/toolbar/* | 指南针、底图切换、缩放、全屏 |
313
+ | js/droneRipple.js / js/qrCodeGenerator.js | 涟漪、二维码 |
314
+
315
+ 另含 `js/stores/mapStore.js`、`js/utils/*`、`js/config/*`、`js/api/*` 等运行依赖。
package/js/basis.js CHANGED
@@ -874,6 +874,7 @@ export function basicConfig() {
874
874
  id: `home_bearing_${Date.now()}`,
875
875
  mapId,
876
876
  color: '#ffd400',
877
+ width: 3,
877
878
  })
878
879
  },
879
880
  },
@@ -1006,6 +1006,8 @@ export function drawFenceNew() {
1006
1006
  let ellipseEntity = null
1007
1007
  // tipEntity:提示文字实体(显示"点击确定圆心"等提示)
1008
1008
  let tipEntity = null
1009
+ // radiusLabelEntity:绘制过程中显示当前半径的标签
1010
+ let radiusLabelEntity = null
1009
1011
  // nameLabelEntity:围栏名称标签实体
1010
1012
  let nameLabelEntity = null
1011
1013
  // handler:屏幕事件处理器(监听鼠标点击、移动等)
@@ -1019,7 +1021,8 @@ export function drawFenceNew() {
1019
1021
  ellipse: `${options.id}_draw_circle_wall`, // 临时椭圆围栏
1020
1022
  center: `${options.id}_draw_center_point`, // 临时圆心点
1021
1023
  active: `${options.id}_draw_active_point`, // 临时边界点
1022
- tip: `${options.id}_draw_tip` // 临时提示文字
1024
+ tip: `${options.id}_draw_tip`, // 临时提示文字
1025
+ radiusLabel: `${options.id}_draw_radius_label`, // 临时半径标签
1023
1026
  }
1024
1027
 
1025
1028
  // ==================== 辅助函数部分 ====================
@@ -1078,6 +1081,23 @@ export function drawFenceNew() {
1078
1081
  return geodesic.surfaceDistance
1079
1082
  }
1080
1083
 
1084
+ const formatRadius = (radius) => {
1085
+ if (!Number.isFinite(radius)) return '0 m'
1086
+ if (radius >= 1000) return `${(radius / 1000).toFixed(2)} km`
1087
+ return `${radius.toFixed(2)} m`
1088
+ }
1089
+
1090
+ const getRadiusLabelPosition = () => {
1091
+ if (!centerPosition || !edgePosition) return null
1092
+ const centerCartographic = Cesium.Cartographic.fromCartesian(centerPosition)
1093
+ const edgeCartographic = Cesium.Cartographic.fromCartesian(edgePosition)
1094
+ return Cesium.Cartesian3.fromRadians(
1095
+ (centerCartographic.longitude + edgeCartographic.longitude) / 2,
1096
+ (centerCartographic.latitude + edgeCartographic.latitude) / 2,
1097
+ 0,
1098
+ )
1099
+ }
1100
+
1081
1101
  /**
1082
1102
  * 获取提示文字的位置(鼠标位置优先)
1083
1103
  *
@@ -1099,7 +1119,7 @@ export function drawFenceNew() {
1099
1119
  }
1100
1120
 
1101
1121
  // 已经有圆心 → 提示用户"移动调整半径,点击或右键完成"
1102
- return '移动鼠标调整半径,点击或右键完成绘制'
1122
+ return `移动鼠标调整半径,当前半径:${formatRadius(getRadius())},点击或右键完成绘制`
1103
1123
  }
1104
1124
 
1105
1125
  /**
@@ -1180,7 +1200,32 @@ export function drawFenceNew() {
1180
1200
  })
1181
1201
  }
1182
1202
 
1183
- // 4. 创建提示文字实体(如果还没有)
1203
+ // 4. 创建半径标签(确定圆心后显示)
1204
+ if (!radiusLabelEntity && centerPosition) {
1205
+ radiusLabelEntity = map.entities.add({
1206
+ id: tempIds.radiusLabel,
1207
+ position: new Cesium.CallbackProperty(() => getRadiusLabelPosition(), false),
1208
+ label: {
1209
+ text: new Cesium.CallbackProperty(() => formatRadius(getRadius()), false),
1210
+ font: 'bold 10px Microsoft YaHei',
1211
+ fillColor: Cesium.Color.WHITE,
1212
+ style: Cesium.LabelStyle.FILL_AND_OUTLINE,
1213
+ outlineColor: Cesium.Color.BLACK,
1214
+ outlineWidth: 2,
1215
+ showBackground: true,
1216
+ backgroundColor: Cesium.Color.fromCssColorString('rgba(0, 0, 0, 0.75)'),
1217
+ backgroundPadding: new Cesium.Cartesian2(4, 4),
1218
+ verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
1219
+ horizontalOrigin: Cesium.HorizontalOrigin.CENTER,
1220
+ pixelOffset: new Cesium.Cartesian2(0, -16),
1221
+ disableDepthTestDistance: Number.POSITIVE_INFINITY,
1222
+ distanceDisplayCondition: new Cesium.DistanceDisplayCondition(0, 2000000),
1223
+ scaleByDistance: new Cesium.NearFarScalar(1000, 1.2, 5000000, 0.6),
1224
+ },
1225
+ })
1226
+ }
1227
+
1228
+ // 5. 创建提示文字实体(如果还没有)
1184
1229
  if (!tipEntity) {
1185
1230
  tipEntity = createMouseTipEntity(map, {
1186
1231
  id: tempIds.tip,
@@ -1196,7 +1241,7 @@ export function drawFenceNew() {
1196
1241
  */
1197
1242
  const cleanupTempEntities = () => {
1198
1243
  // 遍历所有临时实体,如果存在就从地图上移除
1199
- ;[ellipseEntity, centerPointEntity, activePointEntity, tipEntity, nameLabelEntity].forEach((entity) => {
1244
+ ;[ellipseEntity, centerPointEntity, activePointEntity, radiusLabelEntity, tipEntity, nameLabelEntity].forEach((entity) => {
1200
1245
  if (entity) {
1201
1246
  map.entities.remove(entity)
1202
1247
  }
@@ -1205,6 +1250,7 @@ export function drawFenceNew() {
1205
1250
  ellipseEntity = null
1206
1251
  centerPointEntity = null
1207
1252
  activePointEntity = null
1253
+ radiusLabelEntity = null
1208
1254
  nameLabelEntity = null
1209
1255
  }
1210
1256
 
@@ -1273,13 +1319,14 @@ export function drawFenceNew() {
1273
1319
 
1274
1320
  await applyTerrainWallToEntity(map, fenceEntity, circleLngLats, height)
1275
1321
 
1276
- ;[centerPointEntity, activePointEntity, tipEntity].forEach((entity) => {
1322
+ ;[centerPointEntity, activePointEntity, radiusLabelEntity, tipEntity].forEach((entity) => {
1277
1323
  if (entity) {
1278
1324
  map.entities.remove(entity)
1279
1325
  }
1280
1326
  })
1281
1327
  centerPointEntity = null
1282
1328
  activePointEntity = null
1329
+ radiusLabelEntity = null
1283
1330
  tipEntity = null
1284
1331
 
1285
1332
  const centerHeights = await sampleTerrainHeights(map, [centerData])
@@ -115,6 +115,8 @@ export function measureBearing() {
115
115
  }
116
116
 
117
117
  const color = Cesium.Color.fromCssColorString(options.color || '#ffd400')
118
+ const width = options.width ?? 3
119
+ const clampToGround = options.clampToGround ?? true
118
120
 
119
121
  let startPosition = null
120
122
  let endPosition = null
@@ -194,9 +196,10 @@ export function measureBearing() {
194
196
  id: tempIds.line,
195
197
  polyline: {
196
198
  positions: new Cesium.CallbackProperty(() => getLinePositions(), false),
197
- width: 3,
199
+ width: width + 2,
198
200
  material: new Cesium.PolylineGlowMaterialProperty({ color, glowPower: 0.25 }),
199
- clampToGround: true,
201
+ clampToGround,
202
+ antialias: true,
200
203
  },
201
204
  })
202
205
  }
@@ -220,6 +223,7 @@ export function measureBearing() {
220
223
  pixelOffset: new Cesium.Cartesian2(0, -16),
221
224
  disableDepthTestDistance: Number.POSITIVE_INFINITY,
222
225
  distanceDisplayCondition: new Cesium.DistanceDisplayCondition(0, 2000000),
226
+ scaleByDistance: new Cesium.NearFarScalar(1000, 1.2, 5000000, 0.6),
223
227
  },
224
228
  })
225
229
  }
@@ -242,7 +246,69 @@ export function measureBearing() {
242
246
  })
243
247
  }
244
248
 
249
+ const createDeleteButtonEntity = () => {
250
+ if (deleteButtonEntity || !endPosition) return
251
+ const outerGlow = map.entities.add({
252
+ id: `${tempIds.deleteButton}_outer_glow`,
253
+ position: new Cesium.CallbackProperty(() => getMidPosition(), false),
254
+ point: {
255
+ pixelSize: 32,
256
+ color: color.withAlpha(0.15),
257
+ disableDepthTestDistance: Number.POSITIVE_INFINITY,
258
+ heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
259
+ scaleByDistance: new Cesium.NearFarScalar(1000, 1.2, 5000000, 0.5),
260
+ },
261
+ })
262
+ const ring = map.entities.add({
263
+ id: `${tempIds.deleteButton}_ring`,
264
+ position: new Cesium.CallbackProperty(() => getMidPosition(), false),
265
+ ellipse: {
266
+ semiMinorAxis: 14,
267
+ semiMajorAxis: 14,
268
+ material: color.withAlpha(0.6),
269
+ outline: true,
270
+ outlineColor: color.withAlpha(0.9),
271
+ outlineWidth: 2,
272
+ height: 10,
273
+ disableDepthTestDistance: Number.POSITIVE_INFINITY,
274
+ scaleByDistance: new Cesium.NearFarScalar(1000, 1.2, 5000000, 0.5),
275
+ },
276
+ })
277
+ deleteButtonEntity = map.entities.add({
278
+ id: tempIds.deleteButton,
279
+ position: new Cesium.CallbackProperty(() => getMidPosition(), false),
280
+ point: {
281
+ pixelSize: 18,
282
+ color: new Cesium.Color(0.1, 0.2, 0.35, 0.95),
283
+ outlineColor: color.withAlpha(1),
284
+ outlineWidth: 2,
285
+ disableDepthTestDistance: Number.POSITIVE_INFINITY,
286
+ heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
287
+ scaleByDistance: new Cesium.NearFarScalar(1000, 1.2, 5000000, 0.5),
288
+ },
289
+ label: {
290
+ text: '✕',
291
+ font: 'bold 12px Arial',
292
+ fillColor: color.withAlpha(1),
293
+ style: Cesium.LabelStyle.FILL_AND_OUTLINE,
294
+ outlineColor: new Cesium.Color(color.red * 0.6, color.green * 0.6, color.blue * 0.6, 0.8),
295
+ outlineWidth: 3,
296
+ verticalOrigin: Cesium.VerticalOrigin.CENTER,
297
+ horizontalOrigin: Cesium.HorizontalOrigin.CENTER,
298
+ disableDepthTestDistance: Number.POSITIVE_INFINITY,
299
+ distanceDisplayCondition: new Cesium.DistanceDisplayCondition(0, 2000000),
300
+ scaleByDistance: new Cesium.NearFarScalar(1000, 1.2, 5000000, 0.5),
301
+ },
302
+ })
303
+ deleteButtonEntity.outerGlow = outerGlow
304
+ deleteButtonEntity.ring = ring
305
+ }
306
+
245
307
  const removeEntities = () => {
308
+ if (deleteButtonEntity) {
309
+ if (deleteButtonEntity.outerGlow) map.entities.remove(deleteButtonEntity.outerGlow)
310
+ if (deleteButtonEntity.ring) map.entities.remove(deleteButtonEntity.ring)
311
+ }
246
312
  [startPointEntity, endPointEntity, lineEntity, labelEntity, deleteButtonEntity, tipEntity].forEach((entity) => {
247
313
  if (entity) map.entities.remove(entity)
248
314
  })
@@ -289,28 +355,17 @@ export function measureBearing() {
289
355
  }
290
356
 
291
357
  createEndPointEntity()
292
-
293
- deleteButtonEntity = map.entities.add({
294
- id: tempIds.deleteButton,
295
- position: new Cesium.CallbackProperty(() => getMidPosition(), false),
296
- label: {
297
- text: '✕',
298
- font: 'bold 12px Arial',
299
- fillColor: color,
300
- style: Cesium.LabelStyle.FILL_AND_OUTLINE,
301
- outlineColor: Cesium.Color.BLACK,
302
- outlineWidth: 2,
303
- verticalOrigin: Cesium.VerticalOrigin.CENTER,
304
- horizontalOrigin: Cesium.HorizontalOrigin.CENTER,
305
- disableDepthTestDistance: Number.POSITIVE_INFINITY,
306
- },
307
- })
358
+ createDeleteButtonEntity()
308
359
 
309
360
  deleteHandler = new Cesium.ScreenSpaceEventHandler(map.scene.canvas)
310
361
  deleteHandler.setInputAction((movement) => {
311
362
  const picked = map.scene.pick(movement.position)
312
- if (!Cesium.defined(picked?.id)) return
313
- if (picked.id === deleteButtonEntity || picked.id === tempIds.deleteButton) {
363
+ if (!Cesium.defined(picked)) return
364
+ const pickedEntity = picked.id
365
+ if (!Cesium.defined(pickedEntity)) return
366
+ if (typeof pickedEntity === 'string' && pickedEntity === tempIds.deleteButton) {
367
+ destroyGraphic()
368
+ } else if (pickedEntity === deleteButtonEntity) {
314
369
  destroyGraphic()
315
370
  }
316
371
  }, Cesium.ScreenSpaceEventType.LEFT_CLICK)
package/js/setPath.js CHANGED
@@ -1,126 +1,126 @@
1
- /**
2
- * 轨迹设置模块
3
- *
4
- * 提供在Cesium地图上设置无人机轨迹的功能
5
- *
6
- * @author huweili
7
- * @email czxyhuweili@163.com
8
- * @version 1.0.0
9
- */
10
- import * as Cesium from 'cesium'
11
- import { useMapStore } from './stores/mapStore.js'
12
- import { DroneStatus, DroneStatusMap, MapInstanceIds } from './config/index.js'
13
-
14
- export function setPath() {
15
- // 获取地图store实例
16
- const mapStore = useMapStore()
17
-
18
- /**
19
- * 创建无人机轨迹
20
- * @param pointId 无人机ID
21
- * @param startPosition 初始位置
22
- * @param status 无人机状态标识
23
- * @param mapId 地图实例ID
24
- * @returns 轨迹数据
25
- */
26
- const setDroneTrail = (options) => {
27
- const { pointId, startPosition, status = DroneStatus.WHITELIST, mapId } = options
28
- const map = mapStore.getMap(mapId)
29
- if (!map) return
30
-
31
- const trailId = `${pointId}_trail`
32
-
33
- // 如果轨迹已存在,直接返回
34
- if (mapStore.hasDroneTrail(pointId, mapId)) {
35
- console.log(`轨迹 ${trailId} 已存在`)
36
- return mapStore.getDroneTrail(pointId, mapId)
37
- }
38
-
39
- // 获取状态配置
40
- const statusConfig = DroneStatusMap[status]
41
- const trailColor = statusConfig ? Cesium.Color.fromCssColorString(statusConfig.trailColor) : Cesium.Color.fromCssColorString('rgba(0, 255, 145, 1)')
42
-
43
- // 轨迹实例
44
- const initialPosition = startPosition.clone()
45
- let trailData = {
46
- entity: null, // 轨迹实体
47
- positions: [{ position: initialPosition, timestamp: map.clock.currentTime }], // 轨迹位置数组,包含位置和时间戳
48
- renderPositions: [initialPosition], // Cesium渲染直接复用的坐标数组,避免每帧 map 生成新数组
49
- lastUpdateTime: map.clock.currentTime, // 最后更新时间
50
- isVisible: true, // 是否可见
51
- }
52
- trailData.entity = map.entities.add({
53
- id: trailId,
54
- name: `无人机轨迹:${pointId}`,
55
- show: true,
56
- polyline: {
57
- positions: new Cesium.CallbackProperty(() => {
58
- const trailData = mapStore.getDroneTrail(pointId, mapId)
59
- return trailData ? trailData.renderPositions : []
60
- }, false),
61
- width: 2,
62
- material: trailColor,
63
- arcType: Cesium.ArcType.NONE,// 直线连接 - 点与点之间用直线段连接
64
- clampToGround: false
65
- }
66
- })
67
-
68
- mapStore.setDroneTrail(pointId, trailData, mapId)
69
- // console.log(`创建轨迹: ${trailId}, 初始位置数: 1`)
70
- return trailData;
71
- }
72
-
73
- /**
74
- * 清除无人机轨迹
75
- */
76
- const clearDroneTrail = (droneId, mapId) => {
77
- const trailId = `${droneId}_trail`
78
- const trailData = mapStore.getDroneTrail(droneId, mapId)
79
-
80
- if (trailData) {
81
- const map = mapStore.getMap(mapId)
82
- if (map && trailData.entity) {
83
- // 先设置轨迹不可见
84
- // trailData.entity.show = false
85
- // 强制移除轨迹实体
86
- map.entities.remove(trailData.entity)
87
- trailData.entity = null
88
- }
89
- // 清空轨迹点
90
- if (trailData.positions) {
91
- trailData.positions = []
92
- }
93
- if (trailData.renderPositions) {
94
- trailData.renderPositions = []
95
- }
96
- // 设置轨迹不可见
97
- // trailData.isVisible = false
98
- // 从store中清除
99
- mapStore.clearDroneTrail(droneId, mapId)
100
- console.log(`已清除轨迹: ${trailId}`)
101
- }
102
- }
103
-
104
- /**
105
- * 显示/隐藏无人机轨迹
106
- * @param options 配置选项
107
- * @param options.pointId 点ID
108
- * @param options.visible 是否显示
109
- */
110
- const toggleDroneTrail = (options) => {
111
- const { pointId, visible, mapId } = options
112
- const trailId = `${pointId}_trail`
113
- const trailData = mapStore.getDroneTrail(pointId, mapId)
114
-
115
- if (trailData && trailData.entity) {
116
- trailData.entity.show = visible
117
- trailData.isVisible = visible
118
- }
119
- }
120
-
121
- return {
122
- setDroneTrail,
123
- clearDroneTrail,
124
- toggleDroneTrail
125
- }
1
+ /**
2
+ * 轨迹设置模块
3
+ *
4
+ * 提供在Cesium地图上设置无人机轨迹的功能
5
+ *
6
+ * @author huweili
7
+ * @email czxyhuweili@163.com
8
+ * @version 1.0.0
9
+ */
10
+ import * as Cesium from 'cesium'
11
+ import { useMapStore } from './stores/mapStore.js'
12
+ import { DroneStatus, DroneStatusMap, MapInstanceIds } from './config/index.js'
13
+
14
+ export function setPath() {
15
+ // 获取地图store实例
16
+ const mapStore = useMapStore()
17
+
18
+ /**
19
+ * 创建无人机轨迹
20
+ * @param pointId 无人机ID
21
+ * @param startPosition 初始位置
22
+ * @param status 无人机状态标识
23
+ * @param mapId 地图实例ID
24
+ * @returns 轨迹数据
25
+ */
26
+ const setDroneTrail = (options) => {
27
+ const { pointId, startPosition, status = DroneStatus.WHITELIST, mapId } = options
28
+ const map = mapStore.getMap(mapId)
29
+ if (!map) return
30
+
31
+ const trailId = `${pointId}_trail`
32
+
33
+ // 如果轨迹已存在,直接返回
34
+ if (mapStore.hasDroneTrail(pointId, mapId)) {
35
+ console.log(`轨迹 ${trailId} 已存在`)
36
+ return mapStore.getDroneTrail(pointId, mapId)
37
+ }
38
+
39
+ // 获取状态配置
40
+ const statusConfig = DroneStatusMap[status]
41
+ const trailColor = statusConfig ? Cesium.Color.fromCssColorString(statusConfig.trailColor) : Cesium.Color.fromCssColorString('rgba(0, 255, 145, 1)')
42
+
43
+ // 轨迹实例
44
+ const initialPosition = startPosition.clone()
45
+ let trailData = {
46
+ entity: null, // 轨迹实体
47
+ positions: [{ position: initialPosition, timestamp: map.clock.currentTime }], // 轨迹位置数组,包含位置和时间戳
48
+ renderPositions: [initialPosition], // Cesium渲染直接复用的坐标数组,避免每帧 map 生成新数组
49
+ lastUpdateTime: map.clock.currentTime, // 最后更新时间
50
+ isVisible: true, // 是否可见
51
+ }
52
+ trailData.entity = map.entities.add({
53
+ id: trailId,
54
+ name: `无人机轨迹:${pointId}`,
55
+ show: true,
56
+ polyline: {
57
+ positions: new Cesium.CallbackProperty(() => {
58
+ const trailData = mapStore.getDroneTrail(pointId, mapId)
59
+ return trailData ? trailData.renderPositions : []
60
+ }, false),
61
+ width: 2,
62
+ material: trailColor,
63
+ arcType: Cesium.ArcType.NONE,// 直线连接 - 点与点之间用直线段连接
64
+ clampToGround: false
65
+ }
66
+ })
67
+
68
+ mapStore.setDroneTrail(pointId, trailData, mapId)
69
+ // console.log(`创建轨迹: ${trailId}, 初始位置数: 1`)
70
+ return trailData;
71
+ }
72
+
73
+ /**
74
+ * 清除无人机轨迹
75
+ */
76
+ const clearDroneTrail = (droneId, mapId) => {
77
+ const trailId = `${droneId}_trail`
78
+ const trailData = mapStore.getDroneTrail(droneId, mapId)
79
+
80
+ if (trailData) {
81
+ const map = mapStore.getMap(mapId)
82
+ if (map && trailData.entity) {
83
+ // 先设置轨迹不可见
84
+ // trailData.entity.show = false
85
+ // 强制移除轨迹实体
86
+ map.entities.remove(trailData.entity)
87
+ trailData.entity = null
88
+ }
89
+ // 清空轨迹点
90
+ if (trailData.positions) {
91
+ trailData.positions = []
92
+ }
93
+ if (trailData.renderPositions) {
94
+ trailData.renderPositions = []
95
+ }
96
+ // 设置轨迹不可见
97
+ // trailData.isVisible = false
98
+ // 从store中清除
99
+ mapStore.clearDroneTrail(droneId, mapId)
100
+ console.log(`已清除轨迹: ${trailId}`)
101
+ }
102
+ }
103
+
104
+ /**
105
+ * 显示/隐藏无人机轨迹
106
+ * @param options 配置选项
107
+ * @param options.pointId 点ID
108
+ * @param options.visible 是否显示
109
+ */
110
+ const toggleDroneTrail = (options) => {
111
+ const { pointId, visible, mapId } = options
112
+ const trailId = `${pointId}_trail`
113
+ const trailData = mapStore.getDroneTrail(pointId, mapId)
114
+
115
+ if (trailData && trailData.entity) {
116
+ trailData.entity.show = visible
117
+ trailData.isVisible = visible
118
+ }
119
+ }
120
+
121
+ return {
122
+ setDroneTrail,
123
+ clearDroneTrail,
124
+ toggleDroneTrail
125
+ }
126
126
  }
@@ -1,94 +1,94 @@
1
- /**
2
- * 地图全屏控制器
3
- * 提供地图全屏切换功能
4
- *
5
- * @author huweili
6
- * @email czxyhuweili@163.com
7
- * @version 1.0.0
8
- */
9
-
10
- /**
11
- * 触发 Cesium 视图重新调整大小和渲染
12
- * 用于全屏切换后确保地图正确渲染
13
- * @param {import('cesium').Viewer} viewer - Cesium Viewer 实例
14
- */
15
- const resizeViewer = (viewer) => {
16
- requestAnimationFrame(() => {
17
- if (viewer && !viewer.isDestroyed()) {
18
- viewer.resize()
19
- viewer.scene.requestRender()
20
- }
21
- })
22
- }
23
-
24
- /**
25
- * 设置全屏按钮的图标
26
- * 根据全屏状态切换显示全屏图标或退出全屏图标
27
- * @param {HTMLButtonElement} button - 全屏按钮元素
28
- * @param {boolean} isFullscreen - 当前是否为全屏状态
29
- */
30
- const setFullscreenButtonIcon = (button, isFullscreen) => {
31
- const img = button.querySelector('img')
32
- if (!img) return
33
-
34
- img.src = `${import.meta.env.BASE_URL}/images/new/${isFullscreen ? 'nofullScreen' : 'fullScreen'}.svg`
35
- }
36
-
37
- /**
38
- * 切换地图全屏模式
39
- * 通过添加/移除 CSS 类实现地图容器全屏,而非浏览器全屏
40
- * @param {import('cesium').Viewer} viewer - Cesium Viewer 实例
41
- * @param {HTMLButtonElement} button - 触发全屏的按钮元素,用于更新按钮文字和标题
42
- */
43
- const toggleMapFullscreen = (viewer, button) => {
44
- const container = viewer.container
45
- const isFullscreen = container.classList.toggle('cesium-map-custom-fullscreen')
46
-
47
- button.title = isFullscreen ? '退出地图全屏' : '地图全屏'
48
- setFullscreenButtonIcon(button, isFullscreen)
49
- resizeViewer(viewer)
50
- }
51
-
52
- /**
53
- * 动态注入全屏样式到页面头部
54
- * 确保全屏时地图容器占满整个视口
55
- */
56
- const addMapFullscreenStyle = () => {
57
- const styleId = 'cesium-map-custom-fullscreen-style'
58
- if (document.getElementById(styleId)) return
59
-
60
- const style = document.createElement('style')
61
- style.id = styleId
62
- style.textContent = `
63
- .cesium-map-custom-fullscreen {
64
- position: fixed !important;
65
- inset: 0 !important;
66
- width: 100vw !important;
67
- height: 100vh !important;
68
- z-index: 2147483647 !important;
69
- background: #000 !important;
70
- }
71
-
72
- .cesium-map-custom-fullscreen .cesium-viewer,
73
- .cesium-map-custom-fullscreen .cesium-viewer-cesiumWidgetContainer,
74
- .cesium-map-custom-fullscreen .cesium-widget,
75
- .cesium-map-custom-fullscreen .cesium-widget canvas {
76
- width: 100% !important;
77
- height: 100% !important;
78
- }
79
- `
80
- document.head.appendChild(style)
81
- }
82
-
83
- /**
84
- * 创建全屏控制器
85
- * @returns {Object} 包含全屏操作方法的对象
86
- */
87
- export const createFullscreenController = () => {
88
- // 初始化时注入样式
89
- addMapFullscreenStyle()
90
-
91
- return {
92
- toggleMapFullscreen
93
- }
94
- }
1
+ /**
2
+ * 地图全屏控制器
3
+ * 提供地图全屏切换功能
4
+ *
5
+ * @author huweili
6
+ * @email czxyhuweili@163.com
7
+ * @version 1.0.0
8
+ */
9
+
10
+ /**
11
+ * 触发 Cesium 视图重新调整大小和渲染
12
+ * 用于全屏切换后确保地图正确渲染
13
+ * @param {import('cesium').Viewer} viewer - Cesium Viewer 实例
14
+ */
15
+ const resizeViewer = (viewer) => {
16
+ requestAnimationFrame(() => {
17
+ if (viewer && !viewer.isDestroyed()) {
18
+ viewer.resize()
19
+ viewer.scene.requestRender()
20
+ }
21
+ })
22
+ }
23
+
24
+ /**
25
+ * 设置全屏按钮的图标
26
+ * 根据全屏状态切换显示全屏图标或退出全屏图标
27
+ * @param {HTMLButtonElement} button - 全屏按钮元素
28
+ * @param {boolean} isFullscreen - 当前是否为全屏状态
29
+ */
30
+ const setFullscreenButtonIcon = (button, isFullscreen) => {
31
+ const img = button.querySelector('img')
32
+ if (!img) return
33
+
34
+ img.src = `${import.meta.env.BASE_URL}/images/new/${isFullscreen ? 'nofullScreen' : 'fullScreen'}.svg`
35
+ }
36
+
37
+ /**
38
+ * 切换地图全屏模式
39
+ * 通过添加/移除 CSS 类实现地图容器全屏,而非浏览器全屏
40
+ * @param {import('cesium').Viewer} viewer - Cesium Viewer 实例
41
+ * @param {HTMLButtonElement} button - 触发全屏的按钮元素,用于更新按钮文字和标题
42
+ */
43
+ const toggleMapFullscreen = (viewer, button) => {
44
+ const container = viewer.container
45
+ const isFullscreen = container.classList.toggle('cesium-map-custom-fullscreen')
46
+
47
+ button.title = isFullscreen ? '退出地图全屏' : '地图全屏'
48
+ setFullscreenButtonIcon(button, isFullscreen)
49
+ resizeViewer(viewer)
50
+ }
51
+
52
+ /**
53
+ * 动态注入全屏样式到页面头部
54
+ * 确保全屏时地图容器占满整个视口
55
+ */
56
+ const addMapFullscreenStyle = () => {
57
+ const styleId = 'cesium-map-custom-fullscreen-style'
58
+ if (document.getElementById(styleId)) return
59
+
60
+ const style = document.createElement('style')
61
+ style.id = styleId
62
+ style.textContent = `
63
+ .cesium-map-custom-fullscreen {
64
+ position: fixed !important;
65
+ inset: 0 !important;
66
+ width: 100vw !important;
67
+ height: 100vh !important;
68
+ z-index: 2147483647 !important;
69
+ background: #000 !important;
70
+ }
71
+
72
+ .cesium-map-custom-fullscreen .cesium-viewer,
73
+ .cesium-map-custom-fullscreen .cesium-viewer-cesiumWidgetContainer,
74
+ .cesium-map-custom-fullscreen .cesium-widget,
75
+ .cesium-map-custom-fullscreen .cesium-widget canvas {
76
+ width: 100% !important;
77
+ height: 100% !important;
78
+ }
79
+ `
80
+ document.head.appendChild(style)
81
+ }
82
+
83
+ /**
84
+ * 创建全屏控制器
85
+ * @returns {Object} 包含全屏操作方法的对象
86
+ */
87
+ export const createFullscreenController = () => {
88
+ // 初始化时注入样式
89
+ addMapFullscreenStyle()
90
+
91
+ return {
92
+ toggleMapFullscreen
93
+ }
94
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "huweili-cesium",
3
- "version": "1.3.0",
3
+ "version": "1.3.2",
4
4
  "description": "基于 Cesium 的地图工具库(无人机态势、轨迹、围栏、工具栏等)",
5
5
  "type": "module",
6
6
  "main": "./index.js",