cesium-xs-sdk 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json ADDED
@@ -0,0 +1,78 @@
1
+ {
2
+ "name": "cesium-xs-sdk",
3
+ "version": "1.0.0",
4
+ "type": "module",
5
+ "description": "基于 Cesium 1.137 封装的 SDK",
6
+ "main": "dist/cesium-xs-sdk.cjs.js",
7
+ "module": "dist/cesium-xs-sdk.esm.js",
8
+ "browser": "dist/cesium-xs-sdk.umd.js",
9
+ "types": "src/index.d.ts",
10
+ "exports": {
11
+ ".": {
12
+ "import": "./dist/cesium-xs-sdk.esm.js",
13
+ "require": "./dist/cesium-xs-sdk.cjs.js",
14
+ "types": "./src/index.d.ts"
15
+ },
16
+ "./vue": {
17
+ "import": "./src/vue.js",
18
+ "types": "./src/vue.d.ts"
19
+ },
20
+ "./vue2": {
21
+ "import": "./src/vue2.js",
22
+ "types": "./src/vue2.d.ts"
23
+ },
24
+ "./react": {
25
+ "import": "./src/react.js",
26
+ "types": "./src/react.d.ts"
27
+ }
28
+ },
29
+ "files": [
30
+ "dist/",
31
+ "src/",
32
+ "README.md",
33
+ "package.json"
34
+ ],
35
+ "keywords": [
36
+ "cesium",
37
+ "gis",
38
+ "3d",
39
+ "sdk",
40
+ "cesium-xs-sdk"
41
+ ],
42
+ "author": "成都玄宿科技有限公司",
43
+ "license": "MIT",
44
+ "repository": {
45
+ "type": "git",
46
+ "url": "https://gitee.com/d1564427109/cesium-xs-sdk.git"
47
+ },
48
+ "scripts": {
49
+ "build": "rollup -c",
50
+ "package-offline": "node scripts/package-offline.js",
51
+ "release": "npm run build && npm run package-offline",
52
+ "prepublishOnly": "npm run build",
53
+ "test": "vitest run",
54
+ "test:unit": "vitest",
55
+ "test:e2e": "playwright test",
56
+ "test:e2e:ui": "playwright test --ui",
57
+ "test:coverage": "vitest run --coverage"
58
+ },
59
+ "dependencies": {
60
+ "cesium": "^1.137.0"
61
+ },
62
+ "devDependencies": {
63
+ "@playwright/test": "^1.45.0",
64
+ "@rollup/plugin-commonjs": "^25.0.7",
65
+ "@rollup/plugin-node-resolve": "^15.2.3",
66
+ "@rollup/plugin-replace": "^5.0.5",
67
+ "@rollup/plugin-terser": "^0.4.4",
68
+ "@rollup/plugin-typescript": "^12.3.0",
69
+ "@vitest/coverage-v8": "^2.0.0",
70
+ "archiver": "^7.0.1",
71
+ "http-server": "^14.1.1",
72
+ "jsdom": "^24.1.0",
73
+ "rollup": "^4.9.6",
74
+ "rollup-plugin-dts": "^6.4.1",
75
+ "typescript": "^5.5.0",
76
+ "vitest": "^2.0.0"
77
+ }
78
+ }
@@ -0,0 +1,176 @@
1
+ /**
2
+ * 全局配置类(对应平台 Application 单件)
3
+ * 管理 Cesium Token、默认参数、模块开关
4
+ */
5
+ export class Config {
6
+ static instance = null;
7
+ // 单例模式
8
+ static getInstance() {
9
+ if (!this.instance) {
10
+ this.instance = new Config();
11
+ }
12
+ return this.instance;
13
+ }
14
+
15
+ constructor() {
16
+ // 默认配置(对齐平台参数规范)
17
+ this.config = {
18
+ cesiumToken: '', // Cesium Ion Token
19
+ // 场景默认参数
20
+ scene: {
21
+ animation: false,
22
+ timeline: false,
23
+ baseLayerPicker: false,
24
+ fullscreenButton: false,
25
+ geocoder: false,
26
+ homeButton: false,
27
+ infoBox: false,
28
+ sceneModePicker: false,
29
+ selectionIndicator: false,
30
+ navigationHelpButton: false,
31
+ navigationInstructionsInitiallyVisible: false,
32
+ depthTestAgainstTerrain: true, // 默认开启深度检测
33
+ },
34
+ // 图元默认样式:延迟到 getConfig 时再构造,避免在 Cesium 未加载/未 mock 时崩溃
35
+ // (对 SSR 和单元测试更友好)
36
+ };
37
+ }
38
+
39
+ /**
40
+ * 构造图元默认样式(延迟初始化)
41
+ * @private
42
+ */
43
+ #getGraphicDefaults() {
44
+ if (typeof Cesium === 'undefined') {
45
+ return {};
46
+ }
47
+
48
+ const withAlpha = (color, alpha) => {
49
+ if (color && typeof color.withAlpha === 'function') {
50
+ return color.withAlpha(alpha);
51
+ }
52
+ return color;
53
+ };
54
+
55
+ return {
56
+ point: { pixelSize: 8, color: Cesium.Color.RED },
57
+ line: { width: 2, material: Cesium.Color.BLUE },
58
+ polygon: { color: withAlpha(Cesium.Color.GREEN, 0.5) },
59
+ plot: {
60
+ polygon: {
61
+ color: withAlpha(Cesium.Color.BLUE, 0.5),
62
+ outlineColor: Cesium.Color.BLUE,
63
+ outlineWidth: 2
64
+ },
65
+ line: {
66
+ material: Cesium.Color.BLUE,
67
+ width: 2
68
+ }
69
+ }
70
+ };
71
+ }
72
+
73
+ /**
74
+ * 设置全局配置(参数化配置)
75
+ * @param {Object} options 配置项(支持部分覆盖)
76
+ * @example
77
+ * Config.getInstance().setConfig({
78
+ * cesiumToken: 'your-token',
79
+ * scene: { terrainProvider: await Cesium.createWorldTerrainAsync() }
80
+ * });
81
+ */
82
+ setConfig(options) {
83
+ for (const k in options) {
84
+ // 1. 标量/数组/null -> 直接覆盖
85
+ if (
86
+ typeof options[k] !== 'object' ||
87
+ Array.isArray(options[k]) ||
88
+ options[k] === null
89
+ ) {
90
+ this.config[k] = options[k];
91
+ continue;
92
+ }
93
+
94
+ // 2. scene -> 深度缺省合并
95
+ if (k === 'scene') {
96
+ this.config.scene = this.config.scene || {};
97
+ this.#defaultsDeep(this.config.scene, options.scene);
98
+ continue;
99
+ }
100
+
101
+ // 3. 其他对象 -> 浅层缺省(或按需改成深度)
102
+ this.config[k] = this.config[k] || {};
103
+ this.#defaultsShallow(this.config[k], options[k]);
104
+ }
105
+
106
+ console.log('config', this.config);
107
+
108
+
109
+ // Token 同步
110
+ if (options.cesiumToken) {
111
+ Cesium.Ion.defaultAccessToken = options.cesiumToken;
112
+ }
113
+ }
114
+
115
+ /**
116
+ * 获取全局配置
117
+ * @returns {Object} 完整配置
118
+ */
119
+ getConfig() {
120
+ const graphicDefaults = this.#getGraphicDefaults();
121
+ const userGraphic = this.config.graphic || {};
122
+
123
+ // 深度合并 plot,避免用户只传 polygon 时丢失 line 默认样式
124
+ const plot = userGraphic.plot
125
+ ? { ...graphicDefaults.plot, ...userGraphic.plot }
126
+ : graphicDefaults.plot;
127
+
128
+ return {
129
+ ...this.config,
130
+ graphic: {
131
+ ...graphicDefaults,
132
+ ...userGraphic,
133
+ plot
134
+ }
135
+ };
136
+ }
137
+
138
+ #defaultsDeep(target, src) {
139
+ for (const k in src) {
140
+ const sv = src[k];
141
+ const tv = target[k];
142
+
143
+ // 1. 非对象 || 数组 || null -> 直接补缺失
144
+ if (typeof sv !== 'object' || Array.isArray(sv) || sv === null) {
145
+ if (!Object.prototype.hasOwnProperty.call(target, k)) {
146
+ target[k] = sv;
147
+ }
148
+ continue;
149
+ }
150
+
151
+ // 2. 特殊类实例(Promise、TerrainProvider…)-> 整棵补缺失,不展开
152
+ if (
153
+ sv instanceof Promise ||
154
+ (sv.constructor && sv.constructor.name !== 'Object') // 普通 Object 字面量才继续
155
+ ) {
156
+ if (!Object.prototype.hasOwnProperty.call(target, k)) {
157
+ target[k] = sv;
158
+ }
159
+ continue;
160
+ }
161
+
162
+ // 3. 普通对象 -> 递归
163
+ target[k] = tv || {};
164
+ this.#defaultsDeep(target[k], sv);
165
+ }
166
+ }
167
+
168
+ /* 浅层缺省工具 */
169
+ #defaultsShallow(target, src) {
170
+ for (const k in src) {
171
+ if (!Object.prototype.hasOwnProperty.call(target, k)) {
172
+ target[k] = src[k];
173
+ }
174
+ }
175
+ }
176
+ }
@@ -0,0 +1,157 @@
1
+ /**
2
+ * 模块管理器(对应平台 GetModule 逻辑)
3
+ * 统一管理场景、图元、事件模块的实例
4
+ */
5
+ import { SceneModule } from '../modules/SceneModule.js';
6
+ import { GraphicModule } from '../modules/GraphicModule.js';
7
+ import { EventModule } from '../modules/EventModule.js';
8
+ import { EditorModule } from '../modules/EditorModule.js';
9
+ import { Config } from './Config.js';
10
+
11
+ export class ModuleManager {
12
+ static instance = null;
13
+ static getInstance() {
14
+ if (!this.instance) {
15
+ this.instance = new ModuleManager();
16
+ }
17
+ return this.instance;
18
+ }
19
+
20
+ constructor() {
21
+ this.modules = new Map(); // 模块缓存
22
+ this.cesiumViewer = null; // Cesium Viewer 实例(全局唯一)
23
+ }
24
+
25
+ /**
26
+ * 初始化 Cesium 核心实例(插件初始化逻辑)
27
+ * @param {string|HTMLElement} container 容器ID/元素
28
+ * @returns {Cesium.Viewer} Cesium 实例
29
+ */
30
+ initViewer(container) {
31
+ if (this.cesiumViewer) return this.cesiumViewer;
32
+ const config = Config.getInstance().getConfig();
33
+
34
+ this.cesiumViewer = new Cesium.Viewer(container, config.scene);
35
+ // 隐藏版权信息(可选,对齐平台界面规范)
36
+ const creditContainer = this.cesiumViewer.cesiumWidget?.creditContainer;
37
+ if (creditContainer) {
38
+ creditContainer.style.display = 'none';
39
+ }
40
+
41
+ // 初始化所有模块(注入 Viewer 实例)
42
+ this.registerModule('SceneModule', new SceneModule(this.cesiumViewer));
43
+ this.registerModule('GraphicModule', new GraphicModule(this.cesiumViewer));
44
+ this.registerModule('EventModule', new EventModule(this.cesiumViewer));
45
+
46
+ // 初始化编辑器模块(依赖其他模块)
47
+ const editorModule = new EditorModule(this.cesiumViewer);
48
+ editorModule.setDependencies({
49
+ graphicModule: this.getModule('GraphicModule'),
50
+ eventModule: this.getModule('EventModule')
51
+ }).init();
52
+ this.registerModule('EditorModule', editorModule);
53
+
54
+ return this.cesiumViewer;
55
+ }
56
+
57
+ /**
58
+ * 获取模块实例(对应平台 GetModule 函数)
59
+ * @param {string} moduleName 模块名称(SceneModule/GraphicModule/EventModule)
60
+ * @returns {Object} 模块实例
61
+ */
62
+ getModule(moduleName) {
63
+ if (!this.modules.has(moduleName)) {
64
+ throw new Error(`模块 ${moduleName} 未注册,请先初始化 Viewer`);
65
+ }
66
+ return this.modules.get(moduleName);
67
+ }
68
+
69
+ /**
70
+ * Cesium Viewer 快捷访问
71
+ * @returns {Cesium.Viewer}
72
+ */
73
+ get viewer() {
74
+ return this.cesiumViewer;
75
+ }
76
+
77
+ /**
78
+ * 场景模块快捷访问
79
+ * @returns {SceneModule}
80
+ */
81
+ get sceneModule() {
82
+ return this.getModule('SceneModule');
83
+ }
84
+
85
+ /**
86
+ * 图元模块快捷访问
87
+ * @returns {GraphicModule}
88
+ */
89
+ get graphicModule() {
90
+ return this.getModule('GraphicModule');
91
+ }
92
+
93
+ /**
94
+ * 事件模块快捷访问
95
+ * @returns {EventModule}
96
+ */
97
+ get eventModule() {
98
+ return this.getModule('EventModule');
99
+ }
100
+
101
+ /**
102
+ * 编辑器模块快捷访问
103
+ * @returns {EditorModule}
104
+ */
105
+ get editorModule() {
106
+ return this.getModule('EditorModule');
107
+ }
108
+
109
+ /**
110
+ * 注册模块(内部使用)
111
+ * @param {string} moduleName 模块名称
112
+ * @param {Object} moduleInstance 模块实例
113
+ */
114
+ registerModule(moduleName, moduleInstance) {
115
+ this.modules.set(moduleName, moduleInstance);
116
+ }
117
+
118
+ /**
119
+ * 销毁实例(对应平台插件 Destroy 逻辑)
120
+ */
121
+ destroy() {
122
+ if (this.cesiumViewer) {
123
+ // 先通知各模块释放资源
124
+ try {
125
+ const eventModule = this.modules.get('EventModule');
126
+ if (eventModule && typeof eventModule.unregisterAllObservers === 'function') {
127
+ eventModule.unregisterAllObservers();
128
+ }
129
+ } catch (e) {
130
+ console.warn('EventModule 注销失败:', e);
131
+ }
132
+
133
+ try {
134
+ const editorModule = this.modules.get('EditorModule');
135
+ if (editorModule && typeof editorModule.destroy === 'function') {
136
+ editorModule.destroy();
137
+ }
138
+ } catch (e) {
139
+ console.warn('EditorModule 销毁失败:', e);
140
+ }
141
+
142
+ this.cesiumViewer.destroy();
143
+ this.cesiumViewer = null;
144
+ this.modules.clear();
145
+ }
146
+ }
147
+
148
+ /**
149
+ * 重置 ModuleManager 单例(用于完全重新初始化)
150
+ */
151
+ static reset() {
152
+ if (ModuleManager.instance) {
153
+ ModuleManager.instance.destroy();
154
+ ModuleManager.instance = null;
155
+ }
156
+ }
157
+ }