@yangyongtao/gaea 1.1.10 → 1.1.11

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/USAGE.md ADDED
@@ -0,0 +1,200 @@
1
+ # @yangyongtao/gaea 使用文档
2
+
3
+ 基于 Godot WASM 引擎的 Vue 3 三维可视化组件库。提供影像/地形/贴地线加载、相机视角控制、图层树、天气控制、沿线飞行、断面游览、室内游览等能力,并内置 Vite 插件自动注入引擎资源。
4
+
5
+ > 完整可运行示例见 `gaea-ground-test/src/App.vue`,本文所有片段均以其为参考。
6
+
7
+ ---
8
+
9
+ ## 1. 安装
10
+
11
+ ```bash
12
+ npm install @yangyongtao/gaea
13
+ ```
14
+
15
+ peerDependencies(按需安装):`vue ^3.4`、`element-plus ^2.6`(可选)、`pinia ^2.1`(可选)。
16
+
17
+ ---
18
+
19
+ ## 2. Vite 配置
20
+
21
+ 引入并注册 `gaeaVitePlugin`,它会自动注入 `Gaea.js`、提供引擎静态资源、设置 SharedArrayBuffer 所需的跨域隔离响应头。
22
+
23
+ ```js
24
+ // vite.config.js
25
+ import { defineConfig } from 'vite';
26
+ import vue from '@vitejs/plugin-vue';
27
+ import { gaeaVitePlugin } from '@yangyongtao/gaea/plugin';
28
+
29
+ export default defineConfig({
30
+ plugins: [vue(), gaeaVitePlugin()],
31
+ resolve: { preserveSymlinks: true },
32
+ optimizeDeps: { exclude: ['@yangyongtao/gaea'] },
33
+ });
34
+ ```
35
+
36
+ ---
37
+
38
+ ## 3. 快速开始
39
+
40
+ 页面里需要一个 `id="canvas"` 的画布。调用 `setConfig(...)` 后 `new GaeaApp()` 即可自动完成「引擎启动 → 环境初始化 → 图层加载 → 模型加载」。
41
+
42
+ ```vue
43
+ <template>
44
+ <div id="gaea-app">
45
+ <div class="toolbar">
46
+ <button @click="showWeather = !showWeather">天气控制</button>
47
+ <button @click="showFly = !showFly">沿线飞行</button>
48
+ <button @click="showLayerTree = !showLayerTree">图层控制</button>
49
+ <WaterGateTour />
50
+ </div>
51
+
52
+ <div class="canvas-area" id="canvas-container">
53
+ <canvas id="canvas"></canvas>
54
+ </div>
55
+
56
+ <WeatherControl v-if="showWeather" :appInstance="app" @close="showWeather = false" />
57
+ <FlyAlongRoute v-if="showFly" :appInstance="app" @close="showFly = false" />
58
+ <LayerTree v-if="showLayerTree" :appInstance="app" @close="showLayerTree = false" @node-click="onLayerNodeClick" />
59
+ <HydrologicStationDialog />
60
+ <SecTourView />
61
+ </div>
62
+ </template>
63
+
64
+ <script setup>
65
+ import { ref } from 'vue';
66
+ import { GaeaApp, setConfig } from '@yangyongtao/gaea';
67
+ import { WeatherControl, FlyAlongRoute, HydrologicStationDialog, SecTourView, WaterGateTour } from '@yangyongtao/gaea/components';
68
+ import LayerTree from '@yangyongtao/gaea/components/LayerTree.vue';
69
+
70
+ setConfig({
71
+ serveLocal: `${window.location.origin}/static`,
72
+ serveUrl: 'http://192.168.3.151:8088/gaeaExplorerServer/',
73
+ serviceMode: 'platform',
74
+ defaultCameraPosition: '27.3680928977018,120.414139621887,0,109379.690132486,0,0',
75
+ });
76
+
77
+ const app = new GaeaApp();
78
+ window.APP = app; // 组件内部通过 window.APP 兜底获取实例
79
+
80
+ const showWeather = ref(false);
81
+ const showFly = ref(false);
82
+ const showLayerTree = ref(false);
83
+
84
+ function onLayerNodeClick({ node }) {
85
+ app.flyToNode(node);
86
+ }
87
+ </script>
88
+ ```
89
+
90
+ ---
91
+
92
+ ## 4. setConfig 配置项
93
+
94
+ | 参数 | 类型 | 默认值 | 说明 |
95
+ |------|------|--------|------|
96
+ | `serveLocal` | string | `''` | 引擎本地静态资源地址(AssetHost),一般为 `${origin}/static` |
97
+ | `serveUrl` | string | `''` | 服务平台地址(WMTS 影像 / 地形 / 贴地线均基于此) |
98
+ | `serviceMode` | `'platform' \| 'online'` | `'platform'` | **服务模式**:见下方说明 |
99
+ | `tiandituToken` | string | — | 在线模式的天地图 token |
100
+ | `tiandituLevelRange` | [number,number] | `[0,18]` | 天地图层级范围 |
101
+ | `defaultLayers` | Array | 见下 | 服务平台模式下加载的影像图层 |
102
+ | `defaultTerrains` | Array | 见下 | 服务平台模式下加载的地形服务 |
103
+ | `defaultGroundLines` | Array | 见下 | 服务平台模式下加载的贴地线 |
104
+ | `defaultCameraPosition` | string | — | 初始相机视角:`纬度,经度,高程,相机高,俯仰,朝向` |
105
+ | `layerCategories` | Array | 内置 | 图层树分类数据(接口数据会合并进来) |
106
+ | `dataHubApiUrl` | string | `''` | 图层树数据接口地址,为空则只用默认数据 |
107
+ | `onProgress` | function | — | 引擎加载进度回调 `(cur, total) => {}` |
108
+
109
+ ### 4.1 serviceMode —— 服务模式(区分「服务平台」与「在线」)
110
+
111
+ - `'platform'`(服务平台):影像走 `serveUrl` 的 WMTS,并加载 `defaultTerrains` 地形、`defaultGroundLines` 贴地线。
112
+ - `'online'`(在线):**仅加载天地图影像**,不加载地形和贴地线(在线模式目前只有天地图一种影像来源)。
113
+
114
+ ```js
115
+ setConfig({ serviceMode: 'platform' }); // 内网/服务平台
116
+ // 或
117
+ setConfig({ serviceMode: 'online', tiandituToken: '你的token' }); // 在线(天地图)
118
+ ```
119
+
120
+ ### 4.2 defaultLayers —— 影像图层(服务平台模式)
121
+
122
+ ```js
123
+ defaultLayers: [
124
+ { layerName: 'earthland', forMat: 'image/png', min: 0, max: 18, transparency: 0.3 },
125
+ { layerName: '苍南L19', forMat: 'image/png', min: 5, max: 17 },
126
+ ]
127
+ ```
128
+ - `layerName`:WMTS 服务里的图层名(Title)
129
+ - `forMat`:影像格式,如 `image/png`、`image/jpeg`
130
+ - `min` / `max`:显示层级范围
131
+ - `transparency`:透明度(可选)
132
+
133
+ ### 4.3 defaultTerrains —— 地形服务(服务平台模式)
134
+
135
+ ```js
136
+ defaultTerrains: [
137
+ { name: '苍南县地形', url: 'htc/service/tms/1.0.0/苍南县地形@EPSG%3A4326@terrain/' },
138
+ ]
139
+ ```
140
+ - `name`:地形名称
141
+ - `url`:相对 `serveUrl` 的路径(也支持传完整 `http(s)://` 地址)
142
+ - 空数组 `[]` 则不加载地形
143
+
144
+ ### 4.4 defaultGroundLines —— 贴地线(服务平台模式)
145
+
146
+ 依赖 `serveUrl` 的 WMTS 矢量线服务(自动通过 `getAllServe` 获取服务列表后按名匹配)。
147
+
148
+ ```js
149
+ defaultGroundLines: [
150
+ { name: '苍南县边界', range: [0, 9], color: [255, 255, 0], index: 100 },
151
+ { name: '苍南县镇边界', range: [9, 15], color: [0, 255, 0], index: 80 },
152
+ { name: '苍南县村边界', range: [15, 19], color: [255, 255, 255], index: 60 },
153
+ { name: '沿浦海塘工程范围线', range: [0, 21], color: [0, 255, 255], index: 120 },
154
+ ]
155
+ ```
156
+ - `name`:矢量线服务名(Title)
157
+ - `range`:显示层级范围 `[min, max]`
158
+ - `color`:线颜色 `[r, g, b]`(0-255)
159
+ - `index`:渲染优先级
160
+ - 每项可加 `isInitLoad: false` 跳过该条
161
+
162
+ ---
163
+
164
+ ## 5. 组件说明
165
+
166
+ 组件从 `@yangyongtao/gaea/components` 导入;`LayerTree` 需按路径单独导入。多数交互组件接收 `:appInstance="app"`,未传时内部回退到 `window.APP`。
167
+
168
+ | 组件 | 说明 | 主要事件 |
169
+ |------|------|----------|
170
+ | `WeatherControl` | 天气/台风控制面板(含台风路线拾取与播放) | `@close` |
171
+ | `FlyAlongRoute` | 沿线飞行:地图拾取点位,可设飞行高度/时长 | `@close` |
172
+ | `LayerTree` | 图层树,点击节点飞行定位 | `@close`、`@node-click` |
173
+ | `HydrologicStationDialog` | 水文测站弹窗,自监听 `gaea-icon-click` 事件 | — |
174
+ | `SecTourView` | 断面游览滚动条,模型锁定后显示 | — |
175
+ | `WaterGateTour` | 室内游览按钮(下拉选择水闸模型) | — |
176
+
177
+ ---
178
+
179
+ ## 6. 常用实例方法(window.APP / app)
180
+
181
+ | 方法 | 说明 |
182
+ |------|------|
183
+ | `SetPosition('纬度,经度,高程,相机高,俯仰,朝向')` | 定位到指定视角 |
184
+ | `flyToNode({ position:{x,y,z} })` | 飞到指定位置 |
185
+ | `flyAlongPath(lineData, options)` | 沿线飞行,`lineData=[{x:纬度,y:经度,z:高度}]`,`options={duration,xrotation,lockEye,...}` |
186
+ | `stopFlyAlongPath()` | 停止沿线飞行 |
187
+ | `cameraReset()` | 相机复位到 `defaultCameraPosition` |
188
+ | `addInitTerrainServer(terrains?)` | 手动加载地形(不传则用 `defaultTerrains`) |
189
+ | `addGroundLines(lines?)` | 手动加载贴地线(不传则用 `defaultGroundLines`) |
190
+ | `addTyphoonRoute(pointList, options)` | 加载台风路线并播放动画 |
191
+ | `clearTyphoonRoute()` | 清除台风路线 |
192
+
193
+ ---
194
+
195
+ ## 7. 注意事项
196
+
197
+ - 页面必须存在 `id="canvas"` 的 `<canvas>`,引擎会挂载到它上面。
198
+ - 需要跨域隔离(COOP/COEP)才能启用 SharedArrayBuffer,`gaeaVitePlugin` 已自动处理;首次进入若未隔离会自动刷新一次。
199
+ - 服务平台模式下地形/贴地线依赖 `serveUrl` 对应服务,若服务器无对应服务名,控制台会打印「未找到/加载失败」警告,不影响其它功能。
200
+ - 大体积引擎资源(`Gaea.pck` / `Gaea.wasm` / `1111.res` 等)通过 postinstall 脚本下载到本地静态目录,请确保下载源可访问。
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yangyongtao/gaea",
3
- "version": "1.1.10",
3
+ "version": "1.1.11",
4
4
  "description": "Gaea 3D visualization component library - Vue 3 components based on Godot WASM engine. Includes WMTS layer loading, camera view control, Vite plugin auto-injection, etc.",
