@anov/gis-skills-cli 0.0.0-stage → 0.3.3

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.
Files changed (57) hide show
  1. package/CHANGELOG.md +637 -0
  2. package/INSTALL.md +481 -0
  3. package/LICENSE +15 -0
  4. package/README.md +148 -2
  5. package/RELEASING.md +162 -0
  6. package/bin/anov-gis-skills.mjs +470 -0
  7. package/lib/mcp-config.mjs +273 -0
  8. package/package.json +43 -4
  9. package/skills/anovgis-analysis/SKILL.md +585 -0
  10. package/skills/anovgis-effects/SKILL.md +260 -0
  11. package/skills/anovgis-imagery-terrain/SKILL.md +505 -0
  12. package/skills/anovgis-layers/SKILL.md +627 -0
  13. package/skills/anovgis-materials/SKILL.md +635 -0
  14. package/skills/anovgis-models-3dtiles/SKILL.md +448 -0
  15. package/skills/anovgis-pitfalls/SKILL.md +561 -0
  16. package/skills/anovgis-popup-widget/SKILL.md +474 -0
  17. package/skills/anovgis-primitives/SKILL.md +482 -0
  18. package/skills/anovgis-vector-graphics/SKILL.md +602 -0
  19. package/skills/anovgis-viewer/SKILL.md +618 -0
  20. package/skills/using-anovgis/DEMO-MAP.md +64 -0
  21. package/skills/using-anovgis/DEMO-SKILL-MAP.md +248 -0
  22. package/skills/using-anovgis/DOMAINS.md +183 -0
  23. package/skills/using-anovgis/REFERENCE.md +114 -0
  24. package/skills/using-anovgis/SKILL.md +392 -0
  25. package/skills/using-anovgis/templates/README.md +154 -0
  26. package/skills/using-anovgis/templates/combo1-vue3-vite.md +295 -0
  27. package/skills/using-anovgis/templates/combo2-vue2-cli.md +119 -0
  28. package/skills/using-anovgis/templates/combo3-html-cdn.md +107 -0
  29. package/skills/using-anovgis/templates/combo4-vanilla-webpack.md +91 -0
  30. package/skills/using-anovgis/templates/wizard-profiles.md +105 -0
  31. package/vendor/cesiumjs-skills/LICENSE +201 -0
  32. package/vendor/cesiumjs-skills/NOTICE +18 -0
  33. package/vendor/cesiumjs-skills/skills/cesiumjs-3d-tiles/SKILL.md +465 -0
  34. package/vendor/cesiumjs-skills/skills/cesiumjs-camera/SKILL.md +500 -0
  35. package/vendor/cesiumjs-skills/skills/cesiumjs-core-utilities/SKILL.md +403 -0
  36. package/vendor/cesiumjs-skills/skills/cesiumjs-custom-shader/REFERENCE.md +397 -0
  37. package/vendor/cesiumjs-skills/skills/cesiumjs-custom-shader/SKILL.md +351 -0
  38. package/vendor/cesiumjs-skills/skills/cesiumjs-custom-shader/examples/01-diffuse-tint.js +38 -0
  39. package/vendor/cesiumjs-skills/skills/cesiumjs-custom-shader/examples/02-texture-swap.js +42 -0
  40. package/vendor/cesiumjs-skills/skills/cesiumjs-custom-shader/examples/03-feature-id-tileset.js +29 -0
  41. package/vendor/cesiumjs-skills/skills/cesiumjs-custom-shader/examples/04-translucent-override.js +37 -0
  42. package/vendor/cesiumjs-skills/skills/cesiumjs-custom-shader/examples/05-vertex-displacement.js +49 -0
  43. package/vendor/cesiumjs-skills/skills/cesiumjs-custom-shader/examples/06-metadata-ramp.js +34 -0
  44. package/vendor/cesiumjs-skills/skills/cesiumjs-custom-shader/examples/07-voxel-shader.js +27 -0
  45. package/vendor/cesiumjs-skills/skills/cesiumjs-custom-shader/examples/README.md +19 -0
  46. package/vendor/cesiumjs-skills/skills/cesiumjs-custom-shader/examples/_sandcastle-template.html +9 -0
  47. package/vendor/cesiumjs-skills/skills/cesiumjs-entities/SKILL.md +389 -0
  48. package/vendor/cesiumjs-skills/skills/cesiumjs-imagery/SKILL.md +471 -0
  49. package/vendor/cesiumjs-skills/skills/cesiumjs-interaction/SKILL.md +423 -0
  50. package/vendor/cesiumjs-skills/skills/cesiumjs-materials-shaders/SKILL.md +292 -0
  51. package/vendor/cesiumjs-skills/skills/cesiumjs-models-particles/SKILL.md +423 -0
  52. package/vendor/cesiumjs-skills/skills/cesiumjs-primitives/SKILL.md +537 -0
  53. package/vendor/cesiumjs-skills/skills/cesiumjs-spatial-math/SKILL.md +358 -0
  54. package/vendor/cesiumjs-skills/skills/cesiumjs-terrain-environment/SKILL.md +401 -0
  55. package/vendor/cesiumjs-skills/skills/cesiumjs-time-properties/SKILL.md +353 -0
  56. package/vendor/cesiumjs-skills/skills/cesiumjs-viewer-setup/SKILL.md +434 -0
  57. package/vendor/cesiumjs-skills/skills/using-cesiumjs-skills/SKILL.md +35 -0
