gis-view-webgl2 0.1.0 → 0.1.2

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 (87) hide show
  1. package/README.md +40 -8
  2. package/dist/gis-view.css +1 -1
  3. package/dist/index.cjs +1 -1
  4. package/dist/index.d.ts +1036 -249
  5. package/dist/index.js +1 -1
  6. package/docs/AI/345/257/271/350/257/235/346/261/207/346/200/273.md +194 -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 +172 -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 +617 -10
  15. package/docs/demos/ConnectDemo.vue +392 -0
  16. package/docs/demos/CopyMergeDemo.vue +980 -929
  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 +553 -497
  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 +98 -77
  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 +28 -8
  36. package/docs/format/04-/351/200/232/351/201/223/344/270/216/346/240/207/347/255/276.md +5 -4
  37. 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
  38. 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
  39. package/docs/guide/sample-document.html +4 -4
  40. package/docs/index.html +180 -9
  41. 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
  42. package/docs/internals/13-/351/271/260/347/234/274/345/233/276.md +3 -2
  43. 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
  44. 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
  45. 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
  46. package/docs/manual/02-/345/235/220/346/240/207/344/270/216/346/225/260/346/215/256.md +18 -4
  47. package/docs/manual/03-/351/205/215/347/275/256/351/241/271.md +110 -25
  48. package/docs/manual/04-/344/272/213/344/273/266/344/270/216/345/233/236/350/260/203.md +13 -8
  49. 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 +111 -10
  50. 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 +47 -9
  51. package/docs/manual/08-/351/200/211/344/270/255/344/270/216/346/213/220/347/202/271.md +17 -15
  52. package/docs/manual/09-/351/200/232/351/201/223/344/270/216/345/244/232/345/233/236/347/272/277.md +61 -11
  53. 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 +74 -7
  54. package/docs/manual/11-/346/240/267/345/274/217/344/270/216/350/247/204/345/210/231.md +3 -2
  55. package/docs/manual/12-/346/240/207/347/255/276/344/270/216/350/243/205/351/245/260.md +260 -3
  56. package/docs/manual/13-/345/212/250/346/225/210/344/270/216/345/233/276/345/205/203.md +6 -5
  57. package/docs/manual/14-/350/247/206/345/233/276/344/270/216/347/255/233/351/200/211.md +27 -14
  58. package/docs/manual/15-/345/257/274/345/207/272/344/270/216/351/233/206/346/210/220.md +142 -49
  59. package/docs/manual/16-/345/256/236/344/276/213/346/226/271/346/263/225/346/200/273/350/241/250.md +31 -29
  60. package/docs/manual/17-/345/217/202/346/225/260/351/200/237/346/237/245.md +55 -39
  61. package/docs/manual/18-/351/200/220/346/226/271/346/263/225/347/244/272/344/276/213.md +189 -64
  62. 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
  63. package/docs/manual/20-/346/200/247/350/203/275/344/270/216/345/244/247/346/225/260/346/215/256.md +42 -2
  64. 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 +22 -6
  65. package/docs/playground/index.html +5 -5
  66. package/docs/steps/README.md +14 -10
  67. package/docs/steps/check-doc-truth.mjs +1 -1
  68. package/docs/steps/selftest-actions.html +10 -10
  69. package/docs/steps/selftest-data.html +96 -14
  70. package/docs/steps/selftest-decoration.html +577 -0
  71. package/docs/steps/selftest-demo.html +6 -5
  72. package/docs/steps/selftest-demos.html +2201 -1612
  73. package/docs/steps/selftest-docs.html +89 -16
  74. package/docs/steps/selftest-effects.html +5 -5
  75. package/docs/steps/selftest-features.html +757 -86
  76. package/docs/steps/selftest-full.html +583 -583
  77. package/docs/steps/selftest-labels.html +1034 -652
  78. package/docs/steps/selftest-perf.html +1899 -1844
  79. package/docs/steps/selftest-scale.html +117 -7
  80. package/docs/steps/selftest-select.html +24 -17
  81. package/docs/steps/step-10-full.js +1 -1
  82. package/docs//346/216/245/345/217/243/345/215/217/350/256/256.md +167 -17
  83. package/docs//346/225/260/346/215/256/346/240/274/345/274/217.md +1 -1
  84. package/package.json +43 -43
  85. package/docs/demos/HistoryDemo.vue +0 -230
  86. package/docs/demos/InterfaceDemo.vue +0 -309
  87. package/docs/demos/SampleDemo.vue +0 -283