5
5
  "type": "module",
6
6
  "main": "src/index.js",
@@ -14,6 +14,7 @@
14
14
  "import": "./src/components/index.js",
15
15
  "default": "./src/components/index.js"
16
16
  },
17
+ "./components/*": "./src/components/*",
17
18
  "./plugin": {
18
19
  "import": "./src/plugin.js",
19
20
  "default": "./src/plugin.js"
@@ -23,6 +24,7 @@
23
24
  "src/",
24
25
  "scripts/",
25
26
  "README.md",
27
+ "USAGE.md",
26
28
  "CHANGELOG.md",
27
29
  "public/*.js",
28
30
  "public/*.html",
@@ -70,7 +72,8 @@
70
72
  }
71
73
  },
72
74
  "dependencies": {
73
- "@tweenjs/tween.js": "^25.0.0"
75
+ "@tweenjs/tween.js": "^25.0.0",
76
+ "echarts": "^5.5.0"
74
77
  },
75
78
  "license": "MIT",
76
79
  "publishConfig": {
@@ -168,3 +168,114 @@ input {
168
168
  a {
169
169
  color: #fcdab7;
170
170
  }
171
+
172
+ /* daba-tooltip 断面标签 hover 提示框 */
173
+ .daba-tooltip {
174
+ position: fixed;
175
+ z-index: 99999;
176
+ transform: translate(-50%, -100%);
177
+ pointer-events: none;
178
+ display: none;
179
+ min-width: 200px;
180
+ max-width: 320px;
181
+ background: rgba(2, 62, 138, 0.95);
182
+ border: 1px solid rgba(14, 165, 233, 0.6);
183
+ border-radius: 6px;
184
+ padding: 14px 18px;
185
+ box-shadow: 0 4px 20px rgba(0, 50, 100, 0.4);
186
+ font-size: 18px;
187
+ animation: dabaTooltipFadeIn 0.15s ease-out;
188
+ }
189
+ .daba-tooltip::after {
190
+ content: '';
191
+ position: absolute;
192
+ bottom: -6px;
193
+ left: 50%;
194
+ transform: translateX(-50%);
195
+ width: 0;
196
+ height: 0;
197
+ border-left: 6px solid transparent;
198
+ border-right: 6px solid transparent;
199
+ border-top: 6px solid rgba(2, 62, 138, 0.95);
200
+ }
201
+ @keyframes dabaTooltipFadeIn {
202
+ from { opacity: 0; transform: translate(-50%, calc(-100% - 4px)); }
203
+ to { opacity: 1; transform: translate(-50%, -100%); }
204
+ }
205
+ .daba-tooltip-title {
206
+ font-size: 17px; font-weight: 600; color: #e0f7ff;
207
+ padding-bottom: 8px; margin-bottom: 10px;
208
+ border-bottom: 1px solid rgba(255, 255, 255, 0.15);
209
+ }
210
+ .daba-tooltip-item {
211
+ position: relative; padding: 3px 0 3px 14px;
212
+ font-size: 15px; line-height: 1.7; color: #cbd5e1; word-break: break-word;
213
+ }
214
+ .daba-tooltip-item::before {
215
+ content: ''; position: absolute; left: 0; top: 11px;
216
+ width: 5px; height: 5px; border-radius: 50%; background: #38bdf8;
217
+ }
218
+
219
+ /* 断面标签样式 */
220
+ .waterLevel {
221
+ position: absolute;
222
+ z-index: 1000;
223
+ width: 7rem;
224
+ top: 16%;
225
+ left: 30%;
226
+ }
227
+ .waterLevel img {
228
+ width: 100%;
229
+ }
230
+ .waterLevel .content {
231
+ position: absolute;
232
+ top: 16%;
233
+ left: 25%;
234
+ white-space: nowrap;
235
+ }
236
+ .waterLevel .content .text {
237
+ font-size: 20px;
238
+ }
239
+
240
+ .damScreen {
241
+ position: absolute;
242
+ box-sizing: border-box;
243
+ top: 431.312px;
244
+ left: 630.192px;
245
+ width: 18rem;
246
+ height: 3rem;
247
+ padding: 0px;
248
+ margin: 0px;
249
+ overflow: hidden;
250
+ display: block;
251
+ z-index: 3;
252
+ }
253
+ .damScreen img {
254
+ position: absolute;
255
+ width: 100%;
256
+ height: 100%;
257
+ object-fit: cover;
258
+ z-index: 1;
259
+ }
260
+ .damScreen .content {
261
+ display: flex;
262
+ position: relative;
263
+ width: 100%;
264
+ min-height: 100%;
265
+ z-index: 2;
266
+ align-items: center;
267
+ }
268
+ .damScreen .content .box {
269
+ width: 2.2rem;
270
+ height: 100%;
271
+ box-sizing: border-box;
272
+ }
273
+ .damScreen .content .text {
274
+ flex: 1 1 0%;
275
+ height: 100%;
276
+ display: flex;
277
+ font-size: 18px;
278
+ align-items: center;
279
+ justify-content: center;
280
+ box-sizing: border-box;
281
+ }