gis-view-webgl2 0.1.7 → 0.1.9

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 (70) hide show
  1. package/README.md +14 -11
  2. package/dist/gis-view.css +1 -1
  3. package/dist/index.cjs +1 -1
  4. package/dist/index.d.ts +445 -241
  5. package/dist/index.js +1 -1
  6. package/docs/AI/345/257/271/350/257/235/346/261/207/346/200/273.md +65 -498
  7. package/docs/GisView.md +1 -1
  8. package/docs/GisView/345/256/236/347/216/260/345/216/237/347/220/206.md +1 -1
  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 -478
  10. package/docs/demos/BasicDemo.vue +144 -27
  11. package/docs/demos/BatchAddDemo.vue +133 -7
  12. package/docs/demos/ChannelDemo.vue +61 -0
  13. package/docs/demos/ConnectDemo.vue +164 -33
  14. package/docs/demos/CopyMergeDemo.vue +144 -42
  15. package/docs/demos/EventDemo.vue +29 -24
  16. package/docs/demos/LabelDemo.vue +5 -5
  17. package/docs/demos/api-index.js +53 -41
  18. package/docs/demos/gis-view-demo/GisViewDemoCardHeader.vue +1 -1
  19. package/docs/demos/gis-view-demo/GisViewDemoStage.vue +1 -1
  20. package/docs/demos/gis-view-demo/panels/DataPanels.vue +1 -1
  21. package/docs/demos/gis-view-demo/useGisViewDemo.js +31 -33
  22. package/docs/format/02-/350/212/202/347/202/271/344/270/216/347/272/277/350/267/257.md +1 -0
  23. package/docs/format/04-/351/200/232/351/201/223/344/270/216/346/240/207/347/255/276.md +3 -0
  24. 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 +8 -7
  25. package/docs/from0/05-/347/233/270/346/234/272/344/270/216/344/272/244/344/272/222.md +1 -1
  26. package/docs/from0/07-/351/200/232/351/201/223/345/210/206/347/273/204/344/270/216/345/244/232/345/233/236/347/272/277.md +26 -10
  27. package/docs/index.html +136 -13
  28. package/docs/internals/15-04-/351/200/220/350/275/256/350/256/260/345/275/225-/347/203/255/345/212/233/345/233/276/344/270/216/346/200/247/350/203/275.md +10 -0
  29. package/docs/manual/02-/345/235/220/346/240/207/344/270/216/346/225/260/346/215/256.md +1 -1
  30. package/docs/manual/03-/351/205/215/347/275/256/351/241/271.md +82 -14
  31. package/docs/manual/04-/344/272/213/344/273/266/344/270/216/345/233/236/350/260/203.md +23 -17
  32. package/docs/manual/05-/347/224/273/350/264/250/344/270/216/346/211/271/351/207/217/346/233/264/346/226/260.md +65 -0
  33. 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 +9 -10
  34. 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 +100 -40
  35. package/docs/manual/08-/351/200/211/344/270/255/344/270/216/346/213/220/347/202/271.md +11 -7
  36. package/docs/manual/09-/351/200/232/351/201/223/344/270/216/345/244/232/345/233/236/347/272/277.md +66 -6
  37. 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 +226 -493
  38. package/docs/manual/12-/346/240/207/347/255/276/344/270/216/350/243/205/351/245/260.md +28 -5
  39. package/docs/manual/14-/350/247/206/345/233/276/344/270/216/347/255/233/351/200/211.md +46 -14
  40. package/docs/manual/15-/345/257/274/345/207/272/344/270/216/351/233/206/346/210/220.md +5 -2
  41. package/docs/manual/16-/345/256/236/344/276/213/346/226/271/346/263/225/346/200/273/350/241/250.md +34 -29
  42. package/docs/manual/17-/345/217/202/346/225/260/351/200/237/346/237/245.md +30 -22
  43. package/docs/manual/18-/351/200/220/346/226/271/346/263/225/347/244/272/344/276/213.md +168 -81
  44. 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 +1 -1
  45. package/docs/manual/20-/346/200/247/350/203/275/344/270/216/345/244/247/346/225/260/346/215/256.md +5 -3
  46. 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 +9 -6
  47. package/docs/steps/README.md +201 -120
  48. package/docs/steps/bench-scale.html +1 -1
  49. package/docs/steps/index.html +222 -6
  50. package/docs/steps/selftest-actions.html +26 -25
  51. package/docs/steps/selftest-data.html +1 -1
  52. package/docs/steps/selftest-demos.html +290 -16
  53. package/docs/steps/selftest-docs.html +17 -6
  54. package/docs/steps/selftest-features.html +594 -54
  55. package/docs/steps/selftest-full.html +3 -3
  56. package/docs/steps/selftest-labels.html +82 -1
  57. package/docs/steps/selftest-perf.html +62 -7
  58. package/docs/steps/selftest-select.html +71 -6
  59. package/docs/steps/step-05-pick.js +4 -8
  60. package/docs/steps/step-07-channels.js +3 -5
  61. package/docs/steps/step-08-labels.js +3 -3
  62. package/docs/steps/step-10-full.js +3 -3
  63. package/docs/steps/step-12-events.js +41 -24
  64. package/docs//344/273/2160/345/210/260/345/256/214/346/225/264/347/232/204/345/256/236/347/216/260.md +1 -0
  65. package/package.json +1 -1
  66. package/docs/ai/01-/350/265/267/346/272/220/344/270/216/350/277/231/344/273/275/346/261/207/346/200/273/347/232/204/347/224/261/346/235/245.md +0 -29
  67. package/docs/ai/02-/346/214/211/345/206/205/345/256/271/345/210/206/347/261/273-/350/277/231/344/270/200/350/267/257/351/203/275/345/234/250/346/224/271/344/273/200/344/271/210.md +0 -66
  68. package/docs/ai/03-/351/207/215/350/246/201/351/227/256/347/255/224/351/200/211/357/274/210/344/270/200/357/274/211/357/274/232/351/200/211/345/236/213/351/200/232/351/201/223/344/270/216/346/240/267/345/274/217.md +0 -178
  69. package/docs/ai/04-/351/207/215/350/246/201/351/227/256/347/255/224/351/200/211/357/274/210/344/272/214/357/274/211/357/274/232/344/272/244/344/272/222/346/200/247/350/203/275/344/270/216/346/225/260/346/215/256.md +0 -140
  70. package/docs/ai/05-/351/207/215/350/246/201/351/227/256/347/255/224/351/200/211/357/274/210/344/270/211/357/274/211/357/274/232/345/256/277/344/270/273/346/227/201/346/224/257/344/270/216/346/224/266/345/217/243.md +0 -43