@@ -0,0 +1,338 @@
1
+ <script setup>
2
+ /**
3
+ * 扩展图形(graphic):同一张画布上放 SVG 路径、图片与外部 Canvas。
4
+ *
5
+ * 这一页只演示 graphics 这一层:三类图形都按世界坐标锚定,相机平移 / 缩放时只更新
6
+ * DOM;右侧可以现场改透明度 / 旋转 / 层级与 scaleWithView,用公开的增删改方法验证
7
+ * getGraphics() 读数。图形层不参与拾取,也不进入数据与历史。
8
+ */
9
+ import { onBeforeUnmount, onMounted, ref } from 'vue'
10
+ import { createGisView } from '../../src/index.js'
11
+ import { DEMO_CENTER, buildDemoData } from './shared/demoData.js'
12
+ import './shared/demoStyle.css'
13
+
14
+ const emit = defineEmits(['notice'])
15
+ const container = ref(null)
16
+ const countText = ref('—')
17
+ const detailText = ref('—')
18
+ const eventText = ref('正在创建视图…')
19
+ const scaleWithView = ref(false)
20
+ const opacity = ref(0.9)
21
+ const rotation = ref(-8)
22
+ const zIndex = ref(6)
23
+
24
+ const dataset = buildDemoData({ count: 18, channels: 1 })
25
+ const IMAGE_SRC = `data:image/svg+xml;charset=utf-8,${encodeURIComponent(`
26
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 96 96">
27
+ <rect x="4" y="4" width="88" height="88" rx="18" fill="#ffffff" stroke="#3678bf" stroke-width="6"/>
28
+ <circle cx="48" cy="38" r="17" fill="#eaf2fc" stroke="#3678bf" stroke-width="4"/>
29
+ <path d="M28 76l12-15 9 10 10-14 10 19z" fill="#4fd1a5"/>
30
+ <text x="48" y="86" text-anchor="middle" font-family="sans-serif" font-size="14" fill="#2f5e94">IMAGE</text>
31
+ </svg>`)}`
32
+
33
+ let view = null
34
+ let addedSeed = 0
35
+ let imageOffset = 0
36
+ const addedIds = []
37
+
38
+ const createCanvas = () => {
39
+ const canvas = document.createElement('canvas')
40
+ canvas.width = 220
41
+ canvas.height = 64
42
+ const context = canvas.getContext('2d')
43
+ const gradient = context.createLinearGradient(0, 0, 220, 0)
44
+ gradient.addColorStop(0, '#1f5f9f')
45
+ gradient.addColorStop(1, '#39a77c')
46
+ context.fillStyle = gradient
47
+ context.fillRect(0, 0, 220, 64)
48
+ context.fillStyle = 'rgba(255, 255, 255, 0.9)'
49
+ context.fillRect(12, 12, 4, 40)
50
+ context.font = '600 20px sans-serif'
51
+ context.fillText('Canvas', 30, 40)
52
+ context.font = '12px sans-serif'
53
+ context.fillStyle = 'rgba(255, 255, 255, 0.72)'
54
+ context.fillText('外部画布直接挂进图形层', 108, 39)
55
+ return canvas
56
+ }
57
+
58
+ const buildGraphics = () => [
59
+ {
60
+ id: 'graphic-zone',
61
+ type: 'path',
62
+ x: DEMO_CENTER[0],
63
+ y: DEMO_CENTER[1],
64
+ width: 300,
65
+ height: 180,
66
+ viewBox: [0, 0, 300, 180],
67
+ d: 'M20 0H280A20 20 0 0 1 300 20V160A20 20 0 0 1 280 180H20A20 20 0 0 1 0 160V20A20 20 0 0 1 20 0Z',
68
+ anchor: 'center',
69
+ fill: 'rgba(54, 120, 191, 0.08)',
70
+ stroke: '#3678bf',
71
+ strokeWidth: 2,
72
+ lineDash: [9, 6],
73
+ zIndex: 1,
74
+ scaleWithView: true
75
+ },
76
+ {
77
+ id: 'graphic-image',
78
+ type: 'image',
79
+ src: IMAGE_SRC,
80
+ alt: '扩展图形图片示例',
81
+ x: DEMO_CENTER[0] - 1.1,
82
+ y: DEMO_CENTER[1] + 0.55,
83
+ width: 62,
84
+ height: 62,
85
+ anchor: 'center',
86
+ rotation: rotation.value,
87
+ opacity: opacity.value,
88
+ zIndex: zIndex.value,
89
+ scaleWithView: scaleWithView.value
90
+ },
91
+ {
92
+ id: 'graphic-canvas',
93
+ type: 'canvas',
94
+ canvas: createCanvas(),
95
+ x: DEMO_CENTER[0] + 1.0,
96
+ y: DEMO_CENTER[1] - 0.7,
97
+ width: 154,
98
+ height: 45,
99
+ anchor: 'center',
100
+ zIndex: 4,
101
+ scaleWithView: scaleWithView.value
102
+ }
103
+ ]
104
+ const baseIds = new Set(['graphic-zone', 'graphic-image', 'graphic-canvas'])
105
+
106
+ const describe = (item) => item
107
+ ? `${item.id} · ${item.type} · (${item.x.toFixed(2)}, ${item.y.toFixed(2)}) · ${Math.round(item.width)}×${Math.round(item.height)} · z=${item.zIndex}`
108
+ : '没有这一条'
109
+
110
+ const refreshReadout = () => {
111
+ if (!view) {
112
+ return
113
+ }
114
+ const list = view.getGraphics()
115
+ countText.value = `${list.length} 个(基础 3 个 + 运行时 ${Math.max(list.length - 3, 0)} 个)· z 序 ${list.map(item => item.id).join(' → ')}`
116
+ detailText.value = describe(view.getGraphic('graphic-image'))
117
+ }
118
+
119
+ const note = (text) => {
120
+ eventText.value = text
121
+ refreshReadout()
122
+ }
123
+
124
+ const applyImageStyle = () => {
125
+ if (!view) {
126
+ return
127
+ }
128
+ const updated = view.updateGraphic('graphic-image', {
129
+ rotation: Number(rotation.value),
130
+ opacity: Number(opacity.value),
131
+ zIndex: Number(zIndex.value)
132
+ })
133
+ note(updated ? `updateGraphic:图片旋转 ${updated.rotation}° / 透明度 ${updated.opacity} / z=${updated.zIndex}` : 'updateGraphic:图片不存在')
134
+ }
135
+
136
+ const nudgeImage = () => {
137
+ if (!view) {
138
+ return
139
+ }
140
+ imageOffset = imageOffset === 0 ? 36 : 0
141
+ const updated = view.updateGraphic('graphic-image', { offset: [imageOffset, 0] })
142
+ note(updated ? `updateGraphic:offset 改为 [${imageOffset}, 0]` : 'updateGraphic:图片不存在')
143
+ }
144
+
145
+ const applyScaleWithView = () => {
146
+ if (!view) {
147
+ return
148
+ }
149
+ view.updateGraphic('graphic-image', { scaleWithView: scaleWithView.value })
150
+ view.updateGraphic('graphic-canvas', { scaleWithView: scaleWithView.value })
151
+ note(scaleWithView.value ? '图片 / Canvas 改为随相机缩放' : '图片 / Canvas 改为保持屏幕像素尺寸')
152
+ }
153
+
154
+ const addOne = () => {
155
+ if (!view) {
156
+ return
157
+ }
158
+ addedSeed += 1
159
+ const angle = addedSeed * 0.85
160
+ const item = view.addGraphic({
161
+ id: `graphic-marker-${addedSeed}`,
162
+ type: 'path',
163
+ x: DEMO_CENTER[0] + Math.cos(angle) * 0.95,
164
+ y: DEMO_CENTER[1] + Math.sin(angle) * 0.66,
165
+ width: 22,
166
+ height: 22,
167
+ viewBox: [0, 0, 22, 22],
168
+ d: 'M11 0L22 11L11 22L0 11Z',
169
+ anchor: 'center',
170
+ fill: '#ef476f',
171
+ stroke: '#ffffff',
172
+ strokeWidth: 2,
173
+ zIndex: 8
174
+ })
175
+ if (item) {
176
+ addedIds.push(item.id)
177
+ }
178
+ note(item ? `addGraphic:新增 ${item.id}` : 'addGraphic:参数无效')
179
+ }
180
+
181
+ const addMany = () => {
182
+ if (!view) {
183
+ return
184
+ }
185
+ const start = addedSeed
186
+ addedSeed += 2
187
+ const batch = [0, 1].map(slot => ({
188
+ id: `graphic-marker-${start + slot + 1}`,
189
+ type: 'path',
190
+ x: DEMO_CENTER[0] - 0.8 + slot * 0.42,
191
+ y: DEMO_CENTER[1] - 0.92,
192
+ width: 18,
193
+ height: 18,
194
+ viewBox: [0, 0, 18, 18],
195
+ d: 'M0 0H18V18H0Z',
196
+ anchor: 'center',
197
+ fill: slot ? '#f2a33c' : '#06d6a0',
198
+ stroke: '#ffffff',
199
+ strokeWidth: 2,
200
+ zIndex: 7,
201
+ rotation: slot ? 45 : 0
202
+ }))
203
+ const added = view.addGraphics(batch)
204
+ addedIds.push(...added.map(item => item.id))
205
+ note(`addGraphics:一次加入 ${added.length} 个标记`)
206
+ }
207
+
208
+ const removeLatest = () => {
209
+ if (!view) {
210
+ return
211
+ }
212
+ let id = addedIds.pop()
213
+ if (!id) {
214
+ id = [...view.getGraphics()].reverse().find(item => !baseIds.has(item.id))?.id
215
+ }
216
+ const removed = id ? view.removeGraphic(id) : null
217
+ note(removed ? `removeGraphic:删掉 ${removed.id}` : 'removeGraphic:没有运行时新增的图形可删')
218
+ }
219
+
220
+ const clearAll = () => {
221
+ if (!view) {
222
+ return
223
+ }
224
+ const count = view.clearGraphics()
225
+ addedIds.length = 0
226
+ note(`clearGraphics:清空 ${count} 个图形`)
227
+ }
228
+
229
+ const resetAll = () => {
230
+ if (!view) {
231
+ return
232
+ }
233
+ addedIds.length = 0
234
+ imageOffset = 0
235
+ view.updateOptions({ graphics: buildGraphics() })
236
+ note('updateOptions({ graphics }):恢复三类基础图形')
237
+ }
238
+
239
+ const fit = () => view?.fitView(44)
240
+ const zoomBy = factor => view?.zoomBy(factor)
241
+
242
+ onMounted(() => {
243
+ view = createGisView(container.value, {
244
+ points: dataset.points,
245
+ lines: dataset.lines,
246
+ channels: dataset.channels,
247
+ graphics: buildGraphics(),
248
+ pointStyle: { size: 6, color: '#ffffff', strokeColor: '#4c8dff', strokeWidth: 1.5 },
249
+ lineStyle: { width: 1.4, color: 'rgba(120, 168, 226, 0.52)' },
250
+ channelWidth: 2.2,
251
+ showGrid: true,
252
+ gridColor: 'rgba(126, 168, 214, 0.2)',
253
+ fitPadding: 44,
254
+ features: 'view',
255
+ label: { enabled: true, content: '{name}', position: 'top', gap: 7, maxCount: 20, style: { color: '#27405f', fontSize: '11px' } },
256
+ onReady: () => {
257
+ emit('notice', '扩展图形:SVG 路径 / 图片 / Canvas 三类都已挂到画布上')
258
+ refreshReadout()
259
+ },
260
+ onWarning: text => {
261
+ eventText.value = `warning:${text}`
262
+ }
263
+ })
264
+ })
265
+
266
+ onBeforeUnmount(() => {
267
+ view?.destroy()
268
+ view = null
269
+ })
270
+ </script>
271
+
272
+ <template>
273
+ <section class="dv-demo">
274
+ <div class="dv-stage">
275
+ <div ref="container" class="dv-canvas"></div>
276
+ <div class="dv-toolbar">
277
+ <button type="button" @click="fit">适应全部</button>
278
+ <button type="button" @click="zoomBy(1.4)">放大</button>
279
+ <button type="button" @click="zoomBy(1 / 1.4)">缩小</button>
280
+ </div>
281
+ </div>
282
+ <aside class="dv-panel">
283
+ <div class="dv-group">
284
+ <h3>三类图形</h3>
285
+ <p class="dv-hint">蓝框是 SVG <code>path</code>,左侧是内联 SVG 图片,右侧色块是外部 <code>HTMLCanvasElement</code>。三者都按世界坐标锚定,相机移动时只改这一层 DOM。</p>
286
+ <div class="dv-row">
287
+ <label><input v-model="scaleWithView" type="checkbox" data-demo="graphic-scale" @change="applyScaleWithView" /> 图片 / Canvas 随地图缩放</label>
288
+ </div>
289
+ <p class="dv-hint">不勾选时宽高保持屏幕像素;勾选后 zoomBy 会改变它们的屏幕尺寸。蓝框固定为 <code>scaleWithView: true</code>,方便对比。</p>
290
+ </div>
291
+ <div class="dv-group">
292
+ <h3>图片参数(updateGraphic)</h3>
293
+ <div class="dv-row">
294
+ <label>旋转
295
+ <input v-model.number="rotation" type="range" min="-180" max="180" step="1" data-demo="graphic-rotation" @input="applyImageStyle" />
296
+ <span>{{ rotation }}°</span>
297
+ </label>
298
+ </div>
299
+ <div class="dv-row">
300
+ <label>透明度
301
+ <input v-model.number="opacity" type="range" min="0.1" max="1" step="0.05" data-demo="graphic-opacity" @input="applyImageStyle" />
302
+ <span>{{ opacity.toFixed(2) }}</span>
303
+ </label>
304
+ </div>
305
+ <div class="dv-row">
306
+ <label>层级
307
+ <input v-model.number="zIndex" type="range" min="0" max="10" step="1" data-demo="graphic-zindex" @input="applyImageStyle" />
308
+ <span>{{ zIndex }}</span>
309
+ </label>
310
+ </div>
311
+ <div class="dv-row">
312
+ <button type="button" class="dv-button" data-demo="graphic-nudge" @click="nudgeImage">平移 36px</button>
313
+ </div>
314
+ </div>
315
+ <div class="dv-group">
316
+ <h3>运行时增删改</h3>
317
+ <div class="dv-row">
318
+ <button type="button" class="dv-button dv-button--primary" data-demo="graphic-add" @click="addOne">addGraphic</button>
319
+ <button type="button" class="dv-button" data-demo="graphic-add-many" @click="addMany">addGraphics ×2</button>
320
+ </div>
321
+ <div class="dv-row">
322
+ <button type="button" class="dv-button" data-demo="graphic-remove" @click="removeLatest">removeGraphic</button>
323
+ <button type="button" class="dv-button dv-button--danger" data-demo="graphic-clear" @click="clearAll">clearGraphics</button>
324
+ </div>
325
+ <div class="dv-row">
326
+ <button type="button" class="dv-button" data-demo="graphic-reset" @click="resetAll">恢复初始图形</button>
327
+ </div>
328
+ <p class="dv-hint">增删改只动图形层,<code>getData()</code>、历史与选中集都不受影响;批量新增只触发一次变更回调。</p>
329
+ </div>
330
+ <div class="dv-group">
331
+ <h3>读数</h3>
332
+ <p class="dv-readout" data-demo="graphic-count">{{ countText }}</p>
333
+ <p class="dv-readout" data-demo="graphic-detail">{{ detailText }}</p>
334
+ <p class="dv-readout" data-demo="graphic-event" aria-live="polite">{{ eventText }}</p>
335
+ </div>
336
+ </aside>
337
+ </section>
338
+ </template>