@@ -0,0 +1,448 @@
1
+ ---
2
+ name: anovgis-models-3dtiles
3
+ description: '@anov/gis 3D Tiles / glTF 模型模块。涵盖 ANOVGIS.Model(单 glTF)、ANOVGIS.Tileset(3D Tiles 容器)、Cesium3DTileStyle 条件样式、ready 异步回调、clampToGround 贴地、TilesetLayer 容器 + bindPopup 拾取、viewer.flyToTileset 定位、抽壳(quShouBengZhan)、倾斜摄影(qingxieTileset)、自定义 GLSL shader(customshader)、vectortiles 矢量瓦片、PostFog 体积雾、rainSnowPlane 雨雪平面。v1.8.6 新增 `PositonEditor` / `TilesetEditor` 位姿编辑工具、`viewer.flyTo` 可直接传 SDK Primitive/Tileset 用 boundingSphere 兜底、15 个 Primitive 类新增 boundingSphere getter。触发关键词:Model、Tileset、3D Tiles、3dtiles、tileset.json、glTF、GLB、loadGlb、customshader、自定义 shader、GLSL、qingxieTileset、倾斜摄影、quShouBengZhan、抽壳、vectortiles、矢量瓦片、PostFog、rainSnowPlane、雨雪平面、TilesetEditor、PositonEditor、pointShadowing、Cesium3DTileStyle、tileset.ready、tileset.setStyle、tileset.flyTo、tileset.clampToGround、boundingSphere、tilesetpopup、imagerylayerpopup、model.html、loadSnow。Use when 加载单 glTF / 加载 3D Tiles 模型、对 Tileset 做条件样式(按属性着色)、抽壳倾斜摄影、用 PositonEditor / TilesetEditor 编辑模型位姿、给模型绑定 Popup 拾取、加载自定义 shader 模型、批量加载多个 tileset.json。'
4
+ anov-gis-baseline: 1.8.6
5
+ cesium-baseline: 1.143.0
6
+ ---
7
+
8
+ # anovgis-models-3dtiles — @anov/gis 3D Tiles / Model 模块
9
+
10
+ > ⚠️ **优先级**:本 skill 优先于 SDK 源码 / `node_modules/@anov/gis/`。
11
+ > 遇到 API 行为疑问先查本 skill 与 `anovgis-pitfalls`。**严禁**主动 Glob/Grep `node_modules/@anov/gis/src/...` / `dist/...`;除非用户明确要求并承担风险。
12
+ > 调试流程见 `using-anovgis` § 默认调试流程(Chrome DevTools 仅第 5 级兜底)。
13
+ >
14
+ > **Cesium 入口(铁律)**:`const Cesium = window.Cesium`。`@anov/gis` 启动时已把 Cesium 挂到 `window`,**不存在** `ANOVGIS.Cesium` 写法;本 skill 所有 `Cesium.*` 均从此变量取。底层 Cesium API 细节查 `cesiumjs-skills` 对应 skill(API 名通用,`import` 写法换成 `const Cesium = window.Cesium`)。
15
+
16
+ > `@anov/gis` 中所有"模型"都通过 `Model`(单 glTF)或 `Tileset`(3D Tiles)加载。本 skill 涵盖两者 + `Cesium3DTileStyle` 条件样式 + `TilesetLayer` 容器 + 拾取 + v1.8.6 新增的位姿编辑工具。
17
+ >
18
+ > 源码根:`src/graphic/model/`(Model / Tileset);`src/analysis/transformHelper/PositonEditor.js`(v1.8.6 新增 ~1029 行);`src/analysis/transformHelper/TilesetEditor.js`(v1.8.6 新增 ~1034 行)(仅作语义锚点)。
19
+ >
20
+ > **版本基线**:`@anov/gis` v1.8.6;本文档 snippet 基于该版本 SDK 公开 API 行为锁定。
21
+
22
+ ---
23
+
24
+ ## Out-of-scope(v0.2.0 短版)
25
+
26
+ - ❌ 不要写 Vector 16 类(Point / Polyline / Polygon / ...) → `anovgis-vector-graphics`
27
+ - ❌ 不要写 Primitive 19 类(Cloud / FlowLine / ScanCircle / ...) → `anovgis-primitives`
28
+ - ❌ 不要写 `viewer.clock` 时间播放 / `CzmlLayer` playback 完整用法 → v0.3.0 `anovgis-roaming-editor-time`
29
+ - ❌ 不要写 `Cesium3DTileset` 原生 API 完整文档(仅覆盖 SDK 封装部分) → 见 Cesium 文档
30
+ - ❌ 不要写 `PositonEditor` 的非模型编辑用法(如单纯点位编辑控件) → `anovgis-analysis`
31
+
32
+ ---
33
+
34
+ ## 1. 类速查表
35
+
36
+ | 类 | 构造签名 | 用途 | 关键 options |
37
+ |---|---|---|---|
38
+ | `Model` | `new ANOVGIS.Model(options)` | 单 glTF/GLB 模型 | `url, position, scale, minimumPixelSize, maximumScale, color, silhouetteColor, colorBlendMode, colorBlendAmount` |
39
+ | `Tileset` | `new ANOVGIS.Tileset(options)` | 3D Tiles 容器(异步)| `url, maximumScreenSpaceError, skipLevels, highlight, selectedHighlight, pointShadowing` |
40
+ | `Cesium3DTileStyle` | `new ANOVGIS.Cesium3DTileStyle({ color: { conditions: [...] } })` | Tileset 条件样式 | `color, show, meta` |
41
+ | `TilesetLayer` | `new ANOVGIS.TilesetLayer()` | Tileset 容器(必须 addGraphic 才能 popup/事件)| — |
42
+ | `PositonEditor`(v1.8.6)| `new ANOVGIS.PositonEditor(opts)` | 点位/模型平移旋转缩放三轴 gizmo | `translateEnabled, rotateEnabled, scaleEnabled, xAxisLength, rotatePlaneRadius, sizeInPixel, originOffset` |
43
+ | `TilesetEditor`(v1.8.6)| `new ANOVGIS.TilesetEditor(opts)` | Tileset 模型编辑器(继承 PositonEditor + Tileset 特有操作)| 同 PositonEditor + Tileset 属性 |
44
+
45
+ > v1.8.6 起 `PositonEditor` 从 v1.8.4 的 800 行左右扩充到 1029 行;`TilesetEditor` 是 1034 行全新工具。
46
+
47
+ ---
48
+
49
+ ## 2. Snippet(18 个,覆盖 Model / Tileset / Style / 编辑)
50
+
51
+ <a id="s1"></a>
52
+ ### S1. 单 glTF 模型加载
53
+
54
+ ```js
55
+ // 来源: examples/public/examples/html/model/cesium_three.html L447
56
+ const layer = new ANOVGIS.VectorLayer().addTo(viewer); // Model 也走 Entity 体系
57
+ const model = new ANOVGIS.Model({
58
+ position: [116.40, 39.90, 0],
59
+ url: '/data/tree.glb',
60
+ scale: 2.0,
61
+ minimumPixelSize: 64,
62
+ maximumScale: 100
63
+ });
64
+ layer.addGraphic(model);
65
+ viewer.flyTo(model);
66
+ ```
67
+
68
+ > ⚠️ **`Model` 构造只收一个 options 对象**(`position` / `url` 都在里面),不是 `(url, options)` —— 源码 `src/graphic/model/Model.js:7` 是 `constructor(options)`。
69
+ > 同理 `Tileset` / `Cesium3DTileStyle` / `PositonEditor` 也都是单 options 对象。
70
+ > **注意与 `Point` / `Label` / `Billboard` 不同** —— 那三个是 `(position, options)` 双参数(源码 `src/graphic/vector/Point.js:41`)。
71
+
72
+ ### S2. Tileset 加载 + ready 回调 + 调色
73
+
74
+ ```js
75
+ // 来源: examples/public/examples/html/event/tilesetpopup.html L48-93
76
+ const layer = new ANOVGIS.TilesetLayer();
77
+ viewer.addLayer(layer);
78
+
79
+ const tileset = new ANOVGIS.Tileset({
80
+ url: buildConfig.gisStatic + 'beijingchouxi/tileset.json',
81
+ maximumScreenSpaceError: 6,
82
+ skipLevels: true,
83
+ highlight: { color: '#ff0000' }, // 鼠标悬停样式
84
+ selectedHighlight: { color: 'rgba(255,0,255,0.8)' } // 选中样式
85
+ });
86
+
87
+ // 异步加载完成(Cesium 1.143 fromUrl → Promise)
88
+ tileset.ready((t) => {
89
+ t.pointShadowing.enabled = true; // 阴影
90
+ console.log('tileset ready', t);
91
+ });
92
+ layer.addGraphic(tileset);
93
+ ```
94
+
95
+ ### S3. Cesium3DTileStyle 条件样式(按楼层着色)
96
+
97
+ ```js
98
+ // 来源: examples/public/examples/html/event/tilesetpopup.html
99
+ tileset.setStyle(new ANOVGIS.Cesium3DTileStyle({
100
+ color: {
101
+ conditions: [
102
+ ['Number(${floor}) >= 40', 'rgba(45,0,75,0.5)'],
103
+ ['Number(${floor}) >= 20', 'rgba(125,75,150,0.5)'],
104
+ ['Number(${floor}) >= 10', 'rgb(248,176,87)'],
105
+ ['true', 'rgb(127,59,8)']
106
+ ]
107
+ },
108
+ show: '${floor} >= 0' // 全部显示
109
+ }));
110
+ ```
111
+
112
+ ### S4. Tileset 拾取 + Popup(tilesetpopup 模式)
113
+
114
+ ```js
115
+ // 来源: examples/public/examples/html/event/tilesetpopup.html
116
+ layer.bindPopup({ viewer, showTitle: true, useDefaultHtmlTemplate: true });
117
+ layer.addEventListener(ANOVGIS.MouseEventType.CLICK, (e) => {
118
+ layer.popup.show(e.position, {
119
+ title: e.feature.getProperty('name1'),
120
+ fieldsMap: [
121
+ { nameC: '名称', value: e.feature.getProperty('name1') },
122
+ { nameC: '楼层', value: e.feature.getProperty('floor') }
123
+ ]
124
+ });
125
+ });
126
+ viewer.flyToTileset(tileset, 2, 0.5, -35); // pitch=2, range=0.5, heading=-35
127
+ ```
128
+
129
+ ### S5. Tileset 贴地 clampToGround
130
+
131
+ ```js
132
+ // 来源: src/graphic/model/Tileset.js
133
+ tileset.clampToGround();
134
+ // Cesium 1.143:调用后内部把所有 tile 投影到 terrain 上
135
+ // 注意:仅当 viewer.scene.globe.depthTestAgainstTerrain=true 时效果可见
136
+ ```
137
+
138
+ <a id="s6"></a>
139
+ ### S6. 倾斜摄影(qingxieTileset)
140
+
141
+ ```js
142
+ // 来源: examples/public/examples/html/model/qingxieTileset.html
143
+ const tileset = new ANOVGIS.Tileset({
144
+ url: '/data/qingxie_photogrammetry/tileset.json',
145
+ maximumScreenSpaceError: 6
146
+ });
147
+ const layer = new ANOVGIS.TilesetLayer();
148
+ viewer.addLayer(layer);
149
+ layer.addGraphic(tileset);
150
+ tileset.ready(() => {
151
+ viewer.flyToTileset(tileset, 2, 0.5, -45);
152
+ });
153
+ ```
154
+
155
+ <a id="s7"></a>
156
+ ### S7. 抽壳模式(quShouBengZhan)
157
+
158
+ ```js
159
+ // 来源: examples/public/examples/html/model/quShouBengZhan.html
160
+ // 通过自定义 shader 抽壳(只显示模型表面)
161
+ const tileset = new ANOVGIS.Tileset({
162
+ url: '/data/pump_station/tileset.json',
163
+ customShader: new ANOVGIS.CustomShader({
164
+ fragmentShaderText: `
165
+ void fragmentMain(FragmentInput fsInput, inout czm_modelMaterial material) {
166
+ // 抽壳:只显示模型外表面
167
+ material.diffuse = vec3(0.8, 0.9, 1.0);
168
+ }
169
+ `
170
+ })
171
+ });
172
+ const layer = new ANOVGIS.TilesetLayer();
173
+ viewer.addLayer(layer);
174
+ layer.addGraphic(tileset);
175
+ ```
176
+
177
+ <a id="s8"></a>
178
+ ### S8. 自定义 GLSL Shader(customshader 完整示例)
179
+
180
+ ```js
181
+ // 来源: examples/public/examples/html/model/customshader.html
182
+ const tileset = new ANOVGIS.Tileset({
183
+ url: '/data/model/tileset.json',
184
+ customShader: new ANOVGIS.CustomShader({
185
+ vertexShaderText: `
186
+ void vertexMain(VertexInput vsInput, inout vec3 positionMC) {
187
+ // 顶点位移(沿法线凸起)
188
+ positionMC += vsInput.attributes.normalMC * 10.0;
189
+ }
190
+ `,
191
+ fragmentShaderText: `
192
+ void fragmentMain(FragmentInput fsInput, inout czm_modelMaterial material) {
193
+ material.diffuse = vec3(0.0, 1.0, 1.0);
194
+ material.alpha = 0.8;
195
+ }
196
+ `
197
+ })
198
+ });
199
+ ```
200
+
201
+ <a id="s9"></a>
202
+ ### S9. 矢量瓦片(vectortiles)
203
+
204
+ ```js
205
+ // 来源: examples/public/examples/html/model/vectortiles.html
206
+ const layer = new ANOVGIS.VectorLayer().addTo(viewer);
207
+ // vectortiles 实际是 GeoJSON 形式,通过 VectorLayer 加载
208
+ fetch('/data/vectortiles.json').then(r => r.json()).then(geojson => {
209
+ const ds = Cesium.GeoJsonDataSource.load(geojson, {
210
+ stroke: Cesium.Color.fromCssColorString('#2e91e5'),
211
+ fill: Cesium.Color.fromCssColorString('rgba(46,145,229,0.3)'),
212
+ strokeWidth: 2
213
+ });
214
+ viewer.dataSources.add(ds);
215
+ });
216
+ ```
217
+
218
+ <a id="s10"></a>
219
+ ### S10. 体积雾(PostFog)
220
+
221
+ ```js
222
+ // 来源: examples/public/examples/html/model/PostFog.html
223
+ viewer.scene.fog.enabled = true;
224
+ viewer.scene.fog.density = 0.0002; // 雾浓度
225
+ viewer.scene.fog.minimumBrightness = 0.03; // 远处最暗
226
+ // PostRender 加自定义体积雾(基于 GLSL PostProcessStage)
227
+ viewer.scene.postProcessStages.add(new Cesium.PostProcessStage({
228
+ fragmentShader: `
229
+ void main() {
230
+ vec4 color = texture(czm_sceneColor, v_textureCoordinates);
231
+ float depth = czm_readDepth(czm_sceneDepthTexture, v_textureCoordinates);
232
+ // 深度相关雾化
233
+ float fogAmount = clamp(depth * 0.0001, 0.0, 1.0);
234
+ gl_FragColor = mix(color, vec4(0.7, 0.75, 0.8, 1.0), fogAmount);
235
+ }
236
+ `
237
+ }));
238
+ ```
239
+
240
+ <a id="s11"></a>
241
+ ### S11. 雨雪平面(rainSnowPlane)
242
+
243
+ ```js
244
+ // 来源: examples/public/examples/html/model/rainSnowPlane.html
245
+ // 用 ParticleSystem 实现大面积雨雪
246
+ const rainEntity = viewer.entities.add({
247
+ position: Cesium.Cartesian3.fromDegrees(116.40, 39.90, 500),
248
+ particleSystem: new Cesium.ParticleSystem({
249
+ image: '/assets/rain.png',
250
+ startScale: 1.0,
251
+ endScale: 0.0,
252
+ particleLife: 1.5,
253
+ speed: 50.0,
254
+ imageSize: new Cesium.Cartesian2(10, 50),
255
+ emissionRate: 1000,
256
+ lifetime: 16.0,
257
+ loop: true,
258
+ emitter: new Cesium.ConeEmitter(Cesium.Math.toRadians(15.0))
259
+ })
260
+ });
261
+ ```
262
+
263
+ ### S12. Model + Snow 天气联动
264
+
265
+ ```js
266
+ // 来源: examples/public/examples/html/analysis/locateTest.html L230(Model 用法)
267
+ // + examples/public/examples/html/model/loadSnow.html(天气 API)
268
+ const model = new ANOVGIS.Model({
269
+ position: [116.360, 39.930, 80],
270
+ url: '/data/tree.glb',
271
+ scale: 1
272
+ });
273
+ layer.addGraphic(model);
274
+ // 同步开雪
275
+ const weather = new ANOVGIS.Weather(viewer);
276
+ viewer.weather.snow.enable = true;
277
+ viewer.weather.snow.speed = 8;
278
+ ```
279
+
280
+ ### S13. TilesetEditor(v1.8.6 新增 1034 行)位姿编辑
281
+
282
+ ```js
283
+ // 来源: src/analysis/transformHelper/TilesetEditor.js
284
+ const editor = new ANOVGIS.TilesetEditor({
285
+ translateEnabled: true,
286
+ rotateEnabled: true,
287
+ scaleEnabled: true,
288
+ xAxisLength: 100,
289
+ rotatePlaneRadius: 80,
290
+ sizeInPixel: false,
291
+ originOffset: 0
292
+ });
293
+ editor.addTo(viewer);
294
+ editor.bind(tileset); // 绑定 Tileset
295
+ // 编辑完成后通过 editor.getTransform() 拿到 modelMatrix
296
+ const modelMatrix = editor.getTransform();
297
+ console.log('tileset moved to:', ANOVGIS.Transform.transformCartesianToWGS84(
298
+ Cesium.Matrix4.getTranslation(modelMatrix, new Cesium.Cartesian3())
299
+ ));
300
+ // editor.detach(); // 解绑
301
+ ```
302
+
303
+ ### S14. PositonEditor 三轴 gizmo(v1.8.6 扩充到 1029 行)
304
+
305
+ ```js
306
+ // 来源: src/analysis/transformHelper/PositonEditor.js
307
+ const editor = new ANOVGIS.PositonEditor({
308
+ translateEnabled: true, rotateEnabled: true, scaleEnabled: true,
309
+ xAxisLength: 80, yAxisLength: 80, zAxisLength: 80
310
+ });
311
+ editor.addTo(viewer);
312
+ editor.bind(model); // 绑定 Model 或 Entity
313
+ // 事件订阅
314
+ editor.addEventListener('postTransformEvent', (e) => {
315
+ console.log('transform changed:', e.matrix);
316
+ });
317
+ ```
318
+
319
+ ### S15. viewer.flyToTileset 4 参数签名
320
+
321
+ ```js
322
+ // 来源: examples/public/examples/html/event/tilesetpopup.html L93
323
+ // 签名: viewer.flyToTileset(tileset, duration, range, pitch)
324
+ // v1.8.6+ 起也支持 flyTo(tileset, duration, heading, pitch, range=0) 用 boundingSphere 兜底
325
+ viewer.flyToTileset(tileset, 2.0, 0.5, -35);
326
+
327
+ // v1.8.6+ 等价写法(统一 6 参数):
328
+ viewer.flyTo(tileset.nativeObjCesium || tileset, 2.0, 0, Cesium.Math.toRadians(-35), 0);
329
+ ```
330
+
331
+ ### S16. 多 Tileset 加载(数字城市)
332
+
333
+ ```js
334
+ // 来源: examples/public/examples/html/demos/digitalCity.html
335
+ const layer = new ANOVGIS.TilesetLayer();
336
+ viewer.addLayer(layer);
337
+ ['buildings', 'roads', 'trees'].forEach(name => {
338
+ const ts = new ANOVGIS.Tileset({
339
+ url: `/data/city/${name}/tileset.json`,
340
+ maximumScreenSpaceError: 6
341
+ });
342
+ ts.ready(t => console.log(`${name} loaded`));
343
+ layer.addGraphic(ts);
344
+ });
345
+ viewer.flyTo(layer);
346
+ ```
347
+
348
+ ### S17. Tileset 颜色混合 + 高亮
349
+
350
+ ```js
351
+ // 来源: src/graphic/model/Tileset.js
352
+ const tileset = new ANOVGIS.Tileset({
353
+ url: '/data/tileset.json',
354
+ color: Cesium.Color.fromCssColorString('rgba(100,200,255,0.8)'),
355
+ colorBlendMode: Cesium.Cesium3DTileColorBlendMode.HIGHLIGHT,
356
+ colorBlendAmount: 0.5,
357
+ highlight: { color: '#ff0000' },
358
+ selectedHighlight: { color: 'rgba(255,0,255,0.8)' }
359
+ });
360
+ ```
361
+
362
+ ### S18. Tileset 销毁与内存释放
363
+
364
+ ```js
365
+ // 来源: SDK 通用模式
366
+ layer.removeGraphic(tileset); // 从 layer 移除
367
+ tileset.destroy(); // 释放 WebGL 资源(重要!避免内存泄漏)
368
+ // 或直接 viewer.removeLayer(layer) 一次性销毁
369
+ ```
370
+
371
+ ---
372
+
373
+ ## 3. 反模式
374
+
375
+ | 错误 | 后果 | 正确做法 |
376
+ |---|---|---|
377
+ | `new ANOVGIS.Tileset(url)` 后立即 `tileset.nativeObjCesium` | 拿到 undefined(异步加载未完成) | `tileset.ready(cb)` 或 `await tileset.readyPromise` |
378
+ | `viewer.flyTo(tileset, 2, 0, -45, 0)` range 写 0 但 v1.8.5 之前 | 黑屏(无 boundingSphere) | 升级 SDK 到 v1.8.6+ 或手动算 range |
379
+ | `tileset.destroy()` 不调 | WebGL 资源泄漏(多次切换后帧率下降) | layer.removeGraphic(tileset) → tileset.destroy() |
380
+ | 加载 `tileset.json` 但 Cesium Ion 鉴权未配 | 401/403 | 用 Cesium ION 默认 token 或自托管 tileset.json |
381
+ | `setStyle` 频繁调用(每帧) | 重建 shader,帧率骤降 | 改 `tileset.style = newStyle`(setter 内部 diff) |
382
+ | Tileset 路径使用 `file://` | Workers 404 | 必须 HTTP 服务打开(`http-server` / `vite dev`) |
383
+
384
+ ---
385
+
386
+ ## 4. v1.8.6 关键变化
387
+
388
+ | 变化 | 影响 | 迁移建议 |
389
+ |---|---|---|
390
+ | 15 个 Primitive 类新增 `boundingSphere` getter | `viewer.flyTo(primitive, ...)` 自动定位 | 升级后 range=0 自动生效,无需改 snippet |
391
+ | `Viewer.flyTo` / `zoomTo` / `flyToTileset` 支持 SDK Primitive / Tileset | 之前需传 `nativeObjCesium` | 现在两种写法都生效,推荐直接传 SDK 实例 |
392
+ | `PositonEditor` 增强(800 → 1029 行) | 支持更精细的编辑控件 | 新增 `originOffset` / `sizeInPixel` 等参数 |
393
+ | `TilesetEditor` 全新工具(1034 行) | Tileset 专用位姿编辑 | 用于倾斜摄影调位姿、3D Tiles 微调 |
394
+ | `ModelPrimitive.position` null 防御 | 不再崩溃 | 自动 fallback 到默认位置 |
395
+
396
+ ### S19. 建筑白模样式(`buildMaterial` + dat.GUI 切换) — `model/vectortiles1.html` L73-L196
397
+
398
+ > 注:`vectortiles1.html` 文件名误导,实际是 `buildMaterial` 建筑白模 + dat.GUI 切换 5 种样式(原始 / 高度 / 科技 / 夜景 / 单色)。矢量瓦片用法见 [`anovgis-imagery-terrain` § S26](../anovgis-imagery-terrain/SKILL.md#s26-epsg4490-矢量瓦片cgcs2000-地理坐标--offlinemaploadvectortiles_4490html-l36-l56)。
399
+
400
+ ```js
401
+ // 来源: vectortiles1.html L73-L86 + L161-L196
402
+ // 关键 API: ANOVGIS.TilesetLayer + ANOVGIS.Tileset + buildMaterial.setXxxStyle
403
+ const layer = new ANOVGIS.TilesetLayer();
404
+ viewer.addLayer(layer);
405
+ const build = new ANOVGIS.Tileset({
406
+ url: 'beijing_zhf_oldversion_nomaterial/tileset.json',
407
+ skipLevels: true,
408
+ shadows: Cesium.ShadowMode.ENABLED,
409
+ maximumScreenSpaceError: 6,
410
+ enableModelExperimental: true,
411
+ });
412
+ layer.addGraphic(build);
413
+ ANOVGIS.LocateUtil.flyToPosition(viewer, '116.3866336,40.0135969', 0, -26, 8000, 2, null, Cesium.EasingFunction.QUADRATIC_IN_OUT);
414
+
415
+ // dat.GUI 切换 5 种样式:
416
+ buildMaterial.setNoStyle(); // 原始样式
417
+ buildMaterial.setHeightStyle(); // 按高度着色
418
+ buildMaterial.setTechnologyStyle(); // 科技风
419
+ buildMaterial.setNightStyle(); // 夜景风
420
+ buildMaterial.setOneColor(); // 单色
421
+ ```
422
+
423
+ ---
424
+
425
+ ## 5. 关联阅读
426
+
427
+ - SDK 源码:
428
+ - `src/graphic/model/Model.js` — 单 glTF
429
+ - `src/graphic/model/Tileset.js` — 3D Tiles
430
+ - `src/analysis/transformHelper/PositonEditor.js` — v1.8.6
431
+ - `src/analysis/transformHelper/TilesetEditor.js` — v1.8.6
432
+ - 容器:`src/layer/graphic/TilesetLayer.js`
433
+ - 兄弟 skill:
434
+ - [`anovgis-vector-graphics`](../anovgis-vector-graphics/SKILL.md) — Model 基础 + Tileset 简版
435
+ - [`anovgis-layers`](../anovgis-layers/SKILL.md) — TilesetLayer 容器
436
+ - [`anovgis-analysis`](../anovgis-analysis/SKILL.md) — PositonEditor 标绘模式
437
+ - [`anovgis-popup-widget`](../anovgis-popup-widget/SKILL.md) — tilesetpopup 拾取
438
+ - v0.3.0 `anovgis-roaming-editor-time` — TilesetEditor + viewer.clock
439
+ - v0.3.0 `anovgis-custom-primitive-worker` — 自定义 shader 编写
440
+ - 关键 demo:
441
+ - `examples/public/examples/html/model/loadGlb.html`
442
+ - `examples/public/examples/html/model/qingxieTileset.html`
443
+ - `examples/public/examples/html/model/quShouBengZhan.html`
444
+ - `examples/public/examples/html/model/customshader.html`
445
+ - `examples/public/examples/html/event/tilesetpopup.html`
446
+ - `examples/public/examples/html/analysis/tools/positonEditor.html`
447
+ - DOMAINS.md:`#1.1-graphic/`、`#1.4-analysis/`
448
+ - DEMO-SKILL-MAP.md:`#5-model/`、`#7-analysis/`、`#8-event/`