gis-view-webgl2 0.1.4 → 0.1.5
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 +7 -7
- package/dist/index.cjs +1 -1
- package/dist/index.d.ts +140 -20
- package/dist/index.js +1 -1
- package/docs/AI/345/257/271/350/257/235/346/261/207/346/200/273.md +45 -0
- package/docs/GisView.md +53 -53
- package/docs/ai/06-/344/274/232/350/257/235/347/264/242/345/274/225/344/270/216/345/244/215/346/237/245/346/226/271/346/263/225.md +36 -0
- package/docs/demos/ConnectDemo.vue +114 -3
- package/docs/demos/MinimapDemo.vue +62 -16
- package/docs/demos/api-index.js +15 -14
- package/docs/demos/gis-view-demo/GisViewDemoStage.vue +25 -16
- package/docs/demos/gis-view-demo/useGisViewDemo.js +27 -16
- package/docs/index.html +3 -3
- package/docs/internals/13-/351/271/260/347/234/274/345/233/276.md +6 -5
- package/docs/internals/16-01-/344/274/230/345/214/226/344/270/216/345/217/226/350/210/215-/344/270/212.md +5 -3
- package/docs/internals/18-/346/200/247/350/203/275/345/256/236/346/265/213/344/270/216WebGPU/350/257/204/344/274/260.md +12 -0
- package/docs/manual/03-/351/205/215/347/275/256/351/241/271.md +11 -3
- package/docs/manual/09-/351/200/232/351/201/223/344/270/216/345/244/232/345/233/236/347/272/277.md +1 -1
- package/docs/manual/10-/351/200/232/351/201/223/347/274/226/350/276/221/344/270/216/346/226/260/345/242/236.md +423 -3
- package/docs/manual/14-/350/247/206/345/233/276/344/270/216/347/255/233/351/200/211.md +79 -28
- package/docs/manual/16-/345/256/236/344/276/213/346/226/271/346/263/225/346/200/273/350/241/250.md +6 -5
- package/docs/manual/17-/345/217/202/346/225/260/351/200/237/346/237/245.md +5 -4
- package/docs/manual/18-/351/200/220/346/226/271/346/263/225/347/244/272/344/276/213.md +117 -5
- package/docs/manual/21-/350/257/264/346/230/216/344/270/216/345/270/270/350/247/201/351/227/256/351/242/230.md +5 -2
- package/docs/steps/README.md +5 -5
- package/docs/steps/selftest-demos.html +149 -5
- package/docs/steps/selftest-docs.html +3 -3
- package/docs/steps/selftest-full.html +315 -12
- package/docs/steps/selftest-perf.html +39 -1
- package/package.json +1 -1
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
| `channelTangentInset` | `number \| null` | `null` | 两端切点往节点里收多少 CSS 像素:缺省(`null`)按成员回线里最粗那条的线宽收,线因此不会从节点边缘探出去;`0` 表示切点正好落在节点边上,**负数外收**(切点往节点外让、回线整段比节点宽);单个通道可用 `tangentInset` 覆盖;内收两侧合计最多收掉节点宽度的 40%,外收单侧最多让出 50% |
|
|
27
27
|
| `channelMaxGroups` | `number` | `0` | 一条通道最多几个分组(`0` 表示不限):新增通道时用来判断还能不能变成新分组,见「新增通道」 |
|
|
28
28
|
| `channelGroupMaxLines` | `number` | `0` | 一个分组最多几条回线(`0` 表示不限):新增通道时用来判断还能不能并进某一组,见「新增通道」 |
|
|
29
|
-
| `channelDraftStyle` | `GisViewChannelDraftStyle` | 蓝色 2px + 两端圆点,箭头关闭 | 新增通道草稿预览的全局样式:`color` / `width` / `dot` / `dotColor` / `arrow` / `arrowSize` / `arrowPositions` / `arrowReverse` / `arrowColor` / `circuitSpacing` / `opacity` / `customDraw`;`beginAddChannel({ channelDraftStyle })` 可按这一次草稿覆盖,`updateAddChannelStyle(patch)` 可在草稿期间增量修改 |
|
|
29
|
+
| `channelDraftStyle` | `GisViewChannelDraftStyle` | 蓝色 2px + 两端圆点,箭头关闭 | 新增通道草稿预览的全局样式:`color` / `width` / `dot` / `dotColor` / `dots`(`false` 关示例点,或 `{ show, size, color, shape, from, to }` 分端配置;示例点固定在点中的节点中心)/ `layer`(`'above'` 默认,`'below-points'` 让示例线 / 箭头 / `customDraw` 位于真实节点之下)/ `arrow` / `arrowSize` / `arrowPositions` / `arrowReverse` / `arrowColor` / `circuitSpacing` / `opacity` / `customDraw`;`beginAddChannel({ channelDraftStyle })` 可按这一次草稿覆盖,`updateAddChannelStyle(patch)` 可在草稿期间增量修改 |
|
|
30
30
|
| `webglLayers` | `GisViewWebGLLayer[]` | `[]` | WebGL 自定义绘制层:每层提供 `draw({ gl, canvas, viewport, camera, frame, project, unproject, requestRender })`,在内置内容之后按 `order` 绘制;运行时也可用 `addWebGLLayer` / `updateWebGLLayer` / `removeWebGLLayer` 维护 |
|
|
31
31
|
| `background` | `GisViewBackground` | 浅色底 | 背景层,支持底色、图片与 GeoJSON |
|
|
32
32
|
| `pointStyle` | `GisViewPointStyle` | 见下 | 点的默认样式,可被单个点覆盖;运行时按字段合并用 `updatePointStyle(patch)`(`updateOptions({ pointStyle })` 是整份换) |
|
|
@@ -43,7 +43,7 @@
|
|
|
43
43
|
| `labelStates` | `GisViewLabelState[]` | 无 | 标签的运行时状态(`getLabelStates()` 的那一份:拖出来的偏移、改过的内容与样式、运行时加的标签、隐藏覆盖):创建时喂回来就回显,等价于创建之后调 `setLabelStates(states)`;`updateOptions({ labelStates })` 同样认。`exportData({ format: 'input' })` 的结果里就叫 `labelStates`,存档 → 回灌直接接上 |
|
|
44
44
|
| `graphics` | `GisViewGraphic[]` | 无 | 与节点无关的扩展图形:按世界坐标放 SVG 路径 / 图片 / Canvas,支持锚点、偏移、旋转、透明度、`zIndex` 与 `scaleWithView`;位于画布之上、标签之下,运行时用 `addGraphic` / `addGraphics` / `updateGraphic` / `removeGraphic` / `clearGraphics` 增删改,见「扩展图形(graphic)」 |
|
|
45
45
|
| `tooltip` | `GisViewTooltipOptions` | 无 | 悬停提示:点 / 线 / 通道分别配置内容,见「悬浮提示」 |
|
|
46
|
-
| `minimap` | `GisViewMinimapOptions \| null` | 无 | 内置鹰眼图:位置、尺寸、节点 / 线路 / 视口框三份样式与交互都可配,`extent` 决定小图按数据范围还是「数据 ∪ 底图」铺(默认 `auto`,GeoJSON 底图不会缩成一个点),`zoomable`
|
|
46
|
+
| `minimap` | `GisViewMinimapOptions \| null` | 无 | 内置鹰眼图:位置、尺寸、节点 / 线路 / 视口框三份样式与交互都可配,`extent` 决定小图按数据范围还是「数据 ∪ 底图」铺(默认 `auto`,GeoJSON 底图不会缩成一个点),`extentFollowCamera` 默认 `false`、打开后才允许 `auto` 范围随相机收窄。`zoomable` 三态互斥:`false` 关闭、`true` 手动缩放小图自身、`'follow'` 让整体范围跟随主图(`followZoomScale` 是主图倍数的指数,跟随模式下 `setMinimapZoom` / `zoomMinimapBy` 不抢控制权);空白处拖动可平移小图或直接框选让主图显示过去(`dragAction`,`box` 不依赖缩放,手动模式下 Ctrl / ⌘ 才切换动作),每格倍率 `zoomStep`。通道还能只画一根;小图同样支持规则(`pointRules` / `lineRules`,缺省沿用主图规则的颜色、层级、最终节点尺寸与图标、样式链线宽,节点 / 线路尺寸按两边视口比例缩放且不受主图相机倍数影响),可以只画某几层(`levels`)、关掉分层叠画(`layered`)、按三组系数给节点与线路定尺寸(整体倍数 `pointSizeScale` / `lineWidthScale` 对自有与继承要素都生效;跟随小图倍数 `pointZoomScale` / `lineZoomScale` 在小图自身放大时也作用于继承要素;跟随主视图地图倍数 `pointMapZoomScale` / `lineMapZoomScale` 只作用于自有规则 / 样式),视口框与框选矩形的颜色 / 背景 / 边框 / 圆角也能配(`boxStyle` / `selectStyle`),`extent` 还能直接写死一份世界范围、容器可加 `className` / `style`、`layers` 按 `placement` 分数据前 / 数据后、段内按 `order` 拆出多层自绘内容(旧 `draw` 钩子仍兼容并排在最后)、`onInteraction` 在手势结束时给出类型 / 世界坐标 / 相机、`maxPixelRatio` 限制备份倍率上限,不配则不产生任何 DOM,见「鹰眼图」 |
|
|
47
47
|
| `filter` | `GisViewFilterInput \| null` | 无 | 初始筛选条件,等价于创建之后调用 `setFilter`;`mode` 缺省 `'hide'`,写 `'remove'` 则删除不命中的要素,见「筛选」 |
|
|
48
48
|
| `filterWorker` | `boolean \| GisViewFilterWorkerOptions` | `{ threshold: 20000 }` | 筛选是否用 Web Worker 计算:默认点 + 线总数超过阈值才用,`false` 表示始终同步算 |
|
|
49
49
|
| `searchWorker` | `boolean \| GisViewSearchWorkerOptions` | `{ threshold: 20000 }` | [异步搜索](14-视图与筛选.md#搜索与定位)是否用 Web Worker 计算:默认点 + 线总数超过阈值才用,`false` 表示 `searchAsync` 也同步算;同步的 `search` 一直在主线程算,不受这一项影响 |
|
|
@@ -1004,7 +1004,7 @@ view.setFilter(null) // 清掉筛选
|
|
|
1004
1004
|
|
|
1005
1005
|
- **类型**:`GisViewMinimapOptions | null`
|
|
1006
1006
|
- **默认值**:无
|
|
1007
|
-
- **说明**:内置鹰眼图:位置、尺寸、节点 / 线路 /
|
|
1007
|
+
- **说明**:内置鹰眼图:位置、尺寸、节点 / 线路 / 视口框三份样式与交互都可配;`position` / `margin` 定角落,`offset` 相对角落动态移动整张图,`container` 可挂到外部 `div`(`getMinimapElement()` 取根节点做整图拖动)。`extent` 决定小图按数据范围还是「数据 ∪ 底图」铺(默认 `auto`,GeoJSON 底图不会缩成一个点),`extentFollowCamera` 默认 `false`、打开后才允许 `auto` 范围随相机收窄,避免外围要素消失时包围盒与视口框跳动。`zoomable` 三态互斥:`false` 关闭、`true` 手动缩放小图自身、`'follow'` 让整体范围跟随主图(`followZoomScale` 是主图倍数的指数;跟随模式下 `setMinimapZoom` / `zoomMinimapBy` 不抢控制权,`zoom` 是基准倍数);空白处拖动可平移小图或直接框选让主图显示过去(`dragAction`,`box` 不依赖缩放,手动模式下 Ctrl / ⌘ 才切换动作),每格倍率 `zoomStep`。通道关闭 `channelCircuits` 时按当前可见成员逐顶点平均成一根居中代表线;小图同样支持规则(`pointRules` / `lineRules`,缺省沿用主图规则的颜色 / 层级、最终节点尺寸与图标及样式链线宽,节点 / 线路尺寸按两边视口比例缩放且不受主图相机倍数影响),可以只画某几层(`levels`)、关掉分层叠画(`layered`)、按三组系数给节点与线路定尺寸(整体倍数 `pointSizeScale` / `lineWidthScale` 对自有与继承要素都生效;跟随小图倍数 `pointZoomScale` / `lineZoomScale` 在小图自身放大时也作用于继承要素;跟随主视图地图倍数 `pointMapZoomScale` / `lineMapZoomScale` 只作用于自有规则 / 样式),视口框与框选矩形的颜色 / 背景 / 边框 / 圆角也能配(`boxStyle` / `selectStyle`),`backgroundStyle` 显式设置时接管画布底色,`extent` 还能直接写死一份世界范围、容器可加 `className` / `style`、`layers` 按 `placement` 分数据前 / 数据后、段内按 `order` 拆出多层自绘内容(旧 `draw` 钩子仍兼容并排在最后)、`onInteraction` 在手势结束时给出类型 / 世界坐标 / 相机、`maxPixelRatio` 限制备份倍率上限,不配则不产生任何 DOM,见「鹰眼图」
|
|
1008
1008
|
- **参考**:见「鹰眼图」一节,子字段在那里的表里逐个展开
|
|
1009
1009
|
|
|
1010
1010
|
```js
|
|
@@ -1014,6 +1014,14 @@ createGisView(container, {
|
|
|
1014
1014
|
width: 220,
|
|
1015
1015
|
height: 130,
|
|
1016
1016
|
position: 'bottom-right',
|
|
1017
|
+
offset: [0, 0],
|
|
1018
|
+
container: '#minimap-host',
|
|
1019
|
+
backgroundStyle: 'rgba(255, 255, 255, 0.92)',
|
|
1020
|
+
extent: 'auto',
|
|
1021
|
+
extentFollowCamera: false,
|
|
1022
|
+
dragAction: 'box',
|
|
1023
|
+
zoomable: 'follow',
|
|
1024
|
+
followZoomScale: 0.8,
|
|
1017
1025
|
levels: [1, 5, 20],
|
|
1018
1026
|
pointStyle: { color: '#2f6fed' },
|
|
1019
1027
|
layers: [
|
package/docs/manual/09-/351/200/232/351/201/223/344/270/216/345/244/232/345/233/236/347/272/277.md
CHANGED
|
@@ -241,7 +241,7 @@ Demo 的「通道与数据」页直接接了两类假接口:通道分组拐点
|
|
|
241
241
|
|
|
242
242
|
- **加点 / 删点 / 拖点只作用于同一分组**:同一分组共用一条骨架,其余分组的线路不动。
|
|
243
243
|
- 分组结果会写回 `channels[].groups`(`{ id?, lineIds, path?, waypointOffsets? }`),下次 `updateOptions` / 换数据按它重建;也可以一开始就手写 `groups` 而不是 `lineIds` + `path`。
|
|
244
|
-
- `getChannelMembers()` 与鹰眼图都按分组各成一份:`channelCircuits: false`
|
|
244
|
+
- `getChannelMembers()` 与鹰眼图都按分组各成一份:`channelCircuits: false` 时每个分组把当前可见成员逐顶点平均成一根居中代表线(双回线落在两根正中间,三回线落在中间那条)。
|
|
245
245
|
|
|
246
246
|
---
|
|
247
247
|
|
|
@@ -102,6 +102,8 @@ view.beginAddChannel({ from: { id: 'station-a' }, select: true })
|
|
|
102
102
|
view.continueAddChannel({ from: 'station-c', kind: 'line' }) // 连续新增的下一段也能换指定起点
|
|
103
103
|
```
|
|
104
104
|
|
|
105
|
+
> `beginAddChannel` / `continueAddChannel` 只支持预指定 **起点** `from`,没有 `to`。`beginAddChannel({ from: 'station-a', to: 'station-b' })` 里的 `to` 会被忽略:起点已经选好,仍要再点一次终点才能进入 `ready`。想完全程序化地指定两端并落地,用 `addChannel` / `addLine`,不要先开草稿。
|
|
106
|
+
|
|
105
107
|
**直线 / 正交折线(`routing` / `path`)**:`beginAddChannel()` / `continueAddChannel()` 新增 `routing: 'straight' | 'orthogonal'` 与 `path`。`routing` 缺省 `'straight'`;写 `'orthogonal'` 且没有有效中间拐点时,组件自动补一个「先横后纵」的拐点 `[to.x, from.y]`。`path` 是**中间拐点**(不含两端),写了有效拐点就按它走,此时不会再追加自动拐点;草稿与 `commitAddChannel` / `addLine` / `addChannel` 共用同一份路由解析,预览和落地的折线完全一致。`onChannelDraft` / `onChannelDraftClick` 载荷里也带 `routing` / `path`,两端选好后 `path` 是实际会落地的中间拐点。
|
|
106
108
|
|
|
107
109
|
| 字段 | 类型 | 缺省 | 说明 |
|
|
@@ -162,7 +164,7 @@ view.beginAddChannel()
|
|
|
162
164
|
**取消、默认添加,或自行落地**:选完两个节点后草稿只是预览,除非 `autoCommit: true`,否则数据一个字节都不动。三种收尾方式:
|
|
163
165
|
|
|
164
166
|
- `cancelAddChannel()`:收起草稿并补一条 `phase: 'cancel'`;`endAddChannel()` 静默收起。两者都不写数据。
|
|
165
|
-
- `commitAddChannel()`:按推荐方案(或传入的 `resolution
|
|
167
|
+
- `commitAddChannel()`:按推荐方案(或传入的 `resolution` / 新增线路 / 通道对象)走内置落地,草稿里的 `routing` / `path` 会一起交给 `applyChannelAdd`;对象字段优先,见下文「对象直传」。
|
|
166
168
|
- `addLines()` / `addChannels()`:绕开提交,用草稿读数自己落地。独立线路写完整 `path`;通道只把 `path` 当中间拐点。落地后调用 `endAddChannel()` 收起假通道。
|
|
167
169
|
|
|
168
170
|
```js
|
|
@@ -302,7 +304,7 @@ view.addLine({ from: 'station-a', to: 'station-b' }, [{ id: 'n-1' }, { id: 'n-2'
|
|
|
302
304
|
| `lineItems` | `GisViewChannelLineItems` | 无 | 连同线路一起新建的一条 / 一批;给了几条就建几条 |
|
|
303
305
|
| `routing` | `'straight' \| 'orthogonal'` | `'straight'` | 直连,或自动补一个先横后纵的拐点 |
|
|
304
306
|
| `path` | `GisViewCoordinate[]` | 无 | 中间拐点(不含两端);有效时优先于 `routing` 的自动拐点 |
|
|
305
|
-
| `channelDraftStyle` | `GisViewChannelDraftStyle` | 全局 `channelDraftStyle` |
|
|
307
|
+
| `channelDraftStyle` | `GisViewChannelDraftStyle` | 全局 `channelDraftStyle` | 本次草稿的预览样式,草稿结束即丢弃;含两端示例点 `dots` 与示例线路层级 `layer`,见下文「示例点与层级」 |
|
|
306
308
|
| `handoff` | `boolean` | `false` | `ready` 发完就收掉假通道,由使用方自己落地;与 `autoCommit` 同给时先自动落地 |
|
|
307
309
|
| `select` | `boolean` | `false` | 点节点时同步进选中集(走 `onSelect` / `onSelectChange`);预指定 `from` 时起点当场选中 |
|
|
308
310
|
| `channelProps` | `Partial<GisViewChannel>` | 无 | 新通道透传字段(宽度、节点宽度、偏移方式…) |
|
|
@@ -332,7 +334,16 @@ view.updateOptions({
|
|
|
332
334
|
console.log(payload.from.id, payload.to.id, payload.options, payload.preferred)
|
|
333
335
|
// blocked 为 true 时只能放弃,reason 说明原因(同一个节点 / 已有通道的每个方案都不可用)
|
|
334
336
|
// 手动提交:resolution 缺省用 preferred,也可以给 { type: 'joinGroup', groupId }
|
|
335
|
-
|
|
337
|
+
const chosen = payload.options.find(option => option.type === 'joinGroup' && option.enabled)
|
|
338
|
+
if (chosen) {
|
|
339
|
+
// 方案读数是 { type, enabled, count, lineIds, ... },不能整条回传;只取 resolution 认识的四个键
|
|
340
|
+
view.commitAddChannel({
|
|
341
|
+
type: chosen.type,
|
|
342
|
+
groupId: chosen.groupId,
|
|
343
|
+
groupIndex: chosen.groupIndex,
|
|
344
|
+
channelId: chosen.channelId
|
|
345
|
+
})
|
|
346
|
+
}
|
|
336
347
|
}
|
|
337
348
|
if (payload.phase === 'commit') {
|
|
338
349
|
// 落地结果:line 是写进 lines 的新回线(已自动选中)
|
|
@@ -365,6 +376,415 @@ const plan = view.getChannelAddOptions('station-a', 'station-b')
|
|
|
365
376
|
- **移除新增**:`removeLine(lineId)` 把刚落地的这条回线从数据里摘掉,通道声明(`lineIds` 与 `groups`)一起改,通道一条回线都不剩就整条删掉;`removeChannel(channelId)` 整条通道一起删。两个方法都返回结果对象(`{ ok, line / lineIds, channelId, removedChannel, reason? }`),并且已经处理好选中下标 —— 删掉线路之后 `getSelections()` 不会指到别的线上。
|
|
366
377
|
- `getAddChannelDraft()` 读当前草稿(没有草稿时为 `null`);方案表也可以直接问:`getChannelAddOptions(from, to, count?, kind?)`,实例层按节点 id、引擎层同名方法按下标;只要「这两个点之间到底有没有通道 / 有几组」的读数(不做方案判断)用 `getChannelBetween(from, to)` —— 有通道时 `hasChannel: true`、`channel` / `groups` / `groupCount` / `currentGroupId` 与方案表同一份,没有通道时 `hasChannel: false` / `channel: null` / `groups: []`,端点认不出来返回 `null`。
|
|
367
378
|
|
|
379
|
+
**示例点与层级(`channelDraftStyle`)**
|
|
380
|
+
|
|
381
|
+
`channelDraftStyle.dots` 控制草稿两端的示例点:缺省 `true` 按 `dot` / `dotColor` 画,`false` 两个都不画;写成对象可统一设置 `show` / `size` / `color` / `shape`(`'circle'` 或 `'square'`),再用 `dots.from` / `dots.to` 分别覆盖某一端。示例点始终画在**真正点中的节点中心**,不会跟着多回线的法线偏移跑到节点旁边;`dots: false` 只关示例点,预览线仍在。
|
|
382
|
+
|
|
383
|
+
`channelDraftStyle.layer` 决定示例线路画在真实节点的哪一侧:`'above'`(默认)连同箭头 / `customDraw` 一起压在真实节点上;`'below-points'` 先画示例线、箭头与 `customDraw`,再把真实节点整层盖上去,示例线因此位于实际节点层级之下。示例点不受这个开关影响,始终在真实节点之后绘制,保证两端仍看得见。
|
|
384
|
+
|
|
385
|
+
#### `commitAddChannel`:签名、全部传参与五种写法
|
|
386
|
+
|
|
387
|
+
```ts
|
|
388
|
+
commitAddChannel(input?, options?): GisViewChannelAddResult
|
|
389
|
+
|
|
390
|
+
input?:
|
|
391
|
+
| 'auto' | 'newChannel' | 'newGroup' | 'joinGroup' | 'newLine'
|
|
392
|
+
| { type?: 'newChannel' | 'newGroup' | 'joinGroup' | 'newLine'; groupId?: string | number; groupIndex?: number; channelId?: string | number }
|
|
393
|
+
| GisViewLine // 直接线路对象
|
|
394
|
+
| GisViewChannel // 直接通道对象(必须有 lineIds)
|
|
395
|
+
| GisViewChannelAddCommitInput // 容器写法
|
|
396
|
+
| undefined | null
|
|
397
|
+
|
|
398
|
+
options?: {
|
|
399
|
+
auto?: boolean
|
|
400
|
+
continuous?: boolean
|
|
401
|
+
originalEvent?: Event | null
|
|
402
|
+
}
|
|
403
|
+
```
|
|
404
|
+
|
|
405
|
+
**调用前提**:它只负责把当前草稿落地,不能替代 `addChannel` / `addLine` 做无草稿的程序化新增。调用前必须已经按下面的顺序走到 `ready`:
|
|
406
|
+
|
|
407
|
+
1. `beginAddChannel(options?)` 进入草稿,或由 `continueAddChannel(options?)` 开出下一段。
|
|
408
|
+
2. 通过点击选好起点 / 终点;写了 `options.from` 时起点已预选,只需再点终点。草稿配置只支持 `from`,没有 `to`;写 `{ from, to }` 时 `to` 会被忽略。
|
|
409
|
+
3. `getAddChannelDraft()` 返回 `phase: 'ready'`,且 `plan`、`from`、`to` 都有值;`onChannelDraft` 也会收到同一次 `ready`。
|
|
410
|
+
4. 调 `commitAddChannel(...)`。成功后草稿结束、新回线自动选中;连续模式则在原地重开下一段。
|
|
411
|
+
|
|
412
|
+
以下两条任一不满足时不会写数据:
|
|
413
|
+
|
|
414
|
+
| 情况 | 返回 | 草稿 |
|
|
415
|
+
| --- | --- | --- |
|
|
416
|
+
| 功能开关 `channelDraft` 关着 | `{ ok: false, reason: '新增通道已被功能开关关闭' }` | 保留 |
|
|
417
|
+
| 没有草稿、仍在 `start` / `from` / `pick`,或没有可选方案 | `{ ok: false, reason: '还没有选好两个节点' }` | 保留 |
|
|
418
|
+
|
|
419
|
+
**五种写法一览**。识别顺序是:先认无参 / 旧 resolution;其余对象先看有没有容器键,有就按容器处理;没有容器键再按 `lineIds` 或线路形状识别直接对象;实在认不出的对象最后仍交回 `resolution`。所以只要写成下列任一形状,就不需要先调 `addLine` / `addChannel`:
|
|
420
|
+
|
|
421
|
+
| 写法 | 识别条件 | 缺省落地方式 | 典型用途 |
|
|
422
|
+
| --- | --- | --- | --- |
|
|
423
|
+
| 无参 | `input` 为 `undefined` / `null` | 用草稿的 `preferred` 方案 | 接受界面推荐的「新通道 / 新分组 / 并入某组」 |
|
|
424
|
+
| 旧 resolution | 字符串;或只含非 `undefined` 的 `type` / `groupId` / `groupIndex` / `channelId` 的对象 | 按方案表挑一条;`'auto'` 的优先级是 `newChannel → newGroup → joinGroup` | 让用户明确选「新通道 / 新分组 / 并入哪组」 |
|
|
425
|
+
| 直接线路对象 | 普通对象、没有 `lineIds` 数组,且至少有一个:`kind: 'line'`、`path` 数组、`from`、`to`、`start`、`end` | 按独立线路落地,不走通道方案表 | 最后一步直接把业务线路对象交给组件 |
|
|
426
|
+
| 直接通道对象 | 普通对象且 `Array.isArray(lineIds)`;同时不能再出现容器键 `channel` / `line` / `lines` / `lineData` / `lineItems` / `channelGroups` / `group` / `channelProps` / `resolution` | 缺省 `resolution: 'newChannel'`;`lineIds` 是回线 id 种子,`groups` 是分组声明 | 一次写入一条新通道及其全部成员 |
|
|
427
|
+
| 容器对象 | 出现任一容器键:`channel` / `line` / `lines` / `lineData` / `lineItems` / `channelGroups` / `group` / `channelProps` / `resolution`;只写 `lineProps` 也会按容器处理 | 各段分别覆盖草稿;`resolution` 不写时沿用草稿推荐方案 | 需要逐条回线字段、显式覆盖 `routing`,或把通道提交到已有分组 |
|
|
428
|
+
|
|
429
|
+
> 空对象 `{}` 不是「新建通道」,会按旧 resolution 交给方案表(通常得到「指定的通道 / 分组没有可用方案」)。想接受推荐方案请直接不传参。直接线路对象里的 `start` / `end` 只参与形状识别,**不会**替代 `from` / `to`;要让落地点与草稿不同,请写 `from` / `to`。
|
|
430
|
+
|
|
431
|
+
**旧 resolution 的字符串与对象**
|
|
432
|
+
|
|
433
|
+
| `resolution` | 行为 |
|
|
434
|
+
| --- | --- |
|
|
435
|
+
| 不写 / `null` / `'auto'` | 依次找可用的 `newChannel` → `newGroup` → `joinGroup`;前一个不可用就退下一个。独立线路草稿直接按 `newLine` 落地 |
|
|
436
|
+
| `'newChannel'` | 新建通道;两个节点之间已经有通道时找不到同类型可用方案,返回 `ok: false` |
|
|
437
|
+
| `'newGroup'` | 在已有通道里新加一组;没有通道、组数已满或回数余量不够时失败 |
|
|
438
|
+
| `'joinGroup'` | 并入一个可用的已有分组;不带 `groupId` 时沿用方案表挑中的那一组 |
|
|
439
|
+
| `'newLine'` | 只在 `kind: 'line'`(独立线路草稿)时有效;普通通道草稿传它会失败 |
|
|
440
|
+
| `{ type, groupId?, groupIndex?, channelId? }` | 按字段逐项收窄;`type` 缺省时,只写 `groupId` / `groupIndex` 会自动当作 `joinGroup` |
|
|
441
|
+
| `{ groupId }` / `{ groupIndex }` | `joinGroup` 的简写。二者都写时以 `groupId` 为准 |
|
|
442
|
+
| `{ channelId }` | 在指定通道内按「新分组 → 第一个能并的分组」挑;没有已有通道时 `channelId` 只是新通道 id,不会当成并组 |
|
|
443
|
+
| `payload.options.find(option => option.enabled)` | **不能整条回传**。方案读数还带 `enabled` / `count` / `lineCount` / `lineIds`,不满足旧 resolution 的「只含四个键」条件;只取 `{ type, groupId, groupIndex, channelId }` 这个子集 |
|
|
444
|
+
|
|
445
|
+
```js
|
|
446
|
+
// 1. 接受推荐方案
|
|
447
|
+
const accepted = view.commitAddChannel()
|
|
448
|
+
|
|
449
|
+
// 2. 明确要「新建通道」或「并进某个分组」
|
|
450
|
+
view.commitAddChannel('newChannel')
|
|
451
|
+
view.commitAddChannel({ type: 'joinGroup', groupId: 'corridor-1::2' })
|
|
452
|
+
|
|
453
|
+
// 3. 让界面把用户点中的那条方案交回来(只取 resolution 认识的字段)
|
|
454
|
+
view.updateOptions({
|
|
455
|
+
onChannelDraft: payload => {
|
|
456
|
+
if (payload.phase === 'ready' && !payload.blocked) {
|
|
457
|
+
const chosen = payload.options.find(option => option.enabled && option.type === 'joinGroup')
|
|
458
|
+
if (chosen) {
|
|
459
|
+
const result = view.commitAddChannel({
|
|
460
|
+
type: chosen.type,
|
|
461
|
+
groupId: chosen.groupId,
|
|
462
|
+
groupIndex: chosen.groupIndex,
|
|
463
|
+
channelId: chosen.channelId
|
|
464
|
+
})
|
|
465
|
+
console.log(result.ok, result.lineIds, result.channelLineIds)
|
|
466
|
+
}
|
|
467
|
+
}
|
|
468
|
+
}
|
|
469
|
+
})
|
|
470
|
+
```
|
|
471
|
+
|
|
472
|
+
> `ready` 里的 `option` 是**方案读数**,不是可直接回传的 `resolution`。建议固定只取四个定位字段;整条传进来时,带 `lineIds` 的方案可能被识别成直接通道对象,其余带容器键的对象也可能走成容器,而不是按方案表选组。
|
|
473
|
+
|
|
474
|
+
#### 直接线路对象:字段怎么分、`path` 怎么算
|
|
475
|
+
|
|
476
|
+
直接线路对象面向「最后一步已经有一份线路业务数据」的场景。它不要求先建独立线路草稿;只要当前草稿已经 `ready`,传入对象就会按 `kind: 'line'` 落地一条不挂通道的线路。
|
|
477
|
+
|
|
478
|
+
| 对象字段 | 去向 | 说明 |
|
|
479
|
+
| --- | --- | --- |
|
|
480
|
+
| `from` / `to` | 新线路两端 | 覆盖草稿两端;必须是数据里真实存在的节点 id。两端相同会按方案表给出 `blocked` 原因 |
|
|
481
|
+
| `id` | 新回线 id 种子 | 与 `options.lineId` 同义;与已有线路撞车时自动改成 `-1` / `-2` |
|
|
482
|
+
| `name` | 新线路名 | 不写时沿用草稿名(草稿缺省按两端节点生成) |
|
|
483
|
+
| `path` | **中间拐点** | 和草稿的 `path` 同一口径:首尾仍由 `from` / `to` 覆盖;要整条现成折线请用容器里的 `lines: [{ id, path: [首, …, 尾] }]` |
|
|
484
|
+
| `lineProps` | 额外线路字段 | 最后合并,优先级高于对象上的普通业务字段 |
|
|
485
|
+
| 其余字段(`color` / `width` / `lineType` / `voltageLevel`…) | `lineProps` | 原样透传到每一条新回线,可参与热力图、提示、筛选 |
|
|
486
|
+
| `kind` | 只用于识别 | 写 `'line'` 可让一个没有 `from` / `to` / `path` 的对象也按独立线路解释 |
|
|
487
|
+
|
|
488
|
+
```js
|
|
489
|
+
// 直接把业务对象交给草稿提交:虚线、颜色、线宽和自定义字段都会写进新线路
|
|
490
|
+
const result = view.commitAddChannel({
|
|
491
|
+
id: 'drop-line-1',
|
|
492
|
+
name: '备用联络线',
|
|
493
|
+
from: 'station-a',
|
|
494
|
+
to: 'station-b',
|
|
495
|
+
color: '#ff7a45',
|
|
496
|
+
width: 3,
|
|
497
|
+
lineType: 'dashed',
|
|
498
|
+
voltageLevel: '10kV',
|
|
499
|
+
// 中间拐点,不含首尾;首尾仍是 station-a / station-b 的坐标
|
|
500
|
+
path: [[116.72, 39.91], [116.86, 39.95]]
|
|
501
|
+
})
|
|
502
|
+
|
|
503
|
+
console.log(result.ok) // true
|
|
504
|
+
console.log(result.kind) // 'line'
|
|
505
|
+
console.log(result.lineIds) // ['drop-line-1']
|
|
506
|
+
console.log(result.channelId) // null
|
|
507
|
+
```
|
|
508
|
+
|
|
509
|
+
#### 直接通道对象:`lineIds`、`groups` 与样式怎么写
|
|
510
|
+
|
|
511
|
+
直接通道对象适合「一次给全通道 + 成员」。识别它的硬条件是 `lineIds` 必须是数组;没有 `lineIds` 的对象即使写了 `groups`,也只会被当成旧 resolution 或无法识别的对象。
|
|
512
|
+
|
|
513
|
+
| 对象字段 | 去向 | 说明 |
|
|
514
|
+
| --- | --- | --- |
|
|
515
|
+
| `lineIds` | 新回线 id 种子 | 每个 id 生成一条新回线;`lineIds` 为空数组时回线数量回落到草稿的 `circuits` / `lineItems`,不会清空草稿 |
|
|
516
|
+
| `groups` | 分组声明 | 等价于容器的 `channelGroups`;组的 `lineIds` 应使用这次生成的成员 id。第一组不写成员时拿本次全部回线,其余空组会被丢掉 |
|
|
517
|
+
| `id` | 新通道 id | 只决定新通道的身份;回线 id 一律来自 `lineIds`,这个 `id` 不参与逐条回线的 id 或前缀 |
|
|
518
|
+
| `name` | 通道名与新线路名 | 新线路没有逐条 `name` 时一起使用 |
|
|
519
|
+
| `from` / `to` | 新通道两端 | 覆盖草稿;实际回线端点也按它落 |
|
|
520
|
+
| `path` | 通道骨架的中间拐点 | 不含两端;分组各自写了 `path` 时以分组那一份为准 |
|
|
521
|
+
| `lineProps` | 全部新回线的公共字段 | 直接通道对象自己的 `lineProps` 会生效,优先级低于每一条逐条字段;容器写法里的 `channel.lineProps` **不合并**,见下文容器优先级 |
|
|
522
|
+
| 其余字段(`width` / `nodeWidth` / `inset` / `tooltip` / `customCode`…) | `channelProps` | 原样写到新通道上 |
|
|
523
|
+
|
|
524
|
+
```js
|
|
525
|
+
// 通道对象:两个 lineIds 各生成一条回线;groups 把它们分成两组
|
|
526
|
+
view.commitAddChannel({
|
|
527
|
+
id: 'object-channel-1',
|
|
528
|
+
name: '东侧双回',
|
|
529
|
+
from: 'station-a',
|
|
530
|
+
to: 'station-b',
|
|
531
|
+
lineIds: ['object-line-1', 'object-line-2'],
|
|
532
|
+
groups: [
|
|
533
|
+
{ id: 'object-channel-1::1', lineIds: ['object-line-1'], path: [[116.75, 39.86]] },
|
|
534
|
+
{ id: 'object-channel-1::2', lineIds: ['object-line-2'], path: [[116.75, 39.98]] }
|
|
535
|
+
],
|
|
536
|
+
width: 28,
|
|
537
|
+
nodeWidth: 1,
|
|
538
|
+
offsetMode: 'tangent',
|
|
539
|
+
lineProps: { color: '#2f6fd0', width: 2.4, lineType: 'dashed' },
|
|
540
|
+
owner: '运维一班'
|
|
541
|
+
})
|
|
542
|
+
```
|
|
543
|
+
|
|
544
|
+
> 直接通道对象的回数只由 `lineIds` 决定;`lineIds: []` 时回落到草稿的 `lineItems` / `circuits`。直接通道对象上另外写的 `circuits` 不会改回数,它会作为普通通道字段收进 `channelProps`;要覆盖本次回数,请用容器顶层 `circuits`,或在 `beginAddChannel` 时配置。
|
|
545
|
+
>
|
|
546
|
+
> `groups[].lineIds` 应写本次 `lineIds` / `lines` 真正生成的回线 id。写了不存在的 id 不会让整次提交失败:组件会报 warning,并在声明落地前按本次成员表调和(剔掉不属于本次的回线、把没落组的成员补进第一组)。
|
|
547
|
+
|
|
548
|
+
> **直接通道对象缺省按新通道提交**。要在提交对象的同时并进已有分组,必须换成容器写法并写 `resolution`,例如 `{ resolution: { type: 'joinGroup', groupId: 'corridor-1::2' }, lines: [...] }`。直接把 `resolution` 塞进「带 `lineIds` 的通道对象」会把它识别成容器,顶层 `lineIds` 不再作为通道成员使用。
|
|
549
|
+
|
|
550
|
+
#### 容器对象:逐段覆盖与精确优先级
|
|
551
|
+
|
|
552
|
+
容器是表达能力最完整的一种写法。所有段都可省略,写了哪一段就覆盖哪一段,没写的继续沿用当前草稿:
|
|
553
|
+
|
|
554
|
+
| 容器键 | 类型 | 作用 |
|
|
555
|
+
| --- | --- | --- |
|
|
556
|
+
| `channel` | `GisViewChannel` | 新通道声明:`id` / `name` / `from` / `to` / `path` / `lineIds` / `groups` 与业务字段 |
|
|
557
|
+
| `line` | `GisViewLine` | 一条独立线路;缺省把本次 `kind` 定成 `'line'`,不是「只含一条的 `lines`」。只有同时显式写 `kind: 'channel'` 时,它才作为一条成员回线挂进通道 |
|
|
558
|
+
| `lines` | 一条或一批线路数据 | 逐条回线字段,支持对象、裸字符串 / 数字 id;**给了几条就建几条** |
|
|
559
|
+
| `lineData` / `lineItems` | 同上 | `lines` 的兼容别名;三者同时写时的优先级是 `lines > lineData > lineItems` |
|
|
560
|
+
| `channelGroups` / `group` | 一组或整份分组声明 | `channelGroups` 优先于 `group`;都写时以 `channelGroups` 为准 |
|
|
561
|
+
| `channelProps` | `Partial<GisViewChannel>` | 最后覆盖新通道字段,优先级高于 `channel` 上的普通字段 |
|
|
562
|
+
| `lineProps` | `Partial<GisViewLine>` | 公共回线字段;合并顺序是草稿 `lineProps` → 容器顶层 `lineProps` → `line.lineProps`,最后被逐条 `lines[i]` 覆盖。`channel.lineProps` 在容器里不参与合并 |
|
|
563
|
+
| `resolution` | 旧 resolution 的字符串 / 对象 | 不写时:有 `channel` 按 `newChannel`,否则沿用草稿推荐方案 |
|
|
564
|
+
| `kind` | `'channel' \| 'line'` | 显式改这一条是通道还是独立线路 |
|
|
565
|
+
| `from` / `to` / `path` / `routing` | 同草稿 | 顶层端点、中间拐点与走线方式;`routing` 只认容器这一层 |
|
|
566
|
+
| `circuits` | `number` | 没有有效 `lines` 时一次建几回;有 `lines` 时按条数(`circuits` 被忽略) |
|
|
567
|
+
| `id` / `lineId` | 线路 id 种子 | `lineId` 优先;通道 id 请写在 `channel.id` 或 `channelId` |
|
|
568
|
+
| `channelId` / `channelName` | 通道 id / 名称 | `channelId` 在无已有通道时是新通道 id;已有通道时是并组筛选条件 |
|
|
569
|
+
|
|
570
|
+
> 容器顶层只有 `channelGroups` / `group` 是分组键;裸写 `groups` 不会被读取。分组直接写在 `channel.groups`,或用 `channelGroups` / `group`。
|
|
571
|
+
|
|
572
|
+
**逐字段优先级(从高到低)**:
|
|
573
|
+
|
|
574
|
+
| 目标字段 | 优先级 |
|
|
575
|
+
| --- | --- |
|
|
576
|
+
| `from` / `to` | 容器顶层 → `channel` → `line` → `lineItems` 里第一个对象项 → 草稿。前面的裸字符串 / 数字 id 跳过,不贡献端点 |
|
|
577
|
+
| `path`(中间拐点) | 容器顶层 → `line` → `channel` → 草稿 |
|
|
578
|
+
| `routing` | 容器顶层 → 草稿(直接线路 / 直接通道对象没有这一层) |
|
|
579
|
+
| 分组 | `channelGroups` → `group` → `channel.groups` → 不声明(新通道只建一组,组 id 用通道 id) |
|
|
580
|
+
| 逐条回线 | `lines` → `lineData` → `lineItems` → `line` → `channel.lineIds.map(id => ({ id }))` → 草稿 |
|
|
581
|
+
| 线路公共字段(直接线路对象) | 对象上的普通业务字段 → 对象自己的 `lineProps` |
|
|
582
|
+
| 线路公共字段(容器) | 草稿 `lineProps` → 容器顶层 `lineProps` → `line.lineProps` → 逐条 `lines[i]`;**不读 `channel.lineProps`** |
|
|
583
|
+
| 通道字段 | 草稿 `channelProps` → `channel` 上的业务字段 → 容器 `channelProps` |
|
|
584
|
+
| 名称 | 容器 `name` → `channelName` / `channel.name` → `line.name` → 草稿名称 |
|
|
585
|
+
| `resolution` | 容器 `resolution` → 直接通道对象固定 `newChannel` → 草稿 `preferred` |
|
|
586
|
+
|
|
587
|
+
**空数组的规则**:`lines: []`、`lineData: []`、`lineItems: []` **不会清空**草稿里已有的逐条回线,而是沿用草稿。想放弃草稿里的线路,重新 `beginAddChannel()`(不要传 `lineItems`)或改用 `addLine` / `addChannel` 自行落地。
|
|
588
|
+
|
|
589
|
+
```js
|
|
590
|
+
// 容器写法:通道声明、两条回线、分组、样式、走线方式一次给全
|
|
591
|
+
view.commitAddChannel({
|
|
592
|
+
resolution: 'newChannel',
|
|
593
|
+
from: 'station-a',
|
|
594
|
+
to: 'station-b',
|
|
595
|
+
channel: {
|
|
596
|
+
id: 'container-channel-1',
|
|
597
|
+
name: '容器通道',
|
|
598
|
+
nodeWidth: 1,
|
|
599
|
+
width: 32,
|
|
600
|
+
customCode: 'CH-001' // 不在通道保留键里的字段会进 channelProps
|
|
601
|
+
},
|
|
602
|
+
lines: [
|
|
603
|
+
{ id: 'container-line-1', color: '#dd4b2e', width: 2.2, name: '一回' },
|
|
604
|
+
{ id: 'container-line-2', color: '#2ea36b', width: 2.2, name: '二回', voltageLevel: '10kV' }
|
|
605
|
+
],
|
|
606
|
+
channelGroups: [
|
|
607
|
+
{ id: 'container-channel-1::1', lineIds: ['container-line-1'], path: [[116.78, 39.88]] },
|
|
608
|
+
{ id: 'container-channel-1::2', lineIds: ['container-line-2'], path: [[116.78, 39.96]] }
|
|
609
|
+
],
|
|
610
|
+
routing: 'straight',
|
|
611
|
+
lineProps: { opacity: 0.9 },
|
|
612
|
+
channelProps: { tooltip: false }
|
|
613
|
+
})
|
|
614
|
+
```
|
|
615
|
+
|
|
616
|
+
**只给种子、逐条字段另写**:`channel.lineIds` 不会被 `lines` 覆盖成通道成员表 —— 容器里的 `lines` 才是本次新建的回线;`channel.lineIds` 只在没有 `lines` 时提供 id 种子。下面的结果是两条回线、一条新通道:
|
|
617
|
+
|
|
618
|
+
```js
|
|
619
|
+
view.commitAddChannel({
|
|
620
|
+
channel: {
|
|
621
|
+
id: 'seed-channel',
|
|
622
|
+
from: 'station-a',
|
|
623
|
+
to: 'station-b',
|
|
624
|
+
lineIds: ['seed-line-1', 'seed-line-2']
|
|
625
|
+
},
|
|
626
|
+
lineProps: { color: '#2f6fd0', width: 2 }
|
|
627
|
+
})
|
|
628
|
+
```
|
|
629
|
+
|
|
630
|
+
**逐条回线用 `lines` / `lineData` / `lineItems`**:它们接受单对象、对象数组,也接受裸 id。每个对象里的 `id` 就是回线 id;不写 id 时按「通道 id-序号」自动编号,撞车自动加后缀:
|
|
631
|
+
|
|
632
|
+
```js
|
|
633
|
+
view.commitAddChannel({
|
|
634
|
+
channel: { id: 'mixed-channel', from: 'station-a', to: 'station-b' },
|
|
635
|
+
lines: [
|
|
636
|
+
{ id: 'mixed-1', color: '#dd4b2e', width: 2 },
|
|
637
|
+
'mixed-2',
|
|
638
|
+
{ id: 'mixed-3', lineType: 'dotted', label: '三回' }
|
|
639
|
+
],
|
|
640
|
+
group: { id: 'mixed-group', path: [[116.8, 39.9]] }
|
|
641
|
+
})
|
|
642
|
+
```
|
|
643
|
+
|
|
644
|
+
#### 覆盖草稿的端点、路由、名称与 id
|
|
645
|
+
|
|
646
|
+
对象字段覆盖草稿,未写的继续用草稿。最常改的是这四组:
|
|
647
|
+
|
|
648
|
+
```js
|
|
649
|
+
// 端点 / 名称 / 线路 id 种子全部由容器覆盖
|
|
650
|
+
view.commitAddChannel({
|
|
651
|
+
from: 'station-c',
|
|
652
|
+
to: 'station-d',
|
|
653
|
+
name: '改道后的联络线',
|
|
654
|
+
lineId: 'rerouted-line',
|
|
655
|
+
lines: [{ id: 'rerouted-line', color: '#7c4dff' }],
|
|
656
|
+
routing: 'orthogonal'
|
|
657
|
+
})
|
|
658
|
+
|
|
659
|
+
// 只改公共线路字段,其余(含推荐方案、circuits、端点、名称)全部沿用草稿
|
|
660
|
+
view.commitAddChannel({ lineProps: { width: 3.5, opacity: 0.8 } })
|
|
661
|
+
|
|
662
|
+
// 只改通道字段:通道对象的 lineIds 仍按当前草稿回线数生成
|
|
663
|
+
view.commitAddChannel({
|
|
664
|
+
channel: { id: 'styled-channel', from: 'station-a', to: 'station-b', nodeWidth: 0.8 },
|
|
665
|
+
channelProps: { width: 40, offsetMode: 'inset', inset: 0.2 }
|
|
666
|
+
})
|
|
667
|
+
```
|
|
668
|
+
|
|
669
|
+
- `routing: 'orthogonal'` 只在**容器顶层**生效;直接线路 / 直接通道对象上的 `routing` 会进业务字段,不会改变走线。
|
|
670
|
+
- 顶层 `path` 会盖过 `line.path` / `channel.path`;没有顶层 `path` 时才依次看线路、通道和草稿。
|
|
671
|
+
- `lineId` 只是 id 种子:一次多条时自动展开成 `lineId-1` / `lineId-2`;每条自己的 `lines[i].id` 优先级更高。
|
|
672
|
+
- `from` / `to` 可以覆盖草稿端点,但必须能在当前数据里找到;找不到时返回 `{ ok: false, reason: '找不到这两个节点' }`,草稿保留。
|
|
673
|
+
|
|
674
|
+
#### 提交已有通道 / 已有分组:必须显式写 `resolution`
|
|
675
|
+
|
|
676
|
+
直接通道对象默认新建通道。要可预期地并进已有通道 / 指定分组,换成容器写法并在顶层显式写 `resolution`;容器不写时只是沿用草稿推荐方案,不能保证一定是并组。并组时成员由 `lines` 给出,`channel` 段不再负责新建:
|
|
677
|
+
|
|
678
|
+
```js
|
|
679
|
+
// 并进已有通道的指定分组
|
|
680
|
+
const joined = view.commitAddChannel({
|
|
681
|
+
resolution: { type: 'joinGroup', groupId: 'corridor-1::2' },
|
|
682
|
+
lines: [
|
|
683
|
+
{ id: 'join-line-1', color: '#dd4b2e' },
|
|
684
|
+
{ id: 'join-line-2', color: '#2ea36b' }
|
|
685
|
+
],
|
|
686
|
+
lineProps: { width: 2.4 }
|
|
687
|
+
})
|
|
688
|
+
|
|
689
|
+
console.log(joined.ok) // true
|
|
690
|
+
console.log(joined.channelId) // 'corridor-1'
|
|
691
|
+
console.log(joined.groupId) // 'corridor-1::2'
|
|
692
|
+
console.log(joined.channelLineIds) // 并完之后这条通道的完整成员表
|
|
693
|
+
```
|
|
694
|
+
|
|
695
|
+
- `resolution: 'newGroup'` 必须在已有通道的前提下才可用;新组的 id / 拐点用 `channelGroups` 或 `group` 给。
|
|
696
|
+
- 只写 `channelId` / `groupId` / `groupIndex` 也能作为旧简写,但它们只有在两个节点之间已经有通道时才按并组解释。
|
|
697
|
+
- `channelProps` 只在新建通道时写进新通道;并进已有分组时不会改已有通道的字段,需要改通道请另调 `updateChannel`。
|
|
698
|
+
|
|
699
|
+
```js
|
|
700
|
+
// 旧简写:两个对象字段等价
|
|
701
|
+
view.commitAddChannel({ type: 'joinGroup', groupId: 'corridor-1::2' })
|
|
702
|
+
view.commitAddChannel({ groupId: 'corridor-1::2' })
|
|
703
|
+
|
|
704
|
+
// 只指定通道,让组件按「新分组 → 能并的分组」挑
|
|
705
|
+
view.commitAddChannel({ channelId: 'corridor-1' })
|
|
706
|
+
```
|
|
707
|
+
|
|
708
|
+
#### 连续新增、自动提交与事件
|
|
709
|
+
|
|
710
|
+
第二参数只在一次提交里生效:
|
|
711
|
+
|
|
712
|
+
| 字段 | 类型 | 缺省 | 说明 |
|
|
713
|
+
| --- | --- | --- | --- |
|
|
714
|
+
| `auto` | `boolean` | `false` | 只标记本次事件是自动提交;不等于 `beginAddChannel({ autoCommit: true })`。`autoCommit` 由组件内部用 `commitAddChannel('auto', { auto: true })` 提交 |
|
|
715
|
+
| `continuous` | `boolean` | 跟草稿的 `continuous` | 显式 `false` 强制本次落地后结束草稿;`true` 只在草稿本来就是连续模式时有效 |
|
|
716
|
+
| `originalEvent` | `Event \| null` | `null` | 连续模式重开草稿时带回去,供下一次草稿回调使用 |
|
|
717
|
+
|
|
718
|
+
```js
|
|
719
|
+
// 连续新增:本次落地后直接开下一段,并以上一段终点为下一段起点
|
|
720
|
+
view.beginAddChannel({ continuous: true, chain: true, kind: 'channel' })
|
|
721
|
+
|
|
722
|
+
view.updateOptions({
|
|
723
|
+
onChannelDraft: payload => {
|
|
724
|
+
if (payload.phase === 'ready' && !payload.blocked) {
|
|
725
|
+
view.commitAddChannel(undefined, { continuous: true, originalEvent: payload.originalEvent })
|
|
726
|
+
}
|
|
727
|
+
},
|
|
728
|
+
onChannelDraftClick: payload => {
|
|
729
|
+
if (payload.phase === 'commit') {
|
|
730
|
+
console.log('已落地', payload.lineIds, '下一段是否重开', payload.restarted)
|
|
731
|
+
}
|
|
732
|
+
}
|
|
733
|
+
})
|
|
734
|
+
|
|
735
|
+
// 本次之后收手;即使草稿配了 continuous: true,也不会再开下一段
|
|
736
|
+
view.commitAddChannel(undefined, { continuous: false })
|
|
737
|
+
```
|
|
738
|
+
|
|
739
|
+
提交成功时发一条 `onChannelDraft` / `channelDraft`(`phase: 'commit'`);失败时发 `phase: 'blocked'`,并且:非连续模式下草稿同样会结束,连续模式下会照常重开一段让用户继续试。事件载荷常用字段如下:
|
|
740
|
+
|
|
741
|
+
| 字段 | 含义 |
|
|
742
|
+
| --- | --- |
|
|
743
|
+
| `phase` | `'commit'` / `'blocked'` |
|
|
744
|
+
| `auto` / `autoCommit` | 本次是否自动提交 / 草稿是否开了自动提交 |
|
|
745
|
+
| `continuous` / `chain` / `restarted` | 提交后是否重开、是否继承上一段终点、是否真的重开了 |
|
|
746
|
+
| `kind` / `circuits` | 本次加通道还是独立线路、落地几条 |
|
|
747
|
+
| `from` / `to` / `plan` / `options` | 实际端点、方案表与全部方案 |
|
|
748
|
+
| `blocked` / `reason` | 是否失败与原因 |
|
|
749
|
+
| `resolution` | 实际选中的方案 |
|
|
750
|
+
| `line` / `lineId` / `lines` / `lineIds` | 新回线(`line` / `lineId` 是第一条) |
|
|
751
|
+
| `channelId` / `groupId` / `channelLineIds` | 新通道 / 分组与通道完整成员表(独立线路为 `null`) |
|
|
752
|
+
| `lineIndex` | 第一条新回线在 `lines` 里的下标;失败事件里按 `-1` 兜底 |
|
|
753
|
+
| `routing` / `path` | 本次落地用的走线方式与中间拐点 |
|
|
754
|
+
|
|
755
|
+
#### 返回值与错误处理
|
|
756
|
+
|
|
757
|
+
`GisViewChannelAddResult` 与 `addChannel` / `addLine` 共用:
|
|
758
|
+
|
|
759
|
+
| 字段 | 成功时 | 失败时 |
|
|
760
|
+
| --- | --- | --- |
|
|
761
|
+
| `ok` | `true` | `false` |
|
|
762
|
+
| `reason` | 无 | 说明原因(未 ready、找不到节点、方案不可用、端点相同…) |
|
|
763
|
+
| `plan` | 本次方案表 | 能算出方案表时一并带回,供界面重新选择 |
|
|
764
|
+
| `resolution` | 实际方案;独立线路是 `newLine` | 无 |
|
|
765
|
+
| `kind` / `circuits` | `'channel' / 'line'`、回数 | 无 |
|
|
766
|
+
| `line` / `lineId` / `lines` / `lineIds` | 新回线与 id(多回时 `line` 是第一条) | 无 |
|
|
767
|
+
| `lineIndex` | 第一条新回线的下标 | 无 |
|
|
768
|
+
| `channelId` / `groupId` | 新通道 / 分组;独立线路分别为 `null` / `null` | 无 |
|
|
769
|
+
| `channelLineIds` | 通道落地后的完整成员表;独立线路为 `null` | 无 |
|
|
770
|
+
| `channelIndex` | 新通道或并进通道的下标;独立线路为 `-1` | 通常不返回;事件载荷失败时按 `-1` 兜底 |
|
|
771
|
+
|
|
772
|
+
```js
|
|
773
|
+
const result = view.commitAddChannel({ groupId: 'not-exist' })
|
|
774
|
+
if (!result.ok) {
|
|
775
|
+
console.warn(result.reason) // 例如:找不到通道 / 指定分组没有可用方案
|
|
776
|
+
console.table(result.plan?.options ?? []) // 每条方案为什么不可用
|
|
777
|
+
// 失败时草稿是否结束取决于 continuous:非连续模式收起,连续模式重开下一段
|
|
778
|
+
}
|
|
779
|
+
```
|
|
780
|
+
|
|
781
|
+
常见失败原因:
|
|
782
|
+
|
|
783
|
+
- **未 ready**:先完成两次点选,或 `beginAddChannel({ from })` 后补点终点。
|
|
784
|
+
- **功能关闭**:`features: { channelDraft: false }` 时提交直接拒绝。
|
|
785
|
+
- **节点找不到 / 端点相同**:`from` / `to` 覆盖成不存在的 id,或两端指到同一个节点。
|
|
786
|
+
- **方案不可用**:已有通道组数已满、目标分组余量不足,或者 `resolution` 指向不存在的通道 / 分组。
|
|
787
|
+
|
|
368
788
|
**给已有通道加线路 / 删除线路**
|
|
369
789
|
|
|
370
790
|
| 想做什么 | 方法 | 要点 |
|