gis-view-webgl2 0.1.0 → 0.1.1

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 (86) hide show
  1. package/README.md +28 -8
  2. package/dist/gis-view.css +1 -1
  3. package/dist/index.cjs +1 -1
  4. package/dist/index.d.ts +781 -246
  5. package/dist/index.js +1 -1
  6. package/docs/AI/345/257/271/350/257/235/346/261/207/346/200/273.md +129 -0
  7. package/docs/GisView.md +9 -8
  8. package/docs/GisView/345/256/236/347/216/260/345/216/237/347/220/206.md +2 -2
  9. 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 +114 -0
  10. package/docs/api/index.html +545 -59
  11. package/docs/demos/BackendSyncDemo.vue +10 -8
  12. package/docs/demos/BasicDemo.vue +101 -101
  13. package/docs/demos/BatchAddDemo.vue +5 -5
  14. package/docs/demos/ChannelDemo.vue +51 -4
  15. package/docs/demos/ConnectDemo.vue +392 -0
  16. package/docs/demos/CopyMergeDemo.vue +936 -936
  17. package/docs/demos/DecorationDraftDemo.vue +1300 -0
  18. package/docs/demos/DemoShell.vue +569 -240
  19. package/docs/demos/DragDropDemo.vue +11 -11
  20. package/docs/demos/EffectsDemo.vue +6 -6
  21. package/docs/demos/EventDemo.vue +327 -327
  22. package/docs/demos/ExtensionDemo.vue +458 -0
  23. package/docs/demos/GisViewDemo.vue +61 -48
  24. package/docs/demos/GraphicDemo.vue +338 -0
  25. package/docs/demos/LabelDemo.vue +509 -509
  26. package/docs/demos/MinimapDemo.vue +358 -0
  27. package/docs/demos/PerfDemo.vue +29 -0
  28. package/docs/demos/SearchFilterDemo.vue +412 -0
  29. package/docs/demos/StyleDemo.vue +121 -121
  30. package/docs/demos/api-index.js +87 -76
  31. package/docs/demos/demos.js +159 -135
  32. package/docs/demos/shared/demoData.js +107 -107
  33. package/docs/demos/shared/demoStyle.css +249 -249
  34. package/docs/demos/shared/fakeBackend.js +93 -6
  35. package/docs/format/03-/346/213/220/347/202/271/350/243/205/351/245/260/344/270/216/346/240/267/345/274/217.md +24 -6
  36. package/docs/format/06-/345/257/274/345/205/245/345/257/274/345/207/272/344/270/216/346/240/207/345/207/206/346/226/207/346/241/243.md +8 -6
  37. package/docs/format/07-/344/272/213/344/273/266/350/275/275/350/215/267/344/270/216/347/244/272/344/276/213/346/225/260/346/215/256.md +6 -6
  38. package/docs/guide/sample-document.html +4 -4
  39. package/docs/index.html +180 -9
  40. package/docs/internals/11-/350/246/206/347/233/226/345/261/202/346/240/207/347/255/276/344/270/216/346/217/220/347/244/272.md +1 -1
  41. package/docs/internals/13-/351/271/260/347/234/274/345/233/276.md +3 -2
  42. package/docs/internals/15-03-/351/200/220/350/275/256/350/256/260/345/275/225-/346/200/247/350/203/275/344/270/216/344/277/256/345/244/215-/344/270/213.md +16 -0
  43. package/docs/internals/16-03-/344/274/230/345/214/226/344/270/216/345/217/226/350/210/215-/344/270/213.md +11 -0
  44. package/docs/internals/17-/350/260/203/350/257/225/344/270/216/346/211/251/345/261/225/345/273/272/350/256/256.md +1 -1
  45. package/docs/manual/02-/345/235/220/346/240/207/344/270/216/346/225/260/346/215/256.md +11 -2
  46. package/docs/manual/03-/351/205/215/347/275/256/351/241/271.md +89 -20
  47. package/docs/manual/04-/344/272/213/344/273/266/344/270/216/345/233/236/350/260/203.md +13 -8
  48. package/docs/manual/06-/346/225/260/346/215/256/344/270/216/345/234/272/346/231/257/346/233/264/346/226/260.md +11 -10
  49. package/docs/manual/07-/346/214/207/351/222/210/344/270/216/350/246/201/347/264/240/347/274/226/350/276/221.md +9 -9
  50. package/docs/manual/08-/351/200/211/344/270/255/344/270/216/346/213/220/347/202/271.md +13 -11
  51. package/docs/manual/09-/351/200/232/351/201/223/344/270/216/345/244/232/345/233/236/347/272/277.md +3 -3
  52. 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 +47 -5
  53. package/docs/manual/11-/346/240/267/345/274/217/344/270/216/350/247/204/345/210/231.md +3 -2
  54. package/docs/manual/12-/346/240/207/347/255/276/344/270/216/350/243/205/351/245/260.md +215 -2
  55. package/docs/manual/13-/345/212/250/346/225/210/344/270/216/345/233/276/345/205/203.md +6 -5
  56. package/docs/manual/14-/350/247/206/345/233/276/344/270/216/347/255/233/351/200/211.md +27 -14
  57. package/docs/manual/15-/345/257/274/345/207/272/344/270/216/351/233/206/346/210/220.md +142 -49
  58. package/docs/manual/16-/345/256/236/344/276/213/346/226/271/346/263/225/346/200/273/350/241/250.md +25 -29
  59. package/docs/manual/17-/345/217/202/346/225/260/351/200/237/346/237/245.md +47 -39
  60. package/docs/manual/18-/351/200/220/346/226/271/346/263/225/347/244/272/344/276/213.md +161 -64
  61. package/docs/manual/19-/350/257/273/346/225/260/344/270/216/346/213/226/346/213/275/351/242/204/350/247/210.md +4 -4
  62. package/docs/manual/20-/346/200/247/350/203/275/344/270/216/345/244/247/346/225/260/346/215/256.md +39 -2
  63. 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 +21 -5
  64. package/docs/playground/index.html +5 -5
  65. package/docs/steps/README.md +12 -10
  66. package/docs/steps/check-doc-truth.mjs +1 -1
  67. package/docs/steps/selftest-actions.html +10 -10
  68. package/docs/steps/selftest-data.html +96 -14
  69. package/docs/steps/selftest-decoration.html +577 -0
  70. package/docs/steps/selftest-demo.html +6 -5
  71. package/docs/steps/selftest-demos.html +2048 -1624
  72. package/docs/steps/selftest-docs.html +86 -14
  73. package/docs/steps/selftest-effects.html +5 -5
  74. package/docs/steps/selftest-features.html +544 -85
  75. package/docs/steps/selftest-full.html +583 -583
  76. package/docs/steps/selftest-labels.html +797 -660
  77. package/docs/steps/selftest-perf.html +1899 -1844
  78. package/docs/steps/selftest-scale.html +117 -7
  79. package/docs/steps/selftest-select.html +24 -17
  80. package/docs/steps/step-10-full.js +1 -1
  81. package/docs//346/216/245/345/217/243/345/215/217/350/256/256.md +151 -7
  82. package/docs//346/225/260/346/215/256/346/240/274/345/274/217.md +1 -1
  83. package/package.json +42 -42
  84. package/docs/demos/HistoryDemo.vue +0 -230
  85. package/docs/demos/InterfaceDemo.vue +0 -309
  86. package/docs/demos/SampleDemo.vue +0 -283
package/dist/index.d.ts CHANGED
@@ -138,6 +138,20 @@ export type GisViewSymbol = GisViewCircleSymbol | GisViewSquareSymbol | GisViewI
138
138
  /** 符号简写:'circle' / 'square'、注册过的自定义图元名字、图片地址、以 svg 标记开头的字符串 */
139
139
  export type GisViewSymbolInput = GisViewSymbol | 'circle' | 'square' | string
140
140
 
