@pirireis/webglobeplugins 0.6.19 → 0.6.20
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.js +3 -1
- package/circle-line-chain/plugin.js +1 -3
- package/package.json +1 -1
- package/programs/line-on-globe/circle-accurate-3d.js +0 -1
- package/rangerings/rangerings copy.js +219 -0
- package/rangerings-2/plugin.js +3 -0
- package/util/account/single-attribute-buffer-management/buffer-orchestrator.js +5 -76
- package/circle-line-chain/chain-api.md +0 -336
package/bearing-line/plugin.js
CHANGED
|
@@ -473,11 +473,13 @@ export default class Plugin {
|
|
|
473
473
|
|
|
474
474
|
|
|
475
475
|
__fixPartialProperties(propertyIDs) {
|
|
476
|
-
const s = new Set("rgba", "dashOpacity", "circleDashAngle");
|
|
476
|
+
const s = new Set(["rgba", "dashOpacity", "circleDashAngle"]);
|
|
477
477
|
const result = []
|
|
478
478
|
for (const item of propertyIDs) {
|
|
479
479
|
result.push(item);
|
|
480
|
+
console.log(item + " is processing")
|
|
480
481
|
if (s.has(item)) {
|
|
482
|
+
console.log(item + "Mercator is added")
|
|
481
483
|
result.push(item + "Mercator");
|
|
482
484
|
}
|
|
483
485
|
}
|
|
@@ -138,8 +138,6 @@ export class CircleLineChainPlugin {
|
|
|
138
138
|
return new Float32Array(item.chainProperties.rgba);
|
|
139
139
|
}
|
|
140
140
|
}],
|
|
141
|
-
|
|
142
|
-
|
|
143
141
|
// Mercator buffers
|
|
144
142
|
["circleDashAngleMercator", {
|
|
145
143
|
'bufferManager': new BufferManager(gl, 1 * EDGE_COUNT_2D_CIRCLE, { bufferType, initialCapacity }),
|
|
@@ -148,7 +146,7 @@ export class CircleLineChainPlugin {
|
|
|
148
146
|
return new populateFloat32Array.fillFloat32Array(EDGE_COUNT_2D_CIRCLE, item.chainProperties.circleDashAngle / 360);
|
|
149
147
|
}
|
|
150
148
|
}],
|
|
151
|
-
["rgbaCircleMercator", {
|
|
149
|
+
["rgbaCircleMercator", { // 62
|
|
152
150
|
"bufferManager": new BufferManager(gl, 4 * EDGE_COUNT_2D_CIRCLE, { bufferType, initialCapacity }),
|
|
153
151
|
"adaptor": (item) => {
|
|
154
152
|
if (item.circleProperties?.rgba) return populateFloat32Array.fillWithListData(EDGE_COUNT_2D_CIRCLE, item.circleProperties.rgba);
|
package/package.json
CHANGED
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
import { rings } from "../programs";
|
|
2
|
+
import { COMPASS_MODES } from "./enum";
|
|
3
|
+
import { PaddingFreeAngleCache } from "../programs/rings/distancering";
|
|
4
|
+
|
|
5
|
+
import RangeRingAngleText from "./rangeringangletext";
|
|
6
|
+
const { circleProgramCache, PaddingProgramCache, CirclePaddySharedBuffer } = rings;
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* @typedef RangeRingData
|
|
10
|
+
* @property {number} centerX
|
|
11
|
+
* @property {number} centerY
|
|
12
|
+
* @property {Array<Ring>} rings
|
|
13
|
+
*
|
|
14
|
+
* @typedef Ring
|
|
15
|
+
* @property {number} radius
|
|
16
|
+
* @property {number} padding
|
|
17
|
+
* @property {[number, number, number]} color
|
|
18
|
+
*
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
export default class {
|
|
24
|
+
|
|
25
|
+
constructor(id, { oneDegreePadding = true, compass = COMPASS_MODES.REAL, showNumbers = true, numbersStyle = null, opacity = 1 } = {}) {
|
|
26
|
+
this.id = id;
|
|
27
|
+
this.compass = compass;
|
|
28
|
+
this._showNumbers = showNumbers;
|
|
29
|
+
this._numbersStyle = numbersStyle;
|
|
30
|
+
this._opacity = opacity;
|
|
31
|
+
this.circleEdgeCount = 360;
|
|
32
|
+
this._onedegreepaddingOn = oneDegreePadding;
|
|
33
|
+
this.bufferManager = null;
|
|
34
|
+
|
|
35
|
+
this._deleteCounter = 0;
|
|
36
|
+
this._deleteThreshold = 10;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
setOneDegreePaddingOn(oneDegreePadding) {
|
|
41
|
+
this._onedegreepaddingOn = oneDegreePadding;
|
|
42
|
+
this.globe.DrawRender();
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
init(globe, gl) {
|
|
46
|
+
this.gl = gl;
|
|
47
|
+
this.globe = globe;
|
|
48
|
+
this.circleFlatProgram = circleProgramCache.getProgram(globe);
|
|
49
|
+
this.paddyFlatProgram = PaddingProgramCache.getProgram(globe);
|
|
50
|
+
this.paddingFreeAngleProgram = PaddingFreeAngleCache.getProgram(globe);
|
|
51
|
+
if (this._showNumbers) {
|
|
52
|
+
this.textPlugin = new RangeRingAngleText(globe, this.id + "text", { flatCompassMode: this.compass, style: this._numbersStyle, opacity: this._opacity });
|
|
53
|
+
delete this._numbersStyle;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// TODO: Add text free
|
|
58
|
+
free() {
|
|
59
|
+
|
|
60
|
+
this.circleProgramCache?.releaseProgram(this.globe);
|
|
61
|
+
this.PaddingProgramCache?.releaseProgram(this.globe);
|
|
62
|
+
this.PaddingFreeAngleCache?.releaseProgram(this.globe);
|
|
63
|
+
this.gl.deleteVertexArray(this.bufferManager?.vao);
|
|
64
|
+
this.gl.deleteVertexArray(this.paddingBufferManager?.vao);
|
|
65
|
+
this.paddingBufferManager?.free();
|
|
66
|
+
this.bufferManager?.free();
|
|
67
|
+
this.textPlugin?.free();
|
|
68
|
+
this.circleFlatProgram = null;
|
|
69
|
+
this.paddyFlatProgram = null;
|
|
70
|
+
this.bufferManager = null;
|
|
71
|
+
this.paddingBufferManager = null;
|
|
72
|
+
this.textPlugin = null;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
setOpacity(opacity) {
|
|
77
|
+
this._opacity = opacity;
|
|
78
|
+
this.textPlugin?.setOpacity(opacity); // TODO impolement this
|
|
79
|
+
this.globe.DrawRender();
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
setGeometry() {
|
|
83
|
+
this.textPlugin?.setGeometry();
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
draw3D() {
|
|
88
|
+
const { circleFlatProgram, paddyFlatProgram, paddingFreeAngleProgram, bufferManager, compass, gl, circleEdgeCount, paddingBufferManager, _opacity } = this;
|
|
89
|
+
if (this.bufferManager !== null && bufferManager.length > 0) {
|
|
90
|
+
gl.disable(gl.DEPTH_TEST);
|
|
91
|
+
circleFlatProgram.draw(bufferManager, compass, circleEdgeCount, _opacity);
|
|
92
|
+
if (this._onedegreepaddingOn) paddyFlatProgram.draw(bufferManager, 360, compass, _opacity);
|
|
93
|
+
paddingFreeAngleProgram.draw(paddingBufferManager, compass, _opacity);
|
|
94
|
+
gl.enable(gl.DEPTH_TEST);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* @param {RangeRingData} rangeRingData
|
|
102
|
+
* 0 compass limps
|
|
103
|
+
* other real distance limp
|
|
104
|
+
*/
|
|
105
|
+
setCampass(compass) {
|
|
106
|
+
this.compass = compass;
|
|
107
|
+
this.textPlugin?.setCompass(compass);
|
|
108
|
+
this.globe.DrawRender();
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
initilizeBufferManager(initialRingCapacity, bufferDrawType) {
|
|
112
|
+
const { gl, globe } = this
|
|
113
|
+
this.bufferDrawType = bufferDrawType;
|
|
114
|
+
this.bufferManager = new CirclePaddySharedBuffer(gl, globe, { bufferType: bufferDrawType, initialRingCapacity: initialRingCapacity });
|
|
115
|
+
this.paddingBufferManager = this.paddingFreeAngleProgram.createBuffer({ bufferType: bufferDrawType, initialRingCapacity });
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* @typedef {Array<{ringID, radius, paddingRange}>} rings
|
|
121
|
+
* @param {Array<centerID:string, x:number, y:number, stepAngle:number, rgba:[4 numbers], rings:rings} items
|
|
122
|
+
*/
|
|
123
|
+
insertBulk(items) {
|
|
124
|
+
const insertData = ringItemsToCircleBufferInsertDataAdaptor(items);
|
|
125
|
+
|
|
126
|
+
this.bufferManager.insertBulk(insertData);
|
|
127
|
+
for (const item of items) {
|
|
128
|
+
item.paddingAngles = angleToPaddingAngles(item.stepAngle, 0);
|
|
129
|
+
}
|
|
130
|
+
this.paddingBufferManager.insertBulk(items);
|
|
131
|
+
this.textPlugin?.insertBulk(items);
|
|
132
|
+
this.globe.DrawRender();
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
*
|
|
138
|
+
* @param {Array<{centerID, x, y}>} items
|
|
139
|
+
*/
|
|
140
|
+
updateCentersXY(items) {
|
|
141
|
+
this.bufferManager.updateCentersXY(items);
|
|
142
|
+
this.paddingBufferManager.updateCentersXY(items);
|
|
143
|
+
this.textPlugin?.updateCentersXY(items);
|
|
144
|
+
this.globe.DrawRender();
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* @param {Array<{centerID, rgba:[4 numbers]}>} centerColors
|
|
150
|
+
*/
|
|
151
|
+
updateCentersColor(centerColors) {
|
|
152
|
+
this.bufferManager.updateCentersColor(centerColors);
|
|
153
|
+
this.paddingBufferManager.updateCentersColor(centerColors);
|
|
154
|
+
this.globe.DrawRender();
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* @param {Array<{centerID}>} centerIds
|
|
160
|
+
*/
|
|
161
|
+
removeCenters(centerIds) {
|
|
162
|
+
this.bufferManager.removeCenters(centerIds);
|
|
163
|
+
this.paddingBufferManager.removeCenters(centerIds);
|
|
164
|
+
this.textPlugin?.removeCenters(centerIds);
|
|
165
|
+
this._deleteCounter += centerIds.length;
|
|
166
|
+
if (this._deleteCounter > this._deleteThreshold) {
|
|
167
|
+
// this is naive since we are not checking the actual deletion
|
|
168
|
+
// but it works
|
|
169
|
+
this._deleteCounter = 0;
|
|
170
|
+
this.bufferManager.defrag();
|
|
171
|
+
this.paddingBufferManager.defrag();
|
|
172
|
+
}
|
|
173
|
+
this.globe.DrawRender();
|
|
174
|
+
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
/**
|
|
178
|
+
*
|
|
179
|
+
* @param {Array<{centerID, hide, textHide}>} centerHides
|
|
180
|
+
*/
|
|
181
|
+
updateCentersHide(centerHides) {
|
|
182
|
+
this.bufferManager.updateCentersHide(centerHides);
|
|
183
|
+
this.paddingBufferManager.updateCentersHide(centerHides);
|
|
184
|
+
this.textPlugin?.updateCentersHide(centerHides);
|
|
185
|
+
this.globe.DrawRender();
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
|
|
190
|
+
|
|
191
|
+
|
|
192
|
+
const ringItemsToCircleBufferInsertDataAdaptor = (ringItems) => {
|
|
193
|
+
|
|
194
|
+
const result = [];
|
|
195
|
+
for (const { centerID, x, y, rgba, rings, hide = 0, textHide = 0 } of ringItems) {
|
|
196
|
+
const resultRings = [];
|
|
197
|
+
for (const { ringID, radius, padding } of rings) {
|
|
198
|
+
resultRings.push({
|
|
199
|
+
ringID,
|
|
200
|
+
radius,
|
|
201
|
+
padding: padding / 5,
|
|
202
|
+
rgba,
|
|
203
|
+
});
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
result.push({
|
|
207
|
+
centerID,
|
|
208
|
+
x,
|
|
209
|
+
y,
|
|
210
|
+
rings: resultRings,
|
|
211
|
+
hide,
|
|
212
|
+
textHide
|
|
213
|
+
});
|
|
214
|
+
}
|
|
215
|
+
return result;
|
|
216
|
+
};
|
|
217
|
+
|
|
218
|
+
const angleToPaddingAngles = (gapDegree, offsetDegree = 0) => Array.from({ length: Math.ceil(360 / gapDegree) }, (_, i) => (i * gapDegree + offsetDegree) * Math.PI / 180);
|
|
219
|
+
|
|
@@ -29,79 +29,6 @@
|
|
|
29
29
|
|
|
30
30
|
|
|
31
31
|
|
|
32
|
-
/**
|
|
33
|
-
* Scratchpad
|
|
34
|
-
*
|
|
35
|
-
* plugin insertBulk(items){
|
|
36
|
-
* this.offsetManager.autoExtendBuffers(items.length);
|
|
37
|
-
* this.offsetManager.assignOffsets(items); // read item.keys and assign offsets to them.
|
|
38
|
-
* this.attrib1BufferManager.insertBulk(items.map(item => this.attrib1Block(item)), );
|
|
39
|
-
* this.attrib2BufferManager.insertBulk();
|
|
40
|
-
* if (this.attrib3isInNeed) this.attrib3BufferManager.insertBulk(items);
|
|
41
|
-
* this.globe.DrawRender();
|
|
42
|
-
* }
|
|
43
|
-
*
|
|
44
|
-
* useTheCaseThatRequiresAttrib3(){
|
|
45
|
-
* // generate items from other buffers if possible.
|
|
46
|
-
* }
|
|
47
|
-
*
|
|
48
|
-
*
|
|
49
|
-
* assignOffsets(items){
|
|
50
|
-
* for (const item of items){
|
|
51
|
-
* const offset = this.offsetManager.getOffset(item.key) || this.offsetManager.nextOffset();
|
|
52
|
-
* item.__offset__ = offset;
|
|
53
|
-
*
|
|
54
|
-
* allBuffers = [attrib1BufferManager, attrib2BufferManager, attrib3BufferManager]
|
|
55
|
-
* // // not single responsibility ..
|
|
56
|
-
* defrag(allBuffers){
|
|
57
|
-
* for (const bufferManager of allBuffers){
|
|
58
|
-
* bufferManager.defrag(this.offsetManager.offsetMap);
|
|
59
|
-
* }
|
|
60
|
-
* this.offsetManager._defrag();
|
|
61
|
-
* }
|
|
62
|
-
*
|
|
63
|
-
*/
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
/**
|
|
67
|
-
*
|
|
68
|
-
* attrib1BufferManager.insertBulk( items) {
|
|
69
|
-
* gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
|
|
70
|
-
* for (const item of items) {
|
|
71
|
-
* const block = this.itemToBlock(item); // this changes based on inserted data structure and expected block structure.
|
|
72
|
-
* gl.bufferSubData(gl.ARRAY_BUFFER, item.__offset__, block);
|
|
73
|
-
* }
|
|
74
|
-
* gl.bindBuffer(gl.ARRAY_BUFFER, null);
|
|
75
|
-
* }
|
|
76
|
-
*
|
|
77
|
-
* deleteBulk(offsets){
|
|
78
|
-
* gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
|
|
79
|
-
* for (const offset of offsets) {
|
|
80
|
-
* gl.bufferSubData(gl.ARRAY_BUFFER, offset, emptyBlock);
|
|
81
|
-
* }
|
|
82
|
-
* gl.bindBuffer(gl.ARRAY_BUFFER, null);
|
|
83
|
-
* }
|
|
84
|
-
*
|
|
85
|
-
*
|
|
86
|
-
* //
|
|
87
|
-
* defrag(offsetMap){
|
|
88
|
-
* const newArray = new Float32Array(itemCount * itemSize);
|
|
89
|
-
* const bufferData = this._getBufferData();
|
|
90
|
-
* let newOffSet = 0;
|
|
91
|
-
* for (const [key, offSet] of offsetMap) {
|
|
92
|
-
* const bufferOffset = offset;
|
|
93
|
-
* newArray.set(bufferData.slice(bufferOffset, bufferOffset + itemSize), newOffSet);
|
|
94
|
-
newOffset += itemSize * 4;
|
|
95
|
-
}
|
|
96
|
-
*
|
|
97
|
-
* gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
|
|
98
|
-
*
|
|
99
|
-
* }
|
|
100
|
-
*
|
|
101
|
-
* ----------------
|
|
102
|
-
|
|
103
|
-
*/
|
|
104
|
-
|
|
105
32
|
const EXTRA_SIZE = 10;
|
|
106
33
|
|
|
107
34
|
export class BufferOrchestrator {
|
|
@@ -137,7 +64,6 @@ export class BufferOrchestrator {
|
|
|
137
64
|
for (const [key, { bufferManager, adaptor }] of bufferManagersMap) {
|
|
138
65
|
bufferManager.insertBulk(items.map(adaptor), offsets);
|
|
139
66
|
}
|
|
140
|
-
|
|
141
67
|
}
|
|
142
68
|
|
|
143
69
|
|
|
@@ -155,7 +81,9 @@ export class BufferOrchestrator {
|
|
|
155
81
|
}
|
|
156
82
|
if (bufferKeys) {
|
|
157
83
|
for (const key of bufferKeys) {
|
|
158
|
-
const
|
|
84
|
+
const bufferManagerComp = bufferManagersMap.get(key);
|
|
85
|
+
if (bufferManagerComp === undefined) throw new Error("updateBulk bufferKey does not exist");
|
|
86
|
+
const { bufferManager, adaptor } = bufferManagerComp;
|
|
159
87
|
bufferManager.insertBulk(items.map(adaptor), offsets);
|
|
160
88
|
}
|
|
161
89
|
} else {
|
|
@@ -228,7 +156,8 @@ export class BufferOrchestrator {
|
|
|
228
156
|
}
|
|
229
157
|
}
|
|
230
158
|
this._defrag();
|
|
231
|
-
this._length =
|
|
159
|
+
this._length = offsetMap.size;
|
|
160
|
+
this._capacity = newCapacity;
|
|
232
161
|
this.tombstoneOffsets = [];
|
|
233
162
|
}
|
|
234
163
|
|
|
@@ -1,336 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
## insertBulk
|
|
3
|
-
```json
|
|
4
|
-
[
|
|
5
|
-
{
|
|
6
|
-
"chainID": "Mağrib",
|
|
7
|
-
"points": [
|
|
8
|
-
{
|
|
9
|
-
"id": "Fas",
|
|
10
|
-
"long": 0,
|
|
11
|
-
"lat": 0,
|
|
12
|
-
},
|
|
13
|
-
{
|
|
14
|
-
"id":"Cezayir",
|
|
15
|
-
"long": 10,
|
|
16
|
-
"lat": 20,
|
|
17
|
-
},
|
|
18
|
-
{
|
|
19
|
-
"id":"Tunus",
|
|
20
|
-
"long": 10,
|
|
21
|
-
"lat": 15
|
|
22
|
-
}
|
|
23
|
-
],
|
|
24
|
-
"rgba": [1,0,0,1],
|
|
25
|
-
"dashRatio": 0.1,
|
|
26
|
-
"dashOpacity": 0.5,
|
|
27
|
-
"circleDashAngle": 15,
|
|
28
|
-
},
|
|
29
|
-
]
|
|
30
|
-
```
|
|
31
|
-
|
|
32
|
-
```js
|
|
33
|
-
// ["distance"]
|
|
34
|
-
updateCoordinatesBulk( items, contextTextWriterIDs=[]) {
|
|
35
|
-
for ( const item of items){
|
|
36
|
-
this._updateCoordsChain(item.chainID, item.points);
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
_updateCoordsChain(chainID, nodes){
|
|
41
|
-
const chain = this._chainMap(chainID); // chain is a `list`
|
|
42
|
-
const updateIDs = [];
|
|
43
|
-
for ( let i = 0; i< chain.length; i++){
|
|
44
|
-
if ( )
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
```
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
```js
|
|
51
|
-
// text
|
|
52
|
-
const textContextMap = new Map(
|
|
53
|
-
[
|
|
54
|
-
[
|
|
55
|
-
"distance",
|
|
56
|
-
{
|
|
57
|
-
writer: new ContextTextWriter(globe,),
|
|
58
|
-
coordsAdaptor: (item, index, array) => { //
|
|
59
|
-
const { long, lat } = globe.Math.GetMidPoint(item.long, item.lat, item.endLong, item.endLat);
|
|
60
|
-
return {
|
|
61
|
-
long,
|
|
62
|
-
lat,
|
|
63
|
-
}
|
|
64
|
-
},
|
|
65
|
-
textAdaptor: (item) => {
|
|
66
|
-
const distance = globe.Math.GetDist2D(item.long, item.lat, item.endLong, item.endLat);
|
|
67
|
-
return distance.toFixed(2) + "m";
|
|
68
|
-
},
|
|
69
|
-
|
|
70
|
-
}
|
|
71
|
-
]
|
|
72
|
-
]
|
|
73
|
-
)
|
|
74
|
-
|
|
75
|
-
// ["distance"]
|
|
76
|
-
updateCoordinatesBulk(items, textWriterInjectionSubSetIDs = []) {
|
|
77
|
-
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
_updateChainCoords(chainID, points){
|
|
81
|
-
this._updateCoordsBuffer();
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
```
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
---
|
|
88
|
-
|
|
89
|
-
```js
|
|
90
|
-
const connectNaive = (p1, p2) => {p1.set("to",p2);p2.set("from":p1)};
|
|
91
|
-
const Tanca = new Map([["long", 0],[ "lat",0], ["from", null], ["to":null]]);
|
|
92
|
-
const Cebelitarik = new Map([["long", 0],[ "lat",0], ["from", null], ["to":null]]);
|
|
93
|
-
const Cezayir = new Map([["long", 0],[ "lat",0], ["from", null], ["to":null]]);
|
|
94
|
-
const Tunus = new Map([["long", 0],[ "lat",0], ["from", null], ["to":null]]);
|
|
95
|
-
const Tanca = {id, long,lat, toID}
|
|
96
|
-
|
|
97
|
-
plugin.insertBulk([
|
|
98
|
-
{
|
|
99
|
-
chainID: "Mağrib",
|
|
100
|
-
points: [
|
|
101
|
-
{Tanca, to: Cebelitarik}
|
|
102
|
-
{Cebelitarik, to:"Cezayir"},
|
|
103
|
-
{Cezayir, to: "Tunus"}, // implicitly connects to Tunus
|
|
104
|
-
{Tunus, to:null}
|
|
105
|
-
]),
|
|
106
|
-
rgba: [1.0, 0.0, 0.0, 1.0],
|
|
107
|
-
dashRatio: 0.1,
|
|
108
|
-
dashOpacity: 0.5,
|
|
109
|
-
circleDashAngle: 15,
|
|
110
|
-
}
|
|
111
|
-
]);
|
|
112
|
-
```
|
|
113
|
-
Advantage: User knows patterns of position data.
|
|
114
|
-
Disadventage: Not json.
|
|
115
|
-
Bug: How to insert into middle?
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
coordinateAdaptor => (v, i, array) => {
|
|
119
|
-
return {
|
|
120
|
-
(v.long + array[i+1].long) / 2.0,
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
```js
|
|
125
|
-
const connect = (chainMap, chainID, node) => {
|
|
126
|
-
const chain = chainMap.get(chainID);
|
|
127
|
-
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
```
|
|
131
|
-
---
|
|
132
|
-
|
|
133
|
-
## updateCoordinatesBulk
|
|
134
|
-
|
|
135
|
-
updates pointMap;
|
|
136
|
-
then updates buffers from updated version of pointMap;
|
|
137
|
-
|
|
138
|
-
imparatively open next or prev
|
|
139
|
-
|
|
140
|
-
```json
|
|
141
|
-
[
|
|
142
|
-
{
|
|
143
|
-
"chainID": "Mağrib",
|
|
144
|
-
"points": [
|
|
145
|
-
{
|
|
146
|
-
""Fas"": {
|
|
147
|
-
" "l"ong": 100,
|
|
148
|
-
"lat": 30
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
]
|
|
152
|
-
}
|
|
153
|
-
]
|
|
154
|
-
```
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
## deleteBulk
|
|
158
|
-
|
|
159
|
-
```json
|
|
160
|
-
[
|
|
161
|
-
{
|
|
162
|
-
"chainID": "Mağrib",
|
|
163
|
-
"all": false,
|
|
164
|
-
"points": [
|
|
165
|
-
"Fas"
|
|
166
|
-
]
|
|
167
|
-
}
|
|
168
|
-
]
|
|
169
|
-
```
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
## ContextTextWriter
|
|
173
|
-
|
|
174
|
-
```js
|
|
175
|
-
{
|
|
176
|
-
|
|
177
|
-
writer: new ContextTextWriter(globe),
|
|
178
|
-
coordsAdaptor: (item) =>
|
|
179
|
-
if (item.get("next") === null) return false;
|
|
180
|
-
const goe = {
|
|
181
|
-
long: point.get("long"),
|
|
182
|
-
lat: point.get("lat"),
|
|
183
|
-
endLong: point.get("next")?.get("long"),
|
|
184
|
-
endLat: point.get("next")?.get("lat")
|
|
185
|
-
}
|
|
186
|
-
return globe.getMidPoint(geo.long,geo.lat, geo.endLong, geo.endLat)
|
|
187
|
-
}
|
|
188
|
-
},
|
|
189
|
-
textAdaptor: (item) => {
|
|
190
|
-
const angle = item.long, item.lat, item.endLong, item.endLat
|
|
191
|
-
);
|
|
192
|
-
if (angle < 0) {
|
|
193
|
-
return (angle + 360).toFixed(2) + "°";
|
|
194
|
-
}
|
|
195
|
-
return angle.toFixed(2) + "°";
|
|
196
|
-
},
|
|
197
|
-
}
|
|
198
|
-
```
|
|
199
|
-
|
|
200
|
-
---
|
|
201
|
-
|
|
202
|
-
```js
|
|
203
|
-
class Chain{
|
|
204
|
-
constractor(id, {rgba = [1,0,0,1], dashOpacity = 1, dashRatio = 0.1, circleDashAngle = 30 } = []){
|
|
205
|
-
this.id = 0;
|
|
206
|
-
this.idMap = new Map();
|
|
207
|
-
this.list = [];
|
|
208
|
-
this._rgba = rgba;
|
|
209
|
-
this._dashOpacity = dashOpacity;
|
|
210
|
-
this._dashRatio = dashRatio;
|
|
211
|
-
this._circleDashAngle = this.circleDashAngle;
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
add(item, fromID = null){
|
|
215
|
-
this.idMap.set(item.id, item);
|
|
216
|
-
let drawIndex;
|
|
217
|
-
if (from === null) {
|
|
218
|
-
this.list.push(item);
|
|
219
|
-
drawIndex = this.list.length - 1;
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
for ( let i = 0 ; i < this.list.length ; i++){
|
|
223
|
-
if ( fromID === this.list[i].id) {
|
|
224
|
-
drawIndex = i;
|
|
225
|
-
this.list.splice(i, 0, item);
|
|
226
|
-
}
|
|
227
|
-
}
|
|
228
|
-
|
|
229
|
-
this._update( [i, i-1]);
|
|
230
|
-
}
|
|
231
|
-
|
|
232
|
-
nextID(id){
|
|
233
|
-
// for loop if data source is a list. not performand.
|
|
234
|
-
// pointer if data rouce is a node. Clunky
|
|
235
|
-
// reconstract the map on (!append) operation.
|
|
236
|
-
}
|
|
237
|
-
}
|
|
238
|
-
|
|
239
|
-
```
|
|
240
|
-
|
|
241
|
-
---
|
|
242
|
-
## Design Priorities
|
|
243
|
-
|
|
244
|
-
user interaction. insert, update, get data
|
|
245
|
-
some processies are callback. callbacks uses the pattern user insert the data
|
|
246
|
-
|
|
247
|
-
ContextTextWriter Plugin interaction I provided was imparative. I fit to that context because item had required data.
|
|
248
|
-
Current context has uses next objects data in the chain.
|
|
249
|
-
|
|
250
|
-
What is the imparative way to get next data?
|
|
251
|
-
A `function` - A `pointer`
|
|
252
|
-
If I go with a `pointer` I need to get the data with a `pointer`
|
|
253
|
-
How to I provide a `function` to get the next data?
|
|
254
|
-
```js
|
|
255
|
-
getNodeData(chainID, id){
|
|
256
|
-
return this.chainMap.get(chainID).get(id)
|
|
257
|
-
}
|
|
258
|
-
// Problem to use this function the object of getNodeData must be created before creating contextTextWriterMap.
|
|
259
|
-
```
|
|
260
|
-
|
|
261
|
-
how minimally hold the data
|
|
262
|
-
|
|
263
|
-
how to render
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
Edit mod. user asks chain data and bind placeholders.
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
## API
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
getChain(chainID) => {pointID, long, lat}
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
## explore pattern
|
|
280
|
-
|
|
281
|
-
(x, index, array ) doesnt fit.
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
## insertBulk
|
|
287
|
-
```json
|
|
288
|
-
[
|
|
289
|
-
{
|
|
290
|
-
"chainID": "Mağrib",
|
|
291
|
-
"points": [
|
|
292
|
-
{
|
|
293
|
-
"id": "Fas",
|
|
294
|
-
"long": 0,
|
|
295
|
-
"lat": 0,
|
|
296
|
-
"to": "Cezayir"
|
|
297
|
-
},
|
|
298
|
-
{
|
|
299
|
-
"id":"Cezayir",
|
|
300
|
-
"long": 10,
|
|
301
|
-
"lat": 20,
|
|
302
|
-
"to": "Tunus"
|
|
303
|
-
},
|
|
304
|
-
{
|
|
305
|
-
"id":"Tunus",
|
|
306
|
-
"long": 10,
|
|
307
|
-
"lat": 15
|
|
308
|
-
}
|
|
309
|
-
],
|
|
310
|
-
"rgba": [1,0,0,1],
|
|
311
|
-
"dashRatio": 0.1,
|
|
312
|
-
"dashOpacity": 0.5,
|
|
313
|
-
"circleDashAngle": 15,
|
|
314
|
-
},
|
|
315
|
-
]
|
|
316
|
-
```
|
|
317
|
-
|
|
318
|
-
```js
|
|
319
|
-
// ["distance"]
|
|
320
|
-
updateCoordinatesBulk( items, contextTextWriterIDs=[]) {
|
|
321
|
-
for ( const item of items){
|
|
322
|
-
this._updateCoordsChain(item.chainID, item.points);
|
|
323
|
-
}
|
|
324
|
-
}
|
|
325
|
-
|
|
326
|
-
_updateCoordsChain(chainID, nodes){
|
|
327
|
-
const chain = this._chainMap(chainID); // chain is a `list`
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
}
|
|
331
|
-
```
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
##
|
|
335
|
-
Get data from user with `to` keyword. implicitly add from keyword
|
|
336
|
-
|