@pirireis/webglobeplugins 0.6.22 → 0.6.23-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.
@@ -66,7 +66,7 @@ export default class Plugin {
66
66
 
67
67
  this.drawText = drawText;
68
68
 
69
- this.circleFlatEdgeCount = circleFlatEdgeCount + 2;//circleFlatEdgeCount;
69
+ this.circleFlatEdgeCount = circleFlatEdgeCount + 2; //circleFlatEdgeCount;
70
70
  }
71
71
 
72
72
  setDoDrawVRM(bool) {
@@ -230,8 +230,8 @@ export default class Plugin {
230
230
 
231
231
  // normal circle
232
232
  ["circleDashAngle", {
233
- 'bufferManager': new BufferManager(gl, circleFlatEdgeCount, { bufferType, initialCapacity }),
234
- 'adaptor': (item) => new Float32Array(item.rgba),
233
+ 'bufferManager': new BufferManager(gl, 1, { bufferType, initialCapacity }),
234
+ 'adaptor': (item) => new Float32Array([item.circleDashAngle / 360]),
235
235
  }],
236
236
  // CIRCLE Mercator
237
237
  ["rgbaMercator", {
@@ -476,9 +476,7 @@ export default class Plugin {
476
476
  const result = []
477
477
  for (const item of propertyIDs) {
478
478
  result.push(item);
479
- console.log(item + " is processing")
480
479
  if (s.has(item)) {
481
- console.log(item + "Mercator is added")
482
480
  result.push(item + "Mercator");
483
481
  }
484
482
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pirireis/webglobeplugins",
3
- "version": "0.6.22",
3
+ "version": "0.6.23-a",
4
4
  "main": "index.js",
5
5
  "author": "Toprak Nihat Deniz Ozturk",
6
6
  "license": "MIT"
@@ -45,14 +45,12 @@ out float interpolation;
45
45
  out vec4 v_color;
46
46
  out float v_dash_ratio;
47
47
  out float v_dash_opacity;
48
- out vec2 v_limp;
49
48
  void main() {
50
49
  interpolation = float( gl_VertexID ) / ${EDGE_COUNT_ON_SPHERE}.0;
51
50
  if ( is3D ) {
52
51
  float angle = PI * 2.0 * interpolation;
53
52
  vec3 position = circleLimpFromLongLatRadCenterCartesian3D_accurate(center_position3d, radius, angle);
54
53
  gl_Position = cartesian3DToGLPosition(position);
55
- v_limp = vec2(0.0, 0.0);
56
54
  } else {
57
55
  return;
58
56
  }
@@ -73,7 +71,6 @@ in float interpolation;
73
71
  in vec2 v_limp;
74
72
  out vec4 color;
75
73
  void main() {
76
- if ( v_limp.x < -POLE || v_limp.x > POLE || v_limp.y < -POLE || v_limp.y > POLE ){ color = vec4(0.0,0.0,0.0,0.0); return; }
77
74
  color = v_color;
78
75
  color.a *= opacity;
79
76
  if ( v_dash_ratio == 1.0 || v_dash_ratio == 0.0 ) return;
@@ -110,8 +107,8 @@ class Logic {
110
107
  gl.bindAttribLocation(program, 0, "center_position3d");
111
108
  gl.bindAttribLocation(program, 1, "radius");
112
109
  gl.bindAttribLocation(program, 2, "color");
113
- gl.bindAttribLocation(program, 2, "dash_ratio");
114
- gl.bindAttribLocation(program, 3, "dash_opacity");
110
+ gl.bindAttribLocation(program, 3, "dash_ratio");
111
+ gl.bindAttribLocation(program, 4, "dash_opacity");
115
112
  }
116
113
 
117
114
  this.cameraBindingPoint = 0;
@@ -69,8 +69,7 @@ void main() {
69
69
  if (fract(interpolation / (2.0 * v_dash_ratio)) < 0.5 ) {
70
70
  color.a *= v_dash_opacity;
71
71
  }
72
- }
73
- `;
72
+ }`;
74
73
 
75
74
 
76
75
 
@@ -180,9 +179,9 @@ const CircleCache = Object.freeze({
180
179
  });
181
180
 
182
181
 
183
- function centerCoords2dflatDataCreator(globe, centerLong, centerLat, targetLong, targetLat, { startAngleOfCircle = null, edgeCount = EDGE_COUNT } = {}) {
182
+ function centerCoords2dflatDataCreator(globe, centerLong, centerLat, targetLong, targetLat, { startAngleOfCircle = null, edgeCount = EDGE_COUNT, radiusOffset = 0 } = {}) {
184
183
  const centerCoords2dflat = new Float32Array(edgeCount * 2);
185
- const radius2d = globe.Math.GetDist2D(centerLong, centerLat, targetLong, targetLat);
184
+ const radius2d = globe.Math.GetDist2D(centerLong, centerLat, targetLong, targetLat) + radiusOffset;
186
185
  let angle;
187
186
  if (startAngleOfCircle === null) {
188
187
  angle = globe.Math.GetAzimuthAngle(centerLong, centerLat, targetLong, targetLat);
@@ -205,6 +204,26 @@ function centerCoords2dflatDataCreator(globe, centerLong, centerLat, targetLong,
205
204
  return centerCoords2dflat;
206
205
  }
207
206
 
207
+
208
+ function centerCoords2dflatDataCreatorWithRadius(globe, centerLong, centerLat, radius2d, { startAngleOfCircle = null, edgeCount = EDGE_COUNT } = {}) {
209
+ const centerCoords2dflat = new Float32Array(edgeCount * 2);
210
+ const pointsLongLat = globe.Math.GetEllipseGeo(
211
+ centerLong,
212
+ centerLat,
213
+ radius2d,
214
+ radius2d,
215
+ 0,
216
+ 360 / (edgeCount - 2), // 1 for return to start point, 1 for cutting circles
217
+ );
218
+
219
+ for (let i = 1; i < edgeCount; i++) {
220
+ const { long: lg, lat: lt } = pointsLongLat[i - 1];
221
+ centerCoords2dflat.set(globe.api_GetMercator2DPoint(lg, lt), i * 2);
222
+ }
223
+ return centerCoords2dflat;
224
+ }
225
+
226
+
208
227
  export {
209
- CircleCache, EDGE_COUNT, centerCoords2dflatDataCreator
228
+ CircleCache, EDGE_COUNT, centerCoords2dflatDataCreator, centerCoords2dflatDataCreatorWithRadius
210
229
  }
@@ -0,0 +1,145 @@
1
+ import { CameraUniformBlockTotemCache, CameraUniformBlockString } from "../totems";
2
+ import { mercatorXYToGLPosition } from "../../util/shaderfunctions/geometrytransformations";
3
+ import { noRegisterGlobeProgramCache } from "../programcache";
4
+ import { createProgram } from "../../util";
5
+ import { vaoAttributeLoader } from "../../util/account/util";
6
+
7
+ /**
8
+ * This program draws line between points provided from the first and second buffer.
9
+ * draw method gl.drawInstanced( gl.POINTS, 0,2, lineCount);
10
+ * */
11
+
12
+ const Z_ALPHA_MODE = Object.freeze({
13
+ ON: 1,
14
+ OFF: 0
15
+ });
16
+
17
+ const vertexShaderSource = `#version 300 es
18
+ precision highp float;
19
+ ${CameraUniformBlockString}
20
+ ${mercatorXYToGLPosition}
21
+ uniform float opacity;
22
+ uniform int z_alpha_on;
23
+
24
+ in vec2 posA;
25
+ in vec2 posB;
26
+ in vec4 color;
27
+
28
+ out vec4 v_color;
29
+
30
+ void main() {
31
+ if ( is3D ) {
32
+ return;
33
+ }
34
+ float z_alpha;
35
+ if ( z_alpha_on == 1){
36
+ z_alpha = z_level * z_level / (distance(posA, posB) / 100.0 );
37
+ if( z_alpha < 0.1 ) {return;}
38
+ if( z_alpha > 1.0 ) {z_alpha = 1.0;}
39
+ } else {
40
+ z_alpha = 1.0;
41
+ }
42
+ vec2 pos;
43
+ if ( gl_VertexID == 0 ) {
44
+ pos = posA;
45
+ } else {
46
+ pos = posB;
47
+ }
48
+ gl_Position = mercatorXYToGLPosition( pos );
49
+ v_color = color;
50
+ v_color.a *= z_alpha * opacity;
51
+ gl_PointSize = 15.0;
52
+ }`;
53
+
54
+
55
+ const fragmentShaderSource = `#version 300 es
56
+ precision highp float;
57
+ in vec4 v_color;
58
+ out vec4 outColor;
59
+ void main() {
60
+ outColor = v_color;
61
+ }`;
62
+
63
+
64
+ class Logic {
65
+ constructor(globe) {
66
+ this.globe = globe;
67
+ this.gl = globe.gl;
68
+ this.program = createProgram(this.gl, vertexShaderSource, fragmentShaderSource);
69
+ this._lastOpicity = 1.0;
70
+ this._lastZAlphaOn = Z_ALPHA_MODE.OFF;
71
+
72
+ const { gl, program } = this;
73
+ const currentProgram = gl.getParameter(gl.CURRENT_PROGRAM);
74
+ gl.useProgram(program);
75
+ { // assign attribute locations
76
+ gl.bindAttribLocation(program, 0, 'posA');
77
+ gl.bindAttribLocation(program, 1, 'posB');
78
+ gl.bindAttribLocation(program, 2, 'color');
79
+ }
80
+
81
+ { // uniform locations
82
+ this._opacityLocation = gl.getUniformLocation(program, 'opacity');
83
+ this._zAlphaOnLocation = gl.getUniformLocation(program, 'z_alpha_on');
84
+ gl.uniform1i(this._zAlphaOnLocation, this._lastZAlphaOn);
85
+ gl.uniform1f(this._opacityLocation, this._lastOpicity);
86
+ }
87
+ { // uniform block
88
+ this._cameraUniformBlock = CameraUniformBlockTotemCache.get(globe);
89
+ this._cameraBindingPoint = 0;
90
+ const cameraBlockBindingIndex = gl.getUniformBlockIndex(program, 'CameraUniformBlock');
91
+ gl.uniformBlockBinding(program, cameraBlockBindingIndex, this._cameraBindingPoint);
92
+ }
93
+ gl.useProgram(currentProgram);
94
+ }
95
+ createVAO(posAObj, posBObj, colorObj) {
96
+
97
+ const { gl } = this;
98
+ const vao = gl.createVertexArray();
99
+ const type = gl.Float;
100
+ const divisor = 1;
101
+ gl.bindVertexArray(vao);
102
+ [posAObj, posBObj, colorObj].forEach((obj, index) => {
103
+ const { buffer, size, stride, offset } = obj;
104
+ vaoAttributeLoader(gl, index, buffer, size, stride, offset, divisor, type);
105
+ });
106
+ gl.bindVertexArray(null);
107
+ return vao;
108
+ }
109
+
110
+
111
+ draw(vao, lineCount, opacity = 1.0, zAlphaOn = Z_ALPHA_MODE.OFF) {
112
+ const { gl, program, _cameraBindingPoint, _cameraUniformBlock } = this;
113
+ gl.useProgram(program);
114
+ _cameraUniformBlock.bind(_cameraBindingPoint);
115
+ gl.bindVertexArray(vao);
116
+ if (this._lastOpicity !== opacity) {
117
+ this._lastOpicity = opacity;
118
+ gl.uniform1f(this._opacityLocation, opacity);
119
+ }
120
+ if (this._lastZAlphaOn !== zAlphaOn) {
121
+ this._lastZAlphaOn = zAlphaOn;
122
+ gl.uniform1i(this._zAlphaOnLocation, zAlphaOn);
123
+ }
124
+ gl.drawInstanced(gl.POINTS, 0, 2, lineCount);
125
+ _cameraUniformBlock.unbind(_cameraBindingPoint);
126
+ gl.bindVertexArray(null);
127
+ }
128
+
129
+
130
+ free() {
131
+ if (this.isFreed) return;
132
+ const { gl, program, globe } = this;
133
+ CameraUniformBlockTotemCache.release(globe);
134
+ gl.deleteProgram(program);
135
+ this.isFreed = true;
136
+ }
137
+ }
138
+
139
+
140
+ const LinesColorInstancedFlatCache = Object.freeze({
141
+ get: (globe) => { return noRegisterGlobeProgramCache.getProgram(globe, Logic) },
142
+ release: (globe) => { noRegisterGlobeProgramCache.releaseProgram(globe, Logic) }
143
+ });
144
+
145
+ export { LinesColorInstancedFlatCache, Z_ALPHA_MODE };
@@ -1,8 +1,4 @@
1
1
  import { createProgram, shaderfunctions } from "../../../util";
2
- import {
3
- circleLimpFromLongLatRadCenterMercatorRealDistanceNew_accurate,
4
- circleLimpFromLongLatRadCenterCartesian3D_accurate_accurate
5
- } from "../../../util/shaderfunctions/geometrytransformations";
6
2
  import CameraUniformBlockTotem, { CameraUniformBlockString } from "../../totems/camerauniformblock";
7
3
  import { globeProgramCache, noRegisterGlobeProgramCache } from "../../programcache";
8
4
 
@@ -14,12 +10,11 @@ const vertexShader = `#version 300 es ` +
14
10
  shaderfunctions.mercatorXYToGLPosition +
15
11
  shaderfunctions.longLatRadToMercator +
16
12
  shaderfunctions.longLatRadToCartesian3D +
13
+ shaderfunctions.circleLimpFromLongLatRadCenterCartesian3D +
17
14
  shaderfunctions.circleLimpFromLongLatRadCenterMercatorCompass +
18
15
  shaderfunctions.circleLimpFromLongLatRadCenterMercatorRealDistancePadding +
19
16
  shaderfunctions.circleLimpFromLongLatRadCenterMercatorRealDistance + `
20
17
 
21
- ${circleLimpFromLongLatRadCenterCartesian3D_accurate_accurate}
22
-
23
18
  in vec2 center;
24
19
  in float radius;
25
20
  in float pad_range;
@@ -51,7 +46,7 @@ void main() {
51
46
 
52
47
  if ( is3D){
53
48
  gl_Position = projection * view * vec4(
54
- circleLimpFromLongLatRadCenterCartesian3D_accurate( center, radius_, angle) - translate, 1.0);
49
+ circleLimpFromLongLatRadCenterCartesian3D( center, radius_, angle) - translate, 1.0);
55
50
  v_limp = vec2(0.0, 0.0);
56
51
  return;
57
52
  }
@@ -111,6 +106,10 @@ class Logic {
111
106
  }
112
107
 
113
108
 
109
+ draw(vao, length, opaity) {
110
+
111
+ }
112
+
114
113
  draw(attrBufferManager, padCount, compass, opacity) {
115
114
  const { gl, program, _padCountLocation, cameraBlockBindingPoint, cameraBlockTotem, _compassLocation } = this;
116
115
  gl.useProgram(program);
@@ -1,8 +1,4 @@
1
1
  import { createProgram, shaderfunctions } from "../../../util";
2
- import {
3
- circleLimpFromLongLatRadCenterMercatorRealDistanceNew_accurate,
4
- circleLimpFromLongLatRadCenterCartesian3D_accurate_accurate
5
- } from "../../../util/shaderfunctions/geometrytransformations";
6
2
  import CameraUniformBlockTotem, { CameraUniformBlockString } from "../../totems/camerauniformblock";
7
3
  import { globeProgramCache, noRegisterGlobeProgramCache } from "../../programcache";
8
4
 
@@ -14,12 +10,11 @@ const vertexShader = `#version 300 es ` +
14
10
  shaderfunctions.mercatorXYToGLPosition +
15
11
  shaderfunctions.longLatRadToMercator +
16
12
  shaderfunctions.longLatRadToCartesian3D +
13
+ shaderfunctions.circleLimpFromLongLatRadCenterCartesian3D +
17
14
  shaderfunctions.circleLimpFromLongLatRadCenterMercatorCompass +
18
15
  shaderfunctions.circleLimpFromLongLatRadCenterMercatorRealDistancePadding +
19
16
  shaderfunctions.circleLimpFromLongLatRadCenterMercatorRealDistance + `
20
17
 
21
- ${circleLimpFromLongLatRadCenterCartesian3D_accurate_accurate}
22
-
23
18
  in vec2 center;
24
19
  in float radius;
25
20
  in float pad_range;
@@ -51,7 +46,7 @@ void main() {
51
46
 
52
47
  if ( is3D){
53
48
  gl_Position = projection * view * vec4(
54
- circleLimpFromLongLatRadCenterCartesian3D_accurate( center, radius_, angle) - translate, 1.0);
49
+ circleLimpFromLongLatRadCenterCartesian3D( center, radius_, angle) - translate, 1.0);
55
50
  v_limp = vec2(0.0, 0.0);
56
51
  return;
57
52
  }
@@ -19,7 +19,6 @@ const { circleProgramCache, PaddingProgramCache, CirclePaddySharedBuffer } = rin
19
19
  */
20
20
 
21
21
 
22
-
23
22
  export default class {
24
23
 
25
24
  constructor(id, { oneDegreePadding = true, compass = COMPASS_MODES.REAL, showNumbers = true, numbersStyle = null, opacity = 1 } = {}) {
@@ -73,11 +72,7 @@ export default class {
73
72
  }
74
73
 
75
74
 
76
- setOpacity(opacity) {
77
- this._opacity = opacity;
78
- this.textPlugin?.setOpacity(opacity); // TODO impolement this
79
- this.globe.DrawRender();
80
- }
75
+
81
76
 
82
77
  setGeometry() {
83
78
  this.textPlugin?.setGeometry();
@@ -97,6 +92,14 @@ export default class {
97
92
 
98
93
 
99
94
 
95
+
96
+ setOpacity(opacity) {
97
+ this._opacity = opacity;
98
+ this.textPlugin?.setOpacity(opacity); // TODO impolement this
99
+ this.globe.DrawRender();
100
+ }
101
+
102
+
100
103
  /**
101
104
  * @param {RangeRingData} rangeRingData
102
105
  * 0 compass limps
@@ -0,0 +1,7 @@
1
+
2
+ export const ENUM_HIDE = Object.freeze({ SHOW: 0, HIDE: 1, HIDE_1_DEGREE_PADDINGS: 2 });
3
+ export const ENUM_TEXT_HIDE = Object.freeze({ SHOW: 0, HIDE: 1 });
4
+ export const COMPASS_MODES = Object.freeze({
5
+ COMPASS: 1,
6
+ REAL: 0,
7
+ });
@@ -0,0 +1,4 @@
1
+ import { RangeRings } from "./plugin";
2
+ import RangeRingAngleText from './rangeringangletext';
3
+ import { ENUM_HIDE, ENUM_TEXT_HIDE, COMPASS_MODES } from './enum';
4
+ export { RangeRings, ENUM_HIDE, ENUM_TEXT_HIDE, COMPASS_MODES, RangeRingAngleText };
@@ -29,14 +29,381 @@
29
29
  * @property {[number, number, number]} color
30
30
  *
31
31
  *
32
- * @method setOpacity
33
- * @method insertBulk
34
- * @method updateCentersXY
35
- * @method updateCentersColor
36
- * @method removeCenters
37
- * @method updateCentersHide
32
+ * @method insertBulk
33
+ * @typedef {Array<{ringID, radius, paddingRange}>} rings
34
+ * @param {Array<centerID:string, x:number, y:number, stepAngle:number, rgba:[4 numbers], rings:rings} items
35
+
36
+ * @method updateCentersXY @param {Array<{centerID, x, y}>} items
37
+ * @method updateCentersColor @param {Array<{centerID, rgba:[4 numbers]}>} centerColors
38
+ *
39
+ * @method updateCentersHide @param {Array<{centerID, hide, textHide}>} centerHides
40
+ * @method removeCenters @param {Array<{centerID}>} centerIds
41
+ * @method setOpacity @param {number} opacity
38
42
  *
39
43
  * @method setOneDegreePaddingOn // performance consuming, might be removed
40
44
  * @method setCompass // removed
41
45
  *
42
- */
46
+ */
47
+
48
+ import { centerCoords2dflatDataCreatorWithRadius, CircleCache as CircleCache2D } from "../programs/line-on-globe/circle-accurate-flat";
49
+ import { CircleCache as CircleCache3D } from "../programs/line-on-globe/circle-accurate-3d";
50
+ import { LinesColorInstancedFlatCache } from "../programs/line-on-globe/lines-color-instanced-flat";
51
+ import { BufferOrchestrator, BufferManager } from "../util/account";
52
+ import { populateFloat32Array } from "../util/jshelpers/data-filler";
53
+ import { RingAccount, ringKeyMethod, ringBigPaddingKeyMethod } from "./ring-account";
54
+ /**
55
+ * Programs:
56
+ *
57
+ * circle3d circle2d padding3d padding2d
58
+ *
59
+ *
60
+ * */
61
+
62
+
63
+ /**
64
+ * [+] Draw circles
65
+ * [-] BUG BUFFER OVERFLOW
66
+ * [-] Draw one degree paddings 2d
67
+ * [-] Create a program for accurate padding 3d
68
+ * [-] Draw one degree paddings 3d
69
+ * [-] Draw big paddings
70
+ * [-] DrawText
71
+ */
72
+
73
+ // TODO make x, y -> long, lat
74
+
75
+ class RangeRings {
76
+ constructor(id, { oneDegreePadding = true, showNumbers = true, numbersStyle = null, opacity = 1, } = {}) {
77
+
78
+ this.id = id;
79
+
80
+ this._oneDegreePadding = oneDegreePadding;
81
+ this._showNumbers = showNumbers;
82
+ this._numbersStyle = numbersStyle;
83
+ this._opacity = opacity;
84
+ this._circleFlatEdgeCount = 362;
85
+ this._ringAccount = new RingAccount();
86
+
87
+ }
88
+
89
+
90
+ init(globe, gl) {
91
+ this.globe = globe;
92
+ this.gl = gl;
93
+ this._initPrograms();
94
+ this._initBufferManagers();
95
+ }
96
+
97
+
98
+ _initPrograms() {
99
+ const { globe } = this;
100
+ this._circleProgram2D = CircleCache2D.get(globe);
101
+ this._circleProgram3D = CircleCache3D.get(globe);
102
+ this._padding2dProgram = LinesColorInstancedFlatCache.get(globe);
103
+ // this._padding3dProgram
104
+ }
105
+
106
+
107
+ _initBufferManagers() {
108
+ const { globe, gl, _circleFlatEdgeCount } = this;
109
+
110
+ const initialCapacity = 10;
111
+ const bufferType = "DYNAMIC_DRAW";
112
+ // circle2d, circle3d, 1 degree paddings,
113
+ this.bufferOrchestrator = new BufferOrchestrator({ capacity: initialCapacity });
114
+
115
+ this.bufferManagersCompMap = new Map(
116
+ [
117
+ // circle 3D
118
+ ["centerCoords3d", {
119
+ 'bufferManager': new BufferManager(gl, 3, { bufferType, initialCapacity }),
120
+ 'adaptor': (item) => new Float32Array(item.centerCoords3d),
121
+ }],
122
+ ["rgba", {
123
+ 'bufferManager': new BufferManager(gl, 4, { bufferType, initialCapacity }),
124
+ 'adaptor': (item) => new Float32Array(item.hide === 1 ? [0, 0, 0, 0] : item.rgba)
125
+ }],
126
+ ["radius3d", {
127
+ 'bufferManager': new BufferManager(gl, 1, { bufferType, initialCapacity }),
128
+ 'adaptor': (item) => new Float32Array([item.radius])
129
+ }],
130
+ ["circleDashAngle", {
131
+ 'bufferManager': new BufferManager(gl, 1, { bufferType, initialCapacity }),
132
+ 'adaptor': (item) => new Float32Array([1]),
133
+ }],
134
+ ["dashOpacity", {
135
+ 'bufferManager': new BufferManager(gl, 1, { bufferType, initialCapacity }),
136
+ 'adaptor': (item) => new Float32Array([1]),
137
+ }],
138
+
139
+ // circle 2D
140
+ // ["centerCoords2dflatForPadding", {
141
+ // 'bufferManager': new BufferManager(gl, (_circleFlatEdgeCount - 2) * 2, { bufferType, initialCapacity }),
142
+ // 'adaptor': (item) => item.centerCoords2dflatForPadding,
143
+ // }],
144
+ ["centerCoords2dflat", {
145
+ 'bufferManager': new BufferManager(gl, _circleFlatEdgeCount * 2, { bufferType, initialCapacity }),
146
+ 'adaptor': (item) => item.centerCoords2dflat,
147
+ }],
148
+ ["rgbaMercator", {
149
+ 'bufferManager': new BufferManager(gl, 4 * _circleFlatEdgeCount, { bufferType, initialCapacity }),
150
+ 'adaptor': (item) => populateFloat32Array.fillWithListData(_circleFlatEdgeCount, item.hide === 1 ? [0, 0, 0, 0] : item.rgba),
151
+ }],
152
+ ["circleDashAngleMercator", {
153
+ 'bufferManager': new BufferManager(gl, _circleFlatEdgeCount, { bufferType, initialCapacity }),
154
+ 'adaptor': (item) => populateFloat32Array.fillFloat32Array(_circleFlatEdgeCount, 1),
155
+ }],
156
+ ["dashOpacityMercator", {
157
+ 'bufferManager': new BufferManager(gl, _circleFlatEdgeCount, { bufferType, initialCapacity }),
158
+ 'adaptor': (item) => populateFloat32Array.fillFloat32Array(_circleFlatEdgeCount, 1),
159
+ }],
160
+ ]
161
+ );
162
+
163
+ const obj = function (bufferManagerComp, divisor = 1) {
164
+ return { 'buffer': bufferManagerComp.bufferManager.buffer, 'stride': 0, 'offset': 0, divisor }
165
+
166
+ };
167
+ this.circle2DVao = this._circleProgram2D.createVAO(
168
+ ...["centerCoords2dflat", "rgbaMercator", "circleDashAngleMercator", "dashOpacityMercator"].map(key => obj(this.bufferManagersCompMap.get(key)))
169
+ );
170
+ this.circle3DVao = this._circleProgram3D.createVAO(
171
+ ...["centerCoords3d", "radius3d", "rgba", "circleDashAngle", "dashOpacity"].map(key => obj(this.bufferManagersCompMap.get(key)))
172
+ );
173
+
174
+
175
+ // PADDING
176
+ // this one needs glue to assosiate rings and their big paddings since the count for center is not fixed
177
+ this._paddingBufferOrchestrator = new BufferOrchestrator({ capacity: initialCapacity });
178
+ this.bufferManagersCompMapPadding = new Map();
179
+ }
180
+
181
+
182
+ // GLOBE API
183
+
184
+ draw3D() {
185
+ const { globe, gl, circle2DVao, circle3DVao, _circleProgram2D, _circleProgram3D, bufferOrchestrator, _circleFlatEdgeCount, _opacity } = this;
186
+ gl.disable(gl.DEPTH_TEST);
187
+ const is3D = this.globe.api_GetCurrentGeometry() === 0;
188
+ if (is3D) {
189
+ _circleProgram3D.draw(circle3DVao, bufferOrchestrator.length, _opacity);
190
+ } else {
191
+ _circleProgram2D.draw(circle2DVao, bufferOrchestrator.length, _circleFlatEdgeCount, _opacity);
192
+ }
193
+ gl.enable(gl.DEPTH_TEST);
194
+ }
195
+
196
+ free() {
197
+ if (this._isFreed) return;
198
+ const { globe } = this;
199
+ CircleCache2D.release(globe);
200
+ CircleCache3D.release(globe);
201
+ this._isFreed = true;
202
+ }
203
+
204
+
205
+ // API
206
+
207
+ /**
208
+ * @method updateCentersXY @param { Array < { centerID, x, y } >} items
209
+ */
210
+ updateCentersXY(items) {
211
+ // Algorithm
212
+ /**
213
+ * 1. ask centerRingAccount for existing rings COORDINATE RELATED KEYS
214
+ * 2. update centers
215
+ * 3. update buffer orchestators
216
+ */
217
+
218
+ this._ringAccount.updateCentersXY(items);
219
+ const { globe, bufferOrchestrator, bufferManagersCompMap } = this;
220
+ for (const { centerID } of items) {
221
+ const datas = this.__reconstructCenteralRings(centerID);
222
+ // TODO add big paddings when when implemented
223
+ bufferOrchestrator.updateBulk(datas, bufferManagersCompMap, ["centerCoords3d", "centerCoords2dflat",]);//"centerCoords2dflatForPadding"]);
224
+ }
225
+ globe.DrawRender();
226
+ }
227
+
228
+ /**
229
+ * @method insertBulk
230
+ * @typedef { Array < { ringID, radius, paddingRange } >} rings
231
+ * @param { Array < centerID: string, x: number, y: number, stepAngle: number, rgba: [4 numbers], rings: rings, hide, textHide } items
232
+ */
233
+ insertBulk(items) {
234
+ // Algorithm
235
+ /**
236
+ * 1 ask centerRingAccount for existing rings
237
+ * presizely: TODO
238
+ * 2. delete all existing keys with buffer orchestators
239
+ * 3. insert new centerRings to centerRingAccount
240
+ * 4. insert new keys with buffer orchestators
241
+ */
242
+ const { globe, _ringAccount, bufferOrchestrator, bufferManagersCompMap } = this;
243
+ // TODO add delete existing for padding
244
+ for (const item of items) {
245
+ const existingKeys = _ringAccount.ringKeys(item.centerID);
246
+ if (existingKeys.length) {
247
+ bufferOrchestrator.deleteBulk(existingKeys, bufferManagersCompMap);
248
+ }
249
+ }
250
+
251
+ for (const item of items) {
252
+ _ringAccount.insertCenter(item);
253
+ const datas = this.__reconstructCenteralRings(item.centerID);
254
+ bufferOrchestrator.insertBulk(datas, bufferManagersCompMap,);
255
+ }
256
+
257
+ // TODO insert text
258
+ globe.DrawRender();
259
+
260
+ }
261
+
262
+
263
+
264
+
265
+ /**
266
+ * @method updateCentersColor @param { Array < { centerID, rgba: [4 numbers] } >} centerColors
267
+ */
268
+ updateCentersColor(centerColors) {
269
+ // Algorithm
270
+ /**
271
+ * 1. ask centerRingAccount for existing rings COLOR KEYS
272
+ * 2. update centers
273
+ * 3. update buffer orchestators
274
+ */
275
+ this._ringAccount.updateCentersColor(centerColors);
276
+ const { globe, bufferOrchestrator, bufferManagersCompMap } = this;
277
+ for (const { centerID } of centerColors) {
278
+ const datas = this.__reconstructCenteralProperties(centerID);
279
+ bufferOrchestrator.updateBulk(datas, bufferManagersCompMap, ["rgba", "rgbaMercator"]);
280
+ }
281
+ globe.DrawRender();
282
+ }
283
+
284
+ /**
285
+ *
286
+ * @method updateCentersHide @param { Array < { centerID, hide, textHide } >} centerHides
287
+ */
288
+ updateCentersHide(centerHides) {
289
+ // Algorithm
290
+ /**
291
+ * Simple
292
+ * 1. update centers
293
+ * 2. reconstruct data,
294
+ * 3. update color buffer
295
+ * */
296
+
297
+
298
+
299
+ /**
300
+ * Complicated
301
+ * 1. ask centerRingAccount for existing rings HIDE KEYS
302
+ * 2. delete from buffer orchestators
303
+ * 3. mark centers as hidden
304
+ */
305
+
306
+ }
307
+
308
+ /**
309
+ * @method removeCenters @param { Array < { centerID } >} centerIDs
310
+ */
311
+ removeCenters(centerIDs) {
312
+ // Algorithm
313
+ /**
314
+ * 1. ask centerRingAccount for existing rings
315
+ * 2. delete from buffer orchestators
316
+ * 3. delete from centerRingAccount
317
+ */
318
+ const { globe, bufferOrchestrator, bufferManagersCompMap, _ringAccount } = this;
319
+ for (const centerID of centerIDs) {
320
+ const existingKeys = _ringAccount.ringKeys(centerID);
321
+ if (existingKeys.length) {
322
+ bufferOrchestrator.deleteBulk(existingKeys, bufferManagersCompMap);
323
+ }
324
+ }
325
+ globe.DrawRender();
326
+ }
327
+
328
+ /**
329
+ * @method setOpacity @param { number } opacity
330
+ */
331
+ setOpacity(opacity) {
332
+ if (typeof opacity !== "number" || opacity < 0 || opacity > 1) throw new Error("Invalid opacity value");
333
+ this._opacity = opacity;
334
+ this.globe.drawRender();
335
+ }
336
+
337
+
338
+ /**
339
+ * @method setOneDegreePaddingOn // performance consuming, might be removed
340
+ */
341
+ setOneDegreePaddingOn(isOneDegreePaddingOn) {
342
+ // TODO
343
+ if (this._oneDegreePadding === isOneDegreePaddingOn) return;
344
+ this._oneDegreePadding = isOneDegreePaddingOn;
345
+
346
+ // Complicated
347
+ // if (isOneDegreePaddingOn) {
348
+ // // fill the Coordinate Buffer for 1 degree Padding
349
+ // // Use orchastrator to create data for all rings
350
+
351
+ // } else {
352
+ // // empty the Coordinate Buffer for 1 degree Padding
353
+ // }
354
+ }
355
+
356
+
357
+ __reconstructCenteralRings(centerID) {
358
+ const { globe, _circleFlatEdgeCount } = this;
359
+ const centerItem = this._ringAccount.getCenter(centerID);
360
+ if (centerItem === undefined) throw new Error("Center not found");
361
+
362
+ const { x, y, stepAngle, rgba, rings, hide = 0, textHide = 0 } = centerItem;
363
+
364
+ const long = x;
365
+ const lat = y;
366
+ const centerCoords3d = globe.api_GetCartesian3DPoint(long, lat, 0, 0);
367
+
368
+ const result = [];
369
+
370
+ for (const { ringID, radius, paddingRange } of rings) {
371
+ const key = ringKeyMethod(centerID, ringID);
372
+ const centerCoords2dflat = centerCoords2dflatDataCreatorWithRadius(globe, x, y, radius, { edgeCount: _circleFlatEdgeCount });
373
+ // const centerCoords2dflatForPadding = centerCoords2dflatDataCreatorWithRadius(globe, x, y, radius - paddingRange, { edgeCount: _circleFlatEdgeCount - 2 });
374
+ result.push({
375
+ key,
376
+ centerCoords3d,
377
+ centerCoords2dflat,
378
+ radius,
379
+ paddingRange,
380
+ rgba,
381
+ // centerCoords2dflatForPadding,
382
+ hide,
383
+ textHide
384
+ });
385
+ }
386
+ return result;
387
+
388
+ }
389
+
390
+ __reconstructCenteralProperties(centerID) {
391
+ const centerItem = this._ringAccount.getCenter(centerID);
392
+ if (centerItem === undefined) throw new Error("Center not found");
393
+ const { rgba, rings, hide = 0, textHide = 0 } = centerItem;
394
+ const result = [];
395
+ for (const { ringID } of rings) {
396
+ const key = ringKeyMethod(centerID, ringID);
397
+ result.push({
398
+ key,
399
+ rgba,
400
+ hide,
401
+ textHide
402
+ });
403
+ }
404
+ return result;
405
+ }
406
+ }
407
+
408
+
409
+ export { RangeRings };
@@ -0,0 +1,489 @@
1
+
2
+ import {
3
+ CSObjectArrayUpdateTypes,
4
+ } from "@pirireis/webglobe";
5
+ import { ENUM_HIDE, ENUM_TEXT_HIDE, COMPASS_MODES } from "./enum";
6
+
7
+
8
+ const Degree = 180 / Math.PI;
9
+
10
+
11
+
12
+ const fidKey = "__fid__";
13
+
14
+
15
+ const object = {
16
+ "displayName": "RangeRingAngleText",
17
+ "layerType": 3,
18
+ "wkbGeom": null,
19
+ "wfsLayerName": null,
20
+ "objectType": "point",
21
+ "bbox": null,
22
+ "startLod": 2,
23
+ "endLod": 30,
24
+ "continuousLOD": true,
25
+ "MVTXYZName": "hd_seyp",
26
+ "rasterize": false,
27
+ }
28
+
29
+
30
+ export default class RangeRingAngleText {
31
+ constructor(globe, id, { style = null, flatCompassMode = COMPASS_MODES.REAL, hideAll = false, opacity = 1 } = {}) {
32
+ this.globe = globe;
33
+ this.ObjectArray = globe.ObjectArray;
34
+ this.id = id;
35
+ this._flatCompassMode = flatCompassMode;
36
+ this._lastImplicitCompassMode = this.__implicitCompassMode();
37
+
38
+ this._hideAll = hideAll;
39
+ this._opacity = opacity;
40
+ const style_ = style !== null ? style : this.getDefaultStyle();
41
+ this.object = Object.assign({}, object, { style: style_, id: this.id });
42
+
43
+ this._centerCollection = new Map();
44
+ // new inner MAP params
45
+ // hide
46
+ // textHide
47
+
48
+ this.ObjectArray.Add(this.object);
49
+
50
+ }
51
+
52
+ getDefaultStyle() {
53
+ const style = this.ObjectArray.GetDefaultStyle();
54
+ style.fidKey = fidKey;
55
+ const { labels } = style;
56
+ const label = labels[0];
57
+ label.offset = { x: 0, y: 0 };
58
+ label.fontFamily.hollowWidth = 1;
59
+ label.vAlignment = 2;
60
+ label.hAlignment = 2;
61
+ label.size = 17;
62
+ label.text = "`${aci}`"
63
+
64
+ return style;
65
+ }
66
+
67
+
68
+ setStyle(style) {
69
+ if (style === null) return;
70
+ style.opacity = this._opacity;
71
+ this.object.style = style;
72
+ this.ObjectArray.StyleChanged(this.object);
73
+ }
74
+
75
+
76
+ setOpacity(opacity) {
77
+ this._opacity = opacity;
78
+ const { style } = this.object;
79
+ style.opacity = opacity;
80
+ this.ObjectArray.StyleChanged(this.object);
81
+ }
82
+
83
+ setCompass(mode) {
84
+ if (mode === this._flatCompassMode) return;
85
+ this._flatCompassMode = mode;
86
+ this.__onCompassChange();
87
+ }
88
+
89
+
90
+ free() {
91
+ this.flush();
92
+ this.ObjectArray.Delete(this.id);
93
+ }
94
+
95
+
96
+ /**
97
+ * @param {Array<{centerID,stepAngle, x, y, rings>} ringDatas
98
+ * centerID: string | ObjectArray fidKey de kullanilir
99
+ * stepAngle: number | 0-360 arasinda
100
+ * x, y: number | merkez koordinatlari lat long radian. Globe icin dereceye iceride cevrilir
101
+ * rings: Array<{radius: number}> | En buyuk halkaya centik acilari yazilir, Sonraki adim yaricaplarin uzunlugunu yazdirmak
102
+ *
103
+ * eger bir centerID zaten var ise: Onceki noktalar dusurulur ve yeniden eklenir
104
+ *
105
+ * */
106
+ insertBulk(ringDatas) {
107
+ const { _hideAll } = this;
108
+ const addBucket = {
109
+ coords: [],
110
+ coordsZ: [],
111
+ attribs: []
112
+ }
113
+
114
+ const deleteBucket = {
115
+ coords: [],
116
+ coordsZ: [],
117
+ attribs: []
118
+ }
119
+
120
+ for (const { centerID, x, y, rings, stepAngle, hide = ENUM_HIDE.SHOW, textHide = ENUM_TEXT_HIDE.SHOW } of ringDatas) {
121
+ if (this._centerCollection.has(centerID)) {
122
+ this._fillDeleteBucket(centerID, deleteBucket);
123
+ }
124
+ const maxRadius = rings.reduce((acc, { radius }) => Math.max(acc, radius), 0);
125
+ const textHide_ = _hideAll ? ENUM_TEXT_HIDE.HIDE : textHide;
126
+ const show = hide !== ENUM_HIDE.HIDE && textHide_ === ENUM_TEXT_HIDE.SHOW;
127
+ if (show) this._appendCircle(x, y, maxRadius, stepAngle, centerID, addBucket);
128
+ this._centerCollection.set(centerID,
129
+ new Map([
130
+ ["stepAngle", stepAngle],
131
+ ["maxRadius", maxRadius],
132
+ ["x", x],
133
+ ["y", y],
134
+ ["hide", hide],
135
+ ["textHide", textHide_]
136
+ ]));
137
+ }
138
+ if (this._hideAll) return;
139
+ if (deleteBucket.coords.length > 0) this._updateData(deleteBucket, CSObjectArrayUpdateTypes.DELETE);
140
+ if (addBucket.coords.length > 0) this._updateData(addBucket, CSObjectArrayUpdateTypes.ADD);
141
+
142
+ }
143
+
144
+ /**
145
+ * @param {Array<{centerID, x,y}>} centerDatas
146
+ * aci ve radiuslarin tutulmasi gereklidir.
147
+ * */
148
+ updateCentersXY(centerDatas) {
149
+ const updateBucket = {
150
+ coords: [],
151
+ coordsZ: [],
152
+ attribs: []
153
+ }
154
+ for (const { centerID, x, y } of centerDatas) {
155
+ if (this._centerCollection.has(centerID)) {
156
+ const centerMap = this._centerCollection.get(centerID);
157
+ centerMap.set("x", x);
158
+ centerMap.set("y", y);
159
+ const hide = centerMap.get("hide");
160
+ const textHide = centerMap.get("textHide");
161
+ const isHidden = hide === ENUM_HIDE.HIDE || textHide === ENUM_TEXT_HIDE.HIDE;
162
+ if (isHidden) continue;
163
+ const maxRadius = centerMap.get("maxRadius");
164
+ const stepAngle = centerMap.get("stepAngle");
165
+ // long, lat, radius, step, centerID, outBucket
166
+ this._appendCircle(x, y, maxRadius, stepAngle, centerID, updateBucket);
167
+
168
+ }
169
+ }
170
+ // for (const attribs of updateBucket.attribs) {
171
+ // delete attribs["aci"];
172
+ // }
173
+ if (updateBucket.coords.length > 0) {
174
+ this._updateData(updateBucket, CSObjectArrayUpdateTypes.UPDATE);
175
+ }
176
+ }
177
+
178
+
179
+
180
+ /**
181
+ *
182
+ * @param {Array<{centerID:string, hide: bool}} centerHides
183
+ */
184
+ updateCentersHide(centerHides) {
185
+ if (this._hideAll) {
186
+ console.warn("Tum mesafe halkasi yazilari gizli durum. Islem yapilamaz");
187
+ return;
188
+ };
189
+ const addBucket = {
190
+ coords: [],
191
+ coordsZ: [],
192
+ attribs: []
193
+ };
194
+ const deleteBucket = {
195
+ coords: [],
196
+ coordsZ: [],
197
+ attribs: []
198
+ };
199
+ for (const { centerID, textHide = null, hide = null } of centerHides) {
200
+ if (!this._centerCollection.has(centerID)) continue;
201
+ const centerMap = this._centerCollection.get(centerID);
202
+
203
+ const isHidden = centerMap.get("hide") === ENUM_HIDE.HIDE || centerMap.get("textHide") === ENUM_TEXT_HIDE.HIDE;
204
+
205
+ const _hide = hide !== null ? hide : centerMap.get("hide");
206
+ const _textHide = textHide !== null ? textHide : centerMap.get("textHide");
207
+
208
+ const show = _hide !== ENUM_HIDE.HIDE && _textHide === ENUM_TEXT_HIDE.SHOW;
209
+ if (!isHidden && !show) {
210
+ this._fillDeleteBucket(centerID, deleteBucket);
211
+ } else if (isHidden && show) {
212
+ this._appendCircle(centerMap.get("x"), centerMap.get("y"), centerMap.get("maxRadius"), centerMap.get("stepAngle"), centerID, addBucket);
213
+ }
214
+ if (hide !== null) centerMap.set("hide", hide);
215
+ if (textHide !== null) centerMap.set("textHide", textHide);
216
+ }
217
+ if (deleteBucket.coords.length > 0) this._updateData(deleteBucket, CSObjectArrayUpdateTypes.DELETE);
218
+ if (addBucket.coords.length > 0) this._updateData(addBucket, CSObjectArrayUpdateTypes.ADD);
219
+ }
220
+
221
+
222
+ // TODO : Implement this
223
+ removeCenters(centerIDs) {
224
+ const deleteBucket = {
225
+ coords: [],
226
+ coordsZ: [],
227
+ attribs: []
228
+ }
229
+ for (const centerID of centerIDs) {
230
+ if (this._centerCollection.has(centerID)) {
231
+ this._fillDeleteBucket(centerID, deleteBucket);
232
+ this._centerCollection.delete(centerID);
233
+ }
234
+ }
235
+ this._updateData(deleteBucket, CSObjectArrayUpdateTypes.DELETE);
236
+ }
237
+
238
+
239
+ hideAll() {
240
+ this._hideAll = true;
241
+ const deleteBucket = {
242
+ coords: [],
243
+ coordsZ: [],
244
+ attribs: []
245
+ }
246
+ for (const [centerID, centerMap] of this._centerCollection) {
247
+ const hide = centerMap.get("hide");
248
+ const hideText = centerMap.get("textHide");
249
+ centerMap.set("textHide", ENUM_TEXT_HIDE.HIDE);
250
+ if (hide === ENUM_HIDE.HIDE) continue;
251
+ const isHidden = hideText === ENUM_TEXT_HIDE.HIDE;
252
+ if (!isHidden) this._fillDeleteBucket(centerID, deleteBucket);
253
+ }
254
+ this._updateData(deleteBucket, CSObjectArrayUpdateTypes.DELETE);
255
+ }
256
+
257
+ showAll() {
258
+ this._hideAll = false;
259
+ const addBucket = {
260
+ coords: [],
261
+ coordsZ: [],
262
+ attribs: []
263
+ }
264
+ for (const [centerID, centerMap] of this._centerCollection) {
265
+ const hide = centerMap.get("hide");
266
+ if (hide === ENUM_HIDE.HIDE) continue;
267
+ const hideText = centerMap.get("textHide");
268
+ const isHidden = hideText === ENUM_TEXT_HIDE.HIDE;
269
+ if (isHidden) {
270
+ const x = centerMap.get("x");
271
+ const y = centerMap.get("y");
272
+ const maxRadius = centerMap.get("maxRadius");
273
+ const stepAngle = centerMap.get("stepAngle");
274
+ this._appendCircle(x, y, maxRadius, stepAngle, centerID, addBucket);
275
+ centerMap.set("hide", ENUM_HIDE.SHOW);
276
+ centerMap.set("textHide", ENUM_TEXT_HIDE.SHOW);
277
+ }
278
+ }
279
+ if (addBucket.coords.length) this._updateData(addBucket, CSObjectArrayUpdateTypes.ADD);
280
+ }
281
+
282
+
283
+
284
+
285
+ flush() {
286
+ const data = {
287
+ coords: [],
288
+ coordsZ: [],
289
+ attribs: []
290
+ };
291
+ this._idCollector = new Set();
292
+ this.ObjectArray.SetData(this.object, data);
293
+ }
294
+
295
+ //------------------GLOBE EVENTS------------------//
296
+
297
+ setGeometry() {
298
+ this.__onCompassChange();
299
+ }
300
+
301
+
302
+ //------------------PRIVATE METHODS------------------//
303
+
304
+ __implicitCompassMode() {
305
+ const is3D = this.globe.api_GetCurrentGeometry() === 0;
306
+ if (is3D) {
307
+ return COMPASS_MODES.REAL;
308
+ } else {
309
+ return this._flatCompassMode;
310
+ }
311
+ }
312
+
313
+
314
+ __onCompassChange() {
315
+ if (this._lastImplicitCompassMode === this.__implicitCompassMode()) return;
316
+ this._lastImplicitCompassMode = this.__implicitCompassMode();
317
+ this._updateAll();
318
+ }
319
+
320
+
321
+
322
+ // TODO: compass ve gercek mesafeye gore farkli hesaplamalar yapilacak __implicitCompassMode
323
+ _appendCircle(long, lat, radius, step, centerID, outBucket) {
324
+ const currentCompassMode = this.__implicitCompassMode();
325
+ if (currentCompassMode == COMPASS_MODES.REAL) {
326
+ this.__realCoords(long, lat, radius, step, centerID, outBucket);
327
+ } else if (currentCompassMode == COMPASS_MODES.COMPASS) {
328
+ // throw new Error("Not implemented yet");
329
+ this.__compassCoords(long, lat, radius, step, centerID, outBucket);
330
+ }
331
+
332
+ }
333
+
334
+ __realCoords(long, lat, radius, stepAngle, centerID, outBucket) {
335
+ const { coords, coordsZ, attribs } = outBucket;
336
+
337
+ const coords_ = realCircle(long, lat, radius, stepAngle / Degree);
338
+ { // add 0
339
+ const { long, lat } = coords_[0];
340
+ coords.push(long, lat);
341
+ coordsZ.push(0);
342
+ const key = this._key(centerID, 0);
343
+ // fidkey is the key
344
+ attribs.push({
345
+ "__fid__": key,
346
+ "aci": "K"
347
+ });
348
+ }
349
+ let aci = stepAngle;
350
+ for (let i = 1; i < coords_.length; i++) {
351
+ if (aci >= 360) break;
352
+ const { long, lat } = coords_[i];
353
+ coords.push(long, lat);
354
+ coordsZ.push(0);
355
+ const key = this._key(centerID, i);
356
+ // fidkey is the key
357
+ attribs.push({
358
+ "__fid__": key,
359
+ "aci": aci.toString()
360
+ })
361
+ aci += stepAngle;
362
+ }
363
+ }
364
+
365
+
366
+ __compassCoords(long, lat, radius, stepAngle, centerID, outBucket) {
367
+
368
+ const Dlong = Degree * long;
369
+ const Dlat = Degree * lat;
370
+
371
+ const R = 6371.0 * 1000;
372
+ const { coords, coordsZ, attribs } = outBucket;
373
+ const { globe } = this;
374
+ const radianRadius = radius / R;
375
+ const scale = Math.cos(lat);
376
+ { // add 0
377
+ const x = Dlong + Degree * (radianRadius * Math.cos(Math.PI / 2));
378
+ const y = Dlat + Degree * (radianRadius * Math.sin(Math.PI / 2) * scale);
379
+ coords.push(x, y);
380
+ coordsZ.push(0);
381
+ const key = this._key(centerID, 0);
382
+ attribs.push({
383
+ "__fid__": key,
384
+ "aci": "K"
385
+ })
386
+ }
387
+ let aci = stepAngle;
388
+ let i = 1;
389
+ const RStep = stepAngle / Degree;
390
+ for (let cstep = Math.PI / 2 - RStep; cstep > -Math.PI * 1.5; cstep -= RStep) {
391
+ if (aci >= 360) break;
392
+ const x = Dlong + Degree * (radianRadius * Math.cos(cstep));
393
+ const y = Dlat + Degree * (radianRadius * Math.sin(cstep) * scale);
394
+ coords.push(x, y);
395
+ coordsZ.push(0);
396
+ const key = this._key(centerID, i++);
397
+ attribs.push({
398
+ "__fid__": key,
399
+ "aci": Math.floor(aci).toString()
400
+ })
401
+ aci += stepAngle;
402
+ }
403
+ }
404
+
405
+
406
+ _updateData(bucket, mode) {
407
+ this.ObjectArray.UpdateData(this.object, mode, [bucket], { attribs: false, icon: false, text: false });
408
+ }
409
+
410
+
411
+ _key(centerRingKey, limpIndex) {
412
+ return `${centerRingKey}_${limpIndex}`;
413
+ }
414
+
415
+ _fillDeleteBucket(centerID, outDeleteBucket) {
416
+
417
+ const centerMap = this._centerCollection.get(centerID);
418
+ const stepAngle = centerMap.get("stepAngle");
419
+ const { coords, coordsZ, attribs } = outDeleteBucket;
420
+ let i = 0;
421
+ for (let aci = 0; aci < 360; aci += stepAngle) {
422
+ const key = this._key(centerID, i++);
423
+ coords.push(0, 0);
424
+ coordsZ.push(0);
425
+ attribs.push({
426
+ "__fid__": key,
427
+ });
428
+ }
429
+ }
430
+
431
+ _updateAll() {
432
+ const updateBucket = {
433
+ coords: [],
434
+ coordsZ: [],
435
+ attribs: []
436
+ }
437
+ for (const [centerID, centerMap] of this._centerCollection) {
438
+ const isHidden = centerMap.get("hide") === ENUM_HIDE.HIDE || centerMap.get("textHide") === ENUM_TEXT_HIDE.HIDE;
439
+ if (isHidden) continue;
440
+ const x = centerMap.get("x");
441
+ const y = centerMap.get("y");
442
+ const maxRadius = centerMap.get("maxRadius");
443
+ const stepAngle = centerMap.get("stepAngle");
444
+ this._appendCircle(x, y, maxRadius, stepAngle, centerID, updateBucket);
445
+ }
446
+ this._updateData(updateBucket, CSObjectArrayUpdateTypes.UPDATE);
447
+ }
448
+
449
+ }
450
+
451
+
452
+ const readCoords = (long, lat, radius, stepAngle) => {
453
+
454
+ const result = []
455
+ const degree = radius / R;
456
+
457
+ return result;
458
+ }
459
+
460
+
461
+
462
+
463
+ const R = 6371.0;
464
+
465
+ const flatCircle = (longitude, latitude, radius, paddingAngles) => {
466
+ const degree = radius / R;
467
+ const points = [];
468
+
469
+ for (const angle of paddingAngles) {
470
+ const x = longitude + degree * Math.cos(angle);
471
+ const y = latitude + degree * Math.sin(angle);
472
+ points.push({ long: x, lat: y });
473
+ }
474
+ return points;
475
+ }
476
+
477
+ const realCircle = (longitude, latitude, radius, stepAngle) => {
478
+ const R = 6371000;
479
+
480
+ const degree = radius / R;
481
+ const points = [];
482
+ for (let step = Math.PI / 2.0; step > -Math.PI * 1.5; step -= stepAngle) {
483
+ const y = latitude + degree * Math.sin(step);
484
+ const x = longitude + degree * Math.cos(step) / Math.cos(y);
485
+
486
+ points.push({ long: Degree * x, lat: Degree * y });
487
+ }
488
+ return points;
489
+ }
@@ -0,0 +1,92 @@
1
+ /**
2
+ * This account interacts with buffer orchestrations and buffers.
3
+ * For rings, coordinates and paddings
4
+ */
5
+
6
+
7
+
8
+
9
+ import { BufferOrchestrator, BufferManager } from "../util/account";
10
+
11
+
12
+ const ringKeyMethod = (centerID, ringID) => `${centerID}_${ringID}`;
13
+ const ringBigPaddingKeyMethod = (centerID, ringID, angle) => `${centerID}_${ringID}_${angle}`;
14
+
15
+ /**
16
+ * @typedef { Array < { ringID, radius, paddingRange } >} rings
17
+ * @param { Array < centerID: string, x: number, y: number, stepAngle: number, rgba: [4 numbers], rings: rings } items
18
+ */
19
+ class RingAccount {
20
+ constructor() {
21
+ this._centeralMap = new Map(); // key, new MAP(x,y, rings:[])
22
+
23
+ }
24
+
25
+ /**
26
+ * @typedef {centerID, x, y, rings} centeralItem
27
+ *
28
+ */
29
+ insertCenter(centeralItem) {
30
+ this._centeralMap.set(centeralItem.centerID, centeralItem);
31
+ }
32
+
33
+
34
+ getCenter(centerID) {
35
+ return this._centeralMap.get(centerID);
36
+ }
37
+
38
+ updateCentersXY(items) {
39
+ for (const { centerID, x, y } of items) {
40
+ const center = this.getCenter(centerID);
41
+ if (center) {
42
+ center.x = x;
43
+ center.y = y;
44
+ }
45
+ }
46
+ }
47
+
48
+ /**
49
+ *
50
+ * @param {Array<{centerID, rgba}>} centersColor
51
+ */
52
+ updateCentersColor(centersColor) {
53
+ for (const { centerID, rgba } of centersColor) {
54
+ const center = this.getCenter(centerID);
55
+ if (center) {
56
+ center.rgba = rgba;
57
+ }
58
+ }
59
+ }
60
+
61
+ // to delete rings and one degree paddings from buffer
62
+ ringKeys(centerID) {
63
+ const result = [];
64
+ const center = this.getCenter(centerID);
65
+ if (center) {
66
+ const rings = center.rings;
67
+ for (const { ringID } of rings) {
68
+ result.push(ringKeyMethod(centerID, ringID));
69
+ }
70
+ }
71
+ return result;
72
+ }
73
+
74
+ // To delete big paddings from buffer
75
+ ringBigPaddingKeys(centerID) {
76
+ const result = [];
77
+ const center = this.getCenter(centerID);
78
+ if (!center) return;
79
+ const { rings, stepAngle } = center;
80
+ for (const { ringID } of rings) {
81
+ let angle = 0;
82
+ while (angle < 360) {
83
+ result.push(ringBigPaddingKeyMethod(centerID, ringID, angle));
84
+ angle += stepAngle;
85
+ }
86
+ }
87
+ return result;
88
+ }
89
+ }
90
+
91
+
92
+ export { RingAccount, ringKeyMethod, ringBigPaddingKeyMethod };
@@ -1,7 +1,10 @@
1
- export const vaoAttributeLoader = (gl, buffer, position, length, stride, offset, divisor = null) => {
1
+ export const vaoAttributeLoader = (gl, buffer, position, length, stride, offset, divisor = null, type = null) => {
2
+ if (type === null) {
3
+ type = gl.FLOAT;
4
+ }
2
5
  gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
3
6
  gl.enableVertexAttribArray(position);
4
- gl.vertexAttribPointer(position, length, gl.FLOAT, false, stride, offset);
7
+ gl.vertexAttribPointer(position, length, type, false, stride, offset);
5
8
  if (divisor !== null) {
6
9
  gl.vertexAttribDivisor(position, divisor);
7
10
  }