141
+ /** 注册(或覆盖)一支自定义图元画笔;名字为空或画笔不是函数返回 false,不动注册表 */
142
+ export declare const registerSymbolPainter: (name: string, painter: GisViewSymbolPainter) => boolean
143
+ /**
144
+ * 带作用域地注册一支自定义图元画笔:返回清理函数,只在当前注册项仍是这支画笔时删除,
145
+ * 旧插件 / 旧视图卸载不会误删后来覆盖注册的同名画笔。参数不合法时抛 TypeError。
146
+ */
147
+ export declare const defineSymbolPainter: (name: string, painter: GisViewSymbolPainter) => () => boolean
148
+ /** 注销一支自定义图元画笔,返回它之前是否在注册表里 */
149
+ export declare const unregisterSymbolPainter: (name: string) => boolean
150
+ /** 这个名字注册过没有 */
151
+ export declare const hasSymbolPainter: (name: string) => boolean
152
+ /** 当前注册着的自定义图元名字(按注册顺序) */
153
+ export declare const listSymbolPainters: () => string[]
154
+
141
155
  export interface GisViewShadow {
142
156
  color?: string
143
157
  opacity?: number
@@ -419,6 +433,50 @@ export interface GisViewMinimapDrawInfo {
419
433
  data: GisViewMinimapDrawData
420
434
  /** 这一帧的底图(inherit 时是主视图解析好的那一份) */
421
435
  background: GisViewBackground | null
436
+ /** 当前绘制阶段:数据前 / 数据后的自定义层,或兼容旧写法的最终 draw 钩子 */
437
+ stage: GisViewMinimapLayerStage
438
+ }
439
+
440
+ /** 自定义层画在内置线路 / 节点之前还是之后;缺省 after 对应的 above-data */
441
+ export type GisViewMinimapLayerPlacement = 'below-data' | 'above-data'
442
+ /** 回调实际所处的绘制阶段;兼容旧写法的 draw 固定为 overlay */
443
+ export type GisViewMinimapLayerStage = GisViewMinimapLayerPlacement | 'overlay'
444
+
445
+ /**
446
+ * 鹰眼图自定义层:按 placement 分到内置数据前 / 后,组内再按 `order` 依次绘制;
447
+ * 旧 draw 钩子固定最后执行。适合把指北针、网格、业务标记拆成互不干扰的几层。
448
+ */
449
+ export interface GisViewMinimapLayer {
450
+ /** 给这一层一个名字,便于配置与调试(绘制时不需要) */
451
+ id?: string
452
+ /** 叠放顺序:数值小的先画,相同 or 缺省按数组顺序 */
453
+ order?: number
454
+ /** 画在内置线路 / 节点之前(below-data)还是之后(above-data,默认) */
455
+ placement?: GisViewMinimapLayerPlacement
456
+ /** 临时关掉这一层而不必改数组内容 */
457
+ enabled?: boolean
458
+ /** 与 draw 钩子同一份入参:上下文已按备份像素比缩放,直接用 CSS 像素画 */
459
+ draw: (info: GisViewMinimapDrawInfo) => void
460
+ }
461
+
462
+ /** 鹰眼图完成一次交互(长按为触发时)后的通知类型 */
463
+ export type GisViewMinimapInteractionType = 'box-drag' | 'select' | 'pan' | 'zoom' | 'wheel-main' | 'long-press'
464
+
465
+ /** 鹰眼图交互回调:一次手势结束时发一条(长按在触发时发),不在 pointermove 里逐帧触发 */
466
+ export interface GisViewMinimapInteractionInfo {
467
+ type: GisViewMinimapInteractionType
468
+ /** 触发这次交互的原始事件;长按回调保留 pointerdown,其余为 pointerup / wheel */
469
+ originalEvent: Event | null
470
+ /** 指针在小图里的 CSS 像素坐标 */
471
+ local: [number, number]
472
+ /** 同一个位置对应的世界坐标 */
473
+ world: [number, number]
474
+ /** 交互完成时小图自身的倍数 */
475
+ zoom: number
476
+ /** 当前小图铺开的世界范围 */
477
+ extent: GisViewBounds
478
+ camera: GisViewCamera | null
479
+ viewport: GisViewViewport | null
422
480
  }
423
481
 
424
482
  /**
@@ -455,8 +513,12 @@ export interface GisViewMinimapOptions {
455
513
  * 拿到已缩放好的画布上下文、当前范围与 project / unproject,在小图上画标记、指北针这类东西
456
514
  */
457
515
  draw?: (info: GisViewMinimapDrawInfo) => void
516
+ /** 可拆分的自定义绘制层:按 placement 分段、段内按 order,最后才轮到旧的 draw */
517
+ layers?: GisViewMinimapLayer[]
458
518
  /** 小图容器的底色(CSS),默认 rgba(255, 255, 255, 0.92) */
459
519
  backgroundStyle?: string
520
+ /** 小图画布备份像素比上限(默认 4):高分屏或宿主缩放很大时可降到 1 ~ 2 降低填充开销 */
521
+ maxPixelRatio?: number
460
522
  borderColor?: string
461
523
  borderWidth?: number
462
524
  /** 圆角(CSS 像素),默认 6 */
@@ -516,6 +578,8 @@ export interface GisViewMinimapOptions {
516
578
  selectStyle?: GisViewMinimapBoxStyle
517
579
  /** 关掉后鹰眼图只看不动,默认 true */
518
580
  interactive?: boolean
581
+ /** 一次手势完成后的通知(无位移的点击不发):框拖动 / 框选 / 小图平移 / 缩放 / 滚轮缩放主图 / 长按跟随 */
582
+ onInteraction?: (info: GisViewMinimapInteractionInfo) => void
519
583
  /** 长按多久算「要移动视角」(毫秒),默认 180 */
520
584
  longPressDelay?: number
521
585
  /** 在小图上滚轮是否缩放主图(以光标处的世界坐标为锚点),默认 true;zoomable 打开时改由 Ctrl / ⌘ + 滚轮触发 */
@@ -903,6 +967,55 @@ export interface GisViewPointEffectReadout {
903
967
  from: number
904
968
  }
905
969
 
970
+ /** 节点装饰连接线:true 用默认样式,对象可覆盖颜色 / 线宽 / 透明度 / 虚线 */
971
+ export interface GisViewPointDecorationConnector {
972
+ color?: string
973
+ /** 线宽(CSS 像素),缺省 1 */
974
+ width?: number
975
+ /** 透明度,缺省 0.82 */
976
+ opacity?: number
977
+ /** true 等价于 lineType: 'dashed' */
978
+ dashed?: boolean
979
+ lineType?: 'solid' | 'dashed' | 'dotted'
980
+ }
981
+
982
+ /**
983
+ * 节点上的图片 / SVG 装饰:相对节点按屏幕像素偏移,或写死世界坐标。
984
+ * - `offset` / `distance + direction`:相对节点,缩放时保持同样的屏幕像素距离;
985
+ * - `at` / `anchor: 'fixed'`:世界坐标固定,节点移动不跟随;
986
+ * - `connector`:从节点中心画一条连接线到装饰中心。
987
+ */
988
+ export interface GisViewPointDecoration {
989
+ /** 图片 / SVG / 内置形状,和节点的 symbol 写法一样 */
990
+ symbol: GisViewSymbolInput
991
+ /** 定位方式:offset 相对节点(缺省),fixed 写死世界坐标 */
992
+ anchor?: 'offset' | 'fixed'
993
+ /** 相对节点的屏幕像素偏移(x 向右、y 向下),优先于 distance / direction */
994
+ offset?: [number, number] | GisViewCoordinate
995
+ /** 离节点的屏幕像素距离,缺省 28 */
996
+ distance?: number
997
+ /** 相对方向:0 度向上、顺时针,缺省 0(正上方) */
998
+ direction?: number
999
+ /** 固定位置(世界坐标);给了它就按 fixed 处理,优先级最高 */
1000
+ at?: GisViewCoordinate
1001
+ /** 图标旋转角(度),缺省 0 */
1002
+ angle?: number
1003
+ /** 屏幕尺寸(CSS 像素),缺省 18 */
1004
+ size?: number
1005
+ /** 填充 / 色调,缺省白色 */
1006
+ color?: string
1007
+ /** 描边色,缺省透明 */
1008
+ strokeColor?: string
1009
+ /** 描边宽度(CSS 像素),缺省 0 */
1010
+ strokeWidth?: number
1011
+ /** 透明度,缺省 1 */
1012
+ opacity?: number
1013
+ /** 阴影,和节点一样 */
1014
+ shadow?: GisViewShadow
1015
+ /** 是否从节点中心画一条连接线,缺省不画 */
1016
+ connector?: boolean | GisViewPointDecorationConnector
1017
+ }
1018
+
906
1019
  export interface GisViewPoint {
907
1020
  id?: string | number
908
1021
  x: number
@@ -921,6 +1034,8 @@ export interface GisViewPoint {
921
1034
  opacity?: number
922
1035
  shadow?: GisViewShadow
923
1036
  visible?: boolean
1037
+ /** 这个节点上挂的图片 / SVG 装饰:可相对节点偏移、固定世界坐标,也可以带一条连接线 */
1038
+ decorations?: GisViewPointDecoration[]
924
1039
  /** 这个点的标签是否显示:false 时即使启用了标签也不画 */
925
1040
  labelVisible?: boolean
926
1041
  /** 这个点的标签显隐策略:auto 智能隐藏、always 一直显示、hidden 不显示,缺省用 options.label.visibility */
@@ -1113,8 +1228,9 @@ export interface GisViewChannel {
1113
1228
  */
1114
1229
  groups?: GisViewChannelGroup[]
1115
1230
  /**
1116
- * 骨架折线(中心线):两端用 from / to 绑定点 id 时可以只写中间拐点,首尾顶点由节点坐标决定;
1117
- * 完全缺省时取第一条回线自身的路径
1231
+ * 可选。骨架折线(中心线):两端用 from / to 绑定点 id 时可以只写中间拐点,首尾顶点由节点坐标决定,
1232
+ * 不写就是两端直连;未锚定时写完整折线,完全缺省则取第一条回线自身的路径。
1233
+ * 配了 groups 时,第一组没写自己的 path 会回落到这里
1118
1234
  */
1119
1235
  path?: GisViewCoordinate[]
1120
1236
  /**
@@ -1567,6 +1683,12 @@ export interface GisViewChannelDraftOptions {
1567
1683
  linePropsByMember?: Array<Partial<GisViewLine> | undefined>
1568
1684
  /** 第二段 lineItems(一条或一批):与 linePropsByMember 同义,给了几条这一段就加几条(circuits 按它对齐);每项也可以只写一个 id */
1569
1685
  lineItems?: GisViewChannelLineItems
1686
+ /** 走线方式:'straight'(缺省,两端直连)/ 'orthogonal'(自动补一个先横后纵的 90° 拐点) */
1687
+ routing?: 'straight' | 'orthogonal'
1688
+ /** 中间拐点(不含两端):给了就按它折线;routing 的自动拐点只在没给有效拐点时补 */
1689
+ path?: GisViewCoordinate[]
1690
+ /** 本次草稿的预览样式:盖在全局 channelDraftStyle 之上,草稿结束即丢弃 */
1691
+ channelDraftStyle?: GisViewChannelDraftStyle
1570
1692
  /**
1571
1693
  * 交接模式:两个节点选完、发完 phase: 'ready' 就把草稿收掉(假通道当场消失、不补 cancel),
1572
1694
  * 由使用方在事件里自己调 addChannel 落地;与 autoCommit 同时给时 autoCommit 先落地
@@ -1585,7 +1707,8 @@ export interface GisViewChannelDraftOptions {
1585
1707
 
1586
1708
  /**
1587
1709
  * 新增通道的交互载荷:start → from(选好起点,预览线跟随光标)→ ready(选好终点)→ commit / blocked,
1588
- * 取消走 cancel,连续新增落地之后开下一段走 restart,草稿期间点到空白 / 点回起点走 pick。
1710
+ * 取消走 cancel(已选起点后点空白也会直接取消),连续新增落地之后开下一段走 restart,
1711
+ * 还没选起点时点到空白 / 点回起点走 pick。
1589
1712
  * 两个节点的信息(id / 名称 / 坐标)与可选方案(plan)在每个阶段都带着
1590
1713
  */
1591
1714
  export interface GisViewChannelDraftPayload {
@@ -1625,6 +1748,12 @@ export interface GisViewChannelDraftPayload {
1625
1748
  /** 第二段 lineItems(一条或一批):与 linePropsByMember 同一份写法,提交时一起交给 addChannel */
1626
1749
  lineItems?: Array<Partial<GisViewLine> | undefined> | null
1627
1750
  channelProps?: Partial<GisViewChannel>
1751
+ /** 这一次草稿实际生效的预览样式(全局配置 + 本次覆盖) */
1752
+ style: GisViewChannelDraftStyle
1753
+ /** 草稿的走线方式:直线 / 自动正交折线 */
1754
+ routing: 'straight' | 'orthogonal'
1755
+ /** 草稿的中间拐点(已选好两端时是实际会落地的那一份,正交路由的拐点也在这里);没有为 null */
1756
+ path: GisViewCoordinate[] | null
1628
1757
  /** 两个节点都选好之后才有方案表,否则为 null */
1629
1758
  plan: GisViewChannelAddPlan | null
1630
1759
  options: GisViewChannelAddOption[]
@@ -1884,8 +2013,10 @@ export interface GisViewChannelAddInput {
1884
2013
  */
1885
2014
  lineItems?: GisViewChannelLineItems
1886
2015
  channelProps?: Partial<GisViewChannel>
1887
- /** 新建通道时的中间拐点 */
2016
+ /** 中间拐点(不含两端):新建通道写进骨架,新建独立线路展开成完整 path;routing 为 orthogonal 时自动补拐点 */
1888
2017
  path?: GisViewCoordinate[]
2018
+ /** 走线方式:'straight'(缺省)/ 'orthogonal'(自动补一个先横后纵的 90° 拐点) */
2019
+ routing?: 'straight' | 'orthogonal'
1889
2020
  }
1890
2021
 
1891
2022
  /** 第二段线路数据(新签名的 line_data / 旧写法的 lineItems 同一份):对象里的 id 就是回线 id(没写的自动编号),裸字符串 / 数字等价于 { id } */
@@ -1924,6 +2055,48 @@ export interface GisViewChannelDraftStyle {
1924
2055
  width?: number
1925
2056
  /** 两端圆点半径(CSS 像素),0 表示不画 */
1926
2057
  dot?: number
2058
+ /** 端点圆点颜色,缺省沿用 color */
2059
+ dotColor?: string
2060
+ /** 预览线末端是否画方向箭头,缺省 false */
2061
+ arrow?: boolean
2062
+ /** 箭头大小(CSS 像素),缺省 12 */
2063
+ arrowSize?: number
2064
+ /** 箭头沿线的归一化位置:0 起点、0.5 中点、1 终点;单个数或数组都可,arrow 为 true 时生效 */
2065
+ arrowPositions?: number | number[]
2066
+ /** 箭头反向(默认从起点指向终点) */
2067
+ arrowReverse?: boolean
2068
+ /** 箭头颜色,缺省沿用 color */
2069
+ arrowColor?: string
2070
+ /** 通道预览的回线间距(CSS 像素,缺省 10):kind 为 channel 且 circuits > 1 时按它排平行回线 */
2071
+ circuitSpacing?: number
2072
+ /** 整条预览的透明度(0 ~ 1,缺省 1) */
2073
+ opacity?: number
2074
+ /**
2075
+ * 内置预览画完之后的自绘钩子:拿得到最终 GL 上下文、世界坐标路径与每条回线的路径,
2076
+ * 适合画自定义箭头 / 标记 / 光环;下一帧会重新调用,需要主动刷新时调用 context.requestRender()
2077
+ */
2078
+ customDraw?: (context: GisViewChannelDraftDrawContext) => void
2079
+ }
2080
+
2081
+ /** 草稿自绘钩子的上下文:几何都是世界坐标,投影用 project / unproject */
2082
+ export interface GisViewChannelDraftDrawContext {
2083
+ gl: WebGL2RenderingContext
2084
+ canvas: HTMLCanvasElement
2085
+ viewport: GisViewViewport
2086
+ camera: GisViewCamera
2087
+ /** 像素 / 世界单位(与 camera.scale 相同) */
2088
+ scale: number
2089
+ /** 解析后的完整折线(含两端) */
2090
+ path: GisViewCoordinate[]
2091
+ /** 每条回线的实际路径:单回线时只有一条,通道多回线时是平行偏移之后的那几条 */
2092
+ circuitPaths: GisViewCoordinate[][]
2093
+ circuits: number
2094
+ kind: 'channel' | 'line'
2095
+ phase: 'start' | 'from' | 'ready'
2096
+ style: GisViewChannelDraftStyle
2097
+ project(x: number, y: number): [number, number]
2098
+ unproject(x: number, y: number): [number, number]
2099
+ requestRender(): void
1927
2100
  }
1928
2101
  /** 通道成员表:只给成员下标与各自偏移,不复制几何(鹰眼图挑「只画一根」时的中间那条回线用它) */
1929
2102
  export interface GisViewChannelMember {
@@ -2483,7 +2656,7 @@ export type GisViewPointerTarget = 'point' | 'line' | 'channel' | 'waypoint' | '
2483
2656
  /**
2484
2657
  * 一次指针操作的动作名。同一个名字在「按下 / 松开 / 点击」三条事件里含义略有不同:
2485
2658
  * - onPointerDown 是「这一次按下打算做什么」(意图):'pan' / 'dragPoint' / 'dragWaypoint' / 'boxSelect' /
2486
- * 'copy' / 'channelDraft'(点两次加通道)/ 'contextMenu'(右键)/ 'click'(左键按下,但下面没有可拖的东西);
2659
+ * 'copy' / 'channelDraft'(点两次加通道)/ 'decorationDraft'(动态装饰器草稿)/ 'contextMenu'(右键)/ 'click'(左键按下,但下面没有可拖的东西);
2487
2660
  * - onPointerUp 是「刚做完的那一件事」:拖过就是拖动的名字,没拖就是 'click'(配合 action.moved 判读);
2488
2661
  * - onClick / onDblClick 是真正发生的那一件:'select'(点中要素)/ 'click'(没开选中)/ 'dblClick'(双击);
2489
2662
  * - 拐点、标签、选中集各有自己那一套:'addWaypoint' / 'dragWaypoint' / 'selectLabel' / 'dragLabel' /
@@ -2507,7 +2680,8 @@ export type GisViewPointerActionType =
2507
2680
  | 'click'
2508
2681
  | 'pan'
2509
2682
  | 'copy'
2510
- | 'channelDraft'
2683
+ | 'channelDraft'
2684
+ | 'decorationDraft'
2511
2685
  | 'drag'
2512
2686
  | 'pointer'
2513
2687
 
@@ -2955,6 +3129,8 @@ export interface GisViewPointMergePayload {
2955
3129
  target: { index: number; item: GisViewPoint; coordinate: [number, number] }
2956
3130
  /** 停在目标上的光标位置(画布 CSS 像素) */
2957
3131
  screen: [number, number] | null
3132
+ /** 这一次合并是按哪种时机命中的,与 merge.trigger 同一口径 */
3133
+ trigger: GisViewMergeTrigger
2958
3134
  originalEvent: Event | null
2959
3135
  /** 按当前 keep 预演的影响读数(pending / confirm / state 有值;cancel 与对不上数据时为 null) */
2960
3136
  impact: GisViewMergeImpact | null
@@ -3139,13 +3315,13 @@ export interface GisViewRemoveSelectedOutcome {
3139
3315
  }
3140
3316
 
3141
3317
  /**
3142
- * updatePoints / updateLines 里的一条:给一个定位(id / 下标 / `{ id }` / `{ index }`,与公共补丁一起用),
3318
+ * patchPoints / patchLines 里的一条:给一个定位(id / 下标 / `{ id }` / `{ index }`,与公共补丁一起用),
3143
3319
  * 或者「定位 + 自己这一份补丁」(`{ id: 'a', name: 'A' }`)—— id / index 之外的字段就是这一条的补丁
3144
3320
  */
3145
3321
  export type GisViewUpdateItemEntry<T> = GisViewPointRef | (Partial<T> & { id?: string | number; index?: number })
3146
3322
 
3147
3323
  /**
3148
- * updatePoints / updateLines 的返回:改完的那几条按 indexes / items 对应列出(items 是数据里的新对象),
3324
+ * patchPoints / patchLines 的返回:改完的那几条按 indexes / items 对应列出(items 是数据里的新对象),
3149
3325
  * 认不出来的定位在 skipped 里(不影响其余条目)。一次调用只发一条数据变更。
3150
3326
  */
3151
3327
  export interface GisViewUpdateItemsOutcome<T = GisViewPoint | GisViewLine> {
@@ -3162,7 +3338,6 @@ export type GisViewDataChangeType =
3162
3338
  | 'updateData'
3163
3339
  | 'updatePoints'
3164
3340
  | 'updateLines'
3165
- | 'updateChannels'
3166
3341
  | 'updateOptions'
3167
3342
  | 'updateBackground'
3168
3343
  | 'updatePoint'
@@ -3304,6 +3479,45 @@ export interface GisViewEngineStats {
3304
3479
  /** 动画是否还在排下一帧:静止画面是按需渲染的,这时候是 false */
3305
3480
  animating: boolean
3306
3481
  quality: GisViewQualityState
3482
+ /**
3483
+ * 大数据展示模式的有效读数(组件的 getStats() / onStats / onRender 会带上;纯引擎实例没有这一项)。
3484
+ * active 为 true 时标签走避让 / 截断档,线路动点与节点涟漪暂停。
3485
+ */
3486
+ dense?: GisViewDenseState
3487
+ }
3488
+
3489
+ /** 大数据展示模式的三种档位:auto 按阈值自动切,on / off 强制打开或关闭 */
3490
+ export type GisViewDenseMode = 'auto' | 'on' | 'off'
3491
+
3492
+ /**
3493
+ * denseMode 的对象写法:阈值都按「正数才生效」处理,不写用内置缺省。
3494
+ * `visibleThreshold` 是视口内节点数,`densityThreshold` 是每百万 CSS 像素的节点数,
3495
+ * `pointThreshold` 是整份数据的节点总数;任意一项越线就进入 dense。
3496
+ */
3497
+ export interface GisViewDenseModeOptions {
3498
+ mode?: GisViewDenseMode
3499
+ /** 视口内可见节点达到多少个进入密集档,默认 4000 */
3500
+ visibleThreshold?: number
3501
+ /** 每百万 CSS 像素的可见节点密度阈值,默认 3000 */
3502
+ densityThreshold?: number
3503
+ /** 数据总节点数阈值,默认 50000(只看总量,不要求同屏) */
3504
+ pointThreshold?: number
3505
+ }
3506
+
3507
+ /** denseMode 的入参:布尔值 true / false 等价于 'on' / 'off' */
3508
+ export type GisViewDenseModeInput = boolean | GisViewDenseMode | GisViewDenseModeOptions
3509
+
3510
+ /** 大数据展示模式的读数:getStats().dense / onStats / onRender 的 dense 字段 */
3511
+ export interface GisViewDenseState {
3512
+ mode: GisViewDenseMode
3513
+ active: boolean
3514
+ /** 这次判定的依据(checking 表示还在等首帧 / 发散渲染铺完) */
3515
+ reason: 'manual-on' | 'manual-off' | 'total' | 'visible' | 'density' | 'below-threshold' | 'checking'
3516
+ /** 最近一次量到的可见节点数(只数到触发阈值;按总量触发时是 null) */
3517
+ visiblePoints: number | null
3518
+ visibleThreshold: number
3519
+ densityThreshold: number
3520
+ pointThreshold: number
3307
3521
  }
3308
3522
 
3309
3523
  /** 渲染帧回调载荷:onStats 的读数 + 帧序号 / 节流间隔 / 时刻与当前相机 */
@@ -3356,6 +3570,20 @@ export type GisViewConditionOperator = 'eq' | 'ne' | 'gt' | 'gte' | 'lt' | 'lte'
3356
3570
  */
3357
3571
  export type GisViewConditionOperatorTest = (value: unknown) => (current: unknown) => boolean
3358
3572
 
3573
+ /** 注册一个自定义条件运算符;名字为空、与内置重名或工厂不是函数时返回 false */
3574
+ export declare const registerConditionOperator: (name: string, test: GisViewConditionOperatorTest) => boolean
3575
+ /**
3576
+ * 带作用域地注册一个自定义条件运算符:返回清理函数,只在当前注册项仍是这个工厂时删除,
3577
+ * 同名被后注册覆盖时旧清理函数不会误删。参数不合法或撞内置名时抛 TypeError。
3578
+ */
3579
+ export declare const defineConditionOperator: (name: string, test: GisViewConditionOperatorTest) => () => boolean
3580
+ /** 注销一个自定义条件运算符,返回它之前是否在注册表里;内置运算符不能用它摘掉 */
3581
+ export declare const unregisterConditionOperator: (name: string) => boolean
3582
+ /** 这个名字能不能用(内置或注册过的自定义) */
3583
+ export declare const hasConditionOperator: (name: string) => boolean
3584
+ /** 当前能用哪些运算符:内置 14 个在前,自定义按注册顺序跟在后面 */
3585
+ export declare const listConditionOperators: () => string[]
3586
+
3359
3587
  /**
3360
3588
  * 显式条件:`{ field: 'vnkv', op: 'gte', value: 500 }`,op 缺省为 eq,not 取反。
3361
3589
  * field 支持 `props.vnkv` 这样的嵌套路径。
@@ -4075,6 +4303,210 @@ export interface GisViewLineDecoration {
4075
4303
  shadow?: GisViewShadow
4076
4304
  }
4077
4305
 
4306
+ /** 动态装饰器草稿的作用域:单条线路 / 命中线所在分组 / 整条通道(不在通道里时都退回单条) */
4307
+ export type GisViewDecorationDraftScope = 'line' | 'group' | 'channel'
4308
+
4309
+ /** 动态装饰器草稿要命中哪一类要素:线路、节点,或两类同时开启 */
4310
+ export type GisViewDecorationDraftTarget = 'line' | 'point' | 'both'
4311
+
4312
+ /** 节点装饰的位置来源:相对节点偏移 / 固定世界坐标 / 当前鼠标位置;落地关系另由 anchor 决定 */
4313
+ export type GisViewDecorationDraftPointPlacement = 'offset' | 'fixed' | 'pointer'
4314
+
4315
+ /**
4316
+ * 节点装饰的落地关系:
4317
+ * - follow:保留相对节点的屏幕偏移,节点移动 / 画布缩放时跟着节点;
4318
+ * - fixed:保留世界坐标,节点移动后仍停在原处。
4319
+ * 缺省由 placement 推导:offset → follow,fixed / pointer → fixed。
4320
+ */
4321
+ export type GisViewDecorationDraftPointAnchor = 'follow' | 'fixed'
4322
+
4323
+ /** 同一目标位置出现重复装饰时:offset 自动让开,reject 直接不允许添加 */
4324
+ export type GisViewDecorationDraftDuplicateStrategy = 'offset' | 'reject'
4325
+
4326
+ /** 动态装饰器草稿的阶段:start(开启)→ hover(命中跟随)/ leave(移出目标)→ ready(松手命中)→ commit / cancel */
4327
+ export type GisViewDecorationDraftPhase = 'start' | 'hover' | 'leave' | 'ready' | 'update' | 'commit' | 'cancel'
4328
+
4329
+ /**
4330
+ * 动态装饰器草稿的配置:图标 / 大小 / 配色与真实线路、节点装饰同一套写法。
4331
+ * `target` 决定命中线路 / 节点 / 两类同时;线路侧 `parallel` 决定是否跟着方向转、`scope` 决定一次给哪些线路都挂上,
4332
+ * `maxPerLine` / `allowedLines` / `allowedChannels` / `allowedGroups` 限定线路目标;
4333
+ * 节点侧 `placement` 决定位置来源(相对偏移 / 固定坐标 / 鼠标位置),`anchor` 决定落地后跟随节点还是固定世界坐标;
4334
+ * `maxPerPoint` / `allowedPoints` 限定节点目标。
4335
+ * 两边都受 `allowDuplicate` / `duplicateStrategy` / `duplicateDistance` 的重复策略约束。
4336
+ */
4337
+ export interface GisViewDecorationDraftOptions {
4338
+ /** 命中类型,缺省 'line'(保持原有线路装饰器行为) */
4339
+ target?: GisViewDecorationDraftTarget
4340
+ /** 图片 / SVG / 内置形状,缺省 'circle' */
4341
+ symbol?: GisViewSymbolInput
4342
+ /** 屏幕尺寸(CSS 像素),缺省 18 */
4343
+ size?: number
4344
+ /** 填充 / 色调,缺省白色 */
4345
+ color?: string
4346
+ /** 描边色,缺省透明 */
4347
+ strokeColor?: string
4348
+ /** 描边宽度(CSS 像素),缺省 0 */
4349
+ strokeWidth?: number
4350
+ /** 透明度,缺省 1 */
4351
+ opacity?: number
4352
+ /** 阴影,和节点一样 */
4353
+ shadow?: GisViewShadow
4354
+ /** 是否跟着线路方向转,缺省 false(保持水平) */
4355
+ parallel?: boolean
4356
+ /** 作用域,缺省 'line' */
4357
+ scope?: GisViewDecorationDraftScope
4358
+ /** 离线路多远算命中(屏幕像素),缺省 14;只有贴近线路时才出现预览 */
4359
+ maxDistance?: number
4360
+ /** 每条线路最多允许多少个 decoration(按 `lines[].decorations.length` 计),0 / 缺省 = 不限 */
4361
+ maxPerLine?: number
4362
+ /** 每个节点最多允许多少个 decoration(按 `points[].decorations.length` 计),0 / 缺省 = 不限 */
4363
+ maxPerPoint?: number
4364
+ /** 允许挂装饰的线路 id;空数组 / 缺省表示不限制这一类 */
4365
+ allowedLines?: Array<string | number>
4366
+ /** 允许挂装饰的通道 id;空数组 / 缺省表示不限制这一类 */
4367
+ allowedChannels?: Array<string | number>
4368
+ /** 允许挂装饰的分组 id;空数组 / 缺省表示不限制这一类 */
4369
+ allowedGroups?: Array<string | number>
4370
+ /** 允许挂装饰的节点 id;空数组 / 缺省表示不限制这一类 */
4371
+ allowedPoints?: Array<string | number>
4372
+ /** 节点位置来源,缺省 'offset'(相对节点偏移) */
4373
+ placement?: GisViewDecorationDraftPointPlacement
4374
+ /** 落地关系,缺省由 placement 推导:offset → follow,fixed / pointer → fixed */
4375
+ anchor?: GisViewDecorationDraftPointAnchor
4376
+ /** 相对节点的屏幕像素偏移(x 向右、y 向下),优先于 distance / direction */
4377
+ offset?: [number, number] | GisViewCoordinate
4378
+ /** 相对节点的屏幕像素距离,缺省 28 */
4379
+ distance?: number
4380
+ /** 相对方向:0 度向上、顺时针,缺省 0(正上方) */
4381
+ direction?: number
4382
+ /** placement 为 fixed 时的世界坐标;缺省落在节点中心 */
4383
+ at?: GisViewCoordinate
4384
+ /** 节点装饰旋转角(度),缺省 0 */
4385
+ angle?: number
4386
+ /** 节点装饰连接线:true 用默认样式,对象可覆盖颜色 / 线宽 / 透明度 / 虚线 */
4387
+ connector?: boolean | GisViewPointDecorationConnector
4388
+ /** 是否允许同一目标位置上重复添加,缺省 true(保持原有行为) */
4389
+ allowDuplicate?: boolean
4390
+ /** allowDuplicate 为 false 时:offset 自动让开(缺省),reject 直接拦下 */
4391
+ duplicateStrategy?: GisViewDecorationDraftDuplicateStrategy
4392
+ /** 重复判定容差(屏幕像素),缺省 8 */
4393
+ duplicateDistance?: number
4394
+ /** 触发这次草稿的原始事件(begin / update 时可选带进来) */
4395
+ originalEvent?: Event | null
4396
+ }
4397
+
4398
+ /** 草稿作用域展开之后的一条目标线路:线路 id 与它在通道 / 分组里的归属 */
4399
+ export interface GisViewDecorationDraftLineTarget {
4400
+ lineIndex: number
4401
+ lineId: string | number
4402
+ channelId: string | number | null
4403
+ groupId: string | number | null
4404
+ channelIndex: number | null
4405
+ /** 这条线路当前已有的 decoration 数(maxPerLine 判断用) */
4406
+ existingCount: number
4407
+ }
4408
+
4409
+ /** 草稿命中的节点目标:节点 id 与已有装饰数(maxPerPoint 判断用) */
4410
+ export interface GisViewDecorationDraftPointTarget {
4411
+ pointIndex: number
4412
+ pointId: string | number
4413
+ /** 这个节点当前已有的 decoration 数 */
4414
+ existingCount: number
4415
+ x: number
4416
+ y: number
4417
+ }
4418
+
4419
+ /**
4420
+ * 动态装饰器草稿的事件载荷(options.onDecorationDraft / on('decorationDraft') 共用)。
4421
+ * phase 为 leave / cancel 时命中相关的字段为 null;targets 是这一次会挂到哪些线路(单条 / 分组 / 整条通道)。
4422
+ */
4423
+ export interface GisViewDecorationDraftPayload {
4424
+ phase: GisViewDecorationDraftPhase
4425
+ /** 归一化之后的草稿配置 */
4426
+ options: GisViewDecorationDraftOptions
4427
+ /** 符号类型名(circle / square / svg / image),面板读数用 */
4428
+ symbol: string
4429
+ /** 原始符号写法(可直接写进 decorations[].symbol) */
4430
+ symbolInput: GisViewSymbolInput
4431
+ size: number
4432
+ color: string | null
4433
+ strokeColor: string | null
4434
+ strokeWidth: number
4435
+ opacity: number
4436
+ parallel: boolean
4437
+ scope: GisViewDecorationDraftScope
4438
+ maxDistance: number
4439
+ maxPerLine: number
4440
+ maxPerPoint: number
4441
+ allowedLines: Array<string | number>
4442
+ allowedChannels: Array<string | number>
4443
+ allowedGroups: Array<string | number>
4444
+ allowedPoints: Array<string | number>
4445
+ target: GisViewDecorationDraftTarget
4446
+ placement: GisViewDecorationDraftPointPlacement
4447
+ anchor: GisViewDecorationDraftPointAnchor
4448
+ connector: boolean | GisViewPointDecorationConnector | null
4449
+ allowDuplicate: boolean
4450
+ duplicateStrategy: GisViewDecorationDraftDuplicateStrategy
4451
+ duplicateDistance: number
4452
+ /** 本次预览是否因为不允许重复而自动让开了位置 */
4453
+ duplicateAdjusted: boolean
4454
+ /** 最近一次命中的目标为什么不可用:limit(满额)/ not-allowed(白名单)/ targets-missing(目标已不在)/ duplicate(重复) */
4455
+ blockedReason: string | null
4456
+ /** 沿线比例(0~1);离开目标线时为 null */
4457
+ position: number | null
4458
+ /** 指针的画布 CSS 像素坐标 */
4459
+ screen: [number, number] | null
4460
+ /** 图标预览的屏幕坐标(节点装饰的固定 / 偏移位置也在这里) */
4461
+ decorationScreen: [number, number] | null
4462
+ /** 图标最终的世界坐标(线路为沿线落点,节点为吸附位置) */
4463
+ world: [number, number] | null
4464
+ /** 图标当前的屏幕旋转角(弧度;线路 parallel 或节点装饰 angle 换算后) */
4465
+ angle: number
4466
+ lineIndex: number | null
4467
+ lineId: string | number | null
4468
+ item: GisViewLine | null
4469
+ channelId: string | number | null
4470
+ groupId: string | number | null
4471
+ channelIndex: number | null
4472
+ /** 命中的线路读数(nearestLineAt 同一份),离开目标线时为 null */
4473
+ hit: GisViewNearestLine | null
4474
+ /** 本次命中的类型;离开目标时为 null */
4475
+ hitKind: 'line' | 'point' | null
4476
+ /** 与 hitKind 相同(便于面板按 targetKind 读数) */
4477
+ targetKind: 'line' | 'point' | null
4478
+ /** 命中的节点下标 / id / 数据;命中线路时为 null */
4479
+ pointIndex: number | null
4480
+ pointId: string | number | null
4481
+ pointItem: GisViewPoint | null
4482
+ pointHit: GisViewNearestPoint | null
4483
+ targets: GisViewDecorationDraftLineTarget[]
4484
+ pointTargets: GisViewDecorationDraftPointTarget[]
4485
+ lineTargetCount: number
4486
+ pointTargetCount: number
4487
+ /** 本次会写入的目标总数(线路目标 + 节点目标) */
4488
+ targetCount: number
4489
+ /** 与 targetCount 相同,commit 事件里便于统一读数 */
4490
+ count: number
4491
+ /** 归一化之后的真实装饰字段,commit 时逐条写进 decorations */
4492
+ decoration: GisViewLineDecoration | null
4493
+ /** 命中节点时归一化之后的真实装饰字段 */
4494
+ pointDecoration: GisViewPointDecoration | null
4495
+ originalEvent: Event | null
4496
+ }
4497
+
4498
+ /** commitDecorationDraft 的结果:ok 为 false 时 reason 说明原因(no-draft / no-target / limit / not-allowed / targets-missing / duplicate) */
4499
+ export interface GisViewDecorationCommitResult {
4500
+ ok: boolean
4501
+ reason?: string
4502
+ count: number
4503
+ targets: GisViewDecorationDraftLineTarget[]
4504
+ decorations: GisViewLineDecoration[]
4505
+ pointTargets: GisViewDecorationDraftPointTarget[]
4506
+ pointDecorations: GisViewPointDecoration[]
4507
+ draft?: GisViewDecorationDraftPayload
4508
+ }
4509
+
4078
4510
  /** 悬浮提示内容:模板字符串(`{name}` / `{vnkv}`)或返回文本 / 元素 / null 的函数 */
4079
4511
  export type GisViewTooltipContent = string | ((payload: GisViewPickResult) => string | HTMLElement | number | null | undefined)
4080
4512
 
@@ -4423,10 +4855,17 @@ export interface GisViewInitialView {
4423
4855
  }
4424
4856
 
4425
4857
  /**
4426
- * 插件:视图建好之后调用一次,拿到实例本身;返回 { destroy } 时会挂进实例的 destroy。
4858
+ * 插件:视图建好之后调用一次,拿到实例本身与带 apiVersion 的上下文;返回 { destroy } 时会挂进实例的 destroy。
4427
4859
  * 写一次插件,之后换项目直接复用,不必把「URL 同步 / 自建图例 / 业务操作」再抄一遍。
4428
4860
  */
4429
- export type GisViewPlugin = (view: GisViewInstance) => void | { destroy?: () => void }
4861
+ export interface GisViewPluginContext {
4862
+ /** 插件 API 版本:当前为 1;以后只做加字段的向后兼容扩展 */
4863
+ readonly apiVersion: 1
4864
+ /** 与插件第一个参数相同,方便统一改写成只收一个上下文对象 */
4865
+ readonly view: GisViewInstance
4866
+ }
4867
+
4868
+ export type GisViewPlugin = (view: GisViewInstance, context: GisViewPluginContext) => void | { destroy?: () => void }
4430
4869
 
4431
4870
  /**
4432
4871
  * 快捷键写法(大小写不敏感,多个用 + 连接):
@@ -4537,7 +4976,16 @@ export interface GisViewMergeOptions {
4537
4976
  * **缺省关**:写了这份 merge 配置才算开(`enabled: false` 显式关掉),也可以由 features.merge 强制
4538
4977
  */
4539
4978
  enabled?: boolean
4540
- /** 额外的碰撞容差(CSS 像素):两个节点画在屏幕上的半径之和再加它,默认 0 */
4979
+ /**
4980
+ * 拖拽合并的触发时机:
4981
+ * - `'collision'`(缺省):两个节点画在屏幕上的半径之和以内就算碰上,响应更早;
4982
+ * - `'center'`:拖动的节点中心点进入目标节点的屏幕区域(目标节点半径)时才触发,比碰撞更晚、更稳。
4983
+ * 两种都再叠加 `distance` 的像素容差。
4984
+ */
4985
+ trigger?: GisViewMergeTrigger
4986
+ /**
4987
+ * 额外的像素容差(CSS 像素):`'collision'` 加在两个节点屏幕半径之和上,`'center'` 加在目标节点半径上,默认 0
4988
+ */
4541
4989
  distance?: number
4542
4990
  /**
4543
4991
  * 确认方式:组件不弹任何对话框,只把载荷交给使用方 ——
@@ -4560,6 +5008,8 @@ export interface GisViewMergeOptions {
4560
5008
  createItem?: (source: GisViewPoint, target: GisViewPoint, context: GisViewMergeContext) => GisViewPoint
4561
5009
  }
4562
5010
 
5011
+ /** 拖拽合并的触发时机:两个节点的屏幕半径相碰 / 拖动节点中心进入目标节点区域 */
5012
+ export type GisViewMergeTrigger = 'collision' | 'center'
4563
5013
 
4564
5014
  /** 通道选中模式:点中通道里的一条回线时选中什么 */
4565
5015
  export type GisViewChannelSelectMode =
@@ -4590,7 +5040,7 @@ export interface GisViewSelectInBoxOptions {
4590
5040
  originalEvent?: Event | null
4591
5041
  }
4592
5042
 
4593
- /** confirmPointMerge / payload.confirm 的参数:保留哪一端,以及最终节点(可只给要改的字段) */
5043
+ /** resolvePointMerge / payload.confirm 的参数:保留哪一端,以及最终节点(可只给要改的字段) */
4594
5044
  export interface GisViewPointMergeConfirmOptions {
4595
5045
  keep?: GisViewMergeKeep
4596
5046
  item?: Partial<GisViewPoint> | null
@@ -5076,6 +5526,8 @@ export interface GisViewEventMap {
5076
5526
  channelContextMenu: { payload: GisViewChannelContextPayload | null; event: MouseEvent }
5077
5527
  channelDraft: GisViewChannelDraftPayload
5078
5528
  channelDraftClick: GisViewChannelDraftPayload
5529
+ /** 动态装饰器草稿:start / hover / leave / ready / update / commit / cancel */
5530
+ decorationDraft: GisViewDecorationDraftPayload
5079
5531
  /** 分组变化:拆分 / 合并 / 挪线 / 新建组 / 整份声明换(updateChannel),action.type 说明这一笔是什么 */
5080
5532
  channelGroupChange: GisViewChannelGroupChangePayload
5081
5533
  dataChange: GisViewDataChangePayload
@@ -5110,6 +5562,110 @@ export type GisViewEventListener<K extends GisViewEventName> = (payload: GisView
5110
5562
  /** `on('*', fn)` 的回调:载荷类型随事件名变化,第二个参数说明这次是哪一条 */
5111
5563
  export type GisViewAnyEventListener = (payload: GisViewEventMap[GisViewEventName], name: GisViewEventName) => void
5112
5564
 
5565
+ /** 扩展图形类型:SVG 路径 / 图片 / 外部 Canvas */
5566
+ export type GisViewGraphicType = 'path' | 'image' | 'canvas'
5567
+
5568
+ /** 图形的锚点:九宫格名字,或 [x, y](0~1,[0.5, 0.5] 是中心) */
5569
+ export type GisViewGraphicAnchor =
5570
+ | 'center' | 'top' | 'bottom' | 'left' | 'right'
5571
+ | 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right'
5572
+ | [number, number]
5573
+
5574
+ /** 图形的路径 / 图片样式(与直接写在图形对象上的同名字段等价,直接字段优先) */
5575
+ export interface GisViewGraphicStyle {
5576
+ fill?: string
5577
+ stroke?: string
5578
+ lineWidth?: number
5579
+ strokeWidth?: number
5580
+ opacity?: number
5581
+ lineCap?: 'butt' | 'round' | 'square'
5582
+ lineJoin?: 'miter' | 'round' | 'bevel'
5583
+ lineDash?: number[]
5584
+ dash?: number[]
5585
+ dashOffset?: number
5586
+ fillRule?: 'nonzero' | 'evenodd'
5587
+ preserveAspectRatio?: string
5588
+ width?: number
5589
+ height?: number
5590
+ }
5591
+
5592
+ /**
5593
+ * 一个扩展图形(类似 ECharts 的 graphic):画在 WebGL 画布之上、标签之下,
5594
+ * 不参与拾取、不进节点 / 线路数据。`x` / `y` 是世界坐标(也可以写 `position: [x, y]`);
5595
+ * 默认是屏幕像素尺寸,`scaleWithView: true` 时宽高按世界单位随相机缩放。
5596
+ */
5597
+ export interface GisViewGraphic {
5598
+ id?: string | number
5599
+ type?: GisViewGraphicType
5600
+ x?: number
5601
+ y?: number
5602
+ position?: [number, number]
5603
+ width?: number
5604
+ height?: number
5605
+ anchor?: GisViewGraphicAnchor
5606
+ offset?: [number, number]
5607
+ rotation?: number
5608
+ scale?: number | [number, number]
5609
+ opacity?: number
5610
+ visible?: boolean
5611
+ zIndex?: number
5612
+ scaleWithView?: boolean
5613
+ d?: string
5614
+ path?: string
5615
+ viewBox?: string | [number, number, number, number]
5616
+ fill?: string
5617
+ stroke?: string
5618
+ strokeWidth?: number
5619
+ lineCap?: 'butt' | 'round' | 'square'
5620
+ lineJoin?: 'miter' | 'round' | 'bevel'
5621
+ lineDash?: number[]
5622
+ dash?: number[]
5623
+ dashOffset?: number
5624
+ fillRule?: 'nonzero' | 'evenodd'
5625
+ style?: GisViewGraphicStyle
5626
+ src?: string
5627
+ href?: string
5628
+ image?: string
5629
+ alt?: string
5630
+ crossOrigin?: 'anonymous' | 'use-credentials' | ''
5631
+ referrerPolicy?: ReferrerPolicy
5632
+ preserveAspectRatio?: string
5633
+ canvas?: HTMLCanvasElement
5634
+ element?: HTMLCanvasElement
5635
+ }
5636
+
5637
+ /** WebGL 自定义层 draw 回调的上下文:画在组件内置内容之后,坐标是最终画布的设备像素 */
5638
+ export interface GisViewWebGLLayerDrawContext {
5639
+ gl: WebGL2RenderingContext
5640
+ /** 最终画布:width / height 是绘制缓冲尺寸(CSS 尺寸乘 pixelRatio) */
5641
+ canvas: HTMLCanvasElement
5642
+ viewport: GisViewViewport
5643
+ camera: GisViewCamera
5644
+ /** 第几帧(从 1 开始),用来做按帧推进的自定义动画 */
5645
+ frame: number
5646
+ /** 世界坐标 → 画布 CSS 像素 */
5647
+ project(x: number, y: number): [number, number]
5648
+ /** 画布 CSS 像素 → 世界坐标 */
5649
+ unproject(x: number, y: number): [number, number]
5650
+ /** 外部数据变了时请求下一帧(层内动画也可以每帧调用) */
5651
+ requestRender(): void
5652
+ }
5653
+
5654
+ /**
5655
+ * WebGL 自定义层:直接拿组件的 WebGL2 上下文画自己的东西(标记、特效、调试几何…)。
5656
+ * 每层开画前会重置到默认帧缓冲、全画布 viewport 与 SRC_ALPHA / ONE_MINUS_SRC_ALPHA 混合;
5657
+ * 层不影响数据、拾取、标签与导出,只在屏幕上叠加。
5658
+ */
5659
+ export interface GisViewWebGLLayer {
5660
+ /** 层 id:同 id 再加会覆盖;不写自动生成 */
5661
+ id?: string | number
5662
+ /** 绘制顺序,从小到大(缺省 0);同 order 保持加入顺序 */
5663
+ order?: number
5664
+ /** false 时跳过这一层(缺省 true) */
5665
+ enabled?: boolean
5666
+ draw(context: GisViewWebGLLayerDrawContext): void
5667
+ }
5668
+
5113
5669
  export interface GisViewOptions {
5114
5670
  /**
5115
5671
  * 功能开关:预设名('edit' / 'view' / 'static')、开关表或布尔值 ——
@@ -5135,6 +5691,13 @@ export interface GisViewOptions {
5135
5691
  * 缺省 'high',与从前完全一致。运行时 setQuality() 换档、getQuality() 读当前档位与最近一帧耗时。
5136
5692
  */
5137
5693
  quality?: GisViewQualityOptions
5694
+ /**
5695
+ * 大数据展示模式:`'auto'`(缺省)按视口内可见节点数、屏幕密度与数据总量自动切;
5696
+ * `'on'` / `'off'` / true / false 强制开关;对象写法可改三档阈值(见 GisViewDenseModeOptions)。
5697
+ * 进入密集档后标签自动走避让 / 截断(等价 labelOptimize: true),线路动点与节点涟漪暂停;
5698
+ * 运行时用 updateOptions({ denseMode }) 切换,当前有效值与判定依据看 getStats().dense。
5699
+ */
5700
+ denseMode?: GisViewDenseModeInput
5138
5701
  /**
5139
5702
  * 渲染后端开关:'auto'(缺省)/ 'webgl2' / 'webgpu',布尔值 true / false 等价于 'webgpu' / 'webgl2'。
5140
5703
  * 当前实装的绘制后端只有 WebGL2 —— 第 18 章量得很清楚:十万级下换 WebGPU 省不到填充率与
@@ -5148,7 +5711,7 @@ export interface GisViewOptions {
5148
5711
  * 这里是全局缺省,逐条线路的 lines[].effect / 逐点 points[].effect 覆盖它(写法见 GisViewLineEffect /
5149
5712
  * GisViewPointEffect)。不配 = 没有全局缺省(数据里自己配了 effect 的照样动);
5150
5713
  * `false` / `{ enabled: false }` = 一处关掉所有动画(连逐要素配好的也一起关)。
5151
- * 运行时 setEffects() 换一份、getEffects() 读归一化之后的配置、getLineEffects() 读这一帧动点的位置。
5714
+ * 运行时 updateOptions({ effects }) 换一份、getEffects() 读归一化之后的配置、getLineEffects() 读这一帧动点的位置。
5152
5715
  */
5153
5716
  effects?: GisViewEffectsInput
5154
5717
  /**
@@ -5189,6 +5752,8 @@ export interface GisViewOptions {
5189
5752
  channelGroupMaxLines?: number
5190
5753
  /** 新增通道草稿线的样式(跟随光标的那条预览线) */
5191
5754
  channelDraftStyle?: GisViewChannelDraftStyle
5755
+ /** WebGL 自定义层:内置内容之后按 order 绘制;运行时用 addWebGLLayer / updateWebGLLayer 等维护 */
5756
+ webglLayers?: GisViewWebGLLayer[]
5192
5757
  background?: GisViewBackground
5193
5758
  pointStyle?: GisViewPointStyle
5194
5759
  lineStyle?: GisViewLineStyle
@@ -5227,6 +5792,12 @@ export interface GisViewOptions {
5227
5792
  * `exportData({ format: 'input' })` 的结果里叫 `labelStates`,原样接上即可完成存档 → 回灌
5228
5793
  */
5229
5794
  labelStates?: GisViewLabelState[]
5795
+ /**
5796
+ * 与节点无关的扩展图形:在画布之上、标签之下绘制 SVG 路径 / 图片 / Canvas,
5797
+ * 支持世界坐标锚点、旋转、透明度、zIndex 与随视图缩放。运行时用 addGraphic / addGraphics /
5798
+ * updateGraphic / removeGraphic / clearGraphics 增删改;exportImage 的 PNG / SVG 都会带上这一层。
5799
+ */
5800
+ graphics?: GisViewGraphic[]
5230
5801
  /** 悬停提示:配了就按这个配置显示,点 / 线 / 通道可分别配置内容 */
5231
5802
  tooltip?: GisViewTooltipOptions
5232
5803
  /** 初始筛选条件,等价于创建之后调用 setFilter;可以写完整格式,也可以只给节点条件 */
@@ -5367,7 +5938,10 @@ export interface GisViewOptions {
5367
5938
  copy?: GisViewCopyOptions
5368
5939
  /** 合并节点(**缺省关**:写了这份配置才算开):把一个节点拖到另一个节点上(考虑碰撞)时怎么确认与怎么并 */
5369
5940
  merge?: GisViewMergeOptions
5370
- /** 是否允许编辑线路拐点:Ctrl + 点击添加、拖动移动、双击或 Delete 删除;**缺省关**,单条线可用 waypointEditable 覆盖 */
5941
+ /**
5942
+ * 是否允许编辑线路拐点:Ctrl + 点击添加、拖动移动、双击或 Delete 删除;**缺省关**,单条线可用 waypointEditable 覆盖。
5943
+ * `false`(以及 `features: { waypoint: false }`)会同时关闭新增、移动与删除;没有只关其中一项的细分开关
5944
+ */
5371
5945
  waypointEditable?: boolean
5372
5946
  /** 拐点显示时机:selected 只在线路被选中(或刚加过拐点)时显示,always 始终显示;默认 selected */
5373
5947
  waypointVisibility?: 'selected' | 'always'
@@ -5398,7 +5972,7 @@ export interface GisViewOptions {
5398
5972
  */
5399
5973
  renderEmitInterval?: number
5400
5974
  /**
5401
- * 插件:视图建好之后依次调用`plugin(view)`,用来把跨项目复用的逻辑
5975
+ * 插件:视图建好之后依次调用 `plugin(view, context)`(context 带 apiVersion / view),用来把跨项目复用的逻辑
5402
5976
  * (URL 同步、业务快捷操作、自建图例…)封装成一份;返回值里的 destroy 会在 view.destroy() 时回调。
5403
5977
  */
5404
5978
  plugins?: GisViewPlugin[]
@@ -5482,6 +6056,8 @@ export interface GisViewOptions {
5482
6056
  onChannelDraft?: (payload: GisViewChannelDraftPayload) => void
5483
6057
  /** 草稿里每点一次发一条:step 1 拿到起点、step 2 拿到终点(线路结束),载荷与 onChannelDraft 相同 */
5484
6058
  onChannelDraftClick?: (payload: GisViewChannelDraftPayload) => void
6059
+ /** 动态装饰器草稿:鼠标在线路上跟随 / 移出 / 松手 ready,以及 update / commit / cancel */
6060
+ onDecorationDraft?: (payload: GisViewDecorationDraftPayload) => void
5485
6061
  /** 分组变化:拆分 / 合并 / 挪线 / 新建组 / 整份声明换(updateChannel),action.type 说明这一笔是什么 */
5486
6062
  onChannelGroupChange?: (payload: GisViewChannelGroupChangePayload) => void
5487
6063
  onCameraChange?: (camera: GisViewCamera) => void
@@ -5677,48 +6253,6 @@ export interface GisViewExportSelectionResult {
5677
6253
  lineIndexes: number[]
5678
6254
  }
5679
6255
 
5680
- /**
5681
- * exportSelectionData 的选项:选中口径与 exportSelection 完全一致(不给 points 就用当前选中集里的节点,
5682
- * 线路取两端都在导出集里的那些),但出的是一份份业务表口径的记录,按 parts 多选。
5683
- */
5684
- export interface GisViewExportSelectionDataOptions {
5685
- /** 要导出的节点(id / 下标 / `{ id }` / `{ index }`,单个或数组);缺省用当前选中集里的节点 */
5686
- points?: GisViewFeatureRef | GisViewFeatureRef[]
5687
- /** 要导出的线路:缺省取两端都在导出集里的那些(withLines: false 表示不要线路) */
5688
- lines?: GisViewFeatureRef | GisViewFeatureRef[]
5689
- /** 要导出的通道:缺省取成员里有导出线路的那些通道 */
5690
- channels?: GisViewFeatureRef | GisViewFeatureRef[]
5691
- /** 是否带上「两端都在这批节点里」的线路(含通道回线),缺省 true;显式给了 lines 时以 lines 为准 */
5692
- withLines?: boolean
5693
- /** 要哪几份(多选,见 GisViewExportPart);缺省四份都要,选了通道 / 线路会自动带上拐点 */
5694
- parts?: GisViewExportPart | GisViewExportPart[]
5695
- /** 拐点要不要连没编辑过的分组一起列(同 exportParallelGroups 的 all),缺省 false */
5696
- all?: boolean
5697
- /** 额外挂到结果上的字段(同导出数据的 extra) */
5698
- extra?: Record<string, unknown>
5699
- }
5700
-
5701
- /**
5702
- * exportSelectionData 的返回:只带上 parts 选中的那几份(选通道 / 线路时 parallelGroups 会自动在内),
5703
- * 每份与同名的分项导出同一口径 —— points 是 station_data 那一套、lines 是 line_data、
5704
- * channels 是 channel_data、parallelGroups 是 parallel_groups,直接回写业务表。
5705
- */
5706
- export interface GisViewExportSelectionDataResult extends GisViewExportMeta {
5707
- /** ok 为 false 时说明原因(没有选中的节点 / 没找到要导出的节点) */
5708
- reason: string | null
5709
- points?: GisViewStationRecord[]
5710
- lines?: GisViewLineRecord[]
5711
- channels?: GisViewChannelRecord[]
5712
- parallelGroups?: GisViewParallelGroup[]
5713
- /** 这次带了哪几份(view 口径的键名,含自动补上的 parallelGroups) */
5714
- parts: Array<'points' | 'lines' | 'channels' | 'parallelGroups'>
5715
- counts: { points: number; lines: number; channels: number; parallelGroups: number }
5716
- /** 导出用的节点 / 线路 / 通道下标(升序,可以直接交给别的接口继续用) */
5717
- pointIndexes: number[]
5718
- lineIndexes: number[]
5719
- channelIndexes: number[]
5720
- }
5721
-
5722
6256
  /** 定位一条线路 / 一条通道 / 一个分组:与 GisViewPointRef 同一种写法(id、下标或 `{ id }` / `{ index }`) */
5723
6257
  export type GisViewFeatureRef = string | number | { id: string | number } | { index: number }
5724
6258
 
@@ -5852,68 +6386,21 @@ export interface GisViewChannelRecord {
5852
6386
  [key: string]: unknown
5853
6387
  }
5854
6388
 
5855
- /** 导出节点数据(new.json 的 station_data 口径)的选项 */
5856
- export interface GisViewExportStationDataOptions extends GisViewExportFilterOptions {
5857
- /** 要不要带 new.json 顶上那四列四至范围(max_lat / min_lat / max_lon / min_lon),缺省 true */
5858
- box?: boolean
5859
- /** 要不要带 show_station_list / show_station_data(站内母线清单,new.json 里就在节点表隔壁),缺省 true */
5860
- showStation?: boolean
5861
- /** new.json 的 tc_file_path / warning_msg 两列,缺省是空串 / 空数组,也可以走 extra 给 */
5862
- tcFilePath?: string
5863
- warningMsg?: unknown[]
5864
- tc_file_path?: string
5865
- warning_msg?: unknown[]
5866
- }
5867
-
5868
- /** exportStationData 的返回:节点表 + new.json 顶上那几列 */
5869
- export interface GisViewExportStationDataResult extends GisViewExportMeta {
5870
- station_data: GisViewStationRecord[]
5871
- counts: { points: number }
5872
- max_lat?: number | null
5873
- min_lat?: number | null
5874
- max_lon?: number | null
5875
- min_lon?: number | null
5876
- show_station_list?: unknown[]
5877
- show_station_data?: unknown[][]
5878
- tc_file_path?: string
5879
- warning_msg?: unknown[]
5880
- }
6389
+ /** 内置的五档导出格式;自定义名字用 registerExportFormat 注册 */
6390
+ export type GisViewBuiltinExportFormat = 'view' | 'new' | 'test' | 'input' | 'full'
6391
+ /** exportData 认的格式名:内置五档,或注册过的自定义名字 */
6392
+ export type GisViewExportFormat = GisViewBuiltinExportFormat | (string & {})
5881
6393
 
5882
- /** exportPointData 的返回:test.json 的 point_data */
5883
- export interface GisViewExportPointDataResult extends GisViewExportMeta {
5884
- point_data: GisViewPointRecord[]
5885
- counts: { points: number }
5886
- }
5887
-
5888
- /** exportLineData 的返回:test.json 的 line_data */
5889
- export interface GisViewExportLineDataResult extends GisViewExportMeta {
5890
- line_data: GisViewLineRecord[]
5891
- counts: { lines: number }
5892
- }
6394
+ /** 导出范围:all 全量、viewport 当前视口、selection 当前选中集(exportData 的统一入口) */
6395
+ export type GisViewExportScope = 'all' | 'viewport' | 'selection'
5893
6396
 
5894
- /** exportChannelData 的返回:new.json 的 channel_data(counts.lines 是这些通道里回线的总数) */
5895
- export interface GisViewExportChannelDataResult extends GisViewExportMeta {
5896
- channel_data: GisViewChannelRecord[]
5897
- counts: { channels: number; lines: number }
5898
- }
5899
-
5900
- /** 导出拐点分组的选项 */
5901
- export interface GisViewExportParallelGroupsOptions extends GisViewExportFilterOptions {
5902
- /**
5903
- * 缺省 false:只出加过 / 拖过拐点的分组(与 getParallelGroups 同一份);
5904
- * true:把当前所有通道分组(以及通道外带折线的线路)都列出来,声明里原本就写了拐点的也在
5905
- */
5906
- all?: boolean
5907
- }
5908
-
5909
- /** exportParallelGroups 的返回:test.json 的 parallel_groups */
5910
- export interface GisViewExportParallelGroupsResult extends GisViewExportMeta {
5911
- parallel_groups: GisViewParallelGroup[]
5912
- counts: { parallelGroups: number; waypoints: number }
5913
- }
5914
-
5915
- /** 导出数据的选项:format 决定要哪一套列名,points / lines / channels 三个筛选搭着用 */
6397
+ /**
6398
+ * 导出数据的选项:`scope` 决定导哪一块,`format` 决定要哪一套列名,
6399
+ * `parts` 决定要哪些分项,points / lines / channels 三个筛选搭着用。
6400
+ */
5916
6401
  export interface GisViewExportDataOptions extends GisViewExportFilterOptions {
6402
+ /** 导出范围,缺省 'all';selected / visible 之类的同义词在运行时也认 */
6403
+ scope?: GisViewExportScope
5917
6404
  /**
5918
6405
  * 要哪一套:'view'(缺省,节点 / 线路 / 通道 / 拐点分组四份,JS 风格的键名)/
5919
6406
  * 'new'(new.json 口径的整份:station_data + channel_data + 四至范围那几列)/
@@ -5922,27 +6409,64 @@ export interface GisViewExportDataOptions extends GisViewExportFilterOptions {
5922
6409
  * updateData + updateOptions 回显,是回灌 / 存档用的那一档)/
5923
6410
  * 'full'(标准数据文档,见 GisViewDocument:format / version / points / lines / channels /
5924
6411
  * labelStates / view / filter 八列,与 createGisView / importData 的整份入参是同一份写法,
5925
- * 「导出 → 存下来 → 读回来 → 再导出」逐字节相同)
6412
+ * 「导出 → 存下来 → 读回来 → 再导出」逐字节相同);
6413
+ * 也可以是 registerExportFormat 注册过的自定义名字
5926
6414
  */
5927
- format?: 'view' | 'new' | 'test' | 'input' | 'full'
6415
+ format?: GisViewExportFormat
5928
6416
  /**
5929
6417
  * 要哪几份(多选,见 GisViewExportPart):不写是四份都要(老行为),写了只出选中的那几份;
5930
6418
  * 选了通道或线路会自动带上拐点。'new' 口径里线路折在 channel_data 里、'test' 口径里通道写在
5931
6419
  * 回线的 channel_id 列上,这两种口径下「要线路 / 通道」会带上对应那一份
5932
6420
  */
5933
6421
  parts?: GisViewExportPart | GisViewExportPart[]
5934
- /** format 为 'view' / 'test' 时拐点分组要不要连没编辑过的分组一起列(见 exportParallelGroups) */
6422
+ /** format 为 'view' / 'test' 时拐点分组要不要连没编辑过的分组一起列 */
5935
6423
  all?: boolean
5936
6424
  /** format 为 'new' 时 new.json 的 tc_file_path / warning_msg 两列 */
5937
6425
  tcFilePath?: string
5938
6426
  warningMsg?: unknown[]
6427
+ /** format 为 'new' 时要不要带四至范围(max_lat / min_lat / max_lon / min_lon),缺省带 */
6428
+ box?: boolean
6429
+ /** format 为 'new' 时要不要带 show_station_list / show_station_data,缺省带 */
6430
+ showStation?: boolean
6431
+ /** scope 为 'viewport' 时视口外扩的屏幕 CSS 像素,缺省 0 */
6432
+ margin?: number
6433
+ /** scope 为 'viewport' 时直接给一份世界矩形替掉当前视口 */
6434
+ rect?: GisViewBounds
5939
6435
  }
5940
6436
 
6437
+ /**
6438
+ * 自定义导出器拿到的上下文:document 已经按标准文档做过深拷贝、坐标归一与 JSON 安全,
6439
+ * counts 与 documentCounts(document) 同一份;warnings 可以继续追加,exportData 会统一走 onWarning。
6440
+ * 返回值就是 exportData 的返回值,必须是同步的普通数据(不能返回 Promise)。
6441
+ */
6442
+ export interface GisViewExportFormatContext {
6443
+ view: GisViewInstance
6444
+ document: GisViewDocument
6445
+ counts: GisViewDocumentCounts
6446
+ options: GisViewExportDataOptions & { format: string }
6447
+ parts: GisViewExportPart[]
6448
+ warnings: string[]
6449
+ }
6450
+
6451
+ /** 自定义导出器的函数签名;Result 由调用方按自己的 DTO 指定 */
6452
+ export type GisViewExportFormatAdapter<Result = unknown> = (context: GisViewExportFormatContext) => Result
6453
+
5941
6454
  /**
5942
6455
  * exportData 的返回:format 决定带上哪几组键(认键名就知道是哪一套)。
5943
6456
  * counts 四份都有,warnings 是没找到的 id 这类提示
5944
6457
  */
5945
6458
  export interface GisViewExportDataResult extends GisViewExportMeta {
6459
+ /** 这次实际用的导出范围 */
6460
+ scope?: GisViewExportScope
6461
+ /** scope 为 'selection' 时:成功为 null,没有可导出的节点时为原因 */
6462
+ reason?: string | null
6463
+ /** scope 为 'selection' 时导出的节点 / 线路 / 通道下标 */
6464
+ pointIndexes?: number[]
6465
+ lineIndexes?: number[]
6466
+ channelIndexes?: number[]
6467
+ /** scope 为 'viewport' 时这次筛用的世界矩形与屏幕像素外扩 */
6468
+ viewRect?: GisViewBounds
6469
+ margin?: number
5946
6470
  /**
5947
6471
  * format 为 'view'(缺省):节点 / 线路 / 通道(new.json 口径的业务记录);
5948
6472
  * format 为 'input':与 createGisView 入参同构的当前数据副本(拖过的点、改过的拐点、
@@ -5979,28 +6503,6 @@ export interface GisViewExportDataResult extends GisViewExportMeta {
5979
6503
  parts?: Array<'points' | 'lines' | 'channels' | 'parallelGroups'>
5980
6504
  }
5981
6505
 
5982
- /**
5983
- * exportViewportData 的选项:与 exportData 同一套写法,范围改由视口决定 ——
5984
- * points / lines / channels 这三个筛选这一档不认(写了也按视口来),要放宽 / 换范围用 margin / rect
5985
- */
5986
- export interface GisViewExportViewportOptions extends GisViewExportDataOptions {
5987
- /** 视口外再往外扩多少**屏幕 CSS 像素**:贴着边的一圈也带上(按当前 scale 换算),缺省 0 */
5988
- margin?: number
5989
- /** 直接给一份世界矩形替掉当前视口(写法同 getViewRect(),也认 listPoints / listLines 的 inView 那一份) */
5990
- rect?: GisViewBounds
5991
- }
5992
-
5993
- /** 视口导出多带的读数:这次筛用的世界矩形与屏幕像素外扩 */
5994
- export interface GisViewExportViewportMeta {
5995
- /** 这次筛用的世界矩形(含 margin 换算过来的外扩) */
5996
- viewRect: GisViewBounds
5997
- /** 实际生效的屏幕像素外扩,缺省 0 */
5998
- margin: number
5999
- }
6000
-
6001
- /** exportViewportData 的返回:exportData 那一份读数(format 决定带哪几组键)+ viewRect / margin 两条位置读数 */
6002
- export interface GisViewExportViewportResult extends GisViewExportDataResult, GisViewExportViewportMeta {}
6003
-
6004
6506
 
6005
6507
  /**
6006
6508
  * 标准数据文档的一份视图落位:相机那一列(`view.camera`,导出时写全,读回来就在同一屏)。
@@ -6223,6 +6725,34 @@ export interface GisViewSceneRegion {
6223
6725
  * 当前画面的矢量快照:屏幕坐标(CSS 像素)的纯数据,交给 buildSceneSvg 就是一份 SVG。
6224
6726
  * 画序与 WebGL 那一帧一致:背景 → 底图 → 区域 → 网格 → 线 → 点 → 背景点 → 装饰 → 拐点 → 抬层的点 → 标签。
6225
6727
  */
6728
+ /** 矢量快照里的扩展图形(屏幕坐标;href 是图片地址 / Canvas 的 PNG data URL) */
6729
+ export interface GisViewSceneGraphic {
6730
+ id: string
6731
+ type: GisViewGraphicType
6732
+ x: number
6733
+ y: number
6734
+ left: number
6735
+ top: number
6736
+ width: number
6737
+ height: number
6738
+ anchor: [number, number]
6739
+ rotation: number
6740
+ scale: [number, number]
6741
+ opacity: number
6742
+ d: string
6743
+ viewBox: [number, number, number, number]
6744
+ fill: string
6745
+ stroke: string
6746
+ strokeWidth: number
6747
+ lineCap: string
6748
+ lineJoin: string
6749
+ lineDash: number[]
6750
+ dashOffset: number
6751
+ fillRule: string
6752
+ href: string | null
6753
+ preserveAspectRatio: string
6754
+ }
6755
+
6226
6756
  export interface GisViewSceneSnapshot {
6227
6757
  width: number
6228
6758
  height: number
@@ -6233,6 +6763,7 @@ export interface GisViewSceneSnapshot {
6233
6763
  /** 网格(关了网格或带了透明背景时为 null) */
6234
6764
  grid: { d: string; color: string } | null
6235
6765
  regions: GisViewSceneRegion[]
6766
+ /** 数据线路与节点装饰连接线(连接线也画在节点 / 装饰之前) */
6236
6767
  lines: GisViewSceneLine[]
6237
6768
  points: GisViewSceneNode[]
6238
6769
  backgroundPoints: GisViewSceneNode[]
@@ -6240,6 +6771,8 @@ export interface GisViewSceneSnapshot {
6240
6771
  waypoints: GisViewSceneNode[]
6241
6772
  /** 选中 / 拖动中的节点(画在最上面) */
6242
6773
  raised: GisViewSceneNode[]
6774
+ /** 扩展图形(画在标签之前;直接读 engine.snapshotScene 时没有这一列) */
6775
+ graphics?: GisViewSceneGraphic[]
6243
6776
  labels: GisViewLabelBox[]
6244
6777
  }
6245
6778
 
@@ -6256,6 +6789,22 @@ export interface GisViewInstance {
6256
6789
  readonly el: HTMLElement
6257
6790
  readonly canvas: HTMLCanvasElement
6258
6791
  readonly gl: WebGL2RenderingContext | null
6792
+ /** 请求重画一帧:自定义 WebGL 层的数据源变了、组件自己不知道时调用 */
6793
+ requestRender(): GisViewInstance
6794
+ /**
6795
+ * 加一个 WebGL 自定义绘制层(同 id 覆盖):draw 在内置内容之后、最终画布上执行。
6796
+ * 返回卸载函数;层只影响画面,不参与拾取 / 场景解析 / 数据导出。
6797
+ * 同 id 后来被别的层覆盖时,旧卸载函数不会误删新层
6798
+ */
6799
+ addWebGLLayer(layer: GisViewWebGLLayer): () => void
6800
+ /** 改一个 WebGL 层(order / enabled / draw),返回改后的读数;id 不存在时 null */
6801
+ updateWebGLLayer(id: string | number, patch: Partial<GisViewWebGLLayer>): GisViewWebGLLayer | null
6802
+ /** 删一个 WebGL 层,返回删掉的读数;id 不存在时 null */
6803
+ removeWebGLLayer(id: string | number): GisViewWebGLLayer | null
6804
+ /** 清空全部 WebGL 层,返回清掉的条数 */
6805
+ clearWebGLLayers(): number
6806
+ /** 当前 WebGL 层读数(按 order 排好) */
6807
+ getWebGLLayers(): GisViewWebGLLayer[]
6259
6808
  updateOptions(options?: GisViewOptions, replace?: boolean): GisViewInstance
6260
6809
  /**
6261
6810
  * 改全局点样式的某几个字段(字段级合并,不写的保持原来那一份;传 null 清掉整份全局点样式):
@@ -6273,20 +6822,10 @@ export interface GisViewInstance {
6273
6822
  * 第三个参数给 channels 时连通道一起换 —— 切场景(场站与通道整批变了)一次换完、只发一条数据变更。
6274
6823
  * 也收单对象写法:`updateData({ points, lines, channels })` 只换给出的那几列 ——
6275
6824
  * 接口返回的数据先在调用方映射成这三列(见 demo 里的做法),再整份喂进来。
6825
+ * 只换通道声明时写 `updateData({ channels })`(场站与回线数据不动)。
6276
6826
  */
6277
6827
  updateData(points?: GisViewPoint[], lines?: GisViewLine[], channels?: GisViewChannel[]): GisViewInstance
6278
6828
  updateData(payload: GisViewDocumentSource): GisViewInstance
6279
- /**
6280
- * 整份换通道声明(回线怎么分组、骨架拐点在哪):场站与回线数据一个都不动,引擎按新声明重排一遍。
6281
- * 与 updateChannel 的分工:那一条是按 id 给某一条通道打补丁(定向),这一条是全换、点不出某一条;
6282
- * 声明里的 `lineIds` 同样是通道成员的整表 —— 落地前逐条与 `groups` 调和(写了非空 `lineIds`
6283
- * 就以它为准、`groups` 按它收窄;「只写 groups」的声明原样保留);
6284
- * 声明里没写分组 id 时引擎按「单组用通道 id、多组 通道id::序号」补,并把补好的分组(含拐点路径)与对齐后的成员表
6285
- * 写回数据副本;声明里认不出的成员 id、重名的分组 id 各报一句 warning,不静默
6286
- */
6287
- updateChannels(channels?: GisViewChannel[]): GisViewInstance
6288
- updatePoints(points?: GisViewPoint[]): GisViewInstance
6289
- updateLines(lines?: GisViewLine[]): GisViewInstance
6290
6829
  /**
6291
6830
  * 整份喂回一份数据 / 一份标准文档(`exportData` 的五种格式都认,最标准的是 `format: 'full'` 那一份):
6292
6831
  * 顶层出哪一列就应用哪一列,没出的列一个都不动 —— points / lines / channels / labelStates / view / filter
@@ -6372,6 +6911,20 @@ export interface GisViewInstance {
6372
6911
  resetLabel(kind: GisViewLabelKind, ref: GisViewFeatureRef, labelId?: string): boolean
6373
6912
  /** 恢复某一类(不写则两类都恢复)标签的默认:返回清掉几条状态 */
6374
6913
  resetLabels(kind?: GisViewLabelKind): number
6914
+ /** 新增一个扩展图形(世界坐标上的 SVG 路径 / 图片 / Canvas):id 已存在时按更新覆盖 */
6915
+ addGraphic(graphic: GisViewGraphic): GisViewGraphic | null
6916
+ /** 批量新增扩展图形:返回实际加进去的读数数组 */
6917
+ addGraphics(graphics: GisViewGraphic | GisViewGraphic[]): GisViewGraphic[]
6918
+ /** 改一个扩展图形(patch 与创建写法一致):id 不存在时返回 null */
6919
+ updateGraphic(id: string | number, patch: Partial<GisViewGraphic>): GisViewGraphic | null
6920
+ /** 删一个扩展图形:返回删掉的读数;id 不存在时返回 null */
6921
+ removeGraphic(id: string | number): GisViewGraphic | null
6922
+ /** 清空全部扩展图形:返回清掉的条数 */
6923
+ clearGraphics(): number
6924
+ /** 读一个扩展图形(副本,没有时 null) */
6925
+ getGraphic(id: string | number): GisViewGraphic | null
6926
+ /** 现在有哪些扩展图形(按 zIndex、再按加入顺序) */
6927
+ getGraphics(): GisViewGraphic[]
6375
6928
  updateBackground(background?: GisViewBackground): GisViewInstance
6376
6929
  /**
6377
6930
  * 把当前画面导出成图片(data URL):画布内容 + DOM 标签合成到一张 2D 画布上。
@@ -6386,46 +6939,18 @@ export interface GisViewInstance {
6386
6939
  */
6387
6940
  exportSelection(options?: GisViewExportSelectionOptions): Promise<GisViewExportSelectionResult>
6388
6941
  /**
6389
- * 导出「选中的这一撮」的数据(分项多选):选中口径与 exportSelection 一致,
6390
- * 出的是一份份业务表口径的记录(points = station_data、lines = line_data、channels = channel_data、
6391
- * parallelGroups = parallel_groups),选了通道 / 线路自动带上拐点;缺省四份都出
6392
- */
6393
- exportSelectionData(options?: GisViewExportSelectionDataOptions): GisViewExportSelectionDataResult
6394
- /**
6395
- * 一次把数据按概念分好:节点 / 线路 / 通道 / 拐点分组四份互不混在一起,一次拿走(都是拷贝,改它不影响组件内部那一份)。
6942
+ * 统一导出入口:`scope` 决定导全量(all,缺省)/ 视口(viewport)/ 选中(selection),
6943
+ * `parts` 决定要场站 / 线路 / 通道 / 拐点里的哪几份,其余筛选与 format 照旧。
6944
+ * 一次把数据按概念分好:节点 / 线路 / 通道 / 拐点分组四份互不混在一起(都是拷贝,改它不影响组件内部那一份)。
6396
6945
  * 缺省给 { points, lines, channels, parallelGroups };format: 'new' 给 new.json 口径的整份
6397
6946
  * (station_data + channel_data + 四至范围那几列);format: 'test' 给 test.json 口径的整份
6398
6947
  * (point_data + line_data + parallel_groups);format: 'full' 给一份标准数据文档(单独一条重载,
6399
- * 返回 GisViewDocument 本身,八列齐全、没有 ok / counts / warnings 这些读数)
6948
+ * 返回 GisViewDocument 本身,八列齐全、没有 ok / counts / warnings 这些读数);
6949
+ * format 是 registerExportFormat 注册过的名字时,走自定义导出器,返回它的结果(可写泛型指定 DTO)
6400
6950
  */
6401
6951
  exportData(options: GisViewExportDataOptions & { format: 'full' }): GisViewDocument
6952
+ exportData<Result = GisViewExportDataResult>(options: GisViewExportDataOptions & { format: string }): Result
6402
6953
  exportData(options?: GisViewExportDataOptions): GisViewExportDataResult
6403
- /**
6404
- * 导出**视口内**的数据:节点 / 线路 / 通道先按当前可视范围(getViewRect())筛一遍再出 ——
6405
- * 可见判定与图上画出来的那一份、与 listPoints / listLines 的 inView 完全一致(被筛选 / 隐藏、
6406
- * 发散渲染还没铺到的不算);通道取「成员回线有一条在视口里」的那些,分组一起跟着走。
6407
- * 其余参数与 exportData 同写(format / parts / labels / box…),margin 是屏幕 CSS 像素的外扩、
6408
- * rect 可以直接给一份世界矩形;返回里多带 viewRect / margin 两条读数
6409
- */
6410
- exportViewportData(options: GisViewExportViewportOptions & { format: 'full' }): GisViewDocument & GisViewExportViewportMeta
6411
- exportViewportData(options?: GisViewExportViewportOptions): GisViewExportViewportResult
6412
- /**
6413
- * 导出节点数据(new.json 的 station_data 口径):id / 名称 / 电压 / 经纬度 + 站内母线那几列
6414
- * (bus_name_list / bus_id_list / trafo_* / feedin_relation_*),其余业务列原样透传;
6415
- * 一并给 new.json 顶上那几列:四至范围(box,缺省给)与 show_station_list / show_station_data
6416
- */
6417
- exportStationData(options?: GisViewExportStationDataOptions): GisViewExportStationDataResult
6418
- /** 导出节点数据(test.json 的 point_data 口径):同一份节点换一套列名(带 zone_id / zone_name) */
6419
- exportPointData(options?: GisViewExportFilterOptions): GisViewExportPointDataResult
6420
- /**
6421
- * 导出线路数据(test.json 的 line_data 口径):通道回线带上 channel_id / channel_name /
6422
- * parallel_group_id 与第几回,coords_list 是当下画出来的折线(含平行偏移)
6423
- */
6424
- exportLineData(options?: GisViewExportFilterOptions): GisViewExportLineDataResult
6425
- /** 导出通道数据(new.json 的 channel_data 口径):一条通道一行,回线在 line_data 里,整条通道的路由在 coords 里 */
6426
- exportChannelData(options?: GisViewExportFilterOptions): GisViewExportChannelDataResult
6427
- /** 导出拐点分组(test.json 的 parallel_groups 口径):与通道数据分开取,直接回写业务数据 */
6428
- exportParallelGroups(options?: GisViewExportParallelGroupsOptions): GisViewExportParallelGroupsResult
6429
6954
  /**
6430
6955
  * 当前画面的矢量快照(屏幕坐标的线 / 点 / 标签 / 背景 / 网格):导出 SVG 或自拼别的矢量格式时用它。
6431
6956
  * 与 WebGL 那一帧读同一份解析结果,所以颜色 / 线宽 / 线型与画面一致;引擎还没准备好时是 null
@@ -6471,11 +6996,6 @@ export interface GisViewInstance {
6471
6996
  setMinimapZoom(zoom: number): GisViewInstance
6472
6997
  /** 在当前倍数上再乘一个系数,origin 是鹰眼图内的 CSS 像素锚点,缺省取小图中心 */
6473
6998
  zoomMinimapBy(factor: number, origin?: [number, number]): GisViewInstance
6474
- /**
6475
- * 换动画效果的整体配置(写法与 options.effects 一致,见 GisViewEffectsOptions):
6476
- * 样式类快路径 —— 重解析要素、不重铺数据,逐要素的 effect 在这一次重解析里定下来。
6477
- */
6478
- setEffects(effects: GisViewEffectsInput): GisViewInstance
6479
6999
  /** 当前生效的动画效果配置(归一化之后的读数):没配的那一层是 null */
6480
7000
  getEffects(): GisViewEffectsReadout
6481
7001
  /**
@@ -6582,12 +7102,6 @@ export interface GisViewInstance {
6582
7102
  * 「点了一条回线,想知道它属于哪条通道 / 哪一组」用它一句问清。
6583
7103
  */
6584
7104
  getLineChannel(ref: GisViewFeatureRef): GisViewLineChannelInfo | null
6585
- /**
6586
- * 接口选中(换一份选中集):单选传 id,多选传数组,null / 空数组清空。
6587
- * 写法与 selectFeatures 一致 —— 数组里可以混着写 id 与对象(见 GisViewSelectionRef),
6588
- * options.mode 也给同一份('add' / 'toggle' / 'remove')
6589
- */
6590
- select(refs: GisViewSelectionRefs, options?: GisViewSelectOptions): GisViewInstance
6591
7105
  /**
6592
7106
  * 让一批东西变成选中状态(接口选中):与点击选中走同一份 state,因此 getSelections / getSelectionData
6593
7107
  * getSelectionData 立刻就能读回来。认这些写法(见 GisViewSelectionRef):
@@ -6602,7 +7116,7 @@ export interface GisViewInstance {
6602
7116
  * 取消选中:写法与 selectFeatures 完全一样(节点 / 通道 / 线路,一批可以混着写),
6603
7117
  * 把这些从当前选中集里去掉,其余选中原样留着 —— `deselect('p-1')` 取消一个节点、
6604
7118
  * `deselect({ type: 'channel', channelId: 'channel-a' })` 取消整条通道的回线。
6605
- * 一个目标都不给(不传 / 传 null)等于取消全部(与 select(null) 同一件事),
7119
+ * 一个目标都不给(不传 / 传 null)等于取消全部(与 selectFeatures(null) 同一件事),
6606
7120
  * 传空数组是「没有目标」,什么都不做;认不出来的条目跳过
6607
7121
  */
6608
7122
  deselect(refs?: GisViewSelectionRefs): GisViewInstance
@@ -6619,7 +7133,7 @@ export interface GisViewInstance {
6619
7133
  * 当前画布上选中的数据(一次取全):ids / count 与各类型条数(通道回线按通道算一个)、
6620
7134
  * 要素本身 points / lines / channels 三个数组、下标清单 pointIndexes / lineIndexes、
6621
7135
  * items(与 getSelections() 同一份)与世界包围盒 bounds(空选中时 null)。
6622
- * 单击、Ctrl 多选、框选与接口选中(select / selectFeatures / selectInBox)都是同一份 state,不挑选中来源;
7136
+ * 单击、Ctrl 多选、框选与接口选中(selectFeatures / selectInBox)都是同一份 state,不挑选中来源;
6623
7137
  * bounds 走一次 getElementBounds(十万级选中下约 5 ms),只想问「选了哪几个」用 getSelections() 更省
6624
7138
  */
6625
7139
  getSelectionData(): GisViewSelectionData
@@ -6689,10 +7203,6 @@ export interface GisViewInstance {
6689
7203
  * 可以改、也可以 cancel()),组件随后把数据并起来;false 让拖动的节点与跟随它的线路回原位(两站都能取消)
6690
7204
  */
6691
7205
  resolvePointMerge(confirmed?: boolean, options?: GisViewPointMergeConfirmOptions): GisViewPointMergePayload | null
6692
- /** 确认待确认的合并(resolvePointMerge(true) 的别名):可指定保留来源 / 目标并改写最终节点 */
6693
- confirmPointMerge(options?: GisViewPointMergeConfirmOptions): GisViewPointMergePayload | null
6694
- /** 取消待确认的合并(resolvePointMerge(false) 的别名):拖动的节点回原位,数据不动 */
6695
- cancelPointMerge(): GisViewPointMergePayload | null
6696
7206
  /** 合并落地之后收掉引擎里的合并状态(mergePoints 已经调过,自己接界面时用得到) */
6697
7207
  commitPointMerge(): boolean
6698
7208
  /** 合并并不了:把拖动的节点还原回原位并收掉状态(silent 为 true 时不补发 cancel 载荷) */
@@ -6814,6 +7324,8 @@ export interface GisViewInstance {
6814
7324
  beginAddChannel(options?: GisViewChannelDraftOptions): GisViewInstance
6815
7325
  /** 当前新增通道草稿:两个节点的信息与可选方案,没有草稿时为 null */
6816
7326
  getAddChannelDraft(): GisViewChannelDraftPayload | null
7327
+ /** 改当前草稿的预览样式(字段级合并,传 null 回到全局 channelDraftStyle);没有草稿时什么也不做 */
7328
+ updateAddChannelStyle(patch?: GisViewChannelDraftStyle | null): GisViewInstance
6817
7329
  /** 开下一段草稿:连续模式落地时内部自动调用,也可以手动调(没有草稿就按 options 重新进来) */
6818
7330
  continueAddChannel(options?: GisViewChannelDraftOptions): GisViewInstance
6819
7331
  /** 取消新增通道(草稿期间按 Esc 等价;会补一条 phase: 'cancel') */
@@ -6902,7 +7414,7 @@ export interface GisViewInstance {
6902
7414
  * (id / index 之外的字段就是这一条的补丁),或者 `patchPoints(['a', 'b'], { status: 1 })`
6903
7415
  * 把同一份补丁盖到一批节点上。认不出来的记进 skipped,不影响其余条目;
6904
7416
  * 返回 `{ ok, indexes, items, count, skipped }`,只记一条历史、只发一条 updatePoints 数据变更。
6905
- * 与 updatePoints(points) 的分工:那一条是整份替换节点数据,这里只动点到的这几条
7417
+ * 与 `updateData({ points })` 的分工:那一条是整份替换节点数据,这里只动点到的这几条
6906
7418
  */
6907
7419
  patchPoints(entries: GisViewUpdateItemEntry<GisViewPoint> | Array<GisViewUpdateItemEntry<GisViewPoint>>, patch?: Partial<GisViewPoint>): GisViewUpdateItemsOutcome<GisViewPoint>
6908
7420
  /**
@@ -6912,11 +7424,11 @@ export interface GisViewInstance {
6912
7424
  */
6913
7425
  patchLines(entries: GisViewUpdateItemEntry<GisViewLine> | Array<GisViewUpdateItemEntry<GisViewLine>>, patch?: Partial<GisViewLine>): GisViewUpdateItemsOutcome<GisViewLine>
6914
7426
  /**
6915
- * 改某个通道的数据(分组、宽度、端点等)并重渲染(与整份换声明的 updateChannels 一对):
7427
+ * 改某个通道的数据(分组、宽度、端点等)并重渲染(与整份换声明的 `updateData({ channels })` 一对):
6916
7428
  * 成员表没变时只把成员回线换成新几何,成员表换了(改 lineIds)整份重解析。
6917
7429
  * 补丁里的 lineIds 是通道成员的整表 —— 增删线路就是改它:写回声明前与 groups 调和
6918
7430
  * (不在表里的成员从各组剔掉、空组去掉,表里没落进组的成员补进第一组,组剔完回「整条通道一组」);
6919
- * 建视图 / updateChannels / updateOptions / updateData / importData 这些整份提交的入口逐条同一份口径;
7431
+ * 建视图 / updateOptions / updateData / importData 这些整份提交的入口逐条同一份口径;
6920
7432
  * 补丁里写 groups / lineIds 时写完把引擎那边的最终声明(分组 id、拐点路径)写回数据副本、
6921
7433
  * 成员表对齐到各组(拆分 / 挪组之后 lineIds 仍覆盖得上),
6922
7434
  * 并补一条 channelGroups 变更(与 splitChannelGroups / mergeChannelGroups 同一份口径),
@@ -6936,24 +7448,10 @@ export interface GisViewInstance {
6936
7448
  * 不属于这条通道的条目跳过并报一句 warning(同一个条目只提醒一次)
6937
7449
  */
6938
7450
  updateChannel(id: string | number, patch: Partial<GisViewChannel>, linePatches?: GisViewChannelLinePatch | GisViewChannelLinePatch[], lineIds?: string | number | Array<string | number>): GisViewInstance
6939
- /**
6940
- * 逐要素的细粒度改法:一个方法只改一样东西,改完就走 updatePoint / updateLine / updateChannel
6941
- * 的定向更新那条路(只重排受影响的一小片、只发一条数据变更、只落一步历史)。
6942
- * 要素没找到时不抛错:发一条 warning(同一个 id 只提醒一次)并原样返回,链式调用不断。
6943
- */
6944
- /** 只改一个节点的屏幕大小(CSS 像素,再乘 pointSizeScale 与缩放档位) */
6945
- setPointSize(id: string | number, size: number): GisViewInstance
6946
- /** 只换一个节点的图标(内置形状 / 图片 / 自定义 SVG):传 null 清掉逐点符号,回落到规则与 pointStyle */
6947
- setPointSymbol(id: string | number, symbol: GisViewSymbolInput | null): GisViewInstance
6948
- /** 只改一个节点的填充色(悬停 / 选中样式与热力图仍然压过它) */
6949
- setPointColor(id: string | number, color: string): GisViewInstance
7451
+ /** 逐要素的复合改法:同时处理多种字段、通道分组或成员回线时用这些入口;单项字段直接用 updatePoint / updateLine / updateChannel */
6950
7452
  /** 挪一个节点:`movePoint('n1', { x, y })` / `movePoint('n1', [x, y])` / `movePoint('n1', x, y)` 都认,绑定线路与锚定通道跟着重排 */
6951
7453
  movePoint(id: string | number, coordinate: GisViewCoordinate): GisViewInstance
6952
7454
  movePoint(id: string | number, x: number, y: number): GisViewInstance
6953
- /** 只改一条线路的线宽(CSS 像素,再乘 lineWidthScale) */
6954
- setLineWidth(id: string | number, width: number): GisViewInstance
6955
- /** 只改一条线路的颜色 */
6956
- setLineColor(id: string | number, color: string): GisViewInstance
6957
7455
  /** 整份换一条线路的拐点:只写中间拐点、不含首尾两端(单个坐标 = 只留一个拐点,空数组 = 拉直),两端按节点 / start / end 补齐;通道里的回线改的是它所在分组的骨架 */
6958
7456
  setLineWaypoints(id: string | number, coordinates: GisViewCoordinate | GisViewCoordinate[]): GisViewInstance
6959
7457
  /** 一条线路上挂着的装饰(图片 / SVG 标记)清单:要素没找到时给空数组,给的是副本 */
@@ -6966,20 +7464,32 @@ export interface GisViewInstance {
6966
7464
  updateLineDecoration(id: string | number, decorationIndex: number, patch: Partial<GisViewLineDecoration>): GisViewLineDecoration | null
6967
7465
  /** 摘掉一条线路上的某一个装饰(剩下的保持原顺序):返回被摘掉的那一条,没找到返回 null */
6968
7466
  removeLineDecoration(id: string | number, decorationIndex: number): GisViewLineDecoration | null
6969
- /**
6970
- * 只改一条通道的宽度(世界单位;tangent 模式下是最外侧两条回线中心的间距)。
6971
- * 通道默认按两端节点尺寸取宽(nodeWidth 系数),那种模式下这一项只在两端没挂节点时生效,
6972
- * 「调了没反应」先 setChannelNodeWidth(id, 0) 关掉自动取宽
6973
- */
6974
- setChannelWidth(id: string | number, width: number): GisViewInstance
6975
- /** 只改一条通道「按两端节点尺寸取宽」的系数:1 = 回线铺满节点(缺省)、0 = 关掉自动取宽改用通道自己的 width */
6976
- setChannelNodeWidth(id: string | number, nodeWidth: number): GisViewInstance
6977
- /** 只改一条通道两端的内收(占通道宽度,负数外收;传 null 回默认「按线宽收」),只影响 offsetMode 为 inset 的排列 */
6978
- setChannelInset(id: string | number, inset: number | null): GisViewInstance
6979
- /** 只改一条通道两端切点往节点里的内收(CSS 像素):正数内收、负数外收、0 = 切点落在节点边上、null = 按回线线宽收 */
6980
- setChannelTangentInset(id: string | number, tangentInset: number | null): GisViewInstance
6981
- /** 只改一条通道的名称:悬停提示 / 标签模板的 `{name}`、搜索与自建面板都取它(传 null 摘掉名称) */
6982
- setChannelName(id: string | number, name: string | number | null): GisViewInstance
7467
+ /** 一个节点上挂着的装饰清单:节点没找到时给空数组,给的是副本 */
7468
+ getPointDecorations(id: string | number): GisViewPointDecoration[]
7469
+ /** 整份换一个节点的装饰清单(空数组 = 全摘掉),写法与 points[].decorations 一致 */
7470
+ setPointDecorations(id: string | number, decorations: GisViewPointDecoration[]): GisViewInstance
7471
+ /** 给一个节点加一个装饰(追加在末尾):返回加进去的那一条,节点没找到 / 写法不对时返回 null */
7472
+ addPointDecoration(id: string | number, decoration: GisViewPointDecoration): GisViewPointDecoration | null
7473
+ /** 改一个节点上的某一个装饰(按 decorations 的顺序数,只合并这一条的字段):返回改完的那一条,没找到返回 null */
7474
+ updatePointDecoration(id: string | number, decorationIndex: number, patch: Partial<GisViewPointDecoration>): GisViewPointDecoration | null
7475
+ /** 摘掉一个节点上的某一个装饰(剩下的保持原顺序):返回被摘掉的那一条,没找到返回 null */
7476
+ removePointDecoration(id: string | number, decorationIndex: number): GisViewPointDecoration | null
7477
+ /**
7478
+ * 动态装饰器模式:`target` 决定命中线路 / 节点 / 两类同时;开启后鼠标移到目标附近出现临时图标,
7479
+ * 移出目标立即消失;左键松开仍命中才发 `decorationDraft` 的 ready(空白处 / 不允许的目标不发)。
7480
+ * 临时图标不写数据:确认调 `commitDecorationDraft`(整批一次 dataChange + 一条历史),取消调 `cancelDecorationDraft`。
7481
+ * 线路:`parallel` 决定是否跟着切向转,`scope` 取 'line' / 'group' / 'channel' 决定挂到哪些线路。
7482
+ * 节点:`placement` 取 offset / fixed / pointer,`connector` 决定是否从节点中心画连接线。
7483
+ */
7484
+ beginDecorationDraft(options?: GisViewDecorationDraftOptions): GisViewDecorationDraftPayload | null
7485
+ /** 当前草稿读数(与 onDecorationDraft 同一份;没有草稿时 null) */
7486
+ getDecorationDraft(): GisViewDecorationDraftPayload | null
7487
+ /** 改草稿的图标 / 大小 / 方向 / 作用域:命中中的预览与后续提交都用新值 */
7488
+ updateDecorationDraft(patch?: Partial<GisViewDecorationDraftOptions>): GisViewDecorationDraftPayload | null
7489
+ /** 把当前假装饰转成真实数据:逐条追加 decorations,整批一次 dataChange、一条历史 */
7490
+ commitDecorationDraft(overrides?: Partial<GisViewDecorationDraftOptions> & { position?: number }): GisViewDecorationCommitResult
7491
+ /** 取消当前假装饰(Esc 等价):只清预览并发 cancel,数据一个字节都不动 */
7492
+ cancelDecorationDraft(options?: { originalEvent?: Event | null }): GisViewDecorationDraftPayload | null
6983
7493
  /** 只改一条通道的回线线宽:成员回线与通道声明一起改(一次 batch,只发一条数据变更、只落一步历史) */
6984
7494
  setChannelLineWidth(id: string | number, lineWidth: number): GisViewInstance
6985
7495
  /** 整份换一条通道的逐回线颜色:成员回线与通道声明一起改,颜色不够时按顺序循环取,只给一个就整条通道一个色 */
@@ -6991,7 +7501,6 @@ export interface GisViewInstance {
6991
7501
  * 完整格式 `{ points, lines, cascade, worker }`;只筛节点时可以简写成节点条件本身。
6992
7502
  */
6993
7503
  setFilter(filter: GisViewFilterInput | null): GisViewInstance
6994
- clearFilter(): GisViewInstance
6995
7504
  /** 当前筛选条件(简写已经归一成 `{ points: 条件 }`),没设过返回 null */
6996
7505
  getFilter(): GisViewFilter | null
6997
7506
  /** 最近一次筛选结果:Worker 计算时在结果回来之后才会有值 */
@@ -7001,7 +7510,7 @@ export interface GisViewInstance {
7001
7510
  /**
7002
7511
  * 相对上一次对账,位置变过的节点(拖动 / updatePoint / patchPoints / 撤销都算):按 id 去重,
7003
7512
  * 返回 `{ index, id, x, y, item }` 的数组。被删掉的节点不在返回里(账本顺手清掉),
7004
- * 整份换数据(updateData / updatePoints / updateOptions 里换 points)之后以新数据为基准。
7513
+ * 整份换数据(updateData / updateOptions 里换 points)之后以新数据为基准。
7005
7514
  */
7006
7515
  getMovedPoints(): GisViewMovedPoint[]
7007
7516
  /**
@@ -7067,14 +7576,12 @@ export interface GisViewInstance {
7067
7576
  nearestLineAt(x: number, y: number, options?: GisViewNearestLineOptions): GisViewNearestLine | null
7068
7577
  /**
7069
7578
  * 拖拽落点预览:拖拽期间就把「松手之后会长成什么」按规则画到地图上,返回解析后的读数
7070
- * (图标尺寸 / 颜色 / 符号、线宽…);传 null 或调 clearDropPreview() 清掉。
7579
+ * (图标尺寸 / 颜色 / 符号、线宽…);传 null 清掉。
7071
7580
  * 预览与落地走同一条样式链、同一个符号 store,因此读数里的 size 与落地后 getPointStyle() 一个是同一个数
7072
7581
  */
7073
7582
  setDropPreview(preview: GisViewDropPreviewInput | null): GisViewDropPreview | null
7074
7583
  /** 当前落点预览的读数(没有预览时 null) */
7075
7584
  getDropPreview(): GisViewDropPreview | null
7076
- /** 清掉落点预览:与 setDropPreview(null) 同一条路 */
7077
- clearDropPreview(): GisViewInstance
7078
7585
  /* 事件订阅 / 功能开关 / 历史:自建界面直接接的三个入口 */
7079
7586
  /**
7080
7587
  * 订阅事件(与 options 里的回调同一条,同一个事件可以挂多条):返回取消订阅的函数。
@@ -7175,6 +7682,8 @@ export interface GisViewEngineOptions {
7175
7682
  channelGroupMaxLines?: number
7176
7683
  /** 新增通道草稿线的样式(跟随光标的那条预览线) */
7177
7684
  channelDraftStyle?: GisViewChannelDraftStyle
7685
+ /** WebGL 自定义层:与 GisViewOptions.webglLayers 同一份写法 */
7686
+ webglLayers?: GisViewWebGLLayer[]
7178
7687
  background?: GisViewBackground
7179
7688
  pointStyle?: GisViewPointStyle
7180
7689
  lineStyle?: GisViewLineStyle
@@ -7272,7 +7781,7 @@ export interface GisViewEngineOptions {
7272
7781
  shortcuts?: GisViewShortcuts
7273
7782
  /** 复制节点的配置(**缺省关**:写了才算开):开关、落点偏移、id 生成与数据定制 */
7274
7783
  copy?: GisViewCopyOptions
7275
- /** 合并节点的配置(**缺省关**:写了才算开):开关、碰撞容差、确认方式与数据合并规则 */
7784
+ /** 合并节点的配置(**缺省关**:写了才算开):开关、触发时机、像素容差、确认方式与数据合并规则 */
7276
7785
  merge?: GisViewMergeOptions
7277
7786
  /** 是否允许编辑拐点,**缺省关** */
7278
7787
  waypointEditable?: boolean
@@ -7316,6 +7825,8 @@ export interface GisViewEngineOptions {
7316
7825
  onChannelDraft?: (payload: GisViewChannelDraftPayload) => void
7317
7826
  /** 草稿里每点一次发一条:step 1 拿到起点、step 2 拿到终点(线路结束) */
7318
7827
  onChannelDraftClick?: (payload: GisViewChannelDraftPayload) => void
7828
+ /** 动态装饰器草稿:鼠标在线路上跟随 / 移出 / 松手 ready,以及 update / commit / cancel */
7829
+ onDecorationDraft?: (payload: GisViewDecorationDraftPayload) => void
7319
7830
  /** 分组变化:拆分 / 合并 / 挪线 / 新建组 / 整份声明换(updateChannel) */
7320
7831
  onChannelGroupChange?: (payload: GisViewChannelGroupChangePayload) => void
7321
7832
  onStats?: (stats: GisViewEngineStats) => void
@@ -7370,6 +7881,8 @@ export interface GisViewEngine {
7370
7881
  getParallelGroups(): GisViewParallelGroup[]
7371
7882
  /** 通道运行时状态:骨架、回线偏移与每条回线的折线 */
7372
7883
  getChannels(): GisViewChannelInfo[]
7884
+ /** 单条通道运行时状态:只复制这一组;channelId 找不到时可按 channels 下标兜底 */
7885
+ getChannel(channelId?: string | number | null, channelIndex?: number): GisViewChannelInfo | null
7373
7886
  /** 通道成员表:成员回线下标与各自的横向偏移,不复制几何(自建覆盖层按通道分流绘制用它) */
7374
7887
  getChannelMembers(): GisViewChannelMembers[]
7375
7888
  /** 通道分组现状:不传 channelId 返回所有分组 */
@@ -7413,6 +7926,8 @@ export interface GisViewEngine {
7413
7926
  chain?: boolean
7414
7927
  kind?: 'channel' | 'line'
7415
7928
  circuits?: number
7929
+ /** 换这一段草稿的预览样式(字段级合并;null 回到全局 channelDraftStyle,不传就沿用) */
7930
+ channelDraftStyle?: GisViewChannelDraftStyle | null
7416
7931
  /** 换一份逐条回线的属性(不传就沿用这一段草稿原来的) */
7417
7932
  linePropsByMember?: Array<Partial<GisViewLine> | undefined>
7418
7933
  /** 换这一段草稿的交接模式(不传就沿用) */
@@ -7425,6 +7940,12 @@ export interface GisViewEngine {
7425
7940
  cancelChannelDraft(options?: { silent?: boolean }): GisViewChannelDraftPayload | null
7426
7941
  /** 静默收掉草稿:提交之后调用,不发取消事件 */
7427
7942
  clearChannelDraft(): void
7943
+ /** 动态装饰器草稿:开启 / 改选项 / 取读数 / 交出当前结果(不写数据)/ 取消 */
7944
+ beginDecorationDraft(options?: GisViewDecorationDraftOptions): GisViewDecorationDraftPayload | null
7945
+ getDecorationDraft(): GisViewDecorationDraftPayload | null
7946
+ updateDecorationDraft(patch?: Partial<GisViewDecorationDraftOptions>): GisViewDecorationDraftPayload | null
7947
+ takeDecorationDraft(overrides?: Partial<GisViewDecorationDraftOptions> & { position?: number }): GisViewDecorationDraftPayload | null
7948
+ cancelDecorationDraft(options?: { originalEvent?: Event | null }): GisViewDecorationDraftPayload | null
7428
7949
  /** 单个节点的定向更新:只重解析这一个节点,绑定线 / 锚定通道跟着重排;结构变了返回 true(调用方此时看得到整份重排) */
7429
7950
  updatePoint(index: number, item: GisViewPoint): boolean
7430
7951
  /** 单条线路的定向更新:只重排这一条;身份 / 绑定变了时整份重排并返回 true */
@@ -7503,7 +8024,7 @@ export interface GisViewEngine {
7503
8024
  */
7504
8025
  snapshotScene(options?: GisViewSceneSnapshotOptions): GisViewSceneSnapshot
7505
8026
  getStats(): GisViewEngineStats
7506
- /** 换动画效果的整体配置(与组件实例的 setEffects 同一条路) */
8027
+ /** 换动画效果的整体配置(与组件实例的 updateOptions({ effects }) 同一条路) */
7507
8028
  setEffects(effects: GisViewEffectsInput): void
7508
8029
  /** 当前生效的动画效果配置(归一化之后的读数) */
7509
8030
  getEffects(): GisViewEffectsReadout
@@ -7747,9 +8268,6 @@ export declare const createGisEventBus: (host?: GisViewEventBusHost) => GisViewE
7747
8268
  /** 全部可订阅事件名(顺序与组件一致,末尾的 `'*'` 表示「全部事件」) */
7748
8269
  export declare const EVENT_NAMES: GisViewEventNameInput[]
7749
8270
 
7750
- /** 把任意条件输入编成一个判定函数:给不经过视图的批量过滤复用同一套条件语言 */
7751
- export declare const createConditionMatcher: (input: GisViewConditionInput) => (item: unknown, index?: number) => boolean
7752
-
7753
8271
  /** 筛选完整格式的保留键:顶层出现其中之一就不再按「只筛节点」的简写解释 */
7754
8272
  export declare const FILTER_FORM_KEYS: string[]
7755
8273
 
@@ -7847,6 +8365,23 @@ export declare const normalizeDocument: (input: unknown, options?: GisViewNormal
7847
8365
  /** 文档里各列有多少条(拐点 = 线路 path 的中间顶点 + 各分组 path) */
7848
8366
  export declare const documentCounts: (document: GisViewDocument | null | undefined) => GisViewDocumentCounts
7849
8367
 
8368
+ /* ---------- 自定义导出格式(export-formats.js) ---------- */
8369
+
8370
+ /** 注册一个同步导出器;内置名(含大小写变体)、空名或非函数返回 false,同一个自定义名重复注册以后一次为准 */
8371
+ export declare const registerExportFormat: <Result = unknown>(name: string, adapter: GisViewExportFormatAdapter<Result>) => boolean
8372
+ /**
8373
+ * 带作用域地定义自定义导出格式:注册成功返回清理函数,适合在插件 / 组件挂载时注册、卸载时注销。
8374
+ * 清理函数只在当前注册项仍是自己那次定义时删除(同名重复注册且 adapter 相同也算新的一次,不会误删后来覆盖注册的同名适配器),重复调用返回 false。
8375
+ * 名字为空或撞内置保留格式(含大小写变体)时抛 TypeError。
8376
+ */
8377
+ export declare const defineExportFormat: <Result = unknown>(name: string, adapter: GisViewExportFormatAdapter<Result>) => () => boolean
8378
+ /** 注销一个自定义导出格式,返回它之前是否注册着;内置格式永远返回 false */
8379
+ export declare const unregisterExportFormat: (name: string) => boolean
8380
+ /** 这个名字现在能不能直接交给 exportData(内置五档或已注册的自定义格式) */
8381
+ export declare const hasExportFormat: (name: string) => boolean
8382
+ /** 当前可用的全部导出格式:内置五档在前,自定义按注册顺序跟在后面 */
8383
+ export declare const listExportFormats: () => string[]
8384
+
7850
8385
  /* ---------- 渲染后端开关(renderer.js) ---------- */
7851
8386
 
7852
8387
  /** renderer 认的三档写法(与 options.renderer 同一套) */