@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.
- package/CHANGELOG.md +637 -0
- package/INSTALL.md +481 -0
- package/LICENSE +15 -0
- package/README.md +148 -2
- package/RELEASING.md +162 -0
- package/bin/anov-gis-skills.mjs +470 -0
- package/lib/mcp-config.mjs +273 -0
- package/package.json +43 -4
- package/skills/anovgis-analysis/SKILL.md +585 -0
- package/skills/anovgis-effects/SKILL.md +260 -0
- package/skills/anovgis-imagery-terrain/SKILL.md +505 -0
- package/skills/anovgis-layers/SKILL.md +627 -0
- package/skills/anovgis-materials/SKILL.md +635 -0
- package/skills/anovgis-models-3dtiles/SKILL.md +448 -0
- package/skills/anovgis-pitfalls/SKILL.md +561 -0
- package/skills/anovgis-popup-widget/SKILL.md +474 -0
- package/skills/anovgis-primitives/SKILL.md +482 -0
- package/skills/anovgis-vector-graphics/SKILL.md +602 -0
- package/skills/anovgis-viewer/SKILL.md +618 -0
- package/skills/using-anovgis/DEMO-MAP.md +64 -0
- package/skills/using-anovgis/DEMO-SKILL-MAP.md +248 -0
- package/skills/using-anovgis/DOMAINS.md +183 -0
- package/skills/using-anovgis/REFERENCE.md +114 -0
- package/skills/using-anovgis/SKILL.md +392 -0
- package/skills/using-anovgis/templates/README.md +154 -0
- package/skills/using-anovgis/templates/combo1-vue3-vite.md +295 -0
- package/skills/using-anovgis/templates/combo2-vue2-cli.md +119 -0
- package/skills/using-anovgis/templates/combo3-html-cdn.md +107 -0
- package/skills/using-anovgis/templates/combo4-vanilla-webpack.md +91 -0
- package/skills/using-anovgis/templates/wizard-profiles.md +105 -0
- package/vendor/cesiumjs-skills/LICENSE +201 -0
- package/vendor/cesiumjs-skills/NOTICE +18 -0
- package/vendor/cesiumjs-skills/skills/cesiumjs-3d-tiles/SKILL.md +465 -0
- package/vendor/cesiumjs-skills/skills/cesiumjs-camera/SKILL.md +500 -0
- package/vendor/cesiumjs-skills/skills/cesiumjs-core-utilities/SKILL.md +403 -0
- package/vendor/cesiumjs-skills/skills/cesiumjs-custom-shader/REFERENCE.md +397 -0
- package/vendor/cesiumjs-skills/skills/cesiumjs-custom-shader/SKILL.md +351 -0
- package/vendor/cesiumjs-skills/skills/cesiumjs-custom-shader/examples/01-diffuse-tint.js +38 -0
- package/vendor/cesiumjs-skills/skills/cesiumjs-custom-shader/examples/02-texture-swap.js +42 -0
- package/vendor/cesiumjs-skills/skills/cesiumjs-custom-shader/examples/03-feature-id-tileset.js +29 -0
- package/vendor/cesiumjs-skills/skills/cesiumjs-custom-shader/examples/04-translucent-override.js +37 -0
- package/vendor/cesiumjs-skills/skills/cesiumjs-custom-shader/examples/05-vertex-displacement.js +49 -0
- package/vendor/cesiumjs-skills/skills/cesiumjs-custom-shader/examples/06-metadata-ramp.js +34 -0
- package/vendor/cesiumjs-skills/skills/cesiumjs-custom-shader/examples/07-voxel-shader.js +27 -0
- package/vendor/cesiumjs-skills/skills/cesiumjs-custom-shader/examples/README.md +19 -0
- package/vendor/cesiumjs-skills/skills/cesiumjs-custom-shader/examples/_sandcastle-template.html +9 -0
- package/vendor/cesiumjs-skills/skills/cesiumjs-entities/SKILL.md +389 -0
- package/vendor/cesiumjs-skills/skills/cesiumjs-imagery/SKILL.md +471 -0
- package/vendor/cesiumjs-skills/skills/cesiumjs-interaction/SKILL.md +423 -0
- package/vendor/cesiumjs-skills/skills/cesiumjs-materials-shaders/SKILL.md +292 -0
- package/vendor/cesiumjs-skills/skills/cesiumjs-models-particles/SKILL.md +423 -0
- package/vendor/cesiumjs-skills/skills/cesiumjs-primitives/SKILL.md +537 -0
- package/vendor/cesiumjs-skills/skills/cesiumjs-spatial-math/SKILL.md +358 -0
- package/vendor/cesiumjs-skills/skills/cesiumjs-terrain-environment/SKILL.md +401 -0
- package/vendor/cesiumjs-skills/skills/cesiumjs-time-properties/SKILL.md +353 -0
- package/vendor/cesiumjs-skills/skills/cesiumjs-viewer-setup/SKILL.md +434 -0
- package/vendor/cesiumjs-skills/skills/using-cesiumjs-skills/SKILL.md +35 -0
|
@@ -0,0 +1,618 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: anovgis-viewer
|
|
3
|
+
description: '@anov/gis Viewer 与基础模块。涵盖 Viewer 构造扩展选项(geocoderType/baseLayer/showFPS/drillPick 等)、坐标系工具(CoordUtil / WktUtil / ShapeUtil / ThreeCoordTransform / Transform / LocateUtil)、事件枚举(MouseEventType / ViewerEventType / SceneEventType / LayerEventType / GraphicEventType)、flyTo 系列签名、skybox 天空盒切换、defaultView 默认视角、frustum 视锥。触发关键词:Viewer、options、contextOptions、坐标系、事件、flyTo、LocateUtil、ThreeCoordTransform、Transform、applicationApi、createInstance、skybox、天空盒、defaultView、默认视角、frustum。Use when 配置 Viewer 构造参数、做 WGS84↔GCJ02↔BD09 转换、做 Cartesian↔WGS84 互转、用 ShapeUtil.drawCanvalCircle 生成 billboard 贴图、订阅鼠标事件、调用 viewer.flyTo / flyToPosition / flyToTileset、初始化 application 消息通道、切换天空盒 / 默认视角。'
|
|
4
|
+
anov-gis-baseline: 1.8.6
|
|
5
|
+
cesium-baseline: 1.143.0
|
|
6
|
+
---
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# ANOVGIS Viewer 与基础模块
|
|
10
|
+
|
|
11
|
+
> `@anov/gis` **v1.8.6**(Cesium **1.143.0**)。`base/` 子包在 `src/base/index.js` 聚合 controls/event/math/position/state/transform/utils/viewer/anovCesiumBind/frameState。本 skill snippet 行号基于 v1.8.6 SDK 公开 API 行为锁定,跨版本仅作语义锚点。
|
|
12
|
+
|
|
13
|
+
> ⚠️ **优先级**:本 skill 优先于 SDK 源码 / `node_modules/@anov/gis/`。
|
|
14
|
+
> 遇到 API 行为疑问先查本 skill 与 `anovgis-pitfalls`。**严禁**主动 Glob/Grep `node_modules/@anov/gis/src/...` / `dist/...`;除非用户明确要求并承担风险。
|
|
15
|
+
|
|
16
|
+
## Out-of-scope(v0.2.0 短版)
|
|
17
|
+
|
|
18
|
+
- ❌ 不要写 19 类 Primitive(Cloud / FlowLine / ScanCircle / Water / ...) → [`anovgis-primitives`](../anovgis-primitives/SKILL.md)
|
|
19
|
+
- ❌ 不要写 `Model` / `Tileset` 加载 + 调色 + 抽壳 → [`anovgis-models-3dtiles`](../anovgis-models-3dtiles/SKILL.md)
|
|
20
|
+
- ❌ 不要写 `bindPopup` / `bindTooltip` 完整用法 → [`anovgis-popup-widget`](../anovgis-popup-widget/SKILL.md)
|
|
21
|
+
- ❌ 不要写 5 个 Util(Util / DomUtil / WktUtil / CoordUtil / ShapeUtil)完整 API — 本 skill 仅按需引用,见 SDK `src/base/utils/`
|
|
22
|
+
- ❌ 不要写 Imagery / Terrain → [`anovgis-imagery-terrain`](../anovgis-imagery-terrain/SKILL.md)
|
|
23
|
+
- ❌ 不要写天气 / 漫游 / 后期特效 → [`anovgis-effects`](../anovgis-effects/SKILL.md)
|
|
24
|
+
|
|
25
|
+
---
|
|
26
|
+
|
|
27
|
+
## 1. 命名空间速查
|
|
28
|
+
|
|
29
|
+
| 名称 | 来源 | 用途 |
|
|
30
|
+
|---|---|---|
|
|
31
|
+
| `ANOVGIS.Viewer` | `src/base/viewer/Viewer.js` | 主入口;包裹 Cesium 原生 `Viewer` |
|
|
32
|
+
| **Cesium 入口(唯一推荐)** | SDK 启动时主动挂载 | `const Cesium = window.Cesium`(CDN/UMD/ESM 全场景通用) |
|
|
33
|
+
| `ANOVGIS.CoordUtil` | `src/base/utils/CoordUtil.js` | 多边形相交 / 包含等几何判断 |
|
|
34
|
+
| `ANOVGIS.WktUtil` | `src/base/utils/WktUtil.js` | WKT ↔ GeoJSON |
|
|
35
|
+
| `ANOVGIS.ShapeUtil` | `src/base/utils/ShapeUtil.js` | Canvas 贴图(`drawCanvalCircle` 等) |
|
|
36
|
+
| `ANOVGIS.ThreeCoordTransform` | `src/base/transform/ThreeCoordTransform.js` | WGS-84 / GCJ-02 / BD-09 三系互转 |
|
|
37
|
+
| `ANOVGIS.LocateUtil` | `src/base/utils/LocateUtil.js` | `flyToPoint` / `flyToPosition` 等定位静态方法 |
|
|
38
|
+
| `ANOVGIS.FeatureInfoUtil` | `src/base/utils/FeatureInfoUtil.js` | 要素属性信息 |
|
|
39
|
+
| `ANOVGIS.Util` | `src/base/utils/Util.js` | 通用(uuid、merge、深拷贝) |
|
|
40
|
+
| `ANOVGIS.DomUtil` | `src/base/utils/DomUtil.js` | DOM 操作 |
|
|
41
|
+
| `ANOVGIS.Transform` | `src/base/transform/Transform.js` | `Cartesian ↔ WGS84 ↔ Cartographic` 转换 |
|
|
42
|
+
| `ANOVGIS.GeocoderType` | `src/base/controls/geocoder` | 地名搜索类型枚举 |
|
|
43
|
+
|
|
44
|
+
**注意**:`ANOVGIS.PlotUtil` 在 `src/base/utils/PlotUtil.js` 中存在但**未在 `utils/index.js` re-export**,因此 demo 中并未通过 `ANOVGIS.*` 访问。若需要标绘算法,应自行 `import` 该文件内部类,或在仓库内提 PR 补全 re-export。
|
|
45
|
+
|
|
46
|
+
**Cesium 入口写法(铁律)**:
|
|
47
|
+
|
|
48
|
+
```js
|
|
49
|
+
// ✅ 唯一推荐(CDN/UMD/ESM 全场景通用)
|
|
50
|
+
const Cesium = window.Cesium // @anov/gis 启动时主动 window.Cesium = Cesium
|
|
51
|
+
|
|
52
|
+
// ❌ 不要写(v1.8.6 SDK 未把 Cesium 对象本身挂到 ANOVGIS 顶层,undefined)
|
|
53
|
+
const Cesium = ANOVGIS.Cesium
|
|
54
|
+
|
|
55
|
+
// ❌ 不要写(@anov/gis 已封装 Cesium,不需要重复装包)
|
|
56
|
+
import Cesium from 'cesium'
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
**Cesium 私有成员(`_` 开头)**:`@anov/gis` 不会挂到 `ANOVGIS` 上,必须走 `window.Cesium`。例如 `window.Cesium.ArcType.GEODESIC`。
|
|
60
|
+
|
|
61
|
+
---
|
|
62
|
+
|
|
63
|
+
<a id="viewer-params"></a>
|
|
64
|
+
## 2. Viewer 扩展参数(17 个)
|
|
65
|
+
|
|
66
|
+
`ANOVGIS.Viewer` 在 Cesium 原生构造选项之上额外识别下列字段(默认值见 `Viewer.js` 中 `DEF_OPTS`,L22-56)。完整 Cesium 原生字段语义见 `Viewer.js` L58-109 的 JSDoc。
|
|
67
|
+
|
|
68
|
+
| 字段 | 类型 / 默认值 | 说明 |
|
|
69
|
+
|---|---|---|
|
|
70
|
+
| `geocoderType` | `ANOVGIS.GeocoderType.{TIANDITU,GAODE,TENCENT,BAIDU}` | 右上角地名搜索控件的数据源 |
|
|
71
|
+
| `baseLayer` | `ANOVGIS.ImageryType.*` | 简写,等价于 `ImageryLayerFactory.createImageryLayer(...)`。⚠️ **v1.8.6 实测有 bug**(枚举是字符串,如 `TDT` === `'tdt'`,构造传会报 `_layerIndex on string 'tdt'`)——不要用,底图走构造后 `addImageryProvider` |
|
|
72
|
+
| `baseLayerPicker` | `false` | 是否显示底图切换控件(`true` 时加载 LayerControlUitl) |
|
|
73
|
+
| `copyRight` | `false` | 控制台输出版权信息(`CopyRight.consoleOut()`) |
|
|
74
|
+
| `showMapInfo` | `false` | 加载 `MapInfo` 信息栏(鼠标经纬度 / 海拔) |
|
|
75
|
+
| `showFPS` | `false` | `scene.debugShowFramesPerSecond = true` |
|
|
76
|
+
| `flyDuration` | `3` | 初始定位飞行总秒数 |
|
|
77
|
+
| `language` | `'chinese'` \| `'english'` | `'chinese'` 时加载 `TranslateLocal.toChinese()` |
|
|
78
|
+
| `scaleRatio` | `1.0` | 屏幕分辨率缩放(影响高 DPI) |
|
|
79
|
+
| `drillPick` | `false` | 穿透拾取;同步写入 `nativeObjCesium.drillPick` |
|
|
80
|
+
| `minZoom` / `maxZoom` | `0` / `20` | 相机最小 / 最大缩放级别 |
|
|
81
|
+
| `minPitch` / `maxPitch` | `-90` / `0` | 相机最小 / 最大俯仰角(度) |
|
|
82
|
+
| `pitch` | `-90` | 默认俯仰角 |
|
|
83
|
+
| `zoom` | `undefined` | 默认缩放级别 |
|
|
84
|
+
| `center` | `undefined` | 默认中心点(`{lng, lat, alt, heading, pitch}`);提供时启动 `LocateUtil.flyToPosition` |
|
|
85
|
+
|
|
86
|
+
Cesium 原生字段会被 `this._options = { ...DEF_OPTS, ...options, geocoder: false }` 覆盖;ANOVGIS 强制关闭 `geocoder`(自实现地名搜索)。其余 Cesium 原生构造选项如 `contextOptions`、`sceneMode`、`terrainProvider`、`requestRenderMode` 等照常可用。
|
|
87
|
+
|
|
88
|
+
---
|
|
89
|
+
|
|
90
|
+
## 3. 事件枚举
|
|
91
|
+
|
|
92
|
+
所有事件枚举集中在 `src/base/event/EventType.js` 一个文件内(不要去 `event/type/*Type.js` 找,没有)。
|
|
93
|
+
|
|
94
|
+
### `MouseEventType`(Viewer 全局鼠标事件)
|
|
95
|
+
|
|
96
|
+
```text
|
|
97
|
+
LEFT_DOWN, LEFT_UP, CLICK, RIGHT_DOWN, RIGHT_UP, RIGHT_CLICK,
|
|
98
|
+
DB_CLICK, MOUSE_MOVE, WHEEL, MOUSE_OVER, MOUSE_OUT
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
### `ViewerEventType`(Viewer 实例生命周期 + 鼠标)
|
|
102
|
+
|
|
103
|
+
```text
|
|
104
|
+
ADD_LAYER, REMOVE_LAYER, ADD_EFFECT, REMOVE_EFFECT,
|
|
105
|
+
LEFT_DOWN, LEFT_UP, CLICK, RIGHT_DOWN, RIGHT_UP, RIGHT_CLICK,
|
|
106
|
+
DB_CLICK, MOUSE_MOVE, WHEEL,
|
|
107
|
+
FLY_COMPLETE
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
### `SceneEventType`(`scene` 渲染循环事件)
|
|
111
|
+
|
|
112
|
+
```text
|
|
113
|
+
CAMERA_MOVE_END, CAMERA_CHANGED,
|
|
114
|
+
PRE_UPDATE, POST_UPDATE, PRE_RENDER, POST_RENDER,
|
|
115
|
+
MORPH_COMPLETE, CLOCK_TICK, RENDER_ERROR
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
### `LayerEventType`(图层容器事件)
|
|
119
|
+
|
|
120
|
+
```text
|
|
121
|
+
ADD, REMOVE, // 来自 BaseEventType
|
|
122
|
+
LEFT_DOWN, LEFT_UP, CLICK, MOUSE_MOVE,
|
|
123
|
+
RIGHT_DOWN, RIGHT_UP, RIGHT_CLICK, DB_CLICK, MOUSE_OUT
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
### `GraphicEventType`(Graphic / Entity 事件)
|
|
127
|
+
|
|
128
|
+
```text
|
|
129
|
+
ADD, REMOVE,
|
|
130
|
+
LEFT_DOWN, LEFT_UP, CLICK, RIGHT_DOWN, RIGHT_UP, RIGHT_CLICK,
|
|
131
|
+
DB_CLICK, MOUSE_MOVE, MOUSE_OVER, MOUSE_OUT,
|
|
132
|
+
POSITION_UPDATE, BIND_POPUP
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
### 其他枚举(同样从 `EventType.js` 导出)
|
|
136
|
+
|
|
137
|
+
- `LayerGroupEventType = BaseEventType`:`ADD / REMOVE`
|
|
138
|
+
- `TrackEventType`:`ADD, REMOVE, POST_RENDER, ACTIVATE, DEACTIVATE, RESET_TIME_LINE`
|
|
139
|
+
- `PathEventType`:`ADD, REMOVE, POST_RENDER, RESET_TIME_LINE, END, STOP_STAY`
|
|
140
|
+
- `PlotEventType`:`DRAW_START, DRAW_STOP, EDIT_START, EDIT_STOP, DRAW_ANCHOR, CREATE_ANCHOR, UPDATE_ANCHOR, ANCHOR_MOVING, EDIT_ANCHOR_STOP, CLEAR_ANCHOR`
|
|
141
|
+
- `FlyEventType`:`BEGIN, END, STOP_STAY, FLYING`
|
|
142
|
+
- `WidgetEventType`:`OPEN, CLOSE`(信息框面板)
|
|
143
|
+
|
|
144
|
+
### 典型用法
|
|
145
|
+
|
|
146
|
+
```js
|
|
147
|
+
// 来源: examples/public/examples/html/graphics/billboard.html L96-101
|
|
148
|
+
layer.addEventListener(ANOVGIS.MouseEventType.CLICK, () => {
|
|
149
|
+
alert('点击了');
|
|
150
|
+
});
|
|
151
|
+
layer.addEventListener(ANOVGIS.MouseEventType.MOUSE_MOVE, () => {
|
|
152
|
+
console.log('MOUSE_MOVE');
|
|
153
|
+
});
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
---
|
|
157
|
+
|
|
158
|
+
## 4. 5 个 snippet
|
|
159
|
+
|
|
160
|
+
### Snippet 1:坐标系转换(WGS-84 ↔ GCJ-02 ↔ BD-09)
|
|
161
|
+
|
|
162
|
+
`CoordUtil` 不做坐标系转换;正确入口是 `ANOVGIS.ThreeCoordTransform`,所有方法接受 `(lng, lat)`,返回 `[lng, lat]` 数组。
|
|
163
|
+
|
|
164
|
+
```js
|
|
165
|
+
// 来源: src/base/transform/ThreeCoordTransform.js L57-85
|
|
166
|
+
const [gcjLng, gcjLat] = ANOVGIS.ThreeCoordTransform.WGS84ToGCJ02(116.404, 39.915);
|
|
167
|
+
const [wgsLng, wgsLat] = ANOVGIS.ThreeCoordTransform.GCJ02ToWGS84(gcjLng, gcjLat);
|
|
168
|
+
const [bdLng, bdLat] = ANOVGIS.ThreeCoordTransform.GCJ02ToBD09(gcjLng, gcjLat);
|
|
169
|
+
const [back2GcjLng, back2GcjLat] = ANOVGIS.ThreeCoordTransform.BD09ToGCJ02(bdLng, bdLat);
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
### Snippet 2:`ShapeUtil.drawCanvalCircle` 用作 billboard 贴图
|
|
173
|
+
|
|
174
|
+
方法名拼写是 `drawCanvalCircle`(SDK 历史拼写错误,注意不是 `drawCanvasCircle`)。返回 dataURL 字符串,可直接塞进 `billboard.image`。
|
|
175
|
+
|
|
176
|
+
```js
|
|
177
|
+
// 来源: examples/public/examples/html/graphics/billboard.html L79-93
|
|
178
|
+
v.setOptions({
|
|
179
|
+
billboard: {
|
|
180
|
+
image: ANOVGIS.ShapeUtil.drawCanvalCircle(
|
|
181
|
+
Cesium.Color.BLUE.toCssColorString(), // 颜色或 Cesium.Color
|
|
182
|
+
60, // 像素尺寸(正方形)
|
|
183
|
+
[v.attr.name, Math.floor(Math.random() * 300)] // 中心文字 1-2 行
|
|
184
|
+
),
|
|
185
|
+
verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
|
|
186
|
+
disableDepthTestDistance: Number.POSITIVE_INFINITY,
|
|
187
|
+
scaleByDistance: { near: 1000000, nearValue: 1.0, far: 10000000, farValue: 0.0 }
|
|
188
|
+
}
|
|
189
|
+
});
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
### Snippet 3:`Transform` 笛卡尔 ↔ WGS84 转换
|
|
193
|
+
|
|
194
|
+
`Transform` 提供 `Cartesian ↔ WGS84 ↔ Cartographic` 互转,也封装了屏幕坐标 → 世界坐标的便捷方法。`pickPosition`(Cesium 原生)适合命中 Entity / Primitive;屏幕 → WGS84 / Cartesian3 走 SDK 自带方法即可。
|
|
195
|
+
|
|
196
|
+
```js
|
|
197
|
+
// 来源: src/base/transform/Transform.js L19-99
|
|
198
|
+
// Position 对象形如 { lng, lat, alt }
|
|
199
|
+
const cartesian = ANOVGIS.Transform.transformWGS84ToCartesian({ lng: 116.404, lat: 39.915, alt: 100 });
|
|
200
|
+
const wgs84 = ANOVGIS.Transform.transformCartesianToWGS84(cartesian);
|
|
201
|
+
// wgs84 -> Position 实例: { lng, lat, alt }
|
|
202
|
+
|
|
203
|
+
// 屏幕坐标 -> 世界坐标(SDK 自带,3D 模式走 globe.pick,2D 走 ellipsoid)
|
|
204
|
+
// 来源: src/base/transform/Transform.js L172-194
|
|
205
|
+
const handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);
|
|
206
|
+
handler.setInputAction((movement) => {
|
|
207
|
+
const wgs = ANOVGIS.Transform.transformWindowToWGS84(movement.position, viewer);
|
|
208
|
+
console.log(wgs.lng, wgs.lat, wgs.alt);
|
|
209
|
+
|
|
210
|
+
const cartesian3 = ANOVGIS.Transform.transformWindowToCartesian3(movement.position, viewer);
|
|
211
|
+
}, Cesium.ScreenSpaceEventType.LEFT_CLICK);
|
|
212
|
+
|
|
213
|
+
// 需要命中 Entity / Primitive 时,落到 Cesium 原生 pickPosition:
|
|
214
|
+
handler.setInputAction((movement) => {
|
|
215
|
+
const picked = viewer.scene.pickPosition(movement.position);
|
|
216
|
+
if (picked) {
|
|
217
|
+
const wgs = ANOVGIS.Transform.transformCartesianToWGS84(picked);
|
|
218
|
+
console.log('命中实体:', wgs.lng, wgs.lat, wgs.alt);
|
|
219
|
+
}
|
|
220
|
+
}, Cesium.ScreenSpaceEventType.LEFT_CLICK);
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
### Snippet 4:`viewer.addLayer / viewer.removeLayer`
|
|
224
|
+
|
|
225
|
+
`addLayer` / `removeLayer` 是**链式 API**(返回 `this`)。`removeLayer` 接受 layer 实例(不是 id 字符串)。
|
|
226
|
+
|
|
227
|
+
```js
|
|
228
|
+
// 来源: examples/public/examples/html/material/flowPolyline.html L52-100
|
|
229
|
+
let layer = new ANOVGIS.VectorLayer();
|
|
230
|
+
viewer.addLayer(layer); // 链式返回 viewer
|
|
231
|
+
|
|
232
|
+
// layer.addGraphic(...) 等操作完成后
|
|
233
|
+
|
|
234
|
+
viewer.removeLayer(layer); // 接受 layer 实例,不是 id
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
### Snippet 5:`viewer.flyTo`
|
|
238
|
+
|
|
239
|
+
签名是 6 参数:`flyTo(target, duration, heading, pitch, range, completeCallback)`,不是 spec 简写的 `(target, opts)`。`target` 可以是 `Layer`(自动调 `layer.flyTo`)或任何 Cesium 原生可飞对象(Entity / DataSource / Tileset)。
|
|
240
|
+
|
|
241
|
+
```js
|
|
242
|
+
// 来源: examples/public/examples/html/material/flowPolyline.html L99-100
|
|
243
|
+
layer.addGraphic(polyline).addGraphic(polyline1).addGraphic(polyline2).addGraphic(polyline3);
|
|
244
|
+
viewer.flyTo(layer); // target=Layer, duration 默认 2.2s, heading/pitch/range 用默认
|
|
245
|
+
|
|
246
|
+
// 飞到单个 Entity 或 Tileset(严格 6 参数形式):
|
|
247
|
+
viewer.flyTo(
|
|
248
|
+
tileset.nativeObjCesium || tileset,
|
|
249
|
+
2.0, // duration(秒)
|
|
250
|
+
0.0, // heading(弧度)
|
|
251
|
+
Cesium.Math.toRadians(-45), // pitch(弧度)
|
|
252
|
+
0, // range(0 = SDK 自动取值)
|
|
253
|
+
() => console.log('fly complete') // completeCallback
|
|
254
|
+
);
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
---
|
|
258
|
+
|
|
259
|
+
## 4.5 补充 snippet(7 个)
|
|
260
|
+
|
|
261
|
+
### Snippet 6:`viewer.scene.pickPosition` 鼠标拾取世界坐标
|
|
262
|
+
|
|
263
|
+
`pickPosition`(Cesium 原生)返回 `Cesium.Cartesian3`。需要在命中 Entity / Primitive / 地形时取世界坐标。拾取失败(如点到天空)时返回 `undefined`,务必 `Cesium.defined` 判空。
|
|
264
|
+
|
|
265
|
+
```js
|
|
266
|
+
// 来源: examples/public/examples/html/analysis/terraincliping2.html L125-136
|
|
267
|
+
const handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);
|
|
268
|
+
const positions = [];
|
|
269
|
+
handler.setInputAction((movement) => {
|
|
270
|
+
const worldPosition = viewer.scene.pickPosition(movement.position);
|
|
271
|
+
if (Cesium.defined(worldPosition)) {
|
|
272
|
+
const carto = Cesium.Cartographic.fromCartesian(worldPosition);
|
|
273
|
+
positions.push(worldPosition);
|
|
274
|
+
// 转 WGS84 展示:
|
|
275
|
+
const wgs = ANOVGIS.Transform.transformCartesianToWGS84(worldPosition);
|
|
276
|
+
console.log('命中:', wgs.lng, wgs.lat, wgs.alt);
|
|
277
|
+
}
|
|
278
|
+
}, Cesium.ScreenSpaceEventType.LEFT_CLICK);
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
### Snippet 7:`viewer.flyTo` 完整 6 参数签名
|
|
282
|
+
|
|
283
|
+
签名是 `flyTo(target, duration, heading, pitch, range, completeCallback)`。`target` 可以是 `Layer`(自动调 `layer.flyTo`)或 Cesium 原生可飞对象(Entity / DataSource / Tileset)。`heading / pitch / range` 用 0 让 SDK 自行计算。`range = 0` 时 SDK 根据 target boundingSphere 自动取值。
|
|
284
|
+
|
|
285
|
+
```js
|
|
286
|
+
// 来源: examples/public/examples/html/material/flowPolyline.html L100
|
|
287
|
+
// 简单用法:target = Layer,duration 默认 2.2s
|
|
288
|
+
viewer.flyTo(layer);
|
|
289
|
+
|
|
290
|
+
// 完整 6 参数:target = Tileset / Entity / DataSource
|
|
291
|
+
viewer.flyTo(
|
|
292
|
+
tileset.nativeObjCesium || tileset, // target
|
|
293
|
+
2.0, // duration(秒)
|
|
294
|
+
0.0, // heading(弧度,正北=0)
|
|
295
|
+
Cesium.Math.toRadians(-45), // pitch(弧度,-90=俯视)
|
|
296
|
+
0, // range(0 = SDK 自动取 boundingSphere)
|
|
297
|
+
() => console.log('fly complete') // completeCallback
|
|
298
|
+
);
|
|
299
|
+
```
|
|
300
|
+
|
|
301
|
+
### Snippet 8:`viewer.camera.flyToBoundingSphere` 飞到包围球
|
|
302
|
+
|
|
303
|
+
先用 `Cesium.BoundingSphere.fromPoints(allPositions)` 算出所有点的包围球,再用 `flyToBoundingSphere` 飞行。offset 中 heading/pitch/range 控制飞行姿态。
|
|
304
|
+
|
|
305
|
+
```js
|
|
306
|
+
// 来源: examples/public/examples/html/effect/dog2.html L353-372
|
|
307
|
+
const now = Cesium.JulianDate.now();
|
|
308
|
+
const entities = dataSource.entities.values;
|
|
309
|
+
const allPositions = [];
|
|
310
|
+
entities.forEach(entity => {
|
|
311
|
+
if (entity.polygon) {
|
|
312
|
+
const h = entity.polygon.hierarchy.getValue(now);
|
|
313
|
+
if (h && h.positions) allPositions.push(...h.positions);
|
|
314
|
+
}
|
|
315
|
+
});
|
|
316
|
+
if (allPositions.length > 0) {
|
|
317
|
+
const boundingSphere = Cesium.BoundingSphere.fromPoints(allPositions);
|
|
318
|
+
window.viewer.camera.flyToBoundingSphere(boundingSphere, {
|
|
319
|
+
offset: {
|
|
320
|
+
heading: Cesium.Math.toRadians(0.96),
|
|
321
|
+
pitch: Cesium.Math.toRadians(-55),
|
|
322
|
+
range: boundingSphere.radius * 2.5 // 离中心点的距离(米)
|
|
323
|
+
},
|
|
324
|
+
duration: 2
|
|
325
|
+
});
|
|
326
|
+
}
|
|
327
|
+
```
|
|
328
|
+
|
|
329
|
+
### Snippet 9:`viewer.scene.camera.setView` 直接定位(不走动画)
|
|
330
|
+
|
|
331
|
+
`setView` 是**瞬时定位**(无飞行动画),`flyTo` 是动画飞行。`orientation` 字段有两种形式:
|
|
332
|
+
|
|
333
|
+
1. `heading / pitch / roll`(欧拉角,弧度)—— 最常用
|
|
334
|
+
2. `direction / up`(单位向量)—— 与 Three.js 同步相机姿态时使用
|
|
335
|
+
|
|
336
|
+
```js
|
|
337
|
+
// 来源: examples/public/examples/html/performance/js/ThreejsTransform.js L457-464
|
|
338
|
+
// heading/pitch/roll 形式:
|
|
339
|
+
viewer.camera.setView({
|
|
340
|
+
destination: Cesium.Cartesian3.fromDegrees(116.397, 39.916, 1000),
|
|
341
|
+
orientation: {
|
|
342
|
+
heading: 0.0, // 正北
|
|
343
|
+
pitch: Cesium.Math.toRadians(-90), // 俯视
|
|
344
|
+
roll: 0.0
|
|
345
|
+
}
|
|
346
|
+
});
|
|
347
|
+
|
|
348
|
+
// 来源: examples/public/examples/html/performance/js/ThreejsTransform.js L359-366
|
|
349
|
+
// direction/up 单位向量形式(同步 Three.js 相机时):
|
|
350
|
+
viewer.scene.camera.setView({
|
|
351
|
+
destination: cameraPosCesium,
|
|
352
|
+
orientation: {
|
|
353
|
+
direction: directionCesiumCamera,
|
|
354
|
+
up: upCesiumCamera
|
|
355
|
+
}
|
|
356
|
+
});
|
|
357
|
+
```
|
|
358
|
+
|
|
359
|
+
### Snippet 10:`viewer.clock` 当前时间与 `Cesium.JulianDate` 转换
|
|
360
|
+
|
|
361
|
+
`viewer.clock.currentTime` 控制场景时间,常用于动画、阴影、光照等时间敏感渲染。`Cesium.JulianDate.fromDate(new Date(...))` 把 JS `Date` 转为 JulianDate,`Cesium.JulianDate.now()` 取当前时刻。
|
|
362
|
+
|
|
363
|
+
```js
|
|
364
|
+
// 来源: examples/public/examples/html/effect/globalrotate.html L53
|
|
365
|
+
viewer.clock.currentTime = Cesium.JulianDate.fromDate(new Date('2024,4,2 16:10:18'));
|
|
366
|
+
|
|
367
|
+
// 来源: examples/public/examples/html/effect/dog2.html L353
|
|
368
|
+
const now = Cesium.JulianDate.now();
|
|
369
|
+
const h = entity.polygon.hierarchy.getValue(now); // 取当前时刻属性
|
|
370
|
+
|
|
371
|
+
// 暂停 / 继续 / 倍速:
|
|
372
|
+
viewer.clock.shouldAnimate = false; // 暂停
|
|
373
|
+
viewer.clock.shouldAnimate = true; // 继续
|
|
374
|
+
viewer.clock.multiplier = 10; // 10x 倍速播放
|
|
375
|
+
```
|
|
376
|
+
|
|
377
|
+
### Snippet 11:`Transform` 双向 Cartesian ↔ WGS84 转换
|
|
378
|
+
|
|
379
|
+
`Transform.transformCartesianToWGS84(cartesian)` 返回 `Position`(`{lng, lat, alt}`);`Transform.transformWGS84ToCartesian(position)` 返回 `Cesium.Cartesian3`。双向是同步 SDK `Position` 对象的关键。
|
|
380
|
+
|
|
381
|
+
```js
|
|
382
|
+
// 来源: src/base/transform/Transform.js L19-78
|
|
383
|
+
// Cartesian -> WGS84(Position)
|
|
384
|
+
const cartesian = Cesium.Cartesian3.fromDegrees(116.404, 39.915, 100);
|
|
385
|
+
const wgs = ANOVGIS.Transform.transformCartesianToWGS84(cartesian);
|
|
386
|
+
console.log(wgs.lng, wgs.lat, wgs.alt); // 116.404 39.915 100
|
|
387
|
+
|
|
388
|
+
// WGS84 -> Cartesian
|
|
389
|
+
const back = ANOVGIS.Transform.transformWGS84ToCartesian(
|
|
390
|
+
new ANOVGIS.Position(116.404, 39.915, 100)
|
|
391
|
+
);
|
|
392
|
+
console.log(back); // Cesium.Cartesian3
|
|
393
|
+
|
|
394
|
+
// 用途:从 pickPosition / 几何计算得到的 Cartesian3 一律先 transformCartesianToWGS84
|
|
395
|
+
// 再传给 WKT / GeoJSON / ShapeUtil。
|
|
396
|
+
```
|
|
397
|
+
|
|
398
|
+
### Snippet 12:`viewer.scene.globe.depthTestAgainstTerrain` + `pickEllipsoid` 拾取地球椭球面
|
|
399
|
+
|
|
400
|
+
`depthTestAgainstTerrain` 控制 entity / primitive 是否被地形遮挡。无地形(`EllipsoidTerrainProvider`)时默认 `false` 也不影响;有地形时若想让标注 / polygon 浮在地表以上就开 `true`。`pickEllipsoid` 用于无地形或无命中时拾取椭球面(射线和 WGS84 椭球的交点),返回 `Cartesian3`,与俯仰角无关。
|
|
401
|
+
|
|
402
|
+
```js
|
|
403
|
+
// 来源: examples/public/examples/html/analysis/draw.html L138-140
|
|
404
|
+
// 深度测试开关(checkbox 切换)
|
|
405
|
+
function depthTest(t) {
|
|
406
|
+
viewer.scene.globe.depthTestAgainstTerrain = t;
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
// 来源: src/base/viewer/Viewer.js L1144-1154
|
|
410
|
+
// pickEllipsoid 拾取椭球面(无地形或拾取失败时兜底):
|
|
411
|
+
const ellipsoid = viewer.scene.globe
|
|
412
|
+
? viewer.scene.globe.ellipsoid
|
|
413
|
+
: Cesium.Ellipsoid.WGS84;
|
|
414
|
+
const center = new Cesium.Cartesian2(
|
|
415
|
+
viewer.scene.canvas.clientWidth / 2,
|
|
416
|
+
viewer.scene.canvas.clientHeight / 2
|
|
417
|
+
);
|
|
418
|
+
const cartesian = viewer.scene.camera.pickEllipsoid(center, ellipsoid);
|
|
419
|
+
if (cartesian) {
|
|
420
|
+
const carto = ellipsoid.cartesianToCartographic(cartesian);
|
|
421
|
+
console.log(
|
|
422
|
+
Cesium.Math.toDegrees(carto.longitude),
|
|
423
|
+
Cesium.Math.toDegrees(carto.latitude),
|
|
424
|
+
carto.height
|
|
425
|
+
);
|
|
426
|
+
}
|
|
427
|
+
```
|
|
428
|
+
|
|
429
|
+
---
|
|
430
|
+
|
|
431
|
+
## 4.5 Viewer 一级相机状态机(`viewer.getCenter / setZoom / zoomIn / zoomOut`)— `effect/testzoom.html`
|
|
432
|
+
|
|
433
|
+
> ⚠️ v0.2.6 新增。`testzoom.html` 揭示了一套完整的相机状态机 API,比 `viewer.flyTo` 更适合做"地图应用"级别的 zoom/pan 控制(mapbox / 高德地图那种风格)。**此前 v0.2.5 完全漏掉**。
|
|
434
|
+
|
|
435
|
+
### 初始化选项
|
|
436
|
+
|
|
437
|
+
```js
|
|
438
|
+
// 来源: effect/testzoom.html L106-135
|
|
439
|
+
new ANOVGIS.Viewer('cesiumContainer', {
|
|
440
|
+
defaultView: [250, 22, 330, 60],
|
|
441
|
+
center: { lng: 116.397, lat: 39.916 }, // 初始中心
|
|
442
|
+
zoom: 12, // 初始缩放等级(类似 mapbox zoom)
|
|
443
|
+
pitch: -45, // 初始俯仰角(度,负值=俯视)
|
|
444
|
+
minZoom: 3, maxZoom: 18, // zoom 范围限制
|
|
445
|
+
minPitch: -90, maxPitch: -30, // pitch 范围限制
|
|
446
|
+
flyDuration: 2, // 默认飞行时长
|
|
447
|
+
});
|
|
448
|
+
```
|
|
449
|
+
|
|
450
|
+
### 读状态
|
|
451
|
+
|
|
452
|
+
```js
|
|
453
|
+
const center = viewer.getCenter(); // { lng, lat }
|
|
454
|
+
const zoom = viewer.getZoom(); // float (类似 mapbox zoom)
|
|
455
|
+
const pitch = viewer.getPitch(); // float (度)
|
|
456
|
+
const { min, max } = viewer.getZoomRange(); // 当前 zoom 范围
|
|
457
|
+
const { min, max } = viewer.getPitchRange(); // 当前 pitch 范围
|
|
458
|
+
```
|
|
459
|
+
|
|
460
|
+
### 写状态(瞬时,无动画)
|
|
461
|
+
|
|
462
|
+
```js
|
|
463
|
+
viewer.setCenter({ lng: 116.391, lat: 39.912 });
|
|
464
|
+
viewer.setZoom(13);
|
|
465
|
+
viewer.setCenterAndZoom({ lng: 116.397, lat: 39.916 }, 14); // 同时设中心+缩放
|
|
466
|
+
viewer.zoomIn(); // 缩放 +1
|
|
467
|
+
viewer.zoomOut(); // 缩放 -1
|
|
468
|
+
viewer.setPitch(-30); // 俯仰角
|
|
469
|
+
viewer.setZoomRange(5, 15); // 重设 zoom 范围
|
|
470
|
+
```
|
|
471
|
+
|
|
472
|
+
### 保存 / 恢复视图
|
|
473
|
+
|
|
474
|
+
```js
|
|
475
|
+
this.savedView = viewer.getView(); // { center, zoom, heading, pitch }
|
|
476
|
+
viewer.setView(this.savedView); // 瞬时恢复
|
|
477
|
+
viewer.setView(this.savedView, 1.5); // 带动画恢复(1.5s)
|
|
478
|
+
```
|
|
479
|
+
|
|
480
|
+
> ⚠️ 这套 API 与 `viewer.flyTo(target, ...)` 的区别:
|
|
481
|
+
> - `flyTo`: 飞到某个**目标实体**(point / tileset / layer),适合 POI 跳转
|
|
482
|
+
> - `getCenter / setZoom`: 操作**相机状态机**(center + zoom + pitch),适合地图 UI 控件(滚轮缩放 / 拖拽平移 / 复位)
|
|
483
|
+
|
|
484
|
+
---
|
|
485
|
+
|
|
486
|
+
## 5. applicationApi:SDK 与业务消息通道
|
|
487
|
+
|
|
488
|
+
`application` 模块仅实现 `ANOVGIS.init` 与 `viewer.scene.camera.focus` 两个 message name;其余 `name` 静默无响应。**真正的"开箱即用业务 API"位于已抽离的 `@anov/gis.applyfn` 子包,本 skill 不覆盖**(UI 在 `@anov/gis.ui`,Cesium 三方封装在 `@anov/gis.cesiumthreelib`)。
|
|
489
|
+
|
|
490
|
+
### createInstance 真实用法
|
|
491
|
+
|
|
492
|
+
```js
|
|
493
|
+
import ANOVGIS from '@anov/gis';
|
|
494
|
+
|
|
495
|
+
const app = ANOVGIS.createInstance();
|
|
496
|
+
// 实际不做初始化(构造时 options 被丢弃),真正初始化走:
|
|
497
|
+
app.sendMessage({
|
|
498
|
+
name: 'ANOVGIS.init',
|
|
499
|
+
params: { container: 'cesiumContainer', /* ...viewer options */ }
|
|
500
|
+
});
|
|
501
|
+
```
|
|
502
|
+
|
|
503
|
+
> 路径说明:`createInstance` 在 `src/ANOVGIS.js:21` 通过 `export * from './application'` 导出,在 `src/index.js:83` 通过 `ANOVGIS.mixin(...)` 挂到默认导出。`@anov/gis` 包无 `exports` 字段且 `.npmignore` 排除 `/src`,故子路径 `@anov/gis/application` 在发布的 npm 包里解析不了——必须从主入口 `@anov/gis` 取默认导出再调用 `createInstance`。
|
|
504
|
+
|
|
505
|
+
`options` 参数:`createInstance(options)` 调用时 `options` 会被构造器丢弃,真正的初始化通过后续 `sendMessage({ name: 'ANOVGIS.init'/'anovgis.init', params })` 触发。`params` 至少需含 `container`(DOM 容器)以及透传给 `Viewer` 的其他 Cesium 参数。
|
|
506
|
+
|
|
507
|
+
### messageFn / messageStatus
|
|
508
|
+
|
|
509
|
+
`application` 子包不主动执行业务,而是封装"消息分发"机制:
|
|
510
|
+
|
|
511
|
+
- `messageFn.js`:`sendToMessage(messageType, name, status, id, res)` 构造统一响应结构(`id` / `name` / `code` / `msg` / `result`),并定义 `MessageType = { Event, Api }`。
|
|
512
|
+
- `messageStatus.js`:`messageStatus`(含 `code`+`msg`)与 `EMessageStatus`(纯数字枚举)两套状态码表,涵盖 `Success / ModuleNotRegister / EventHandleFailed` 等。`codeMessageMap` 仅含 `200` 兜底映射。
|
|
513
|
+
|
|
514
|
+
调用方通过 `app.sendMessage({ name, id, params })` 发送 API 调用;通过 `app.receiveMessage(cb)` 订阅 `Event` / `Api` 两类消息。`name === 'ANOVGIS.init'` 会创建 `Viewer`,`name === 'viewer.scene.camera.focus'` 会调用 `camera.flyTo`。
|
|
515
|
+
|
|
516
|
+
**来源**:`src/application/index.js`、`src/application/applicationApi.js`、`src/application/messageFn.js`、`src/application/messageStatus.js`。
|
|
517
|
+
|
|
518
|
+
---
|
|
519
|
+
|
|
520
|
+
## Viewer 工具栏默认全开(v0.2.4 加)
|
|
521
|
+
|
|
522
|
+
通用 demo / 教学 / 业务项目,Viewer 右上角工具栏**默认全部显示**,与 `examples/public/examples/html/basemap/tdtSatelliteImage.html` L96-101 对齐:
|
|
523
|
+
|
|
524
|
+
```js
|
|
525
|
+
// ✅ 推荐:默认全开
|
|
526
|
+
new ANOVGIS.Viewer('cesiumContainer', {
|
|
527
|
+
// 全部 true(用户视角下默认就要显示)
|
|
528
|
+
baseLayerPicker: true,
|
|
529
|
+
fullscreenButton: true,
|
|
530
|
+
homeButton: true,
|
|
531
|
+
sceneModePicker: true,
|
|
532
|
+
navigationHelpButton: true,
|
|
533
|
+
// 与本约定无关的可以关(典型 demo 不需要)
|
|
534
|
+
timeline: false, // 时间轴(只有 CZML/动画 demo 需要)
|
|
535
|
+
animation: false, // 仿真时钟 UI(同上)
|
|
536
|
+
vrButton: false, // VR(已淘汰)
|
|
537
|
+
})
|
|
538
|
+
```
|
|
539
|
+
|
|
540
|
+
**为什么**:Cesium 右上角的工具栏是**用户预期的导航能力**(底图切换 / 主页 / 2D-3D 切换)。全关等于剥夺基本功能,用户会觉得"这地球怎么啥都没有"。**只有明确要纯净态**(截图、嵌入大屏、视频录制)才逐一关,且注释说明。
|
|
541
|
+
|
|
542
|
+
**仅在以下场景才逐一关**:
|
|
543
|
+
- 大屏嵌入 + 不需要导航 → `baseLayerPicker: false, homeButton: false`
|
|
544
|
+
- 单页应用 + 业务 UI 接管 → `fullscreenButton: false`(自己的 fullscreen 控件)
|
|
545
|
+
- 移动端嵌入 → 全部保留
|
|
546
|
+
|
|
547
|
+
---
|
|
548
|
+
|
|
549
|
+
|
|
550
|
+
---
|
|
551
|
+
|
|
552
|
+
## 典型工作流(4 步)
|
|
553
|
+
|
|
554
|
+
```js
|
|
555
|
+
// 1. 设置静态资源 baseUrl(必须先于 new Viewer)
|
|
556
|
+
ANOVGIS.setBaseUrl('/anov-gis-sdk/resources/');
|
|
557
|
+
|
|
558
|
+
// 2. 创建 Viewer
|
|
559
|
+
const viewer = new ANOVGIS.Viewer('cesiumContainer', {
|
|
560
|
+
contextOptions: { id: 'cesiumCanvas' },
|
|
561
|
+
geocoderType: ANOVGIS.GeocoderType.TIANDITU,
|
|
562
|
+
// ⚠️ 不要传 baseLayer(v0.2.10 实测 v1.8.6 会报 _layerIndex on string 错)——底图构造后 addImageryProvider
|
|
563
|
+
});
|
|
564
|
+
|
|
565
|
+
// 3. 加载图层
|
|
566
|
+
viewer.addLayer(new ANOVGIS.GeoJsonLayer(url, opts));
|
|
567
|
+
|
|
568
|
+
// 4. 监听事件
|
|
569
|
+
viewer.getLayer(id).addEventListener(ANOVGIS.MouseEventType.CLICK, handler);
|
|
570
|
+
```
|
|
571
|
+
|
|
572
|
+
|
|
573
|
+
---
|
|
574
|
+
|
|
575
|
+
### E. 多 Viewer 实例。每 Viewer 占独立 DOM + 独立 WebGL 上下文;`contextOptions.id` 必须不同(截图依赖 canvas id)。
|
|
576
|
+
|
|
577
|
+
```js
|
|
578
|
+
// 来源: examples/.../basemap/CesiumTerrain.html L31 + ArcGISTerrain.html L30
|
|
579
|
+
const opts = (id) => ({
|
|
580
|
+
contextOptions: { id, webgl: { preserveDrawingBuffer: true }, showRenderLoopErrors: false },
|
|
581
|
+
geocoderType: ANOVGIS.GeocoderType.TIANDITU,
|
|
582
|
+
baseLayerPicker: true, fullscreenButton: false, homeButton: true,
|
|
583
|
+
sceneModePicker: true, navigationHelpButton: true, copyRight: false, showMapInfo: true,
|
|
584
|
+
});
|
|
585
|
+
window.viewerLeft = new ANOVGIS.Viewer('cesiumLeft', opts('cesiumCanvasLeft'));
|
|
586
|
+
viewerLeft.scene.setTerrain(Cesium.Terrain.fromWorldTerrain());
|
|
587
|
+
const arcgis = await Cesium.ArcGISTiledElevationTerrainProvider.fromUrl(
|
|
588
|
+
'https://elevation3d.arcgis.com/arcgis/rest/services/WorldElevation3D/Terrain3D/ImageServer'
|
|
589
|
+
);
|
|
590
|
+
window.viewerRight = new ANOVGIS.Viewer('cesiumRight', opts('cesiumCanvasRight'));
|
|
591
|
+
viewerRight.terrainProvider = arcgis;
|
|
592
|
+
```
|
|
593
|
+
|
|
594
|
+
> WebGL 上下文有上限(同源约 16),多 Viewer 务必在 `beforeUnmount`/`destroy` 释放。
|
|
595
|
+
|
|
596
|
+
|
|
597
|
+
---
|
|
598
|
+
|
|
599
|
+
### F. iframe + `about:srcdoc`。`about:srcdoc` iframe 的 `window.location.href` 为 `"about:srcdoc"`,Cesium `isCrossOriginUrl()` 用 anchor 协议/host 比对会判同源 worker 为跨域。SDK `src/index.js` 已做:① 从 `<script src="/anov-gis-sdk/...">` 推断 baseUrl;② monkey-patch `HTMLAnchorElement.href` setter 把 `"about:srcdoc"` 重写为父页 href。
|
|
600
|
+
|
|
601
|
+
```html
|
|
602
|
+
<!-- 来源: src/index.js L89-135 -->
|
|
603
|
+
<iframe srcdoc="
|
|
604
|
+
<!DOCTYPE html><html><body style='margin:0'>
|
|
605
|
+
<div id='cesiumContainer' style='width:100%;height:100vh'></div>
|
|
606
|
+
<script src='https://unpkg.com/@anov/gis@1.7.7/dist/index.js'><\/script>
|
|
607
|
+
<link rel='stylesheet' href='https://unpkg.com/@anov/gis@1.7.7/dist/index.css'>
|
|
608
|
+
<script>
|
|
609
|
+
ANOVGIS.setBaseUrl('https://unpkg.com/@anov/gis@1.7.7/dist/resources/');
|
|
610
|
+
window.viewer = new ANOVGIS.Viewer('cesiumContainer', {
|
|
611
|
+
contextOptions: { id: 'cesiumCanvas', webgl: { preserveDrawingBuffer: true } },
|
|
612
|
+
geocoderType: ANOVGIS.GeocoderType.TIANDITU,
|
|
613
|
+
});
|
|
614
|
+
<\/script></body></html>"></iframe>
|
|
615
|
+
```
|
|
616
|
+
|
|
617
|
+
> 跨域 iframe 需父页 `document.domain` 一致或 CSP 显式放行 worker 资源。
|
|
618
|
+
|