gis-view-webgl2 0.1.1 → 0.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +23 -7
- package/dist/gis-view.css +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.d.ts +563 -61
- package/dist/index.js +1 -1
- package/docs/AI/345/257/271/350/257/235/346/261/207/346/200/273.md +182 -0
- package/docs/GisView.md +2 -2
- 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 +165 -0
- package/docs/api/index.html +1 -1
- package/docs/demos/ApiCoverageDemo.vue +644 -0
- package/docs/demos/ChannelDemo.vue +580 -18
- package/docs/demos/ClusterDemo.vue +251 -0
- package/docs/demos/CopyMergeDemo.vue +60 -10
- package/docs/demos/EventDemo.vue +3 -3
- package/docs/demos/GisViewDemo.vue +64 -8809
- package/docs/demos/LabelDemo.vue +67 -11
- package/docs/demos/api-index.js +58 -41
- package/docs/demos/demos.js +33 -16
- package/docs/demos/gis-view-demo/GisViewDemoCardHeader.vue +28 -0
- package/docs/demos/gis-view-demo/GisViewDemoDialogs.vue +82 -0
- package/docs/demos/gis-view-demo/GisViewDemoFooter.vue +16 -0
- package/docs/demos/gis-view-demo/GisViewDemoHeading.vue +16 -0
- package/docs/demos/gis-view-demo/GisViewDemoPanelStack.vue +71 -0
- package/docs/demos/gis-view-demo/GisViewDemoStage.vue +219 -0
- package/docs/demos/gis-view-demo/demo.css +1230 -0
- package/docs/demos/gis-view-demo/demoContext.js +12 -0
- package/docs/demos/gis-view-demo/panels/DataPanels.vue +303 -0
- package/docs/demos/gis-view-demo/panels/OpsPanels.vue +174 -0
- package/docs/demos/gis-view-demo/panels/StylePanels.vue +561 -0
- package/docs/demos/gis-view-demo/panels/ViewPanels.vue +396 -0
- package/docs/demos/gis-view-demo/useGisViewDemo.js +6188 -0
- 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 +4 -2
- package/docs/format/04-/351/200/232/351/201/223/344/270/216/346/240/207/347/255/276.md +5 -4
- 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 +3 -2
- package/docs/internals/16-03-/344/274/230/345/214/226/344/270/216/345/217/226/350/210/215-/344/270/213.md +1 -1
- package/docs/manual/02-/345/235/220/346/240/207/344/270/216/346/225/260/346/215/256.md +10 -4
- package/docs/manual/03-/351/205/215/347/275/256/351/241/271.md +105 -16
- package/docs/manual/04-/344/272/213/344/273/266/344/270/216/345/233/236/350/260/203.md +8 -8
- 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 +100 -0
- 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 +78 -3
- package/docs/manual/08-/351/200/211/344/270/255/344/270/216/346/213/220/347/202/271.md +31 -5
- package/docs/manual/09-/351/200/232/351/201/223/344/270/216/345/244/232/345/233/236/347/272/277.md +64 -10
- 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 +65 -8
- package/docs/manual/12-/346/240/207/347/255/276/344/270/216/350/243/205/351/245/260.md +54 -1
- package/docs/manual/13-/345/212/250/346/225/210/344/270/216/345/233/276/345/205/203.md +3 -0
- package/docs/manual/14-/350/247/206/345/233/276/344/270/216/347/255/233/351/200/211.md +35 -19
- package/docs/manual/15-/345/257/274/345/207/272/344/270/216/351/233/206/346/210/220.md +5 -0
- package/docs/manual/16-/345/256/236/344/276/213/346/226/271/346/263/225/346/200/273/350/241/250.md +18 -6
- package/docs/manual/17-/345/217/202/346/225/260/351/200/237/346/237/245.md +47 -22
- package/docs/manual/18-/351/200/220/346/226/271/346/263/225/347/244/272/344/276/213.md +80 -13
- package/docs/manual/20-/346/200/247/350/203/275/344/270/216/345/244/247/346/225/260/346/215/256.md +27 -0
- 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 -5
- package/docs/steps/README.md +18 -10
- package/docs/steps/selftest-actions.html +3 -5
- package/docs/steps/selftest-demo.html +27 -18
- package/docs/steps/selftest-demos.html +578 -53
- package/docs/steps/selftest-docs.html +7 -6
- package/docs/steps/selftest-effects.html +200 -0
- package/docs/steps/selftest-features.html +725 -12
- package/docs/steps/selftest-labels.html +323 -4
- package/docs/steps/selftest-perf.html +293 -20
- package/docs/steps/selftest-scale.html +52 -29
- package/docs/steps/step-10-full.js +1 -1
- package/docs/steps/step-12-events.js +1 -1
- package/docs//346/216/245/345/217/243/345/215/217/350/256/256.md +17 -11
- package/package.json +2 -2
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
| `lines[].path` | `GisViewCoordinate[]` | 这条线路的整条折线:首尾是端点(绑了 `from` / `to` 时取节点坐标),中间的点就是拐点。只有两端点时没有拐点 |
|
|
10
10
|
| `lines[].from` / `to` + `path` | `id` + `GisViewCoordinate[]` | 两端绑节点时 `path` 照样要写全(首尾两个顶点会被节点坐标替换):拖节点时端点跟着走,拐点一个都不动 |
|
|
11
11
|
| `channels[].path` / `channels[].groups[].path` | `GisViewCoordinate[]` | 通道**骨架**的中间拐点(两端由通道的 `from` / `to` 补齐):同一分组里的所有回线共用这一条骨架 |
|
|
12
|
+
| `channels[].groups[].waypointOffsets` | `Record<string, GisViewCoordinate>` | 分组刚性拐点偏移:键是含首尾端点的骨架顶点序号(只认中间拐点),值是组内所有回线在该顶点的世界坐标增量 |
|
|
12
13
|
|
|
13
14
|
**`path` 要写全**:线路的 `path` 是整条折线,首尾两个顶点给的是端点(绑了 `from` / `to` 时引擎用节点当前坐标替换它们),
|
|
14
15
|
**拐点 = 第 2 ~ n-1 个顶点**。只写中间那几个点会被首尾替换掉、直接退化成两端直连 —— 想要两个拐点就写成四个顶点;
|
|
@@ -23,7 +24,7 @@
|
|
|
23
24
|
|
|
24
25
|
两种写法在 `sample-waypoints.json` / `sample-channels.json` 里各有一份可以对着看。
|
|
25
26
|
|
|
26
|
-
**通道 /
|
|
27
|
+
**通道 / 分组的拐点存在公共骨架和分组偏移两层**:`channels[].path`(单组)与 `channels[].groups[].path`(多组)是整组共用的骨架中间拐点;`waypointOffsets` 只记 `channelWaypointDragMode: 'vertex'` 拖出来的按序号刚性增量。每条回线画出来的折线是“公共骨架 → 车道平行偏移 → 分组刚性偏移”之后的结果(只读,不回写)。读取时 `getChannelGroups(channelId)` 的 `path` / `skeleton` / `waypointOffsets` 是分组那一份,`getChannelGroupWaypoints(channelId, groupId)` 返回里的 `scope: 'group'` 说明这一点,`lines[].derived: true` 的 `path` / `waypoints` 才是各条回线偏移后的读数。偏移不写或为空对象就是普通平行骨架;切回 `'parallel'` 不会自动清掉已有偏移。
|
|
27
28
|
|
|
28
29
|
读写接口(都在实例方法里,逐要素改不改整份数据):
|
|
29
30
|
|
|
@@ -42,7 +43,8 @@
|
|
|
42
43
|
```js
|
|
43
44
|
view.exportData({ format: 'test', parts: ['waypoint'] })
|
|
44
45
|
// { parallel_groups: [{ group_id, member_line_ids, group_route: [[x, y], [拐点], …, [x, y]] }], counts, warnings }
|
|
45
|
-
// group_route
|
|
46
|
+
// group_route 含两端,中间就是拐点;有 waypointOffsets 时已经叠成实际路由
|
|
47
|
+
// 通道的每个分组各成一组,通道外的折线线路自己成一组
|
|
46
48
|
```
|
|
47
49
|
|
|
48
50
|
事件:`onWaypointChange` 的载荷给 `phase`(`add` / `remove` / `select` / `start` / `move` / `end`)、`lineIndex` / `pathIndex` / `coordinate`、
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
| `circuits` | `number` | `1` | 回线数量(`createChannels` 用它展开回线) |
|
|
13
13
|
| `lineIds` | `Array<string \| number>` | 无(`createChannels` 生成的那一份就是它) | 组成这条通道的线路 id,**顺序即回线顺序**(沿骨架左法线从负到正) |
|
|
14
14
|
| `path` | `GisViewCoordinate[]` | 无(两端直连) | 骨架的**中间拐点**(不含两端,两端由节点坐标补齐):与线路的 `path` 相反,这里只写中间 |
|
|
15
|
-
| `groups` | `GisViewChannelGroup[]` | 无(= 一个通道一组) | 分组声明:`[{ id, lineIds, path }]`,一组一条走廊;拆分 / 合并的结果写在这里,见「分组」 |
|
|
15
|
+
| `groups` | `GisViewChannelGroup[]` | 无(= 一个通道一组) | 分组声明:`[{ id, lineIds, path, waypointOffsets? }]`,一组一条走廊;拆分 / 合并的结果写在这里,见「分组」 |
|
|
16
16
|
| `width` / `offsetMode` / `inset` / `tangentInset` | `number` / `'tangent' \| 'inset'` / `number` / `number \| null` | 分别回落到 `options.channelWidth`(`0.02`)/ `'tangent'` / `options.channelInset`(`0`)/ `options.channelTangentInset`(`null` = 按回线线宽收) | 通道外观:宽度(`tangent` 下是最外侧两条回线的中心距)、偏移方式、内收比例(负数为外收)、两端切点内收 |
|
|
17
17
|
| `nodeWidth` | `number` | `options.channelNodeWidth`(`1`) | 「按两端节点尺寸取宽」的倍数:`1` = 回线正好铺在节点两边,`0` = 关掉自动取宽改用 `width` / `channelWidth` |
|
|
18
18
|
| `colors` / `lineWidth` / `opacity` | 数组 / 数字 | `options.colors`(`CHANNEL_DEFAULT_COLORS`)/ 无 / `1` | 回线的逐回颜色(不够时按顺序循环取)、线宽、透明度 |
|
|
@@ -29,9 +29,10 @@
|
|
|
29
29
|
- **成员池 = 顶层 `lineIds` + 只写在 `groups` 里的回线**(按分组顺序补在后面):车道顺序、「两端从第一条回线继承」与分组编辑(`splitChannelGroups` / `mergeChannelGroups` / `moveChannelLine` / `addChannelGroup`)都按这一份口径认成员。因此**只写 `groups`、完全不写顶层 `lineIds` 的通道也支持**:渲染照常,拆 / 并 / 挪分组、`removeLines` 收拾成员一样生效(`lineIds` 只列了一部分、其余只在 `groups` 里写的情况同理)。
|
|
30
30
|
- **往通道里加一条回线**:数据侧先有这条线(`lines[].id`)再写进 `lineIds` / `groups`;运行时用 `addChannelLines(channelId, lineIds)` 挂现成的线,或让 `updateChannel` 的第三段带着定义当场建 —— 认不出的成员 id 给了 `from` / `to`(两端都能在 `points` 里找到)、给了能用的 `path`,或这条通道自己声明了两端时就建(表单整份覆盖成员表走的这条路);`updateChannel` 的第四段 `lineIds` 是**整表对齐**:与第三段的线路数组一起给时,表里有、数据里没有的当场建,表里有的逐条改,表里没有了的旧成员直接从数据里删(视图跟着少);只传线路数组(不传第四段)就只改 id 匹配的成员、数量不动。移出用 `removeChannelLines`(留线)/ `removeLines`(删线)。
|
|
31
31
|
- **分组 id 在一条通道里要唯一**:id 是写回声明、按 id 指名分组的键(`moveChannelLine` / 选中 / 分组拐点读数都按它找组),两个组同名时只会认第一组。`addChannelGroup(..., { id })` 撞上已有分组时**返回 `ok: false`** 并说明(想并进去用 `moveChannelLine`);`splitChannelGroups` 这类不写 id 的入口按 `${通道 id}::N` 自动编号,不会撞名。
|
|
32
|
-
-
|
|
33
|
-
-
|
|
34
|
-
-
|
|
32
|
+
- 同一分组内的回线共用一条骨架:`parallel` 模式拖任一回线的拐点整组一起折,`vertex` 模式只移同组同一序号的拐点;两端节点、宽度、颜色这些配置仍由**通道**统管。
|
|
33
|
+
- **存的是公共骨架 + 分组偏移**:`groups[].path` 只有一条(整组共用),`groups[].waypointOffsets` 记 `vertex` 拖动按骨架序号产生的刚性增量;逐条回线各自的拐点不落数据 —— 加 / 删 / 拖只写这两层、按各条车道偏移推出来的是只读读数(`getChannelGroupWaypoints` 的 `scope: 'group'` / `lines[].derived`)。
|
|
34
|
+
- **`waypointOffsets` 的键按含首尾端点的骨架序号算**:只接受中间拐点,值可以是 `[dx, dy]` 或 `{ x, y }`;组内所有成员回线都叠这一份偏移。不写或写空对象是普通平行骨架,切回 `parallel` 不会自动清空;要清除就重写分组声明并带上当前 `path`、省略该项。
|
|
35
|
+
- 运行时读数:`getChannels()` 给**分组级**的一项(`{ id, channelId, channelIndex, lineIndexes, skeleton, waypointOffsets, offsets, paths, from, to, anchored, spacing }`,
|
|
35
36
|
一条通道拆成几组就有几项,`id` 是分组 id、`channelId` 才是通道 id);
|
|
36
37
|
`getChannelGroups(channelId)` 按通道 id 或通道定义 id 取该通道的全部分组,读数更细
|
|
37
38
|
(另给 `lineIds` / `lineCount` / `waypointCount` / `edited` / `current` 与可直接写回 `declaredPath` 的 `path`)。
|
|
@@ -41,8 +41,9 @@
|
|
|
41
41
|
| `onLabelClick` / `onLabelDrag` / `onLabelContextMenu` / `onLabelDblClick` | `kind` / `index` / `id` / `labelId` / `item` / `label`(这一条标签的 id、内容、来源、合并后的样式)/ `parent`(挂在哪条要素上,线路在通道里时带通道 / 分组)/ `state` |
|
|
42
42
|
| `onQualityChange` | `{ mode, name, level, glow, ornament, scale, budgetMs, frameMs }` |
|
|
43
43
|
|
|
44
|
-
|
|
45
|
-
|
|
44
|
+
三个事件的总线载荷是 `{ payload, event }`(要原样带回 DOM 事件):`pointerDown` / `pointerUp` / `contextMenu`,
|
|
45
|
+
回调那一侧仍是 `(payload, event)` 两个参数,`view.on` 订阅时记得拆包;通道回线的右键上下文在同一份
|
|
46
|
+
`contextMenu` 载荷的 `channelContext` 上。
|
|
46
47
|
|
|
47
48
|
### 自建面板常用的读数
|
|
48
49
|
|
|
@@ -97,7 +97,7 @@
|
|
|
97
97
|
|
|
98
98
|
### 16.70 自适应比例为什么给「联动指数」留一个没写的状态、updateLine 的拐点口径怎么定、API 速查页的数据是怎么长出来的(本轮已做 / 留档)
|
|
99
99
|
|
|
100
|
-
-
|
|
100
|
+
- **缩放联动指数的历史取舍与现行口径**:`pointZoomScale` / `lineZoomScale` 现在仍以 `0` 为缺省(尺寸不跟缩放走),要跟随地图就显式写指数;原来自适应比例开关负责给「没写」的项兜底,后来确认它只是把两项指数隐式设成 `1`,无法解决远处孤立点撑大包围盒导致的节点拥挤,因此已移除。`setZoomBaseScale(scale?)` 保留:它仍走 `SCALE_ONLY_KEYS` 那条「只改尺寸」的增量路(不动几何、不重解析),基准不给参数就取当前 `camera.scale`,配合 `getZoomBaseScale()` 读回。包围盒撑大时的间距问题改由 `fitSpacing` 处理:适应视图时按可见节点最近中心距反推比例,**相机中心仍取普通适应的包围盒中心**;只有比例被提高,不再按最近节点对或节点中位数另算中心。`measurePointSpacing()` 因此只保留距离扫描,`reflowChannelWidths()` 对单组通道在宽度输入未变时直接跳过车道与折线重算,见主手册「适应视图的节点间距(fitSpacing)」。
|
|
101
101
|
- **为什么「单独改某个线路」不新开一个方法,而是把 `updateLine` 的口径写清楚**:线路能改的就三类 —— 属性(颜色 / 宽度 / 线形…)、几何(拐点)、分组归属(`groupId` / `groupIndex` / `channelId`),`updateLine(id, patch)` 本来就都收:`path` 是整条折线(含首尾两端,`[x, y]` 或 `{ x, y }`),只想改中间拐点用 `setLineWaypoints`(两端从 `from` / `to` 或 `start` / `end` 推),属性与分组指令一次下发时按「线路数据只发一条 `updateLine`、分组再发一条 `channelGroups`」走,指令本身不写进线路数据。这三条口径补进主表、参数速查与逐方法示例,自测新增三条钉住「一次下发只发一条」与「指令不进数据」。
|
|
102
102
|
- **为什么 API 速查页的数据不手写**:手写的清单一改源码就漂。数据还是同一份《GisView.md》:`docs/steps/gen-api-index.mjs` 原来就导出成员 / 分组 / options,这一轮给每条补上 `examples: [{ group, code, from }]` —— 示例来自「逐方法示例」一节,解析时按 `####` 分组、围栏切块,成员名取首行注释冒号前的标识符;首行没点名、但代码里真实出现 `view.某成员(` 的块按兜底认领。`check-doc-coverage.mjs` 因此多了一项「实例成员 × 逐方法示例」:235 个成员每个都要在示例里露面,缺一个就 FAIL(补「自定义运算符」那一段就是这个对账逼出来的)。页面(`docs/api/index.html`)自包含:左侧分组 + 搜索 + 类型开关,右侧成员卡(参数 / 返回 / 说明 / 示例 + 高亮 + 复制),底部 options 逐条列四件套;自测页通过 `__gisApi` 钩子读它的 DOM,钉住 235 张卡都有示例、86 个 options 四件套、搜索过滤与 `select(名字)` 高亮、类型开关能单独收起属性。
|
|
103
103
|
- **验证**:`npx tsc --noEmit` 0 错;十三页自测共 **1625** 条 0 FAIL(`selftest-scale.html` 95 / `selftest-features.html` 522 / `selftest-demos.html` 150 / `selftest-docs.html` 73);`npm run check:docs` 全绿;`npm run build` 通过。
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
- **选哪一对**:只要世界坐标(读落点、对账)用 `clientToWorld` / `worldToClient`;要把鼠标位置喂给只吃画布像素的接口 —— `pick` / `getContextAt` / `nearestPointsAt` / `nearestLineAt` / `getFeaturesInRect` / `selectInBox` / `setDropPreview({ screen })` / `zoomTo(scale, origin)` 的锚点 —— 先用 `clientToScreen` 转一档(世界坐标喂不进这些接口);手上已经握着画布像素(`getPointer().screen`、拾取载荷的 `screen`、`listPoints({ withScreen })`),要摆 `position: fixed` 的浮层用 `screenToClient`。两对数学上可互推(`clientToScreen` 的结果就等于 `project(clientToWorld(...))`),专名省掉绕世界坐标那一步,也与指针事件共用同一份 canvas rect 缓存 —— 组件自己的提示框跟随(`handlePointerMove`)走的也是它。
|
|
15
15
|
- **像素比**:默认取 `window.devicePixelRatio`,用 `pixelRatio` 覆盖。线宽、节点尺寸、虚线图案、光标热点都是 **CSS 像素**,在高分屏上会按像素比放大到设备像素,因此屏幕上看起来始终一样大。另外有一层画布**像素预算**(`maxCanvasPixels`,默认 400 万):全屏 / 高分屏下 CSS 面积一大,渲染倍率就按 `sqrt(预算 / CSS 面积)` 压下来 —— 填充率不随屏幕面积线性上涨(全屏 + dpr 2 曾经是窗口态的十倍像素),线宽与字号仍然是 CSS 像素,观感基本不变。
|
|
16
16
|
- **宿主缩放**:页面用 CSS `zoom`(大屏适配的常见做法:`document.body.style.zoom = innerWidth / 1920`)或祖先的 `transform: scale` 把这一层整体放大 / 缩小时,组件里的 **CSS 像素一律是布局像素** —— 线宽、节点尺寸、字号跟着页面一起变大,与旁边的 DOM 一致(不是保持设备像素大小不变)。画布备份像素按「设备像素比 × 显示比例」开,缩放之后仍然 1:1 落在设备像素上,画面不发糊。`getViewport()` 里的 `displayScale` 就是这个比例(1 表示没有缩放):自建 DOM 覆盖层时,`getBoundingClientRect()` 量到的是缩放后的视觉像素,除以它才是与 `project()` / `unproject()` 同一套坐标。指针事件(`onHover` / `onPointer` / `getPointer`)与 `project` / `unproject` 已经是布局像素,直接用;`onViewport` 回调也会带上这个字段。**运行期**改 CSS `zoom` 不用自己做什么:内容盒与设备像素两档 `ResizeObserver` 各挂一个实例(同一个实例对同一元素再 `observe` 一次是改选项、会把前一次顶掉),放大 / 缩小都会自己补一次重排(逐帧实测:第 2 帧起显示比例 / 备份像素 / 标签偏移 / 指针命中全部对齐,demo 的「宿主缩放」滑杆来回拉也跟得上),运行期改祖先的 `transform: scale` 不动布局、观察不到,把新比例交给 `view.resize()`(或在窗口 resize 时一起改)即可同步;显示比例 1% 以内按 1 处理、夹在 0.1 ~ 8,鹰眼图的备份像素在这条乘积小于 1 时按 1 倍开(轻微超采样,只会更清楚)。
|
|
17
|
-
- **尺寸的三个层次**(节点与线路都有):要素自身的 `size` / `width` → 规则的 `size` / `width` → 全局 `pointStyle` / `lineStyle`;再乘 `pointSizeScale` / `lineWidthScale`(常数倍数)与地图缩放的联动指数 `pointZoomScale` / `lineZoomScale`(0 表示不跟随,1
|
|
17
|
+
- **尺寸的三个层次**(节点与线路都有):要素自身的 `size` / `width` → 规则的 `size` / `width` → 全局 `pointStyle` / `lineStyle`;再乘 `pointSizeScale` / `lineWidthScale`(常数倍数)与地图缩放的联动指数 `pointZoomScale` / `lineZoomScale`(0 表示不跟随,1 表示与地图同倍率)。
|
|
18
18
|
|
|
19
19
|
- **经纬度与 GeoJSON**:配了 GeoJSON 背景(`background.geoJson`)就多一套换算:`lngLatToWorld` / `worldToLngLat` 把经纬度接到画出来的世界坐标上(`aspectScale` 只压经度、绕整体范围中心),`lngLatToScreen` / `screenToLngLat` 直接连到画布 CSS 像素;数据不在底图的坐标系里时用 `createGeoMapper` / `mapDataToGeoJson` 把点、线路与通道搬到画出来的底图上,见「经纬度与数据映射」。
|
|
20
20
|
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
| `lngLatToWorld(lng, lat)` / `worldToLngLat(x, y)` | 经纬度 ↔ 世界坐标 | 已经含 `aspectScale`:`lngLatToWorld(rawBounds.minX, …)` 正好落在底图左边缘,与画出来的底图完全对齐 |
|
|
29
29
|
| `lngLatToScreen(lng, lat)` / `screenToLngLat(x, y)` | 经纬度 ↔ 画布 CSS 像素 | 画布内的像素坐标(左上角为原点),与 `onPointer` / `getPointer()` 用的是同一套 |
|
|
30
30
|
|
|
31
|
-
`getPointer()` 与 `onPointer` 回调共用同一份光标状态 `{ inside, screen, world, lngLat }`:`screen` 是画布 CSS 像素、`world` 是世界坐标、`lngLat` 是反算出来的经纬度(没有 GeoJSON 背景时为 `null`);鼠标移出画布时 `inside: false`,其余字段保留最后一次的值。各类指针载荷(`onHover` / `onClick` / `onDblClick` / `onPointerDown` / `onPointerUp` / `onContextMenu
|
|
31
|
+
`getPointer()` 与 `onPointer` 回调共用同一份光标状态 `{ inside, screen, world, lngLat }`:`screen` 是画布 CSS 像素、`world` 是世界坐标、`lngLat` 是反算出来的经纬度(没有 GeoJSON 背景时为 `null`);鼠标移出画布时 `inside: false`,其余字段保留最后一次的值。各类指针载荷(`onHover` / `onClick` / `onDblClick` / `onPointerDown` / `onPointerUp` / `onContextMenu`)在配了 GeoJSON 背景时也会多带一个 `lngLat` 字段。
|
|
32
32
|
|
|
33
33
|
数据本身不在底图的坐标系里(例如底图是经纬度、数据是另一套投影坐标)时,用映射器把数据搬到画出来的底图上:
|
|
34
34
|
|
|
@@ -138,6 +138,7 @@ createGisView(container, { points, lines, channels })
|
|
|
138
138
|
| `visible` | `boolean` | `false` 时不画 |
|
|
139
139
|
| `decorations` | `GisViewLineDecoration[]` | 沿线挂的图片 / SVG,见「线路上的装饰」 |
|
|
140
140
|
| `direction` | `GisViewLineDirectionInput` | 这条线自己的方向箭头(静态,不跑动):`true` 用 `options.lineDirection`、对象逐字段覆盖、`false` / `null` 关掉;按弧长摆、朝向跟着切向(起点 → 终点),见「线路方向箭头(lineDirection)」 |
|
|
141
|
+
| `forward` | `boolean` | 业务正向,默认 `true`:从 `from` / `path[0]` 走向 `to` / `path[last]`。写 `false` 时装饰位置与朝向、方向箭头、线路动画都按反方向解释;它与 `effect.reverse` / `direction.reverse` 是异或关系(反两次等于正一次),不改写 `path` 本身 |
|
|
141
142
|
| `lineLabel` / `lineLabelPosition` / `lineLabelVisibility` / `lineLabelOffset` / `lineLabelParallel` | | 这条线自己的标签配置(`lineLabelParallel` 是这条线自己的「与线路平行」开关) |
|
|
142
143
|
| `labels` | `GisViewItemLabel \| GisViewItemLabel[]` | 这条线上的标签清单(逐条写,与节点的 `labels` 同一套,额外认 `parallel`),见「标签(labels,导入即回显)」 |
|
|
143
144
|
| `tooltip` | `GisViewTooltipContent \| false` | 这条线的提示内容 |
|
|
@@ -183,6 +184,10 @@ createGisView(container, { points, lines }) // 不配 label / lineLabel 也画
|
|
|
183
184
|
| `visibility` | `'auto' \| 'always' \| 'hidden'` | 这一条的显隐策略 |
|
|
184
185
|
| `hidden` | `boolean` | 这一条不画(等于 `visibility: 'hidden'`;`removeLabel` 对声明里那一条落的覆盖就是它) |
|
|
185
186
|
| `parallel` | `boolean` | 线路标签:这一条是否跟着线路方向转 |
|
|
187
|
+
| `overlapMode` | `'shift' \| 'hide'` | 碰撞后的处理方式:换落点或直接不画;逐条覆盖全局的 `overlapMode` |
|
|
188
|
+
| `avoidOverlap` | `boolean` | 这一条是否参与避让;写 `false` 时即使全局开着避让也会画出来(`LabelDemo` 用它让两条标签同时出现) |
|
|
189
|
+
| `draggable` | `boolean` | 这一条能不能拖动;逐条覆盖 `options.label` / `options.lineLabel` 的 `draggable` |
|
|
190
|
+
| `editable` | `boolean` | 这一条能不能点选编辑;逐条覆盖 `options.label` / `options.lineLabel` 的 `editable`,写 `false` 时点击不触发 `labelClick` |
|
|
186
191
|
| `className` | `string` | 这一条的附加类名 |
|
|
187
192
|
| `added` | `boolean` | 这条是运行时加的(`addLabel`),持久化 / 整份回显时按它重建 |
|
|
188
193
|
|
|
@@ -231,8 +236,9 @@ const next = createGisView(el, {
|
|
|
231
236
|
| 字段 | 类型 | 说明 |
|
|
232
237
|
| --- | --- | --- |
|
|
233
238
|
| `id` | `string \| number` | 通道 id:同 id 的通道在数据刷新之间保留已编辑过的骨架 |
|
|
239
|
+
| `visible` | `boolean` | `false` 时整条通道与成员回线一起不画;数据、分组、拐点与编辑状态保留,改回 `true` 立即恢复 |
|
|
234
240
|
| `lineIds` | `Array<string \| number>` | 通道内的线路 id,**顺序就是回线顺序**(沿骨架左法线方向) |
|
|
235
|
-
| `groups` | `GisViewChannelGroup[]` | 分组声明:`{ id?, lineIds, path? }
|
|
241
|
+
| `groups` | `GisViewChannelGroup[]` | 分组声明:`{ id?, lineIds, path?, waypointOffsets? }`。缺省是「一个通道一组」;`waypointOffsets` 是 `vertex` 拖动按骨架序号记的刚性偏移 |
|
|
236
242
|
| `path` | `GisViewCoordinate[]` | 骨架的中间拐点(两端用 `from` / `to` 绑节点时只需写中间) |
|
|
237
243
|
| `from` / `to` | `string \| number` | 两端节点:声明了任意一端,两端就都必须落在节点上,节点不存在时整条通道与回线都不显示 |
|
|
238
244
|
| `width` | `number` | 通道宽度(覆盖 `channelWidth`),只在 `nodeWidth` 为 0 或两端没锚定时真正生效 |
|
|
@@ -243,7 +249,7 @@ const next = createGisView(el, {
|
|
|
243
249
|
| `tooltip` | `GisViewTooltipContent \| false` | 通道回线悬停时的提示内容(`{name}` 是通道名,`{circuits}` 是回数) |
|
|
244
250
|
| `cursor` / `ctrlCursor` | `GisViewCursorValue` | 悬停到这条通道回线上时的光标(回线自身也配了 `cursor` 时以回线为准) |
|
|
245
251
|
|
|
246
|
-
分组的语义:**一个通道默认一组**,拆分之后每组有自己的成员与拐点;加点 / 拖点只作用于同一分组,没列进任何分组的线路并回第一组。运行时读数用 `getChannelGroups()`,写回用 `groups[].path
|
|
252
|
+
分组的语义:**一个通道默认一组**,拆分之后每组有自己的成员与拐点;加点 / 拖点只作用于同一分组,没列进任何分组的线路并回第一组。运行时读数用 `getChannelGroups()`,写回用 `groups[].path`(它已经是「可以直接写回数据的中间拐点」)与 `waypointOffsets`(`vertex` 拖动的刚性偏移,键按含首尾端点的骨架序号算)。
|
|
247
253
|
|
|
248
254
|
### createChannels
|
|
249
255
|
|
|
@@ -19,6 +19,7 @@
|
|
|
19
19
|
| `points` | `GisViewPoint[]` | `[]` | 点数据,`x` / `y` 为世界坐标(经纬度、投影米或任意平面坐标) |
|
|
20
20
|
| `lines` | `GisViewLine[]` | `[]` | 线数据,`start` / `end` 支持 `{ x, y }` 或 `[x, y]`,折线用 `path`,端点可用 `from` / `to` 绑定点 id |
|
|
21
21
|
| `channels` | `GisViewChannel[]` | `[]` | 通道:把若干条线路组织成并行敷设的多回线走廊,回线几何由骨架折线按偏移推导;两端可用 `from` / `to` 绑在节点上 |
|
|
22
|
+
| `pointCluster` | `boolean \| GisViewPointClusterOptions` | 关 | 点聚合:`true` 使用缺省档(屏幕半径 60px / 至少 2 点 / 不限缩放),对象写法可调 `enabled` / `radius` / `minPoints` / `maxZoom`。聚合圆替代密集原始点参与绘制、拾取、快照与导出;原始 `points` / `getData()` 不变,缩放超过 `maxZoom` 后恢复逐点显示,见「点聚合(pointCluster)」 |
|
|
22
23
|
| `channelWidth` | `number` | `0.02` | 通道宽度的世界单位写法(`tangent` 模式下是最外侧两条回线中心的间距,`inset` 模式下先按它算再收),**只在 `nodeWidth` 为 0 或两端没绑节点时才真正决定宽度**;单个通道可用 `width` 覆盖 |
|
|
23
24
|
| `channelInset` | `number` | `0` | `offsetMode: 'inset'` 时从切点收 / 放的比例(占通道宽度):正数内收(最多 0.42),**负数外收**(最多 -0.5,可用区间撑到 2 倍宽);单个通道可用 `inset` 覆盖,见「通道与多回线」 |
|
|
24
25
|
| `channelNodeWidth` | `number` | `1` | 节点宽度倍数:通道宽度按两端节点尺寸取的倍数,`1` 表示回线正好铺在节点两边、节点放大回线跟着变宽,`0` 表示所有通道退回 `width` / `channelWidth` 的世界单位写法,单个通道可用 `nodeWidth` 覆盖 |
|
|
@@ -37,6 +38,7 @@
|
|
|
37
38
|
| `prebake` | `GisViewPrebakeOptions \| true` | 关 | 贴图符号预热:把「这次画面会出现什么」提前告诉组件 —— 两种写法:`combos` 逐组合(精确,`getSymbolCombos()` 收出来的那份)/ `symbols × pointColors × sizes` 与 `lineColors × 线路动画图标` 全排列(省事,颜色与尺寸由同一个字段决定时会多烤很多)—— 第一帧之前就烤好,画到它们时命中的是现成的贴图(省掉解码 + 光栅化那一下);组合数与数据量无关,不配就是从前那条按需路径。读数 `getPrebake()` / `getSymbolCombos()`、手动再烤一遍 `runPrebake()`,见「贴图符号预热(prebake)」 |
|
|
38
39
|
| `label` | `GisViewLabelOptions \| GisViewLabelOptions[]` | 无 | 节点标签:内容 / 位置 / 显隐 / 避让 / 拖动与编辑都可配,**写数组就是同一个节点上多条标签**,与 `lineLabel` 共用一套避让网格,见「节点标签」 |
|
|
39
40
|
| `labelOptimize` | `boolean` | `false` | 标签显示优化开关:**缺省关 = 强制显示**(不避让、不按 `maxCount` 截断、不设 `scanLimit` / 扫描预算,节点 / 线路的每个可见要素该出现的标签一条不少);写 `true` 与从前一致 —— 避让 / 换落点 / 数量上限 / 候选上限全部生效。标签订得密、数据量大(十万级)时建议打开,见「标签显示优化开关」 |
|
|
41
|
+
| `labelRender` | `'auto' \| 'canvas' \| 'dom'` | `'auto'` | 纯文本标签的容器渲染方式:`auto` 在强制显示档(`labelOptimize` 未开且未进密集档)下,同一层纯文本标签达到 1024 条时改画到一张 Canvas;`canvas` 不受数量阈值限制,优化档 / 密集档也强制画布并直接用画布尺寸参与避让;`dom` 始终逐条建 `.gis-view__label`。HTML / 元素内容 / 可拖拽 / 可编辑 / 超出 Canvas 样式能力的标签仍走 DOM。只影响容器,不改内容、锚点、显隐以及 `maxCount` / `when` / `scanLimit` 等优化策略,见「标签容器渲染(labelRender)」 |
|
|
40
42
|
| `lineLabel` | `GisViewLineLabelOptions \| GisViewLineLabelOptions[]` | 无 | 线路标签:位置沿线走(比例 / 百分比 / 绝对距离),内容、避让、显隐都可配,与节点标签共用一套避让网格;**写数组就是同一条线上多条标签**,见「线路标签」 |
|
|
41
43
|
| `labelStates` | `GisViewLabelState[]` | 无 | 标签的运行时状态(`getLabelStates()` 的那一份:拖出来的偏移、改过的内容与样式、运行时加的标签、隐藏覆盖):创建时喂回来就回显,等价于创建之后调 `setLabelStates(states)`;`updateOptions({ labelStates })` 同样认。`exportData({ format: 'input' })` 的结果里就叫 `labelStates`,存档 → 回灌直接接上 |
|
|
42
44
|
| `graphics` | `GisViewGraphic[]` | 无 | 与节点无关的扩展图形:按世界坐标放 SVG 路径 / 图片 / Canvas,支持锚点、偏移、旋转、透明度、`zIndex` 与 `scaleWithView`;位于画布之上、标签之下,运行时用 `addGraphic` / `addGraphics` / `updateGraphic` / `removeGraphic` / `clearGraphics` 增删改,见「扩展图形(graphic)」 |
|
|
@@ -47,17 +49,19 @@
|
|
|
47
49
|
| `searchWorker` | `boolean \| GisViewSearchWorkerOptions` | `{ threshold: 20000 }` | [异步搜索](14-视图与筛选.md#搜索与定位)是否用 Web Worker 计算:默认点 + 线总数超过阈值才用,`false` 表示 `searchAsync` 也同步算;同步的 `search` 一直在主线程算,不受这一项影响 |
|
|
48
50
|
| `pointHoverStyle` / `pointSelectStyle` | `GisViewPointStyle` | 无 | 点的悬停 / 选中样式;没配就不改变外观(悬停仍然触发回调与提示、选中仍然进选中集合),要反馈就自己配一份 |
|
|
49
51
|
| `lineHoverStyle` / `lineSelectStyle` | `GisViewLineStyle` | 无 | 线的悬停 / 选中样式;没配同样不改变外观 |
|
|
52
|
+
| `cascadeHighlight` | `boolean \| GisViewCascadeHighlightOptions` | 关 | 点击级联高亮:`true` 亮节点 + 直连线路;对象可设 `enabled`、`scope`、`triggerOnClick`、`triggerOnMultiSelect`、`triggerOnBoxSelect`、独立的 `pointStyle` / `lineStyle` 与 `clearOnEmptyClick`。它不改选中集,见「点击级联高亮」 |
|
|
50
53
|
| `pointMultiSelectStyle` / `pointBoxSelectStyle` | `GisViewPointStyle` | 无 | 多选(Ctrl + 点击)/ 框选(Shift + 拖动,可改 `shortcuts.boxSelect`)命中的点样式,缺省与 `pointSelectStyle` 一致,单个点可用 `multiSelectStyle` / `boxSelectStyle` 覆盖 |
|
|
51
54
|
| `lineMultiSelectStyle` | `GisViewLineStyle` | 无 | 多选命中时的线样式,缺省与 `lineSelectStyle` 一致,单条线可用 `multiSelectStyle` 覆盖;框选出来的线路仍走 `lineSelectStyle`(线路没有单独的框选样式) |
|
|
52
55
|
| `defaultHighlight` | `boolean` | `false` | 没有配置状态样式时是否仍用尺寸 / 宽度增幅与强调环画出内置强调;默认 `false`(不配样式就不改变外观),设为 `true` 可退回旧行为 |
|
|
53
|
-
| `pointSizeScale` / `lineWidthScale`、`pointZoomScale` / `lineZoomScale`、`zoomBaseScale` | `number` | `1` / `0` | 两组系数各管一件事,不重复:`pointSizeScale` / `lineWidthScale` 是与地图无关的整体放大(常数倍数,屏幕上的大小因此恒定),`pointZoomScale` / `lineZoomScale` 是「跟随地图缩放」的指数(0 表示不跟随,1 表示与地图同倍率放大,0.5 是地图放大 4 倍、要素放大 2 倍),绘制尺寸是两者相乘;`zoomBaseScale`
|
|
54
|
-
| `
|
|
56
|
+
| `pointSizeScale` / `lineWidthScale`、`pointZoomScale` / `lineZoomScale`、`zoomBaseScale` | `number` | `1` / `0` | 两组系数各管一件事,不重复:`pointSizeScale` / `lineWidthScale` 是与地图无关的整体放大(常数倍数,屏幕上的大小因此恒定),`pointZoomScale` / `lineZoomScale` 是「跟随地图缩放」的指数(0 表示不跟随,1 表示与地图同倍率放大,0.5 是地图放大 4 倍、要素放大 2 倍),绘制尺寸是两者相乘;`zoomBaseScale` 是联动基准,缺省取首次适应视图时的比例 |
|
|
57
|
+
| `fitSpacing` | `boolean \| GisViewFitSpacingOptions` | 关 | 适应视图的节点间距兜底:`true` 用 `{ minDistance: 24, maxZoom: 0 }`,对象可改最小中心距(CSS 像素)与相对普通适应比例的上限(`0` 表示不限);只在首次默认适应与 `fitView()` 生效,远处孤立点允许落到视口外,见「适应视图的节点间距(fitSpacing)」 |
|
|
55
58
|
| `boxSelect` | `boolean` | `false` | 是否允许按住框选快捷键(`shortcuts.boxSelect`,默认 Shift)拖动鼠标框选要素;**缺省关**,写 `boxSelect: true` 或 `features: { boxSelect: true }` 才开。框选默认只收节点,`selectionKinds` 可把线路 / 通道也纳入 |
|
|
56
59
|
| `multiSelect` | `boolean` | `false` | 多选开关:打开后不用按修饰键,直接单击节点 / 线路就取反累加选中(与按住 `shortcuts.multiSelect` 点击同一套行为、同一个 `multiSelectStyle`;取反那一下不经过 `onClick`,`onSelectChange.action.type` 是 `toggleSelect`);**缺省关**,关着时多选走框选(`boxSelect`)与按住多选快捷键(默认 Ctrl / ⌘)。运行时 `updateOptions({ multiSelect })` 切换只重画一帧、不重排场景 |
|
|
57
60
|
| `selectionKinds` | `GisViewSelectionKindsInput` | 无(框选只收节点;Ctrl 多选收节点 / 线路 / 通道) | 框选与 Ctrl / 多选点击的类型过滤:`'point'` 节点、`'line'` 通道外的独立线路、`'channel'` 通道回线;可写数组任意组合,`'all'` / `true` 全开,`false` / `null` 全关。通道回线只归 `channel` 管,通道外的线路只归 `line` 管;通道回线仍按 `channelSelectMode` 摊开。不写时保留旧口径;普通单选与 `select` / `selectFeatures` 不受它限制。运行时走 `updateOptions({ selectionKinds })`,见「框选」与「选择类型过滤」 |
|
|
58
61
|
| `selectionBoxStyle` | `GisViewSelectionBoxStyle` | 蓝底 0.16 透明 + 1px 蓝框 | 框选矩形的填充与边框:`fill`、`fillOpacity`、`stroke`、`strokeWidth` |
|
|
59
62
|
| `selectionOnTop` | `boolean` | `true` | 选中的节点 / 拖动中的整组 / 待确认合并的目标节点,以及选中线路所在的整条通道,是否画在所有要素之上(与 `zIndex` 无关),见「选中 / 拖动的层级」 |
|
|
60
|
-
| `channelSelectMode` | `'line' \| 'group' \| 'channel'` | `'line'` | 通道选中模式:点中通道里的一条回线时选中什么 —— `'line'` 只选这一条、`'group'` 连它所在的分组一起、`'channel'`
|
|
63
|
+
| `channelSelectMode` | `'line' \| 'group' \| 'channel'` | `'line'` | 通道选中模式:点中通道里的一条回线时选中什么 —— `'line'` 只选这一条、`'group'` 连它所在的分组一起、`'channel'` 整条通道(所有分组的回线);通道以外的线路永远只选自己。普通点选与 Ctrl / ⌘ + 点击加点共用这一档高亮范围;Ctrl / ⌘ + 点击在 `group` / `channel` 下按整批取反;切换走 `updateOptions({ channelSelectMode })`,只重画一帧、不重排场景,见「通道选中模式」 |
|
|
64
|
+
| `channelWaypointDragMode` | `'parallel' \| 'vertex'` | `'parallel'` | 分组拐点拖动模式:`'parallel'` 沿用共用骨架 + 平行偏移(和原有逻辑一致),`'vertex'` 只平移当前分组同一 `pathIndex` 的拐点,其他拐点与分组不动;普通线路始终只动自己。`vertex` 的结果写进 `groups[].waypointOffsets`,切换走 `updateOptions({ channelWaypointDragMode })`,下一次拖动生效,见「分组拐点拖动模式」 |
|
|
61
65
|
| `waypointEditable` | `boolean` | `false` | 是否允许编辑线路拐点(按住加点快捷键 `shortcuts.addWaypoint`(默认 Ctrl / ⌘)+ 点击添加、拖动移动、双击或删除快捷键删除),单条线可用 `waypointEditable` 覆盖;**缺省关**,写 `waypointEditable: true` 或 `features: { waypoint: true }` 才开。`false`(以及 `features: { waypoint: false }`)会同时关闭新增、移动与删除,没有只关其中一项的细分开关;`shortcuts.addWaypoint` 仍只决定加点的组合键 |
|
|
62
66
|
| `waypointVisibility` | `'selected' \| 'always'` | `'selected'` | 拐点显示时机:`selected` 只显示选中线路(以及刚加过拐点的线路)的拐点,`always` 全部显示 |
|
|
63
67
|
| `waypointStyle` / `waypointSelectStyle` | `GisViewPointStyle` | 无 | 拐点(线路 `path` 的中间顶点)的默认 / 选中样式,**支持配置**:字段与节点样式同款;缺省是白底蓝圈的 9px 圆点,`waypointSelectStyle` 没配时选中拐点用内置强调环,见「线路拐点」的「拐点样式」小节 |
|
|
@@ -66,10 +70,11 @@
|
|
|
66
70
|
| `gridSize` | `number` | `96` | 网格线的屏幕目标间距,实际步长吸附到 1 / 2 / 5 × 10^n |
|
|
67
71
|
| `showGrid` | `boolean` | `false` | 是否绘制网格:与其它功能开关同一条口径,**缺省关**,写 `showGrid: true` 才画 |
|
|
68
72
|
| `interactive` | `boolean` | (缺省全关) | 查看类交互的「详细配置手动打开」写法:写 `true` 打开拖拽平移 / 滚轮缩放 / 右键回调(等价 `pan` / `zoom` / `contextMenu` 三个开关),不写就是全关 |
|
|
69
|
-
| `preventContextMenu` | `boolean` | `true` | 组件接住右键时是否收掉浏览器的系统菜单(`contextmenu` 的默认行为):`contextMenu` 开着(或 `interactive: true` / `features: 'view'`)时组件才接右键,接住时一律 `preventDefault()`,点 / 线 / 空白 / 通道都一样;想让系统菜单自己弹就写 `false`(`onContextMenu`
|
|
73
|
+
| `preventContextMenu` | `boolean` | `true` | 组件接住右键时是否收掉浏览器的系统菜单(`contextmenu` 的默认行为):`contextMenu` 开着(或 `interactive: true` / `features: 'view'`)时组件才接右键,接住时一律 `preventDefault()`,点 / 线 / 空白 / 通道都一样;想让系统菜单自己弹就写 `false`(`onContextMenu` 照常发)。右键整个不接时(`contextMenu` 缺省关)系统菜单自然照弹 |
|
|
70
74
|
| `clickable` | `boolean` | (缺省全关) | 查看类交互的「详细配置手动打开」写法:写 `true` 打开悬停高亮与点击选中(等价 `hover` / `select` 两个开关),要素自身可用 `clickable: false` 逐个关掉 |
|
|
71
75
|
| `draggable` | `boolean` | `false` | 点是否可拖拽,单个点可用 `draggable` 覆盖;**缺省关**,写 `draggable: true` 或 `features: { drag: true }` 才开 |
|
|
72
76
|
| `liveDrag` | `boolean` | `true` | 拖动节点时线路是否实时跟随:`false` 时拖动期间线路与通道原地不动,松手(`pointerup`)后一次性更新到新位置 |
|
|
77
|
+
| `lineFollowsNode` | `boolean` | `true` | 线路 / 通道是否跟随节点的生命周期:`true` 时隐藏、删除、筛选收起节点会连同绑定线路与通道一起处理;`false` 时节点退场只影响节点,线路 / 通道停在最后一份坐标与解析尺寸。筛选没有显式写 `cascade` 时,关闭它会把默认联动从 `'binding'` 改为 `false`;显式 `cascade` 始终优先。运行时用 `updateOptions({ lineFollowsNode })` 切换,见「筛选」 |
|
|
73
78
|
| `shortcuts` | `GisViewShortcuts` | 见「快捷键」 | 所有快捷键都可自定义:框选 / 多选 / 加点 / 复制 / 粘贴 / 取消 / 删除 / 适应视图,没写的动作沿用默认值,写 `false` 等于关掉这个动作的快捷键 |
|
|
74
79
|
| `copy` | `GisViewCopyOptions` | 缺省关 | 复制节点(**写了这份配置才算开**,`enabled: false` 显式关掉):`enabled` 开关、`offset` 落点偏移(默认 `[28, 24]` 像素)、`autoCommit`(交互入口落地前是否自动确认:不写就是落地,`false` 停在预览态等 `commitPointCopy()` / 载荷里的 `payload.commit()`)、`idPrefix`(默认 `copy-`)、`createId` / `createItem` 定制复制品,见「节点复制」 |
|
|
75
80
|
| `remove` | `GisViewRemoveOptions` | 缺省关 | 删除选中的拐点 / 线路 / 节点(**写了这份配置才算开**,`enabled: false` 显式关掉):`enabled` 开关、`scope`(`confirm()` 不带参数时的缺省范围:`'lines'` 只删选中的回线 / `'groups'` 连所在分组 / `'channels'` 连整条通道,缺省 `'lines'`)、`confirm`(不写停在 `pending` 等使用方裁决 / `false` 直接删 / 函数自行裁决,支持 Promise)。Delete 键与 `requestRemove()` 都先出一份「要删什么、连带什么」的载荷,确认之后才动数据;删节点会连挂在它身上的线路与被它锚定的通道一起删,见「删除(remove)」 |
|
|
@@ -101,11 +106,11 @@
|
|
|
101
106
|
| 分组 | 字段 |
|
|
102
107
|
| --- | --- |
|
|
103
108
|
| 总开关与历史 | `features` · `history` |
|
|
104
|
-
| 数据与背景 | `points` · `lines` · `channels` · `background` |
|
|
105
|
-
| 通道几何 | `channelWidth` · `channelInset` · `channelNodeWidth` · `channelTangentInset` · `channelMaxGroups` · `channelGroupMaxLines` · `channelDraftStyle` · `channelSelectMode` |
|
|
106
|
-
| 样式与规则 | `pointStyle` · `lineStyle` · `pointRules` / `lineRules` · `heatmap` · `effects` · `lineDirection` · `prebake` · `label` · `labelOptimize` · `lineLabel` · `labelStates` · `tooltip` · `pointSizeScale` / `lineWidthScale`、`pointZoomScale` / `lineZoomScale`、`zoomBaseScale` · `cursorStyle` · `gridColor` · `gridSize` · `showGrid` |
|
|
109
|
+
| 数据与背景 | `points` · `lines` · `channels` · `pointCluster` · `background` |
|
|
110
|
+
| 通道几何 | `channelWidth` · `channelInset` · `channelNodeWidth` · `channelTangentInset` · `channelMaxGroups` · `channelGroupMaxLines` · `channelDraftStyle` · `channelSelectMode` · `channelWaypointDragMode` |
|
|
111
|
+
| 样式与规则 | `pointStyle` · `lineStyle` · `pointRules` / `lineRules` · `heatmap` · `effects` · `lineDirection` · `prebake` · `label` · `labelOptimize` · `labelRender` · `lineLabel` · `labelStates` · `tooltip` · `pointSizeScale` / `lineWidthScale`、`pointZoomScale` / `lineZoomScale`、`zoomBaseScale` · `cursorStyle` · `gridColor` · `gridSize` · `showGrid` |
|
|
107
112
|
| 状态样式与选中 | `pointHoverStyle` / `pointSelectStyle` · `lineHoverStyle` / `lineSelectStyle` · `pointMultiSelectStyle` / `pointBoxSelectStyle` · `lineMultiSelectStyle` · `defaultHighlight` · `selectionBoxStyle` · `selectionOnTop` · `waypointStyle` / `waypointSelectStyle` |
|
|
108
|
-
| 交互开关 | `boxSelect` · `multiSelect` · `waypointEditable` · `waypointVisibility` · `interactive` · `preventContextMenu` · `clickable` · `draggable` · `liveDrag` · `shortcuts` · `copy` · `remove` · `merge` |
|
|
113
|
+
| 交互开关 | `boxSelect` · `multiSelect` · `waypointEditable` · `waypointVisibility` · `interactive` · `preventContextMenu` · `clickable` · `draggable` · `liveDrag` · `lineFollowsNode` · `shortcuts` · `copy` · `remove` · `merge` |
|
|
109
114
|
| 视图与相机 | `minScale` / `maxScale` · `fitPadding` · `fitOnInit` · `initialView` · `zoomStep` |
|
|
110
115
|
| 画质与渲染 | `quality` · `width` / `height` · `pixelRatio` · `maxCanvasPixels` · `antialias` · `interactionThinLines` · `interactionNoMsaa` · `renderer` · `webglLayers` |
|
|
111
116
|
| 大数据(筛选 / 搜索 / 读数) | `denseMode` · `filter` · `filterWorker` · `searchWorker` · `progressiveInit` · `statsInterval` · `renderEmitInterval` |
|
|
@@ -178,7 +183,7 @@ const lines = [
|
|
|
178
183
|
|
|
179
184
|
- **类型**:`GisViewChannel[]`
|
|
180
185
|
- **默认值**:`[]`
|
|
181
|
-
- **说明**:通道:把若干条线路组织成并行敷设的多回线走廊,回线几何由骨架折线按偏移推导;两端可用 `from` / `to`
|
|
186
|
+
- **说明**:通道:把若干条线路组织成并行敷设的多回线走廊,回线几何由骨架折线按偏移推导;两端可用 `from` / `to` 绑在节点上,每条通道可写 `visible: false` 整条收起(成员回线、分组与拐点保留,改回 `true` 恢复)
|
|
182
187
|
- **示例**:
|
|
183
188
|
|
|
184
189
|
```js
|
|
@@ -190,6 +195,24 @@ const channels = [{
|
|
|
190
195
|
}]
|
|
191
196
|
```
|
|
192
197
|
|
|
198
|
+
#### `pointCluster`
|
|
199
|
+
|
|
200
|
+
- **类型**:`boolean | GisViewPointClusterOptions`
|
|
201
|
+
- **默认值**:关
|
|
202
|
+
- **说明**:点聚合。`true` 等价于 `{ enabled: true, radius: 60, minPoints: 2, maxZoom: 0 }`;对象写法里的 `enabled` 缺省 `true`,`radius` 是屏幕 CSS 像素半径(缺省 60,夹在 8 ~ 500),`minPoints` 是合成一个聚合圆所需的最少点数(缺省 2,最小 2),`maxZoom` 是相机比例相对 `zoomBaseScale` / 首次适应视图比例的倍数,超过后展开原始点(`0` 表示不限)。聚合用固定网格建组,单次按数据量 O(n) 扫描;平移复用当前成员,只在缩放、配置、数据、选中、拖动、合并或复制预览变化时重算。聚合期间发散初始化和追加式补点暂停;选中、拖动、待确认合并与复制预览中的点强制保持单成员。它只改展示与命中结果:`getData()` 仍是原始数据,`listPoints({ visibleOnly: false })` 仍能列全,默认 `visibleOnly: true` 会跳过被聚合圆收起的成员;`getClusters()` 含单成员展示组,`getPointCluster()` 返回归一化配置与当前 `active`,统计在 `getStats().clusterCount` / `clusterPointCount` / `clusterMs`。点击聚合圆只发 `clusterClick` / `onClusterClick`,不选中内部节点。推荐与 `denseMode` 配合使用;需要看真实符号时用 `maxZoom`,或直接把 `pointCluster` 设为 `false`。演示见 `?demo=cluster`
|
|
203
|
+
- **示例**:
|
|
204
|
+
|
|
205
|
+
```js
|
|
206
|
+
const view = createGisView(container, {
|
|
207
|
+
points,
|
|
208
|
+
pointCluster: { radius: 64, minPoints: 3, maxZoom: 2.5 }
|
|
209
|
+
})
|
|
210
|
+
|
|
211
|
+
view.updateOptions({ pointCluster: false }) // 关掉,原始点全部恢复
|
|
212
|
+
const groups = view.getClusters() // 含 count: 1 的单成员
|
|
213
|
+
const { active, radius } = view.getPointCluster() // 当前缩放档是否仍在聚合
|
|
214
|
+
```
|
|
215
|
+
|
|
193
216
|
#### `background`
|
|
194
217
|
|
|
195
218
|
- **类型**:`GisViewBackground`
|
|
@@ -263,9 +286,16 @@ view.updateOptions({ channelWidth: 0.08 }) // 没绑节点的那几条跟着
|
|
|
263
286
|
|
|
264
287
|
- **类型**:`'line' | 'group' | 'channel'`
|
|
265
288
|
- **默认值**:`'line'`
|
|
266
|
-
- **说明**:通道选中模式:点中通道里的一条回线时选中什么 —— `'line'` 只选这一条、`'group'` 连它所在的分组一起、`'channel'`
|
|
289
|
+
- **说明**:通道选中模式:点中通道里的一条回线时选中什么 —— `'line'` 只选这一条、`'group'` 连它所在的分组一起、`'channel'` 整条通道(所有分组的回线);通道以外的线路永远只选自己。普通点选与 Ctrl / ⌘ + 点击加点共用这一档高亮范围;Ctrl / ⌘ + 点击在 `group` / `channel` 下按整批取反;切换走 `updateOptions({ channelSelectMode })`,只重画一帧、不重排场景,见「通道选中模式」
|
|
267
290
|
- **参考**:见「通道选中模式(channelSelectMode)」一节,子字段在那里的表里逐个展开
|
|
268
291
|
|
|
292
|
+
#### `channelWaypointDragMode`
|
|
293
|
+
|
|
294
|
+
- **类型**:`'parallel' | 'vertex'`
|
|
295
|
+
- **默认值**:`'parallel'`
|
|
296
|
+
- **说明**:分组拐点拖动模式。`'parallel'` 沿用共用骨架 + 平行偏移,拖动时拐角处的相邻顶点可能随 miter 一起微调;`'vertex'` 只把当前分组同一 `pathIndex` 的拐点按相同世界增量平移,组内每条回线都跟着这个序号走,其他拐点与其它分组保持不动。普通线路不受这一项影响;`'vertex'` 的结果写进 `groups[].waypointOffsets`(键按含首尾端点的骨架序号算,只认中间拐点),切换走 `updateOptions({ channelWaypointDragMode })`,下一次拖动生效。切换模式不会清掉已有偏移;要恢复纯平行骨架,重写分组声明并带上当前 `path`、省略 `waypointOffsets`
|
|
297
|
+
- **参考**:见「分组拐点拖动模式(channelWaypointDragMode)」与「分组拐点:把某一组拉走」
|
|
298
|
+
|
|
269
299
|
### 样式与规则
|
|
270
300
|
|
|
271
301
|
#### `pointStyle`
|
|
@@ -377,6 +407,13 @@ view.updateOptions({ prebake: { combos: view.getSymbolCombos().combos } })
|
|
|
377
407
|
- **说明**:标签显示优化开关:**缺省关 = 强制显示**(不避让、不按 `maxCount` 截断、不设 `scanLimit` / 扫描预算,节点 / 线路的每个可见要素该出现的标签一条不少);写 `true` 与从前一致 —— 避让 / 换落点 / 数量上限 / 候选上限全部生效。标签订得密、数据量大(十万级)时建议打开,见「标签显示优化开关」
|
|
378
408
|
- **参考**:见「标签显示优化开关(labelOptimize)」一节,子字段在那里的表里逐个展开
|
|
379
409
|
|
|
410
|
+
#### `labelRender`
|
|
411
|
+
|
|
412
|
+
- **类型**:`'auto' | 'canvas' | 'dom'`
|
|
413
|
+
- **默认值**:`'auto'`
|
|
414
|
+
- **说明**:纯文本标签的容器画法。`auto` 只在**强制显示档**(缺省 `labelOptimize: false` 且 `denseMode` 未激活)启用:节点层或线路层里可画布的纯文本标签达到 **1024** 条时,该层改用一张 Canvas,不再逐条建 `.gis-view__label`。`canvas` 显式选择画布,不受 1024 条阈值限制,`labelOptimize: true` 或密集档也生效;`maxCount` / `when` / `scanLimit` / 避让与换落点仍照常执行,只是尺寸直接取画布测量结果,不创建也不测量 DOM。`dom` 始终逐条建 DOM,保持旧行为。`html: true`、函数返回 `HTMLElement`、可拖拽 / 可编辑,以及带 Canvas 不支持样式的标签在三种模式下都仍保留 DOM。它和 `html` 是两件事:`html` 只控制字符串按文本还是 HTML 解析,`html: false` 仍然会建 `div`;见「标签容器渲染(labelRender)」
|
|
415
|
+
- **参考**:见「标签容器渲染(labelRender)」一节
|
|
416
|
+
|
|
380
417
|
#### `lineLabel`
|
|
381
418
|
|
|
382
419
|
- **类型**:`GisViewLineLabelOptions | GisViewLineLabelOptions[]`
|
|
@@ -425,12 +462,12 @@ view.clearGraphics()
|
|
|
425
462
|
- **说明**:两组系数各管一件事,不重复:`pointSizeScale` / `lineWidthScale` 是与地图无关的整体放大(常数倍数,屏幕上的大小因此恒定),`pointZoomScale` / `lineZoomScale` 是「跟随地图缩放」的指数(0 表示不跟随,1 表示与地图同倍率放大,0.5 是地图放大 4 倍、要素放大 2 倍),绘制尺寸是两者相乘;`zoomBaseScale` 是联动基准,缺省取首次适应视图时的比例
|
|
426
463
|
- **参考**:见「点配置」一节,子字段在那里的表里逐个展开
|
|
427
464
|
|
|
428
|
-
#### `
|
|
465
|
+
#### `fitSpacing`
|
|
429
466
|
|
|
430
|
-
- **类型**:`boolean`
|
|
431
|
-
-
|
|
432
|
-
-
|
|
433
|
-
-
|
|
467
|
+
- **类型**:`boolean | GisViewFitSpacingOptions`
|
|
468
|
+
- **默认值**:关
|
|
469
|
+
- **说明**:适应视图的节点间距兜底。普通适应按数据包围盒铺满,远处多一个孤立点就会把比例压小、主体节点挤成一团;打开后先按普通规则算出适应比例,再用**可见节点最近的正中心距**反推一个更高的比例(最近距离达到 `minDistance` 为止)。**只改比例,不改中心**:相机中心仍取普通适应的包围盒中心,最近节点对并列时不挑中点、不跳视点。`maxZoom` 是相对普通适应比例的上限,`0` 表示不限;两种情况仍受 `maxScale` 约束。重合坐标不算有效间距,少于两个不同位置时不调整。显式写了 `initialView.scale` / `zoom` 时以显式值为准;运行时 `updateOptions` 不会当场移动相机,需要再调 `fitView()`
|
|
470
|
+
- **参考**:见「适应视图的节点间距(fitSpacing)」一节
|
|
434
471
|
|
|
435
472
|
#### `cursorStyle`
|
|
436
473
|
|
|
@@ -489,6 +526,40 @@ createGisView(container, {
|
|
|
489
526
|
})
|
|
490
527
|
```
|
|
491
528
|
|
|
529
|
+
#### `cascadeHighlight`
|
|
530
|
+
|
|
531
|
+
- **类型**:`boolean | GisViewCascadeHighlightOptions`
|
|
532
|
+
- **默认值**:关
|
|
533
|
+
- **说明**:点击级联高亮,和选中集是两份互不污染的状态。点节点时亮自身、直接相连的线路和另一端节点;点线路 / 通道回线时只亮两端节点。直接选中的节点 / 线路始终走选中样式,只有邻接项套 `pointStyle` / `lineStyle`。变化会通过 `onCascadeHighlight` / `cascadeHighlight` 事件给出,读数用 `getCascadeHighlight()`
|
|
534
|
+
- **参考**:见「点击级联高亮」一节
|
|
535
|
+
- **子字段**:
|
|
536
|
+
|
|
537
|
+
| 字段 | 类型 | 缺省 | 说明 |
|
|
538
|
+
| --- | --- | --- | --- |
|
|
539
|
+
| `enabled` | `boolean` | `true` | 开关;写对象且 `enabled: false` 等于关闭 |
|
|
540
|
+
| `scope` | `'points' \| 'both'` | `'both'` | `points` 只亮节点;`both` 同时亮直连线路(通道回线也按线路处理) |
|
|
541
|
+
| `triggerOnClick` | `boolean` | `true` | 普通单击是否触发 / 更新级联。设 `false` 时单击只走选中,并收掉旧级联 |
|
|
542
|
+
| `triggerOnMultiSelect` | `boolean` | `true` | Ctrl / ⌘ 累加点击、以及 `options.multiSelect` 的累加单击是否触发级联;设 `false` 时多选只改选中集 |
|
|
543
|
+
| `triggerOnBoxSelect` | `boolean` | `false` | 框选 / `selectInBox()` 是否触发级联。打开后框内所有命中项一起算邻接并集,直接命中的项仍走框选样式 |
|
|
544
|
+
| `pointStyle` | `GisViewPointStyle` | 琥珀色描边、`sizeScale: 1.2` | 级联节点样式,整份替换;字段同 `pointStyle` |
|
|
545
|
+
| `lineStyle` | `GisViewLineStyle` | 琥珀色、`width: 2.6`、`opacity: 0.95` | 级联线路样式,整份替换;字段同 `lineStyle` |
|
|
546
|
+
| `clearOnEmptyClick` | `boolean` | `true` | 点空白处是否收掉级联;`false` 时保留当前读数 |
|
|
547
|
+
|
|
548
|
+
`true` 等价于全部缺省值(`scope: 'both'`、`triggerOnClick: true`、`triggerOnMultiSelect: true`、`triggerOnBoxSelect: false`)。框选触发时 `origin` 取框内按数据顺序的第一个命中项,作为这一批级联的代表来源。
|
|
549
|
+
- **示例**:
|
|
550
|
+
|
|
551
|
+
```js
|
|
552
|
+
createGisView(container, {
|
|
553
|
+
points, lines, channels,
|
|
554
|
+
cascadeHighlight: {
|
|
555
|
+
scope: 'points',
|
|
556
|
+
triggerOnBoxSelect: true,
|
|
557
|
+
pointStyle: { color: '#fff7ed', strokeColor: '#f59e0b', strokeWidth: 2, sizeScale: 1.2 }
|
|
558
|
+
},
|
|
559
|
+
onCascadeHighlight: payload => console.log(payload?.pointIndexes)
|
|
560
|
+
})
|
|
561
|
+
```
|
|
562
|
+
|
|
492
563
|
#### `pointMultiSelectStyle` / `pointBoxSelectStyle`
|
|
493
564
|
|
|
494
565
|
- **类型**:`GisViewPointStyle`
|
|
@@ -607,7 +678,7 @@ view.selectInBox(rect, { selectionKinds: 'channel' }) // 仅这一次只框通
|
|
|
607
678
|
|
|
608
679
|
- **类型**:`boolean`
|
|
609
680
|
- **默认值**:`true`
|
|
610
|
-
- **说明**:组件接住右键时是否收掉浏览器的系统菜单(`contextmenu` 的默认行为):`contextMenu` 开着(或 `interactive: true` / `features: 'view'`)时组件才接右键,接住时一律 `preventDefault()`,点 / 线 / 空白 / 通道都一样;想让系统菜单自己弹就写 `false`(`onContextMenu`
|
|
681
|
+
- **说明**:组件接住右键时是否收掉浏览器的系统菜单(`contextmenu` 的默认行为):`contextMenu` 开着(或 `interactive: true` / `features: 'view'`)时组件才接右键,接住时一律 `preventDefault()`,点 / 线 / 空白 / 通道都一样;想让系统菜单自己弹就写 `false`(`onContextMenu` 照常发)。右键整个不接时(`contextMenu` 缺省关)系统菜单自然照弹
|
|
611
682
|
|
|
612
683
|
#### `clickable`
|
|
613
684
|
|
|
@@ -627,6 +698,22 @@ view.selectInBox(rect, { selectionKinds: 'channel' }) // 仅这一次只框通
|
|
|
627
698
|
- **默认值**:`true`
|
|
628
699
|
- **说明**:拖动节点时线路是否实时跟随:`false` 时拖动期间线路与通道原地不动,松手(`pointerup`)后一次性更新到新位置
|
|
629
700
|
|
|
701
|
+
#### `lineFollowsNode`
|
|
702
|
+
|
|
703
|
+
- **类型**:`boolean`
|
|
704
|
+
- **默认值**:`true`
|
|
705
|
+
- **说明**:线路 / 通道是否跟随节点的生命周期。默认 `true`:节点被 `visible: false`、`removePoints` 或筛选收起时,绑定的线路和以它为端点的通道一起退场,删节点也会连带删除这些线路 / 通道。写 `false` 后只动节点:节点隐藏或筛掉时,线路与通道停在最后一次解析出的坐标、骨架与宽度;删除节点也不删线路 / 通道;节点仍在时拖动它,线路照常实时更新。筛选没有显式写 `cascade` 时,关闭它会把默认联动从 `'binding'` 改为 `false`;条件里显式写了 `cascade` 仍以显式值为准。运行时用 `updateOptions({ lineFollowsNode })` 切换,会按新口径重算当前筛选
|
|
706
|
+
- **参考**:见「筛选」与「通道与多回线」;筛选条件自身的字段见「[筛选](../manual/14-视图与筛选.md#筛选)」
|
|
707
|
+
- **示例**:
|
|
708
|
+
|
|
709
|
+
```js
|
|
710
|
+
const view = createGisView(container, { lineFollowsNode: false })
|
|
711
|
+
|
|
712
|
+
view.removePoints('station-1') // 只删节点;绑定线路 / 通道继续按最后坐标画
|
|
713
|
+
view.setFilter({ vn_kv: { gte: 525 } }) // 未写 cascade:只隐藏不符合条件的节点
|
|
714
|
+
view.updateOptions({ lineFollowsNode: true })
|
|
715
|
+
```
|
|
716
|
+
|
|
630
717
|
#### `shortcuts`
|
|
631
718
|
|
|
632
719
|
- **类型**:`GisViewShortcuts`
|
|
@@ -947,4 +1034,6 @@ const view = createGisView(container, {
|
|
|
947
1034
|
|
|
948
1035
|
---
|
|
949
1036
|
|
|
1037
|
+
**相关章节**:[07 指针与要素编辑](07-指针与要素编辑.md) · [09 通道与多回线](09-通道与多回线.md) · [14 视图与筛选](14-视图与筛选.md) · [16 实例方法总表](16-实例方法总表.md)
|
|
1038
|
+
|
|
950
1039
|
[← 02 坐标与数据](02-坐标与数据.md) · [手册目录](../GisView.md) · [04 事件与回调 →](04-事件与回调.md)
|
|
@@ -9,10 +9,12 @@
|
|
|
9
9
|
| `onReady` | `{ canvas, gl }` | WebGL2 上下文与缓冲区就绪 |
|
|
10
10
|
| `onSelect` | `GisViewSelectPayload \| null` | 选中状态变化:点击为 `{ items, box: null, originalEvent }`,框选(默认按住 Shift)为 `{ items, box, originalEvent }`,点击空白处清空时为 `null`;Ctrl 点击节点的累加选中也走这里 |
|
|
11
11
|
| `onClick` | `GisViewClickPayload \| null` | 单击要素或空白处(空白处为 `null`):`type` / `item` / `index` / `screen` / `coordinate` / `button` / `selection` / `originalEvent` 之外还有 `action`(`type` 是 `select` / `clearSelection` / `click`,`double` 说明这一下是不是双击里的第二下,`press` / `duration` / `longPress` 说明这一次按下想做什么、按了多久、算不算长按),见「指针事件」 |
|
|
12
|
+
| `onClusterClick` | `GisViewClusterClickPayload` | 点中多成员聚合圆:带 `id` / `count` / `pointIndexes` / `pointIds` / `bounds` / `radius` / `coordinate` / `screen` / `selection` / `action`(`action.type` 恒为 `clusterClick`、`action.target` 为 `cluster`)。这一条**不会同时发 `onClick`**,也不会改动选中集;聚合圆内部的原始节点不参与普通点击 |
|
|
12
13
|
| `onDblClick` | `GisViewClickPayload \| null` | 双击要素或空白处(320ms / 6px 内连续两次单击):`action.type` 是 `dblClick`、`action.double` 为 `true` |
|
|
13
14
|
| `onPointerDown` | `GisViewPointerPayload` | 左键 / 中键 / 右键按下:命中的要素、`button` / `buttons` 与光标位置;`action.type` 是这一次按下的**意图**(`dragPoint` / `dragWaypoint` / `boxSelect` / `pan` / `copy` / `channelDraft` / `contextMenu`…),`action.target` 说明点的是什么、`action.data` 直接给到那份数据,见「指针事件」 |
|
|
14
15
|
| `onPointerUp` | `GisViewPointerPayload` | 左键 / 中键 / 右键抬起,与 `onPointerDown` 成对:`action.type` 是**刚做完的那件事**(拖过就是 `dragPoint` / `dragWaypoint` / `boxSelect` / `pan`,没拖就是 `click`),`action.moved` 说明这一次是拖还是点,另带 `action.press`(按下时的意图)/ `duration`(按了多久)/ `longPress`(长按) |
|
|
15
|
-
| `onContextMenu` | `GisViewPointerPayload` |
|
|
16
|
+
| `onContextMenu` | `GisViewPointerPayload` | 每一次右键:点、线、通道、空白都只发这一条(要素信息在载荷里);`action.type` 固定是 `contextMenu`、`action.target` 说明点的是点 / 线 / 通道 / 空白。命中通道回线时,同一载荷另带 `channelContext`(几组 / 当前哪组 / 可用交互),不再有单独的通道右键回调。要自己弹菜单就在回调里渲染。**右键回调缺省关**(`contextMenu` / `interactive` 都没写时组件不接右键),写 `interactive: true` / `contextMenu: true` 或 `features: 'view'` 才发;接住右键时系统菜单默认已被收掉(`preventContextMenu` 缺省 `true`),想看系统菜单写 `preventContextMenu: false` |
|
|
17
|
+
| `onCascadeHighlight` | `GisViewCascadeHighlightInfo \| null` | 点击级联高亮变了:载荷带来源 `origin`(节点 / 线路 / 通道回线)、范围 `scope` 与亮着的 `points` / `lines` / `pointIndexes` / `lineIndexes`,与 `getCascadeHighlight()` 同一份;点空白或关掉开关时是 `null`。这条高亮不改选中集,事件总线名为 `cascadeHighlight` |
|
|
16
18
|
| `onHover` | `GisViewHoverPayload \| null` | 悬停要素变化(空白处 / 移出画布是 `null`):与拾取结果同一份读数(`type` / `index` / `item` + 通道字段,另有光标位置 `x` / `y` / `world` / `clientX` / `clientY`、选中集 `selection` 与 `lngLat`)+ `action`(`type` 恒为 `hover`、`target` 说明停在什么上面、`button` 是 `none`、`modifiers` 是当下的修饰键);程序化悬停 `hoverAt()` 也走同一条 |
|
|
17
19
|
| `onFilter` | `GisViewFilterResult` | 筛选完成(含 Worker 异步返回):隐藏的点 / 线下标、剩余可见数量、是否用了 Worker 与计算耗时 |
|
|
18
20
|
| `onCursor` | `[number, number] \| null` | 光标世界坐标,移出画布时为 `null` |
|
|
@@ -22,7 +24,6 @@
|
|
|
22
24
|
| `onPointMerge` | `GisViewPointMergePayload \| GisViewMergeResult \| GisViewMergeFailure \| GisViewMergeSelectedPayload` | 合并节点:拖到另一个节点上时先发 `pending`(组件不弹任何界面,在回调里调 `payload.confirm()` / `cancel()` 裁决,或存下来自己接界面),之后发 `confirm`(载荷里的 `item` 是合并结果,可改 / 可取消)、`cancel`,数据并完 / 并失败再发一条 `merge`(`ok: true` / `ok: false`);拖拽入口的载荷带 `trigger`(`'collision'` / `'center'`),说明这一次按哪种时机命中;框选 / 多选之后调 `mergeSelectedPoints()` 时**逐对发 `merge`**,收尾再发一条 `phase: 'mergeSelected'` 的汇总(`merged` 逐对列出、`skipped` 说明谁没并进去),见「节点合并」 |
|
|
23
25
|
| `onRemove` | `GisViewRemovePayload` | 删除请求(Delete 键 / `requestRemove()`):`pending` 时给一份载荷说明要删什么、连带什么、能按哪些范围删(`points` / `lines` / `waypoints` / `groups` / `channels` / `actions` / `counts`),确认之后发 `phase: 'remove'`(`result` 是结果)、取消发 `phase: 'cancel'`;组件不弹任何界面,弹不弹、怎么弹都由使用方决定(在回调里调 `payload.confirm(scope)` / `payload.cancel()`,或存下来自己接界面),见「删除(remove)」 |
|
|
24
26
|
| `onWaypointChange` | `GisViewWaypointPayload` | 拐点新增 / 选中 / 删除与拖动,`phase` 为 `add` / `select` / `remove` 或拖动时的 `start` / `move` / `end`,载荷带最新线路数据与所属集合的 `group_id`;通道内的回线共用骨架,载荷是**被操作的那条回线**的推导结果。同步后端只接改变数据的 `add` / `remove` / `end`,并用 `getChannelGroupWaypoints().path` 提交整份骨架,见「通道与多回线」 |
|
|
25
|
-
| `onChannelContextMenu` | `GisViewChannelContextPayload \| null` | 右键点中通道回线:给出这条通道的上下文(有几组、当前是哪一组、分组列表与可用交互),点空白处给 `null`(用它收框);**落在节点上时也给 `null`**(点的层级高于线,见「通道右键交互框」) |
|
|
26
27
|
| `onChannelDraft` | `GisViewChannelDraftPayload` | 新增通道草稿:`start` / `from` / `ready` / `pick` / `restart` / `cancel` / `commit` / `blocked`,两个节点的信息、`routing` / `path` 与可选方案都在载荷里(`path` 是中间拐点),见「新增通道」 |
|
|
27
28
|
| `onChannelDraftClick` | `GisViewChannelDraftPayload` | 草稿里**每点一次**都发一条:`step` 为 `1` 时拿到起点、`2` 时拿到终点(线路到此结束);加上 `phase: 'pick'` 时是点在空白或点回起点;载荷与 `onChannelDraft` 相同 |
|
|
28
29
|
| `onDecorationDraft` | `GisViewDecorationDraftPayload` | 动态装饰器草稿:`start` 开启 → `hover` 跟随命中线路或节点 / `leave` 移出收掉 → 左键在目标上松开发 `ready`(空白处不发)→ `commit` / `cancel`;`target` 为 `line` / `point` / `both`,`scope` 为 `line` / `group` / `channel`,节点侧 `placement` 为 `offset` / `fixed` / `pointer`,白名单、上限与重复策略见「动态装饰器草稿」 |
|
|
@@ -154,12 +155,12 @@ view.off('*') // 不传 handler = 摘掉这个事件的全部订阅,返回摘
|
|
|
154
155
|
| 约定 | 说明 |
|
|
155
156
|
| --- | --- |
|
|
156
157
|
| 事件名与回调一一对应 | `dataChange` 就是 `onDataChange`、`selectChange` 就是 `onSelectChange`,载荷完全同一份;`GisViewEventMap` 是事件名到载荷的类型表,`EVENT_NAMES` 是运行时的名字数组 |
|
|
157
|
-
| 要 DOM
|
|
158
|
+
| 要 DOM 事件的三个 | `pointerDown` / `pointerUp` / `contextMenu` 的载荷是 `{ payload, event }`(与回调的两个参数一一对应),其余事件的载荷与回调相同 |
|
|
158
159
|
| 回调抛错不扩散 | 订阅者抛错只走 `onError`:不打断其它订阅者,也不影响组件自己的流程 |
|
|
159
160
|
| 高频事件不白算 | 组件内部按「有没有人订阅」短路(`count(name) \|\| count('*')`):没人听的时候不构造载荷,`pointer` / `hover` / `render` 这些每帧级别的事件也可以直接订阅 |
|
|
160
161
|
| 订阅时机 | 创建时的 `ready` 与首次 `dataChange` 发生在 `createGisView` 返回之前,这两条要在 options 里写回调(`onReady` 等) |
|
|
161
162
|
|
|
162
|
-
全部事件名(与 `EVENT_NAMES` 一致):`ready`、`error`、`warning`、`viewport`、`cameraChange`、`cursor`、`hover`、`pointer`、`pointerDown`、`pointerUp`、`contextMenu`、`click`、`dblClick`、`labelClick`、`labelDrag`、`labelChange`、`labelContextMenu`、`labelDblClick`、`select`、`selectChange`、`pointDrag`、`pointCopy`、`pointMerge`、`remove`、`waypointChange`、`
|
|
163
|
+
全部事件名(与 `EVENT_NAMES` 一致):`ready`、`error`、`warning`、`viewport`、`cameraChange`、`cursor`、`hover`、`pointer`、`pointerDown`、`pointerUp`、`contextMenu`、`click`、`clusterClick`、`dblClick`、`labelClick`、`labelDrag`、`labelChange`、`labelContextMenu`、`labelDblClick`、`select`、`selectChange`、`cascadeHighlight`、`pointDrag`、`pointCopy`、`pointMerge`、`remove`、`waypointChange`、`channelDraft`、`channelDraftClick`、`decorationDraft`、`channelGroupChange`、`dataChange`、`dataRendered`、`filter`、`history`、`featureChange`、`qualityChange`、`optionChange`、`shortcut`、`stats`、`render`、`destroy`,加上 `'*'`。
|
|
163
164
|
|
|
164
165
|
## 功能开关
|
|
165
166
|
|
|
@@ -182,7 +183,7 @@ createGisView('#map', {
|
|
|
182
183
|
| 预设 | 效果 |
|
|
183
184
|
| --- | --- |
|
|
184
185
|
| `'edit'` | 全开(编辑类也一起打开),等价于 `features: true` |
|
|
185
|
-
| `'view'` | 只读浏览:一次打开查看类(平移缩放、悬停、选中、右键回调、键盘),`boxSelect` / `drag` / `waypoint` / `copy` / `merge` / `remove` / `channelDraft`
|
|
186
|
+
| `'view'` | 只读浏览:一次打开查看类(平移缩放、悬停、选中、右键回调、键盘),`boxSelect` / `drag` / `waypoint` / `copy` / `merge` / `remove` / `channelDraft` 仍关着 —— 「能看能选、改不动数据」 |
|
|
186
187
|
| `'static'` | 静态图:显式全关(含标签 / 提示 / 鹰眼图),只剩画布与数据;留着这个名字方便「从全开切回静态」 |
|
|
187
188
|
|
|
188
189
|
| 开关 | 关掉之后 | 没写时跟随 |
|
|
@@ -198,8 +199,7 @@ createGisView('#map', {
|
|
|
198
199
|
| `merge` | 拖到另一个节点上合并 | 写了 `merge` 且 `merge.enabled !== false`(缺省关) |
|
|
199
200
|
| `remove` | Delete 删除选中的拐点 / 线路 / 节点(先出删除载荷,确认之后才动数据) | 写了 `remove` 且 `remove.enabled !== false`(缺省关) |
|
|
200
201
|
| `channelDraft` | 新增通道草稿(程序化 `addChannel()` 不受限) | 关(缺省) |
|
|
201
|
-
| `
|
|
202
|
-
| `contextMenu` | 右键回调(关掉之后组件不接右键,浏览器菜单照常弹;通道右键框也要它先开着) | `interactive === true`(缺省关) |
|
|
202
|
+
| `contextMenu` | 右键回调(关掉之后组件不接右键,浏览器菜单照常弹;通道回线的 `channelContext` 也随这条一起给) | `interactive === true`(缺省关) |
|
|
203
203
|
| `tooltip` | 悬停提示(悬停样式与 `onHover` 还在) | 配了 `tooltip` 且没写 `enabled: false` |
|
|
204
204
|
| `label` / `lineLabel` | 节点 / 线路标签图层 | 配了且没写 `enabled: false`(不配不产生 DOM) |
|
|
205
205
|
| `minimap` | 内置鹰眼图 | 配了 `minimap` 且没写 `enabled: false` |
|
|
@@ -209,7 +209,7 @@ createGisView('#map', {
|
|
|
209
209
|
|
|
210
210
|
### 两层开关:`features` 与详细配置(重合的那几对)
|
|
211
211
|
|
|
212
|
-
同一件事常能写在两个地方(开关表 / 各自的详细配置),这不是重复,是「**一行说清整体口径**」与「**逐项微调**」两层。逐项对完
|
|
212
|
+
同一件事常能写在两个地方(开关表 / 各自的详细配置),这不是重复,是「**一行说清整体口径**」与「**逐项微调**」两层。逐项对完 17 个开关的关系是三类:
|
|
213
213
|
|
|
214
214
|
| 能力 | 开关 | 详细配置 | 谁说了算 |
|
|
215
215
|
| --- | --- | --- | --- |
|