@@ -58,23 +58,24 @@ const describePayload = (payload) => {
58
58
  if (payload.index !== undefined) parts.push(`index=${payload.index}`)
59
59
  if (payload.labelId !== undefined) parts.push(`labelId=${payload.labelId}`)
60
60
  if (payload.count !== undefined) parts.push(`count=${payload.count}`)
61
- if (payload.selection?.count !== undefined) parts.push(`selection=${payload.selection.count}`)
62
- if (payload.channelId !== undefined) parts.push(`channel=${payload.channelId}`)
63
- if (payload.camera !== undefined) parts.push('camera=…')
61
+ if (payload.channelId !== undefined) parts.push(`channel=${payload.channelId}`)
62
+ if (payload.camera !== undefined) parts.push('camera=…')
63
+ if (payload.idleTime !== undefined) parts.push(`idleTime=${Math.round(payload.idleTime)}ms`)
64
+ if (payload.timeout !== undefined) parts.push(`timeout=${payload.timeout}ms`)
64
65
  if (payload.screen !== undefined) parts.push(`screen=[${payload.screen.map(value => Number(value).toFixed(0)).join(', ')}]`)
65
66
  if (payload.action) {
66
67
  const action = payload.action
67
- parts.push(`action=${action.type}/${action.target}${action.moved ? '+moved' : ''}${action.double ? '+double' : ''}@${action.button ?? '-'}`)
68
- parts.push(`data=${dataLabel(action.data)}`)
68
+ parts.push(`action=${action.type}/${action.target}${action.moved ? '+moved' : ''}${action.double ? '+double' : ''}@${payload.originalEvent?.button ?? '-'}`)
69
+ parts.push(`data=${dataLabel(hitDataOf(payload))}`)
69
70
  }
70
71
  if (!parts.length) parts.push(`keys=[${Object.keys(payload).slice(0, 6).join(', ')}]`)
71
72
  return parts.join(' · ')
72
73
  }
73
74
 
