@pirireis/webglobeplugins 0.6.29-c → 0.6.31-a
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/bearing-line/plugin copy.js +542 -0
- package/bearing-line/plugin.js +63 -87
- package/circle-line-chain/plugin.js +18 -18
- package/package.json +1 -1
- package/util/check/get.js +1 -0
- package/write-text/context-text3.js +2 -0
|
@@ -0,0 +1,542 @@
|
|
|
1
|
+
import { pieceOfPieProgramCache } from '../programs/rings/partial-ring/piece-of-pie';
|
|
2
|
+
import { LineOnGlobeCache } from '../programs/line-on-globe/naive-accurate';
|
|
3
|
+
import { CircleCache as Circle3DCache } from '../programs/line-on-globe/circle-accurate-3d';
|
|
4
|
+
import { CircleCache, EDGE_COUNT as flatCircleEdgeCount, centerCoords2dflatDataCreator } from '../programs/line-on-globe/circle-accurate-flat';
|
|
5
|
+
import { BufferOrchestrator, BufferManager } from '../util/account';
|
|
6
|
+
import { mapGetOrThrow } from "../util/check/get";
|
|
7
|
+
import { populateFloat32Array } from "../util/jshelpers/data-filler";
|
|
8
|
+
import { ContextTextWriter } from '../write-text/context-text'
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
export const RINGPARTIAL_DRAW_MODE = Object.freeze({
|
|
12
|
+
LINE_STRIP: "LINE_STRIP",
|
|
13
|
+
TRIANGLE_FAN: "TRIANGLE_FAN",
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
const constraintFloat = (x, lowerBound, upperBound) => {
|
|
17
|
+
if (typeof x !== "number") throw new Error("type must be numberic")
|
|
18
|
+
if (lowerBound > x || x > upperBound) throw new Error(`input must be between ${lowerBound} - ${upperBound}`)
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* partial ring angle should be different on globe and mercator.
|
|
23
|
+
*
|
|
24
|
+
*/
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* @typedef {Object}textContextInjection
|
|
29
|
+
* @property {string} id
|
|
30
|
+
* @property {function} coordsAdaptor
|
|
31
|
+
* @property {function} textAdaptor
|
|
32
|
+
* @property {ContextTextWriter} writer
|
|
33
|
+
*
|
|
34
|
+
*/
|
|
35
|
+
|
|
36
|
+
// TODO UPDATE TO ContextTextWriter3
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
export default class Plugin {
|
|
40
|
+
/**
|
|
41
|
+
*
|
|
42
|
+
* @param {*} id
|
|
43
|
+
* @param {Map<[K ,{writer:ContextTextWriter, coordsAdaptor, textAdaptor}]} textContextInjectionMap import { ContextTextWriter } from '@pirireis/webglobeplugins/write-text/context-text';
|
|
44
|
+
*
|
|
45
|
+
*/
|
|
46
|
+
|
|
47
|
+
constructor(id,
|
|
48
|
+
{
|
|
49
|
+
opacity = 1,
|
|
50
|
+
textContextInjectionMap = new Map(),
|
|
51
|
+
drawVRM = true,
|
|
52
|
+
drawBearingLine = true,
|
|
53
|
+
drawAngleRing = true,
|
|
54
|
+
drawText = true,
|
|
55
|
+
circleFlatEdgeCount = flatCircleEdgeCount - 2
|
|
56
|
+
} = {}) {
|
|
57
|
+
this.id = id;
|
|
58
|
+
this._opacity = opacity;
|
|
59
|
+
this.bufferOrchestrator = new BufferOrchestrator({ capacity: 10 });
|
|
60
|
+
this._checkTextContextInjectionMap(textContextInjectionMap);
|
|
61
|
+
this._textContextInjectionMap = textContextInjectionMap;
|
|
62
|
+
this.drawVRM = drawVRM;
|
|
63
|
+
this.drawBearingLine = drawBearingLine;
|
|
64
|
+
this.drawAngleRing = drawAngleRing;
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
this.drawText = drawText;
|
|
68
|
+
|
|
69
|
+
this.circleFlatEdgeCount = circleFlatEdgeCount + 2; //circleFlatEdgeCount;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
setDoDrawVRM(bool) {
|
|
73
|
+
if (bool === this.drawVRM) return;
|
|
74
|
+
this.drawVRM = bool;
|
|
75
|
+
this.globe.DrawRender();
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
setDoDrawText(bool) {
|
|
79
|
+
if (bool === this.drawText) return;
|
|
80
|
+
this.drawText = bool;
|
|
81
|
+
this.globe.DrawRender();
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
setDoDrawText(bool) {
|
|
85
|
+
if (bool === this.drawText) return;
|
|
86
|
+
this.drawText = bool;
|
|
87
|
+
this.globe.DrawRender();
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
_checkTextContextInjectionMap(textContextInjectionMap) {
|
|
91
|
+
if (!(textContextInjectionMap instanceof Map)) throw new TypeError("textContextInjectionMap is not instance of Map");
|
|
92
|
+
textContextInjectionMap.forEach((v) => {
|
|
93
|
+
if (typeof v !== 'object') throw new TypeError("textContextInjectionMap format is wrong");
|
|
94
|
+
if (typeof v.coordsAdaptor !== 'function') throw new TypeError("textContextInjectionMap coordsAdaptor format is wrong");
|
|
95
|
+
if (typeof v.textAdaptor !== 'function') throw new TypeError("textContextInjectionMap textAdaptor format is wrong");
|
|
96
|
+
if (!(v.writer instanceof ContextTextWriter)) throw new TypeError("textContextInjectionMap writer is not instance of ContextTextWriter");
|
|
97
|
+
})
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
setDoDrawAngleRing(bool) {
|
|
101
|
+
if (bool === this.drawAngleRing) return;
|
|
102
|
+
this.drawAngleRing = bool;
|
|
103
|
+
this.globe.DrawRender();
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
settextContextInjectionMap(textContextInjectionMap, data = null) {
|
|
108
|
+
this._textContextInjectionMap = textContextInjectionMap;
|
|
109
|
+
this._textContextInjectionMap.forEach(({ writer }) => writer.clear());
|
|
110
|
+
if (data) {
|
|
111
|
+
for (const item of data) {
|
|
112
|
+
this._insertTexts(item);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
setOpacity(opacity) {
|
|
119
|
+
constraintFloat(opacity, 0, 1);
|
|
120
|
+
this._opacity = opacity;
|
|
121
|
+
this._textContextInjectionMap.forEach(({ writer }) => writer.setOpacity(opacity));
|
|
122
|
+
this.globe.DrawRender();
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
init(globe, gl) {
|
|
129
|
+
this.gl = gl;
|
|
130
|
+
this.globe = globe;
|
|
131
|
+
this.lineProgram = LineOnGlobeCache.get(globe);
|
|
132
|
+
this.ringProgram = pieceOfPieProgramCache.get(globe);
|
|
133
|
+
this.circleProgram = CircleCache.get(globe);
|
|
134
|
+
this.circle3DProgram = Circle3DCache.get(globe);
|
|
135
|
+
const circleFlatEdgeCount = this.circleFlatEdgeCount
|
|
136
|
+
{
|
|
137
|
+
// createBuffers
|
|
138
|
+
const bufferType = "DYNAMIC_DRAW";
|
|
139
|
+
const initialCapacity = this.bufferOrchestrator.capacity;
|
|
140
|
+
this.bufferManagersCompMap = new Map(
|
|
141
|
+
[
|
|
142
|
+
|
|
143
|
+
["centerCoords2d", {
|
|
144
|
+
'bufferManager': new BufferManager(gl, 2, { bufferType, initialCapacity }),
|
|
145
|
+
'adaptor': (item) => new Float32Array(globe.api_GetMercator2DPoint(item.long, item.lat)),
|
|
146
|
+
}],
|
|
147
|
+
["centerCoords2dflat", {
|
|
148
|
+
'bufferManager': new BufferManager(gl, circleFlatEdgeCount * 2, { bufferType, initialCapacity }),
|
|
149
|
+
'adaptor': (item) => item.centerCoords2dflat,
|
|
150
|
+
}],
|
|
151
|
+
["centerCoords3d", {
|
|
152
|
+
'bufferManager': new BufferManager(gl, 3, { bufferType, initialCapacity }),
|
|
153
|
+
'adaptor': (item) => new Float32Array(globe.api_GetCartesian3DPoint(item.long, item.lat, 0, 0)),
|
|
154
|
+
}],
|
|
155
|
+
["targetCoords2d", {
|
|
156
|
+
'bufferManager': new BufferManager(gl, 2, { bufferType, initialCapacity }),
|
|
157
|
+
'adaptor': (item) => new Float32Array(globe.api_GetMercator2DPoint(item.endLong, item.endLat))
|
|
158
|
+
}],
|
|
159
|
+
["targetCoords3d", {
|
|
160
|
+
'bufferManager': new BufferManager(gl, 3, { bufferType, initialCapacity }),
|
|
161
|
+
'adaptor': (item) => new Float32Array(globe.api_GetCartesian3DPoint(item.endLong, item.endLat, 0, 0))
|
|
162
|
+
}],
|
|
163
|
+
["bearingTargetCoords2d", {
|
|
164
|
+
'bufferManager': new BufferManager(gl, 2, { bufferType, initialCapacity }),
|
|
165
|
+
'adaptor': (item) => new Float32Array(globe.api_GetMercator2DPoint(item.bearingLong, item.bearingLat))
|
|
166
|
+
}],
|
|
167
|
+
["bearingTargetCoords3d", {
|
|
168
|
+
'bufferManager': new BufferManager(gl, 3, { bufferType, initialCapacity }),
|
|
169
|
+
'adaptor': (item) => new Float32Array(globe.api_GetCartesian3DPoint(item.bearingLong, item.bearingLat, 0, 0))
|
|
170
|
+
}],
|
|
171
|
+
["startAngle", {
|
|
172
|
+
'bufferManager': new BufferManager(gl, 1, { bufferType, initialCapacity }),
|
|
173
|
+
'adaptor': (item) => new Float32Array([item.startAngle])
|
|
174
|
+
}],
|
|
175
|
+
["tailAngle", {
|
|
176
|
+
'bufferManager': new BufferManager(gl, 1, { bufferType, initialCapacity }),
|
|
177
|
+
'adaptor': (item) => new Float32Array([item.tailAngle])
|
|
178
|
+
}],
|
|
179
|
+
["startAngle2d", {
|
|
180
|
+
'bufferManager': new BufferManager(gl, 1, { bufferType, initialCapacity }),
|
|
181
|
+
'adaptor': (item) => new Float32Array([item.startAngle2d])
|
|
182
|
+
}],
|
|
183
|
+
["tailAngle2d", {
|
|
184
|
+
'bufferManager': new BufferManager(gl, 1, { bufferType, initialCapacity }),
|
|
185
|
+
'adaptor': (item) => new Float32Array([item.tailAngle2d])
|
|
186
|
+
}],
|
|
187
|
+
["startAngle3d", {
|
|
188
|
+
'bufferManager': new BufferManager(gl, 1, { bufferType, initialCapacity }),
|
|
189
|
+
'adaptor': (item) => new Float32Array([item.startAngle3d])
|
|
190
|
+
}],
|
|
191
|
+
["tailAngle3d", {
|
|
192
|
+
'bufferManager': new BufferManager(gl, 1, { bufferType, initialCapacity }),
|
|
193
|
+
'adaptor': (item) => new Float32Array([item.tailAngle3d])
|
|
194
|
+
}],
|
|
195
|
+
["bearingDashRatio", {
|
|
196
|
+
'bufferManager': new BufferManager(gl, 1, { bufferType, initialCapacity }),
|
|
197
|
+
'adaptor': (item) => new Float32Array([0])
|
|
198
|
+
}],
|
|
199
|
+
["rgba", {
|
|
200
|
+
'bufferManager': new BufferManager(gl, 4, { bufferType, initialCapacity }),
|
|
201
|
+
'adaptor': (item) => new Float32Array(item.rgba)
|
|
202
|
+
}],
|
|
203
|
+
["radius", {
|
|
204
|
+
'bufferManager': new BufferManager(gl, 1, { bufferType, initialCapacity }),
|
|
205
|
+
'adaptor': (item) => new Float32Array([item.radius])
|
|
206
|
+
}],
|
|
207
|
+
["rgbaMode", {
|
|
208
|
+
'bufferManager': new BufferManager(gl, 1, { bufferType, initialCapacity }),
|
|
209
|
+
'adaptor': (item) => new Float32Array([item.rgbaMode])
|
|
210
|
+
}],
|
|
211
|
+
["dashRatio", {
|
|
212
|
+
'bufferManager': new BufferManager(gl, 1, { bufferType, initialCapacity }),
|
|
213
|
+
'adaptor': (item) => new Float32Array([item.dashRatio])
|
|
214
|
+
}],
|
|
215
|
+
["bearingAngle", {
|
|
216
|
+
'bufferManager': new BufferManager(gl, 1, { bufferType, initialCapacity }),
|
|
217
|
+
'adaptor': (item) => new Float32Array([item.bearingAngle])
|
|
218
|
+
}],
|
|
219
|
+
["bigRadius", {
|
|
220
|
+
'bufferManager': new BufferManager(gl, 1, { bufferType, initialCapacity }),
|
|
221
|
+
'adaptor': (item) => new Float32Array([item.bigRadius])
|
|
222
|
+
}],
|
|
223
|
+
["dashOpacity", {
|
|
224
|
+
'bufferManager': new BufferManager(gl, 1, { bufferType, initialCapacity }),
|
|
225
|
+
'adaptor': (item) => new Float32Array([item.dashOpacity]),
|
|
226
|
+
}],
|
|
227
|
+
|
|
228
|
+
// normal circle
|
|
229
|
+
["circleDashAngle", {
|
|
230
|
+
'bufferManager': new BufferManager(gl, 1, { bufferType, initialCapacity }),
|
|
231
|
+
'adaptor': (item) => new Float32Array([item.circleDashAngle / 360]),
|
|
232
|
+
}],
|
|
233
|
+
// CIRCLE Mercator
|
|
234
|
+
["rgbaMercator", {
|
|
235
|
+
'bufferManager': new BufferManager(gl, 4 * circleFlatEdgeCount, { bufferType, initialCapacity }),
|
|
236
|
+
'adaptor': (item) => populateFloat32Array.fillWithListData(circleFlatEdgeCount, item.rgba),
|
|
237
|
+
}],
|
|
238
|
+
["circleDashAngleMercator", {
|
|
239
|
+
'bufferManager': new BufferManager(gl, circleFlatEdgeCount, { bufferType, initialCapacity }),
|
|
240
|
+
'adaptor': (item) => populateFloat32Array.fillFloat32Array(circleFlatEdgeCount, item.circleDashAngle / 360),
|
|
241
|
+
}],
|
|
242
|
+
["dashOpacityMercator", {
|
|
243
|
+
'bufferManager': new BufferManager(gl, circleFlatEdgeCount, { bufferType, initialCapacity }),
|
|
244
|
+
'adaptor': (item) => populateFloat32Array.fillFloat32Array(circleFlatEdgeCount, item.dashOpacity),
|
|
245
|
+
}],
|
|
246
|
+
|
|
247
|
+
]
|
|
248
|
+
);
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
|
|
252
|
+
const obj = function (bufferManagerComp, divisor = 1) {
|
|
253
|
+
return { 'buffer': bufferManagerComp.bufferManager.buffer, 'stride': 0, 'offset': 0, divisor }
|
|
254
|
+
|
|
255
|
+
};
|
|
256
|
+
|
|
257
|
+
this.lineVao = this.lineProgram.createVAO(
|
|
258
|
+
...['centerCoords2d', 'centerCoords3d', 'targetCoords2d', 'targetCoords3d', 'dashRatio', 'dashOpacity', 'rgba'].map(key => obj(this.bufferManagersCompMap.get(key))));
|
|
259
|
+
this.ringVao = this.ringProgram.createVAO(
|
|
260
|
+
...['centerCoords2d', 'centerCoords3d',
|
|
261
|
+
'startAngle2d',
|
|
262
|
+
'tailAngle2d',
|
|
263
|
+
'startAngle3d',
|
|
264
|
+
'tailAngle3d',
|
|
265
|
+
'rgba',
|
|
266
|
+
'radius',
|
|
267
|
+
'rgbaMode'].map(key => obj(this.bufferManagersCompMap.get(key))));
|
|
268
|
+
{
|
|
269
|
+
this.bearingLineVAO = this.lineProgram.createVAO(
|
|
270
|
+
...['centerCoords2d', 'centerCoords3d', 'bearingTargetCoords2d', 'bearingTargetCoords3d', 'bearingDashRatio', 'dashOpacity', 'rgba'].map(key => obj(this.bufferManagersCompMap.get(key))));
|
|
271
|
+
}
|
|
272
|
+
// centerObj, startAngleObj, radiusObj, colorObj, dashRatioObj, dashOpacityObj
|
|
273
|
+
this.circleVao = this.circleProgram.createVAO(
|
|
274
|
+
...["centerCoords2dflat", "rgbaMercator", "circleDashAngleMercator", "dashOpacityMercator"].map(key => obj(this.bufferManagersCompMap.get(key)))
|
|
275
|
+
);
|
|
276
|
+
this.circle3DVao = this.circle3DProgram.createVAO(
|
|
277
|
+
...["centerCoords3d", "bigRadius", "rgba", "circleDashAngle", "dashOpacity"].map(key => obj(this.bufferManagersCompMap.get(key)))
|
|
278
|
+
);
|
|
279
|
+
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
|
|
283
|
+
|
|
284
|
+
draw3D() {
|
|
285
|
+
const { gl } = this;
|
|
286
|
+
gl.disable(gl.DEPTH_TEST);
|
|
287
|
+
const is3D = this.globe.api_GetCurrentGeometry() === 0;
|
|
288
|
+
this.lineProgram.draw(this.lineVao, this.bufferOrchestrator.length, this._opacity);
|
|
289
|
+
if (this.drawAngleRing) {
|
|
290
|
+
this.ringProgram.draw(this.bufferOrchestrator.length, this.ringVao, 360, this._opacity * 0.8, RINGPARTIAL_DRAW_MODE.TRIANGLE_FAN);
|
|
291
|
+
this.ringProgram.draw(this.bufferOrchestrator.length, this.ringVao, 360, this._opacity, RINGPARTIAL_DRAW_MODE.LINE_STRIP);
|
|
292
|
+
}
|
|
293
|
+
if (this.drawBearingLine) {
|
|
294
|
+
this.lineProgram.draw(this.bearingLineVAO, this.bufferOrchestrator.length, this._opacity * 0.8);
|
|
295
|
+
}
|
|
296
|
+
if (this.drawVRM) {
|
|
297
|
+
if (is3D) {
|
|
298
|
+
this.circle3DProgram.draw(this.circle3DVao, this.bufferOrchestrator.length, this._opacity);
|
|
299
|
+
} else {
|
|
300
|
+
this.circleProgram.draw(this.circleVao, this.bufferOrchestrator.length, this.circleFlatEdgeCount, this._opacity);
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
if (this.drawText) {
|
|
304
|
+
this._textContextInjectionMap.forEach((e) => { e.writer.draw(); });
|
|
305
|
+
}
|
|
306
|
+
gl.enable(gl.DEPTH_TEST);
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
|
|
310
|
+
/**
|
|
311
|
+
* @typedef {{key, long, lat, endLong, endLat, bearingAngle, radius, rgba:[4numbers], rgbaMode, bigRadius, dashRatio, dashOpacity, circleDashAngle}} item
|
|
312
|
+
* @property {string} key
|
|
313
|
+
* @property {number} long
|
|
314
|
+
* @property {number} lat
|
|
315
|
+
* @property {number} endLong
|
|
316
|
+
* @property {number} endLat
|
|
317
|
+
* @property {number} bearingAngle 0-360
|
|
318
|
+
* @property {number} radius angle ring radius
|
|
319
|
+
* @property {Array<4numbers>} rgba [r,g,b,a]
|
|
320
|
+
* @property {number} rgbaMode 0 constant, 1 fading, 2 hides angle ring
|
|
321
|
+
* @property {number} bigRadius undefined means it will be calculated from long, lat, endLong, endLat
|
|
322
|
+
* @property {number} dashRatio 0-1
|
|
323
|
+
* @property {number} dashOpacity 0-1
|
|
324
|
+
* @property {number} circleDashAngle 0-360
|
|
325
|
+
* @param {Array<item>} items
|
|
326
|
+
* @param {Array<string>} textWriterInjectionSubSetIDs | textContextInjectionMap keys to be used for writing text.
|
|
327
|
+
*/
|
|
328
|
+
insertBulk(items, textWriterInjectionSubSetIDs = []) {
|
|
329
|
+
const { globe, bufferOrchestrator, bufferManagersCompMap } = this;// angleTextContext, distanceTextContext,
|
|
330
|
+
const textWriterInjectionSubSets = textWriterGetOrThrow(this._textContextInjectionMap, textWriterInjectionSubSetIDs);
|
|
331
|
+
const data = []
|
|
332
|
+
for (let item of items) {
|
|
333
|
+
this._insertTexts(item, textWriterInjectionSubSets);
|
|
334
|
+
data.push(this.__insertAdaptor(item));
|
|
335
|
+
}
|
|
336
|
+
bufferOrchestrator.insertBulk(data, bufferManagersCompMap);
|
|
337
|
+
this._textContextInjectionMap.forEach((v) => {
|
|
338
|
+
const { writer } = v;
|
|
339
|
+
writer.updateOpacityBulk(items, (e) => e.key, (e) => e.rgba[3]);
|
|
340
|
+
})
|
|
341
|
+
globe.DrawRender();
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
|
|
345
|
+
|
|
346
|
+
|
|
347
|
+
deleteBulk(keys) {
|
|
348
|
+
this.bufferOrchestrator.deleteBulk(keys, this.bufferManagersCompMap);
|
|
349
|
+
this._deleteTexts(keys);
|
|
350
|
+
this.globe.DrawRender();
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
|
|
354
|
+
defrag() {
|
|
355
|
+
this.bufferOrchestrator.defrag(this.bufferManagersCompMap);
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
/**
|
|
359
|
+
*
|
|
360
|
+
* @param {Array<{key, long, lat, endLong, endLat, bearingAngle}>} items
|
|
361
|
+
* @param {Array<string>} textWriterInjectionSubSetIDs | textContextInjectionMap keys to be used for writing text.
|
|
362
|
+
*/
|
|
363
|
+
updateCoordinatesBulk(items, textWriterInjectionSubSetIDs = []) {
|
|
364
|
+
const injectionsSubSet = textWriterGetOrThrow(this._textContextInjectionMap, textWriterInjectionSubSetIDs);;
|
|
365
|
+
const { globe, bufferOrchestrator, bufferManagersCompMap, } = this;
|
|
366
|
+
const data = []
|
|
367
|
+
for (let item of items) {
|
|
368
|
+
this._insertTexts(item, injectionsSubSet);
|
|
369
|
+
data.push(this.__updateCoordsAdaptor(item));
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
bufferOrchestrator.updateBulk(data, bufferManagersCompMap, ["centerCoords2d", "centerCoords3d", "targetCoords2d", "targetCoords3d", "startAngle", "tailAngle",
|
|
373
|
+
"startAngle2d", "tailAngle2d", "startAngle3d", "tailAngle3d", "bearingTargetCoords2d", "bearingTargetCoords3d", "centerCoords2dflat",
|
|
374
|
+
"bearingAngle", "bigRadius", "radius"]);
|
|
375
|
+
globe.DrawRender();
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
|
|
379
|
+
/**
|
|
380
|
+
*
|
|
381
|
+
* @param {*} items some colums EXCEPT positional ones
|
|
382
|
+
* @param {string} propertyIDs
|
|
383
|
+
* @param {string} textWriterInjectionSubSetIDs
|
|
384
|
+
* Do NOT send empty data if property ID of this data is entered or NaN is loaded to the buffer, resulting in an unwanted behaviour.
|
|
385
|
+
*/
|
|
386
|
+
updatePartial(items, propertyIDs = [], textWriterInjectionSubSetIDs = []) { // textWriterInjectionSubSetIDs = []
|
|
387
|
+
if (propertyIDs.length === 0) console.warn("updatePartial is called with no target propertyIDs");
|
|
388
|
+
const fixedPropertyIDs = this.__fixPartialProperties(propertyIDs)
|
|
389
|
+
const { _textContextInjectionMap, bufferOrchestrator, bufferManagersCompMap } = this;
|
|
390
|
+
const writers = textWriterGetOrThrow(this._textContextInjectionMap, textWriterInjectionSubSetIDs);
|
|
391
|
+
for (let item of items) { this._insertTexts(item, writers) }
|
|
392
|
+
bufferOrchestrator.updateBulk(items, bufferManagersCompMap, fixedPropertyIDs);
|
|
393
|
+
// patch to update text opacity
|
|
394
|
+
for (const property of fixedPropertyIDs) {
|
|
395
|
+
if (property === "rgba") {
|
|
396
|
+
_textContextInjectionMap.forEach((v) => {
|
|
397
|
+
const { writer } = v;
|
|
398
|
+
writer.updateOpacityBulk(items, (e) => e.key, (e) => e.rgba[3]);
|
|
399
|
+
})
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
this.globe.DrawRender();
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
|
|
406
|
+
__insertAdaptor(item) {
|
|
407
|
+
|
|
408
|
+
const rgba = item.rgba !== undefined ? item.rgba : [0, 0, 0, 0];
|
|
409
|
+
const rgbaMode = item.rgbaMode !== undefined ? item.rgbaMode : 0;
|
|
410
|
+
const dashRatio = item.dashRatio !== undefined ? item.dashRatio : 1.0;
|
|
411
|
+
const dashOpacity = item.dashOpacity !== undefined ? item.dashOpacity : 0.9;
|
|
412
|
+
const circleDashAngle = item.circleDashAngle !== undefined ? item.circleDashAngle : 360;
|
|
413
|
+
|
|
414
|
+
const coordsData = this.__updateCoordsAdaptor(item);
|
|
415
|
+
|
|
416
|
+
return {
|
|
417
|
+
...coordsData,
|
|
418
|
+
rgba,
|
|
419
|
+
dashRatio,
|
|
420
|
+
dashOpacity,
|
|
421
|
+
circleDashAngle,
|
|
422
|
+
rgbaMode
|
|
423
|
+
};
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
|
|
427
|
+
__updateCoordsAdaptor(item) {
|
|
428
|
+
const { globe } = this;
|
|
429
|
+
const lat = radian(item.lat)
|
|
430
|
+
const long = radian(item.long)
|
|
431
|
+
const endLat = radian(item.endLat)
|
|
432
|
+
const endLong = radian(item.endLong)
|
|
433
|
+
const bigRadius = item.bigRadius !== undefined ? item.bigRadius : globe.Math.GetDist3D(item.long, item.lat, item.endLong, item.endLat);
|
|
434
|
+
const radius = item.radius !== undefined ? item.radius : bigRadius * 0.2;
|
|
435
|
+
const { long: bearingLong, lat: bearingLat } = globe.Math.FindPointByPolar(item.long, item.lat, bigRadius, item.bearingAngle)
|
|
436
|
+
const startAngle2d = calculateStartAngle(long, lat, endLong, endLat);
|
|
437
|
+
const bearingAngle2d = calculateStartAngle(long, lat, radian(bearingLong), radian(bearingLat))
|
|
438
|
+
let tailAngle2d = bearingAngle2d - startAngle2d;
|
|
439
|
+
if (tailAngle2d > 0) {
|
|
440
|
+
tailAngle2d -= Math.PI * 2;
|
|
441
|
+
}
|
|
442
|
+
const bearingAngle = radian(item.bearingAngle - 90);
|
|
443
|
+
const startAngleOfCircle = globe.Math.GetAzimuthAngle(item.long, item.lat, item.endLong, item.endLat) //startAngle2d * 180 / Math.PI;
|
|
444
|
+
const startAngle3d = radian(startAngleOfCircle) - radian(90);
|
|
445
|
+
let tailAngle3d = bearingAngle - startAngle3d;
|
|
446
|
+
if (tailAngle3d > 0) {
|
|
447
|
+
tailAngle3d -= Math.PI * 2;
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
const centerCoords2dflat = centerCoords2dflatDataCreator(globe, item.long, item.lat, item.endLong, item.endLat, { startAngleOfCircle, edgeCount: this.circleFlatEdgeCount });
|
|
451
|
+
return {
|
|
452
|
+
key: item.key,
|
|
453
|
+
lat: item.lat,
|
|
454
|
+
long: item.long,
|
|
455
|
+
endLat: item.endLat,
|
|
456
|
+
endLong: item.endLong,
|
|
457
|
+
bearingAngle,
|
|
458
|
+
radius,
|
|
459
|
+
bigRadius,
|
|
460
|
+
startAngle2d,
|
|
461
|
+
tailAngle2d,
|
|
462
|
+
startAngle3d,
|
|
463
|
+
tailAngle3d,
|
|
464
|
+
bearingLong,
|
|
465
|
+
bearingLat,
|
|
466
|
+
centerCoords2dflat
|
|
467
|
+
};
|
|
468
|
+
}
|
|
469
|
+
|
|
470
|
+
|
|
471
|
+
__fixPartialProperties(propertyIDs) {
|
|
472
|
+
const s = new Set(["rgba", "dashOpacity", "circleDashAngle"]);
|
|
473
|
+
const result = []
|
|
474
|
+
for (const item of propertyIDs) {
|
|
475
|
+
result.push(item);
|
|
476
|
+
if (s.has(item)) {
|
|
477
|
+
result.push(item + "Mercator");
|
|
478
|
+
}
|
|
479
|
+
}
|
|
480
|
+
return result;
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
//TODO free
|
|
484
|
+
free() {
|
|
485
|
+
if (this.isFreed) return;
|
|
486
|
+
this.bufferManagersCompMap.forEach(({ bufferManager, adaptor }) => {
|
|
487
|
+
bufferManager.free();
|
|
488
|
+
});
|
|
489
|
+
const { gl, globe } = this;
|
|
490
|
+
gl.deleteVertexArray(this.lineVao);
|
|
491
|
+
gl.deleteVertexArray(this.ringVao);
|
|
492
|
+
gl.deleteVertexArray(this.bearingLineVAO);
|
|
493
|
+
gl.deleteVertexArray(this.circleVao);
|
|
494
|
+
gl.deleteVertexArray(this.circle3DVao);
|
|
495
|
+
LineOnGlobeCache.release(globe);
|
|
496
|
+
pieceOfPieProgramCache.release(globe);
|
|
497
|
+
CircleCache.release(globe);
|
|
498
|
+
Circle3DCache.release(globe)
|
|
499
|
+
this.isFreed = true;
|
|
500
|
+
}
|
|
501
|
+
|
|
502
|
+
|
|
503
|
+
|
|
504
|
+
|
|
505
|
+
_insertTexts(item, textWriterInjectionSubSet) {
|
|
506
|
+
//TODO This method can be more performant if it works horizontally, tabular
|
|
507
|
+
textWriterInjectionSubSet.forEach((v) => {
|
|
508
|
+
const { coordsAdaptor, textAdaptor, writer } = v
|
|
509
|
+
const { lat, long } = coordsAdaptor(item);
|
|
510
|
+
const text = textAdaptor(item);
|
|
511
|
+
writer.insertText(item.key, lat, long, text);
|
|
512
|
+
});
|
|
513
|
+
}
|
|
514
|
+
|
|
515
|
+
|
|
516
|
+
_deleteTexts(keys) {
|
|
517
|
+
this._textContextInjectionMap.forEach((e) => {
|
|
518
|
+
e.writer.deleteTextBulk(keys);
|
|
519
|
+
});
|
|
520
|
+
}
|
|
521
|
+
|
|
522
|
+
|
|
523
|
+
}
|
|
524
|
+
|
|
525
|
+
|
|
526
|
+
|
|
527
|
+
const radian = (degree) => degree * Math.PI / 180;
|
|
528
|
+
|
|
529
|
+
const integralSec = (angle) => {
|
|
530
|
+
return Math.log(Math.tan(angle / 2 + Math.PI / 4));
|
|
531
|
+
}
|
|
532
|
+
|
|
533
|
+
const textWriterGetOrThrow = mapGetOrThrow("BearingLine textContextInjection id does not exist in map")
|
|
534
|
+
|
|
535
|
+
const calculateStartAngle = (long, lat, endLong, endLat) => {
|
|
536
|
+
const dLat = (integralSec(endLat) - integralSec(lat)); // Because lines are strectes toward poles.
|
|
537
|
+
const dLong = endLong - long;
|
|
538
|
+
|
|
539
|
+
let angle = -Math.atan2(dLat, dLong);
|
|
540
|
+
return angle;
|
|
541
|
+
}
|
|
542
|
+
|
package/bearing-line/plugin.js
CHANGED
|
@@ -5,7 +5,7 @@ import { CircleCache, EDGE_COUNT as flatCircleEdgeCount, centerCoords2dflatDataC
|
|
|
5
5
|
import { BufferOrchestrator, BufferManager } from '../util/account';
|
|
6
6
|
import { mapGetOrThrow } from "../util/check/get";
|
|
7
7
|
import { populateFloat32Array } from "../util/jshelpers/data-filler";
|
|
8
|
-
import {
|
|
8
|
+
import { ContextTextWriter3 } from '../write-text/context-text3'
|
|
9
9
|
|
|
10
10
|
|
|
11
11
|
export const RINGPARTIAL_DRAW_MODE = Object.freeze({
|
|
@@ -29,7 +29,7 @@ const constraintFloat = (x, lowerBound, upperBound) => {
|
|
|
29
29
|
* @property {string} id
|
|
30
30
|
* @property {function} coordsAdaptor
|
|
31
31
|
* @property {function} textAdaptor
|
|
32
|
-
* @property {
|
|
32
|
+
* @property {ContextTextWriter3} writer
|
|
33
33
|
*
|
|
34
34
|
*/
|
|
35
35
|
|
|
@@ -40,14 +40,15 @@ export default class Plugin {
|
|
|
40
40
|
/**
|
|
41
41
|
*
|
|
42
42
|
* @param {*} id
|
|
43
|
-
* @param {Map<[
|
|
43
|
+
* @param {Map<[key, ContextTextWriter3]>} textWritersMap
|
|
44
44
|
*
|
|
45
45
|
*/
|
|
46
46
|
|
|
47
47
|
constructor(id,
|
|
48
48
|
{
|
|
49
49
|
opacity = 1,
|
|
50
|
-
|
|
50
|
+
textWritersMap = new Map(),
|
|
51
|
+
textDataPreAdaptor = null,
|
|
51
52
|
drawVRM = true,
|
|
52
53
|
drawBearingLine = true,
|
|
53
54
|
drawAngleRing = true,
|
|
@@ -57,12 +58,15 @@ export default class Plugin {
|
|
|
57
58
|
this.id = id;
|
|
58
59
|
this._opacity = opacity;
|
|
59
60
|
this.bufferOrchestrator = new BufferOrchestrator({ capacity: 10 });
|
|
60
|
-
this.
|
|
61
|
-
this.
|
|
61
|
+
this._checkTextContextWriterInjectionMap(textWritersMap);
|
|
62
|
+
this._textWritersMap = textWritersMap;
|
|
63
|
+
this._textWritersMap.forEach((writer) => writer.keyAdaptor = (item) => item.key);
|
|
62
64
|
this.drawVRM = drawVRM;
|
|
63
65
|
this.drawBearingLine = drawBearingLine;
|
|
64
66
|
this.drawAngleRing = drawAngleRing;
|
|
65
67
|
|
|
68
|
+
this._textDataPreAdaptor = textDataPreAdaptor;
|
|
69
|
+
this._memoryForText = new Map();
|
|
66
70
|
|
|
67
71
|
this.drawText = drawText;
|
|
68
72
|
|
|
@@ -87,15 +91,7 @@ export default class Plugin {
|
|
|
87
91
|
this.globe.DrawRender();
|
|
88
92
|
}
|
|
89
93
|
|
|
90
|
-
|
|
91
|
-
if (!(textContextInjectionMap instanceof Map)) throw new TypeError("textContextInjectionMap is not instance of Map");
|
|
92
|
-
textContextInjectionMap.forEach((v) => {
|
|
93
|
-
if (typeof v !== 'object') throw new TypeError("textContextInjectionMap format is wrong");
|
|
94
|
-
if (typeof v.coordsAdaptor !== 'function') throw new TypeError("textContextInjectionMap coordsAdaptor format is wrong");
|
|
95
|
-
if (typeof v.textAdaptor !== 'function') throw new TypeError("textContextInjectionMap textAdaptor format is wrong");
|
|
96
|
-
if (!(v.writer instanceof ContextTextWriter)) throw new TypeError("textContextInjectionMap writer is not instance of ContextTextWriter");
|
|
97
|
-
})
|
|
98
|
-
}
|
|
94
|
+
|
|
99
95
|
|
|
100
96
|
setDoDrawAngleRing(bool) {
|
|
101
97
|
if (bool === this.drawAngleRing) return;
|
|
@@ -104,27 +100,14 @@ export default class Plugin {
|
|
|
104
100
|
}
|
|
105
101
|
|
|
106
102
|
|
|
107
|
-
settextContextInjectionMap(textContextInjectionMap, data = null) {
|
|
108
|
-
this._textContextInjectionMap = textContextInjectionMap;
|
|
109
|
-
this._textContextInjectionMap.forEach(({ writer }) => writer.clear());
|
|
110
|
-
if (data) {
|
|
111
|
-
for (const item of data) {
|
|
112
|
-
this._insertTexts(item);
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
|
|
118
103
|
setOpacity(opacity) {
|
|
119
104
|
constraintFloat(opacity, 0, 1);
|
|
120
105
|
this._opacity = opacity;
|
|
121
|
-
this.
|
|
106
|
+
this._textWritersMap.forEach((writer) => writer.setOpacity(opacity));
|
|
122
107
|
this.globe.DrawRender();
|
|
123
108
|
}
|
|
124
109
|
|
|
125
110
|
|
|
126
|
-
|
|
127
|
-
|
|
128
111
|
init(globe, gl) {
|
|
129
112
|
this.gl = gl;
|
|
130
113
|
this.globe = globe;
|
|
@@ -168,14 +151,7 @@ export default class Plugin {
|
|
|
168
151
|
'bufferManager': new BufferManager(gl, 3, { bufferType, initialCapacity }),
|
|
169
152
|
'adaptor': (item) => new Float32Array(globe.api_GetCartesian3DPoint(item.bearingLong, item.bearingLat, 0, 0))
|
|
170
153
|
}],
|
|
171
|
-
|
|
172
|
-
'bufferManager': new BufferManager(gl, 1, { bufferType, initialCapacity }),
|
|
173
|
-
'adaptor': (item) => new Float32Array([item.startAngle])
|
|
174
|
-
}],
|
|
175
|
-
["tailAngle", {
|
|
176
|
-
'bufferManager': new BufferManager(gl, 1, { bufferType, initialCapacity }),
|
|
177
|
-
'adaptor': (item) => new Float32Array([item.tailAngle])
|
|
178
|
-
}],
|
|
154
|
+
|
|
179
155
|
["startAngle2d", {
|
|
180
156
|
'bufferManager': new BufferManager(gl, 1, { bufferType, initialCapacity }),
|
|
181
157
|
'adaptor': (item) => new Float32Array([item.startAngle2d])
|
|
@@ -212,10 +188,7 @@ export default class Plugin {
|
|
|
212
188
|
'bufferManager': new BufferManager(gl, 1, { bufferType, initialCapacity }),
|
|
213
189
|
'adaptor': (item) => new Float32Array([item.dashRatio])
|
|
214
190
|
}],
|
|
215
|
-
|
|
216
|
-
'bufferManager': new BufferManager(gl, 1, { bufferType, initialCapacity }),
|
|
217
|
-
'adaptor': (item) => new Float32Array([item.bearingAngle])
|
|
218
|
-
}],
|
|
191
|
+
|
|
219
192
|
["bigRadius", {
|
|
220
193
|
'bufferManager': new BufferManager(gl, 1, { bufferType, initialCapacity }),
|
|
221
194
|
'adaptor': (item) => new Float32Array([item.bigRadius])
|
|
@@ -277,6 +250,7 @@ export default class Plugin {
|
|
|
277
250
|
...["centerCoords3d", "bigRadius", "rgba", "circleDashAngle", "dashOpacity"].map(key => obj(this.bufferManagersCompMap.get(key)))
|
|
278
251
|
);
|
|
279
252
|
|
|
253
|
+
|
|
280
254
|
}
|
|
281
255
|
|
|
282
256
|
|
|
@@ -301,7 +275,7 @@ export default class Plugin {
|
|
|
301
275
|
}
|
|
302
276
|
}
|
|
303
277
|
if (this.drawText) {
|
|
304
|
-
this.
|
|
278
|
+
this._textWritersMap.forEach((writer) => writer.draw());
|
|
305
279
|
}
|
|
306
280
|
gl.enable(gl.DEPTH_TEST);
|
|
307
281
|
}
|
|
@@ -323,29 +297,34 @@ export default class Plugin {
|
|
|
323
297
|
* @property {number} dashOpacity 0-1
|
|
324
298
|
* @property {number} circleDashAngle 0-360
|
|
325
299
|
* @param {Array<item>} items
|
|
326
|
-
* @param {Array<string>}
|
|
300
|
+
* @param {Array<string>} textWriterIDs | textWritersMap keys to be used for writing text.
|
|
327
301
|
*/
|
|
328
|
-
insertBulk(items,
|
|
302
|
+
insertBulk(items, { textWriterIDs = [] } = {}) {
|
|
329
303
|
const { globe, bufferOrchestrator, bufferManagersCompMap } = this;// angleTextContext, distanceTextContext,
|
|
330
|
-
const textWriterInjectionSubSets = textWriterGetOrThrow(this._textContextInjectionMap, textWriterInjectionSubSetIDs);
|
|
331
304
|
const data = []
|
|
332
305
|
for (let item of items) {
|
|
333
|
-
this._insertTexts(item, textWriterInjectionSubSets);
|
|
334
306
|
data.push(this.__insertAdaptor(item));
|
|
335
307
|
}
|
|
336
308
|
bufferOrchestrator.insertBulk(data, bufferManagersCompMap);
|
|
337
|
-
this.
|
|
338
|
-
|
|
339
|
-
writer.updateOpacityBulk(items, (e) => e.key, (e) => e.rgba[3]);
|
|
340
|
-
})
|
|
309
|
+
this.__insertTexts(items, textWriterIDs);
|
|
310
|
+
|
|
341
311
|
globe.DrawRender();
|
|
342
312
|
}
|
|
343
313
|
|
|
344
314
|
|
|
345
|
-
|
|
315
|
+
updateText(textWriterIDs) {
|
|
316
|
+
const textWritersMap = textWriterGetOrThrow(this._textWritersMap, textWriterIDs);
|
|
317
|
+
this._memoryForText.forEach((item) => {
|
|
318
|
+
textWritersMap.forEach((writer) => writer.insertText(item));
|
|
319
|
+
});
|
|
320
|
+
this.globe.DrawRender();
|
|
321
|
+
}
|
|
346
322
|
|
|
347
323
|
deleteBulk(keys) {
|
|
348
324
|
this.bufferOrchestrator.deleteBulk(keys, this.bufferManagersCompMap);
|
|
325
|
+
for (const key of keys) {
|
|
326
|
+
this._memoryForText.delete(key);
|
|
327
|
+
}
|
|
349
328
|
this._deleteTexts(keys);
|
|
350
329
|
this.globe.DrawRender();
|
|
351
330
|
}
|
|
@@ -355,23 +334,21 @@ export default class Plugin {
|
|
|
355
334
|
this.bufferOrchestrator.defrag(this.bufferManagersCompMap);
|
|
356
335
|
}
|
|
357
336
|
|
|
337
|
+
|
|
358
338
|
/**
|
|
359
|
-
*
|
|
360
339
|
* @param {Array<{key, long, lat, endLong, endLat, bearingAngle}>} items
|
|
361
|
-
* @param {Array<string>}
|
|
340
|
+
* @param {Array<string>} textWriterIDs | textWritersMap keys to be used for writing text.
|
|
362
341
|
*/
|
|
363
|
-
updateCoordinatesBulk(items,
|
|
364
|
-
const injectionsSubSet = textWriterGetOrThrow(this._textContextInjectionMap, textWriterInjectionSubSetIDs);;
|
|
342
|
+
updateCoordinatesBulk(items, { textWriterIDs = [] } = {}) {
|
|
365
343
|
const { globe, bufferOrchestrator, bufferManagersCompMap, } = this;
|
|
366
344
|
const data = []
|
|
367
345
|
for (let item of items) {
|
|
368
|
-
this._insertTexts(item, injectionsSubSet);
|
|
369
346
|
data.push(this.__updateCoordsAdaptor(item));
|
|
370
347
|
}
|
|
371
|
-
|
|
372
|
-
bufferOrchestrator.updateBulk(data, bufferManagersCompMap, ["centerCoords2d", "centerCoords3d", "targetCoords2d", "targetCoords3d",
|
|
348
|
+
this.__insertTexts(items, textWriterIDs);
|
|
349
|
+
bufferOrchestrator.updateBulk(data, bufferManagersCompMap, ["centerCoords2d", "centerCoords3d", "targetCoords2d", "targetCoords3d",
|
|
373
350
|
"startAngle2d", "tailAngle2d", "startAngle3d", "tailAngle3d", "bearingTargetCoords2d", "bearingTargetCoords3d", "centerCoords2dflat",
|
|
374
|
-
"
|
|
351
|
+
"bigRadius", "radius"]);
|
|
375
352
|
globe.DrawRender();
|
|
376
353
|
}
|
|
377
354
|
|
|
@@ -380,37 +357,46 @@ export default class Plugin {
|
|
|
380
357
|
*
|
|
381
358
|
* @param {*} items some colums EXCEPT positional ones
|
|
382
359
|
* @param {string} propertyIDs
|
|
383
|
-
* @param {string}
|
|
360
|
+
* @param {string} textWriterIDs
|
|
384
361
|
* Do NOT send empty data if property ID of this data is entered or NaN is loaded to the buffer, resulting in an unwanted behaviour.
|
|
362
|
+
*{ textWriterIDs = []}
|
|
385
363
|
*/
|
|
386
|
-
updatePartial(items, propertyIDs = [],
|
|
364
|
+
updatePartial(items, propertyIDs = [], { textWriterIDs = [] } = {}) {
|
|
387
365
|
if (propertyIDs.length === 0) console.warn("updatePartial is called with no target propertyIDs");
|
|
388
366
|
const fixedPropertyIDs = this.__fixPartialProperties(propertyIDs)
|
|
389
|
-
const {
|
|
390
|
-
const writers = textWriterGetOrThrow(this._textContextInjectionMap, textWriterInjectionSubSetIDs);
|
|
391
|
-
for (let item of items) { this._insertTexts(item, writers) }
|
|
367
|
+
const { bufferOrchestrator, bufferManagersCompMap } = this;
|
|
392
368
|
bufferOrchestrator.updateBulk(items, bufferManagersCompMap, fixedPropertyIDs);
|
|
393
369
|
// patch to update text opacity
|
|
394
|
-
|
|
395
|
-
if (property === "rgba") {
|
|
396
|
-
_textContextInjectionMap.forEach((v) => {
|
|
397
|
-
const { writer } = v;
|
|
398
|
-
writer.updateOpacityBulk(items, (e) => e.key, (e) => e.rgba[3]);
|
|
399
|
-
})
|
|
400
|
-
}
|
|
401
|
-
}
|
|
370
|
+
this.__insertTexts(items, textWriterIDs);
|
|
402
371
|
this.globe.DrawRender();
|
|
403
372
|
}
|
|
404
373
|
|
|
405
374
|
|
|
406
|
-
|
|
375
|
+
_checkTextContextWriterInjectionMap(textContextWriterInjectionMap) {
|
|
376
|
+
if (!(textContextWriterInjectionMap instanceof Map)) throw new Error("textContextWriterInjectionMap is not an instance of Map");
|
|
377
|
+
textContextWriterInjectionMap.forEach((v) => {
|
|
378
|
+
if (!(v instanceof ContextTextWriter3)) throw new Error("textContextWriterInjectionMap element is not an instance of ContextTextWriter3");
|
|
379
|
+
});
|
|
380
|
+
}
|
|
381
|
+
|
|
407
382
|
|
|
383
|
+
__insertTexts(items, textWriterIDs) {
|
|
384
|
+
const textWritersMap = textWriterGetOrThrow(this._textWritersMap, textWriterIDs);
|
|
385
|
+
for (const item of items) {
|
|
386
|
+
const oldItem = this._memoryForText.get(item.key);
|
|
387
|
+
let _item = oldItem !== undefined ? { ...oldItem, ...item } : item;
|
|
388
|
+
if (this._textDataPreAdaptor !== null) _item = this._textDataPreAdaptor(_item);
|
|
389
|
+
this._memoryForText.set(item.key, _item);
|
|
390
|
+
textWritersMap.forEach((writer) => writer.insertText(_item));
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
__insertAdaptor(item) {
|
|
408
395
|
const rgba = item.rgba !== undefined ? item.rgba : [0, 0, 0, 0];
|
|
409
396
|
const rgbaMode = item.rgbaMode !== undefined ? item.rgbaMode : 0;
|
|
410
397
|
const dashRatio = item.dashRatio !== undefined ? item.dashRatio : 1.0;
|
|
411
398
|
const dashOpacity = item.dashOpacity !== undefined ? item.dashOpacity : 0.9;
|
|
412
399
|
const circleDashAngle = item.circleDashAngle !== undefined ? item.circleDashAngle : 360;
|
|
413
|
-
|
|
414
400
|
const coordsData = this.__updateCoordsAdaptor(item);
|
|
415
401
|
|
|
416
402
|
return {
|
|
@@ -502,24 +488,14 @@ export default class Plugin {
|
|
|
502
488
|
|
|
503
489
|
|
|
504
490
|
|
|
505
|
-
_insertTexts(item, textWriterInjectionSubSet) {
|
|
506
|
-
//TODO This method can be more performant if it works horizontally, tabular
|
|
507
|
-
textWriterInjectionSubSet.forEach((v) => {
|
|
508
|
-
const { coordsAdaptor, textAdaptor, writer } = v
|
|
509
|
-
const { lat, long } = coordsAdaptor(item);
|
|
510
|
-
const text = textAdaptor(item);
|
|
511
|
-
writer.insertText(item.key, lat, long, text);
|
|
512
|
-
});
|
|
513
|
-
}
|
|
514
|
-
|
|
515
|
-
|
|
516
491
|
_deleteTexts(keys) {
|
|
517
|
-
this.
|
|
518
|
-
|
|
492
|
+
this._textWritersMap.forEach((writer) => {
|
|
493
|
+
writer.deleteTextBulk(keys);
|
|
519
494
|
});
|
|
520
495
|
}
|
|
521
496
|
|
|
522
497
|
|
|
498
|
+
|
|
523
499
|
}
|
|
524
500
|
|
|
525
501
|
|
|
@@ -41,18 +41,18 @@ export class CircleLineChainPlugin {
|
|
|
41
41
|
/**
|
|
42
42
|
*
|
|
43
43
|
* @param {*} id
|
|
44
|
-
* @param {Map<[key, ContextTextWriter3]}
|
|
44
|
+
* @param {Map<[key, ContextTextWriter3]} textWritersMap //import { ContextTextWriter3 } from "@pirireis/webglobeplugins/write-text/context-text3";
|
|
45
45
|
*/
|
|
46
46
|
constructor(id, {
|
|
47
47
|
drawCircleOn = true,
|
|
48
|
-
|
|
48
|
+
textWritersMap = new Map(),
|
|
49
49
|
textDataPreAdaptor = null,
|
|
50
50
|
circleFlatEdgeCount = flatCircleEdgeCount - 2
|
|
51
51
|
} = {}) {
|
|
52
52
|
this.id = id;
|
|
53
|
-
this.
|
|
54
|
-
this.
|
|
55
|
-
this.
|
|
53
|
+
this._checktextWritersMap(textWritersMap);
|
|
54
|
+
this._textWritersMap = textWritersMap;
|
|
55
|
+
this._textWritersMap.forEach((writer) => writer.setKeyAdaptor((v, i, c, properties) => v.__identity__));
|
|
56
56
|
this._opacity = 1;
|
|
57
57
|
this._chainListMap = new ChainListMap(keyMethod);
|
|
58
58
|
this.bufferOrchestrator = new BufferOrchestrator({ capacity: 10 });
|
|
@@ -69,10 +69,10 @@ export class CircleLineChainPlugin {
|
|
|
69
69
|
this._initOrchestrations()
|
|
70
70
|
}
|
|
71
71
|
|
|
72
|
-
|
|
73
|
-
if (!(
|
|
74
|
-
|
|
75
|
-
if (!(v instanceof ContextTextWriter3)) throw new Error("
|
|
72
|
+
_checktextWritersMap(textWritersMap) {
|
|
73
|
+
if (!(textWritersMap instanceof Map)) throw new Error("textWritersMap is not an instance of Map");
|
|
74
|
+
textWritersMap.forEach((v) => {
|
|
75
|
+
if (!(v instanceof ContextTextWriter3)) throw new Error("textWritersMap element is not an instance of ContextTextWriter3");
|
|
76
76
|
});
|
|
77
77
|
}
|
|
78
78
|
|
|
@@ -258,7 +258,7 @@ export class CircleLineChainPlugin {
|
|
|
258
258
|
* @property {number} lat
|
|
259
259
|
* @property {StyleProperties} circleProperties
|
|
260
260
|
*/
|
|
261
|
-
insertBulk(data, { textWriterIDs = [] } =
|
|
261
|
+
insertBulk(data, { textWriterIDs = [] } = {}) {
|
|
262
262
|
// first insert everything to implicit structure,
|
|
263
263
|
// then iterate over data again to update text
|
|
264
264
|
// let _reconstractChainBufferData method interact with data and bufferOrchestrator.
|
|
@@ -302,7 +302,7 @@ export class CircleLineChainPlugin {
|
|
|
302
302
|
setOpacity(opacity) {
|
|
303
303
|
if (typeof opacity !== 'number') throw new Error("opacity must be a number");
|
|
304
304
|
if (opacity < 0 || 1 < opacity) throw new Error("opacity must be between 0-1");
|
|
305
|
-
this.
|
|
305
|
+
this._textWritersMap.forEach((writer) => writer.setOpacity(opacity));
|
|
306
306
|
this._opacity = opacity;
|
|
307
307
|
this.globe.DrawRender();
|
|
308
308
|
}
|
|
@@ -322,8 +322,8 @@ export class CircleLineChainPlugin {
|
|
|
322
322
|
for (const chainKey of chainKeys) {
|
|
323
323
|
bufferKeys.push(...this._chainListMap.deleteChainAndReturnChainKeys(chainKey));
|
|
324
324
|
}
|
|
325
|
-
this.
|
|
326
|
-
this._updateTexts(chainKeys, this.
|
|
325
|
+
this._textWritersMap.forEach((writer) => writer.deleteTextBulk(bufferKeys));
|
|
326
|
+
this._updateTexts(chainKeys, this._textWritersMap.keys());
|
|
327
327
|
this.bufferOrchestrator.deleteBulk(bufferKeys, this.bufferManagersCompMap);
|
|
328
328
|
this.globe.DrawRender();
|
|
329
329
|
}
|
|
@@ -340,7 +340,7 @@ export class CircleLineChainPlugin {
|
|
|
340
340
|
bufferKeys.push(...this._chainListMap.deleteNodesBelongToAChain(chainKey, nodeKeys));
|
|
341
341
|
chainKeysToReconstuct.push(chainKey);
|
|
342
342
|
});
|
|
343
|
-
this.
|
|
343
|
+
this._textWritersMap.forEach((writer) => writer.deleteTextBulk(bufferKeys));
|
|
344
344
|
this.bufferOrchestrator.deleteBulk(bufferKeys, this.bufferManagersCompMap);
|
|
345
345
|
this._reconstructChains(chainKeysToReconstuct);
|
|
346
346
|
this._updateTexts(chainKeysToReconstuct, textWriterIDs);
|
|
@@ -359,7 +359,7 @@ export class CircleLineChainPlugin {
|
|
|
359
359
|
|
|
360
360
|
_updateTexts(chainKeys, textWriterIDs) {
|
|
361
361
|
if (textWriterIDs.length === 0) return;
|
|
362
|
-
const textWriters = textWriterGetOrThrow(this.
|
|
362
|
+
const textWriters = textWriterGetOrThrow(this._textWritersMap, textWriterIDs)
|
|
363
363
|
chainKeys.forEach((chainKey) => {
|
|
364
364
|
this._chainListMap.textUpdate(chainKey, textWriters, this._textDataPreAdaptor);
|
|
365
365
|
})
|
|
@@ -419,7 +419,7 @@ export class CircleLineChainPlugin {
|
|
|
419
419
|
CircleCache.release(this.globe);
|
|
420
420
|
Circle3DCache.release(this.globe);
|
|
421
421
|
LineToTheOriginCache.release(this.globe);
|
|
422
|
-
this.
|
|
422
|
+
this._textWritersMap.forEach((writer) => writer.free());
|
|
423
423
|
const { gl } = this;
|
|
424
424
|
gl.deleteVertexArray(this.lineVao);
|
|
425
425
|
gl.deleteVertexArray(this.circleVao2d);
|
|
@@ -434,7 +434,7 @@ export class CircleLineChainPlugin {
|
|
|
434
434
|
const { gl, globe } = this;
|
|
435
435
|
gl.disable(gl.DEPTH_TEST);
|
|
436
436
|
this.lineProgram.draw(this.lineVao, this.bufferOrchestrator.length, this._opacity);
|
|
437
|
-
this.
|
|
437
|
+
this._textWritersMap.forEach((writer) => writer.draw());
|
|
438
438
|
// this.lineToTheOriginProgram.draw(this.toOriginVao, this.bufferOrchestrator.length, this._opacity);
|
|
439
439
|
const is3D = globe.api_GetCurrentGeometry() === 0;
|
|
440
440
|
if (this._drawCircleOn) {
|
|
@@ -454,4 +454,4 @@ const radiusMethod = (globe) => (v, i, array) => {
|
|
|
454
454
|
return globe.Math.GetDist3D(v.long, v.lat, array[i + 1].long, array[i + 1].lat)
|
|
455
455
|
}
|
|
456
456
|
|
|
457
|
-
const textWriterGetOrThrow = mapGetOrThrow("
|
|
457
|
+
const textWriterGetOrThrow = mapGetOrThrow("textWriterIDs is invalid")
|
package/package.json
CHANGED
package/util/check/get.js
CHANGED