74
75
  /**
75
- * action.data 给的是哪一份数据:节点 / 线路 / 通道看 id,选中集报条数,
76
- * 标签事件(labelClick / labelDrag / labelContextMenu / labelDblClick)给的是 { label, parent } —— 报内容与它挂在哪个要素上。
77
- */
76
+ * 命中的数据在载荷顶层:节点 / 线路看 item,通道看 channel,选中集报 items 条数,
77
+ * 标签(labelClick / labelDrag / labelContextMenu / labelDblClick)看 label / parent。
78
+ */
78
79
  const dataLabel = (value) => {
79
80
  if (Array.isArray(value)) return `${value.length} 项`
80
81
  if (!value || typeof value !== 'object') return String(value)
@@ -88,12 +89,10 @@ const dataLabel = (value) => {
88
89
  return value.id ?? value.channelId ?? value.name ?? `对象 keys=[${Object.keys(value).slice(0, 4).join(', ')}]`
89
90
  }
90
91
 
91
- /**
92
- * 要 DOM 事件的三个事件(pointerDown / pointerUp / contextMenu)在总线上
93
- * 载荷是 `{ payload, event }`(与回调的两个参数一一对应),其余事件载荷就是回调里那一份 —— 这里统一拆开。
94
- */
95
- const EVENT_PAYLOAD_EVENTS = new Set(['pointerDown', 'pointerUp', 'contextMenu'])
96
- const unwrapPayload = (raw, name) => (EVENT_PAYLOAD_EVENTS.has(name) && raw && typeof raw === 'object' && 'payload' in raw ? raw.payload : raw)
92
+ /** 一次事件里可读的那份顶层数据:不把通道 / 分组上下文再打成一个 action.data */
93
+ const hitDataOf = payload => payload.item ?? payload.channel ?? payload.label ?? payload.line
94
+ ?? (payload.type === 'cluster' ? { id: payload.id, count: payload.count } : null)
95
+ ?? (Array.isArray(payload.items) ? payload.items : null)
97
96
 
98
97
  /** 会带 action 的事件名:* 订阅里从载荷上认出「这一次是什么操作」 */
99
98
  const ACTION_EVENTS = new Set(['click', 'dblClick', 'pointerDown', 'pointerUp', 'contextMenu', 'labelClick', 'labelDrag', 'labelContextMenu', 'labelDblClick', 'selectChange', 'waypointChange'])
@@ -117,8 +116,11 @@ const buildOptions = () => ({
117
116
  channels: dataset.channels,
118
117
  pointStyle: { size: 7, color: '#ffffff', strokeColor: '#4c8dff', strokeWidth: 1.5 },
119
118
  lineStyle: { width: 1.5, color: 'rgba(120, 168, 226, 0.55)' },
120
- showGrid: true,
121
- fitPadding: 60,
119
+ showGrid: true,
120
+ fitPadding: 60,
121
+ // 停手 3 秒发一次 idle,事件日志与计数里都能看到;
122
+ // onCameraChange / cameraChange 也在这条链路上,高频开关打开后能看到逐帧载荷。
123
+ idleTimeout: 3000,
122
124
  label: { content: '{name}', position: 'top', gap: 8, maxCount: 30, draggable: true, editable: true, style: { color: '#27405f', fontSize: '12px' } },
123
125
  // 标签按优化档显示(限数 + 避让),见 docs/GisView.md 的「标签显示优化开关」
124
126
  labelOptimize: true,
@@ -171,7 +173,10 @@ const methods = [
171
173
  { name: 'focusOn(前三个节点, { select: true })', run: () => { const ids = (view?.getData().points ?? []).slice(0, 3).map(point => point.id ?? 0); return ids.length > 0 ? view?.focusOn(ids, { select: true }) : null } },
172
174
  { name: 'getStats()', run: () => view?.getStats() },
173
175
  { name: 'getQuality()', run: () => view?.getQuality() },
174
- { name: 'getCamera()', run: () => view?.getCamera() },
176
+ { name: 'getCamera()', run: () => view?.getCamera() },
177
+ { name: 'getScale()', run: () => view?.getScale() },
178
+ { name: 'setScale(当前 × 1.25)', run: () => view?.setScale(view.getScale() * 1.25) },
179
+ { name: 'getIdleTime()', run: () => view?.getIdleTime() },
175
180
  { name: 'getBounds()', run: () => view?.getBounds() },
176
181
  { name: 'getFilterResult()', run: () => view?.getFilterResult() },
177
182
  { name: 'getLabelStates()', run: () => view?.getLabelStates() },
@@ -257,10 +262,8 @@ const dismissCopy = () => {
257
262
 
258
263
  onMounted(() => {
259
264
  view = createGisView(container.value, buildOptions())
260
- // 一条 '*' 订阅全部事件:回调拿到的第二参就是事件名(与 options 里的 onXxx 同一份载荷)
261
- offAll = view.on('*', (raw, name) => {
262
- // 四个要 DOM 事件的事件先拆包,后面按「载荷就是回调里那一份」统一读
263
- const payload = unwrapPayload(raw, name)
265
+ // 一条 '*' 订阅全部事件:回调拿到的第二参就是事件名;载荷与 options 里的 onXxx 完全同一份
266
+ offAll = view.on('*', (payload, name) => {
264
267
  counts.value = { ...counts.value, [name]: (counts.value[name] ?? 0) + 1 }
265
268
  // 合并 / 复制:同一条 * 订阅里收中间态,确认条与日志读的是同一份载荷
266
269
  if (name === 'pointMerge') {
@@ -275,8 +278,10 @@ onMounted(() => {
275
278
  if (ACTION_EVENTS.has(name) && payload?.action) {
276
279
  // 一次操作的判读:什么操作 / 点到了什么 / 拿到了什么数据 —— 左键与右键都走这一套
277
280
  const action = payload.action
278
- const held = Object.entries(action.modifiers ?? {}).filter(([, on]) => on).map(([key]) => key).join('+')
279
- lastAction.value = `${name}:${action.type} → ${action.target}${action.data === undefined || action.data === null ? '' : ` · ${dataLabel(action.data)}`}${action.button ? ` · ${action.button}` : ''}${held ? ` · ${held}` : ''}${action.moved ? ' · 拖动过' : ''}${action.double ? ' · 双击第二下' : ''}`
281
+ const event = payload.originalEvent
282
+ const held = [event?.ctrlKey && 'ctrl', event?.metaKey && 'meta', event?.shiftKey && 'shift', event?.altKey && 'alt'].filter(Boolean).join('+')
283
+ const data = hitDataOf(payload)
284
+ lastAction.value = `${name}:${action.type} → ${action.target}${data === null || data === undefined ? '' : ` · ${dataLabel(data)}`}${event ? ` · button ${event.button}` : ''}${held ? ` · ${held}` : ''}${action.moved ? ' · 拖动过' : ''}${action.double ? ' · 双击第二下' : ''}`
280
285
  }
281
286
  if (!showHighFrequency.value && HIGH_FREQUENCY.has(name)) {
282
287
  return
@@ -350,7 +355,7 @@ onBeforeUnmount(() => {
350
355
  <div class="dv-group">
351
356
  <h3>动作判读(action)</h3>
352
357
  <p class="dv-readout">{{ lastAction }}</p>
353
- <p class="dv-hint">在画布上点一下 / 右键 / 拖一段 / 框选一下:这里按 action.type 说清「是什么操作」、action.target 说清「点到了什么」、action.data 就是那一份数据(点 / 线是数据里的对象、通道回线是通道定义)。</p>
358
+ <p class="dv-hint">在画布上点一下 / 右键 / 拖一段 / 框选一下:action.type 说清「是什么操作」、action.target 说清「点到了什么」,命中的数据直接读载荷顶层的 item / channel / label 等字段;按键与修饰键读 originalEvent。</p>
354
359
  </div>
355
360
  <div class="dv-group">
356
361
  <h3>事件计数(* 订阅)</h3>
@@ -338,11 +338,11 @@ const onLabelDrag = (payload) => {
338
338
  const onLabelContextMenu = (payload) => {
339
339
  hit.value = payload
340
340
  syncFormFromHit()
341
- // 用载荷里的 clientX / clientY 把自绘菜单贴在指针位置(系统菜单已被 preventContextMenu 收掉)
342
- menu.open = true
343
- menu.x = payload.clientX
344
- menu.y = payload.clientY
345
- pushLog('labelContextMenu', `右键 ${describeLabel(payload)} @ ${payload.clientX}, ${payload.clientY}`)
341
+ // 用原始指针事件的 clientX / clientY 把自绘菜单贴在指针位置(系统菜单已被 preventContextMenu 收掉)
342
+ menu.open = true
343
+ menu.x = payload.originalEvent?.clientX ?? 0
344
+ menu.y = payload.originalEvent?.clientY ?? 0
345
+ pushLog('labelContextMenu', `右键 ${describeLabel(payload)} @ ${menu.x}, ${menu.y}`)
346
346
  }
347
347
 
348
348
  const onLabelDblClick = (payload) => {