@pirireis/webglobeplugins 0.15.21-alpha → 0.15.24

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (33) hide show
  1. package/Math/arc.js +1 -2
  2. package/Math/circle-cdf-points.js +1 -170
  3. package/Math/circle.js +0 -25
  4. package/Math/vec3.js +1 -1
  5. package/altitude-locator/plugin.js +1 -1
  6. package/package.json +1 -1
  7. package/point-tracks/plugin.js +5 -6
  8. package/programs/line-on-globe/lines-color-instanced-flat.js +0 -1
  9. package/programs/point-on-globe/element-globe-surface-glow.js +0 -1
  10. package/programs/totems/camerauniformblock.js +7 -0
  11. package/programs/totems/canvas-webglobe-info.js +9 -9
  12. package/programs/totems/globe-changes.js +21 -14
  13. package/range-tools-on-terrain/bearing-line/plugin.js +2 -5
  14. package/range-tools-on-terrain/circle-line-chain/chain-list-map.js +4 -9
  15. package/range-tools-on-terrain/circle-line-chain/plugin.js +4 -2
  16. package/range-tools-on-terrain/range-ring/adapters.js +25 -9
  17. package/range-tools-on-terrain/range-ring/plugin.js +200 -5
  18. package/range-tools-on-terrain/range-ring/types.js +9 -1
  19. package/semiplugins/lightweight/line-plugin.js +33 -15
  20. package/semiplugins/shape-on-terrain/arc-plugin.js +162 -99
  21. package/semiplugins/shape-on-terrain/circle-plugin.js +170 -83
  22. package/semiplugins/shape-on-terrain/padding-1-degree.js +244 -63
  23. package/util/account/single-attribute-buffer-management/buffer-orchestrator.js +1 -1
  24. package/util/build-strategy/static-dynamic.js +11 -1
  25. package/util/frame-counter-trigger.js +84 -0
  26. package/wind/imagetovectorfieldandmagnitude.js +23 -0
  27. package/wind/index.js +2 -2
  28. package/wind/plugin.js +30 -9
  29. package/write-text/context-text4.js +140 -0
  30. package/Math/arc-generate-points copy.js +0 -366
  31. package/Math/globe-util/horizon-plane.js +0 -112
  32. package/altitude-locator/draw-subset-obj.js +0 -16
  33. package/semiplugins/shape-on-terrain/derived/padding-plugin.js +0 -101
package/Math/arc.js CHANGED
@@ -143,8 +143,7 @@ function _populatePointsWithClosestPointInsideArc(out, arc, count, closestPoint)
143
143
  * @param {Vec3} cameraPosition - The position of the camera.
144
144
  * @param {number} quaternionReuseCount - The number of times to apply the same rotation before recalculating. Higher is faster but less accurate.
145
145
  */
146
- function _distanceSampling(out, count, inArc, cameraPosition = vec3create(0, 0, 0), // TODO
147
- quaternionReuseCount = 1) {
146
+ function _distanceSampling(out, count, inArc, cameraPosition = vec3create(0, 0, 0), quaternionReuseCount = 1) {
148
147
  if (count === 0) {
149
148
  return;
150
149
  }
@@ -1,168 +1,4 @@
1
1
  import { RADIANS } from "./methods";
2
- function createTemplate(intervalCount, strength = 1.0) {
3
- const out = new Array(intervalCount);
4
- const TOTAL = 1;
5
- let cummulative = 0;
6
- if (strength <= 0) {
7
- // If strength is 0, distribute evenly.
8
- const step = TOTAL / (intervalCount - 1);
9
- for (let i = 0; i < intervalCount; i++) {
10
- out[i] = cummulative;
11
- cummulative += step;
12
- }
13
- out[intervalCount - 1] = TOTAL; // Ensure the last value is exactly TOTAL
14
- return out;
15
- }
16
- // If strength is greater than 0, bias towards the start.
17
- const weights = new Array(intervalCount);
18
- let currentStep = 1;
19
- let totalWeight = 0;
20
- // Calculate weights for each interval, decreasing for later intervals.
21
- for (let i = 0; i < intervalCount; i++) {
22
- // Using (i + 1) in the denominator gives earlier intervals the highest weight.
23
- totalWeight += currentStep;
24
- weights[i] = totalWeight;
25
- currentStep += strength;
26
- }
27
- // Distribute the total angle based on the weights.
28
- for (let i = 0; i < intervalCount; i++) {
29
- // Round to the nearest whole number for this interval.
30
- out[i] = (weights[i] / totalWeight) * TOTAL;
31
- }
32
- if (out[intervalCount - 1] !== TOTAL) {
33
- out[intervalCount - 1] = TOTAL;
34
- }
35
- // console.log("createTemplate", "strength", strength, "intervalCount", intervalCount, "out", out);
36
- return out;
37
- }
38
- function interpolation(a, b, t) {
39
- return a + (b - a) * t;
40
- }
41
- /**
42
- * Populates the `out` array with values from the `template` array,
43
- * distributing the surplus length as interpolated values between the template samples.
44
- *
45
- * @param out The destination array to be filled. Its length must be >= template.length.
46
- * @param template An ordered array of numbers to be placed in the `out` array.
47
- * @param strength A parameter controlling the distribution bias of surplus samples.
48
- * - strength = 0: Surplus samples are distributed evenly.
49
- * - strength > 0: Surplus samples are biased towards the start of the template.
50
- * - Higher values create a stronger bias.
51
- */
52
- function increasePopulation(// TODO: THERE IS A BUG
53
- out, template, strength = 1.0) {
54
- const sourceLength = template.length;
55
- const destinationLength = out.length;
56
- const outLengthAtStart = out.length;
57
- // --- Handle Edge Cases ---
58
- // If the template is empty, there is nothing to interpolate from.
59
- if (sourceLength === 0) {
60
- return;
61
- }
62
- // If the template has only one value, fill the output array with that value.
63
- if (sourceLength === 1) {
64
- out.fill(template[0]);
65
- return;
66
- }
67
- // If the destination is not larger than the source, just copy the template values.
68
- if (destinationLength <= sourceLength) {
69
- for (let i = 0; i < destinationLength; i++) {
70
- out[i] = template[i];
71
- }
72
- return;
73
- }
74
- // --- Main Logic ---
75
- const surplus = destinationLength - sourceLength;
76
- const numGaps = sourceLength - 1;
77
- // This array will hold the number of extra samples to add in each gap.
78
- const surplusPerGap = new Array(numGaps).fill(0);
79
- if (surplus > 0) {
80
- // --- Step 1: Determine the distribution of surplus items ---
81
- // If strength is 0, distribute surplus items as evenly as possible.
82
- if (strength <= 0) {
83
- const baseToAdd = Math.floor(surplus / numGaps);
84
- const remainder = surplus % numGaps;
85
- for (let i = 0; i < numGaps; i++) {
86
- // Distribute the remainder one by one to the first gaps.
87
- surplusPerGap[i] = baseToAdd + (i < remainder ? 1 : 0);
88
- }
89
- }
90
- else {
91
- // Biased Distribution: more items in earlier gaps.
92
- const weights = new Array(numGaps);
93
- let totalWeight = 0;
94
- // A. Calculate a weight for each gap. The weight decreases for later gaps.
95
- // The `strength` parameter makes this decay steeper.
96
- for (let i = 0; i < numGaps; i++) {
97
- // Using (i + 1) in the denominator gives earlier gaps (i=0) the highest weight.
98
- const weight = Math.pow(1 / (i + 1), strength);
99
- weights[i] = weight;
100
- totalWeight += weight;
101
- }
102
- // B. Distribute the surplus based on the calculated weights.
103
- // This method ensures the total distributed count equals the surplus.
104
- let distributedCount = 0;
105
- for (let i = 0; i < numGaps - 1; i++) {
106
- const idealCount = (weights[i] / totalWeight) * surplus;
107
- // Round to the nearest whole number for this gap.
108
- const countForThisGap = Math.ceil(idealCount);
109
- surplusPerGap[i] = countForThisGap;
110
- distributedCount += countForThisGap;
111
- }
112
- // Assign the remainder to the last gap to guarantee the sum is correct.
113
- //surplusPerGap[numGaps - 1] = surplus - distributedCount;
114
- // add to first
115
- const leftover = surplus - distributedCount;
116
- if (leftover > 0) {
117
- surplusPerGap[0] += leftover; // Add any leftover to the first gap.
118
- }
119
- console.log("leftover", leftover, "distributedCount", distributedCount, "surplus", surplus);
120
- }
121
- }
122
- // --- Step 2: Populate the `out` array ---
123
- let outIndex = 0;
124
- for (let i = 0; i < surplusPerGap.length; i++) {
125
- if (typeof surplusPerGap[i] !== "number" || isNaN(surplusPerGap[i]) || !isFinite(surplusPerGap[i])) {
126
- console.warn("increasePopulation: Invalid surplusPerGap value at index", i, ":", surplusPerGap[i]);
127
- }
128
- }
129
- for (let i = 0; i < sourceLength; i++) {
130
- // A. Add the original template item.
131
- out[outIndex++] = template[i];
132
- // B. If this is not the last template item, fill the gap after it.
133
- if (i < numGaps) {
134
- const numToAdd = surplusPerGap[i];
135
- if (numToAdd <= 0)
136
- continue;
137
- const startVal = template[i];
138
- const endVal = template[i + 1];
139
- // C. Add the interpolated ("surplus") items for this gap.
140
- // The total number of intervals in this gap is numToAdd + 1.
141
- const totalIntervals = numToAdd + 1;
142
- for (let j = 1; j <= numToAdd; j++) {
143
- const t = j / totalIntervals; // The interpolation factor (0 < t < 1)
144
- // Linear interpolation: out = start * (1 - t) + end * t
145
- const interpolatedValue = startVal * (1 - t) + endVal * t;
146
- out[outIndex++] = interpolatedValue;
147
- if (outIndex >= out.length) {
148
- console.warn("increasePopulation: Output array overflow. Stopping early.");
149
- console.warn("processeed item ratio:", i, "/", sourceLength);
150
- let count = numToAdd - j;
151
- console.log("count", count);
152
- for (let _i = i; _i < sourceLength; _i++) {
153
- count += surplusPerGap[_i];
154
- }
155
- console.warn("increasePopulation: Not enough space to add", count, "more items.");
156
- return; // Prevent overflow if the output array is not large enough.
157
- }
158
- }
159
- }
160
- }
161
- // --- Step 3: Ensure the output length is correct ---
162
- if (outLengthAtStart !== out.length) {
163
- console.warn("increasePopulation: Output length mismatch. Expected", outLengthAtStart, "but got", out.length);
164
- }
165
- }
166
2
  function createCummulativeTemplate(numberOfPoints, strength, denseRatio = 0.5 // Ratio of points to be densely packed at the start.
167
3
  ) {
168
4
  // Handle edge cases for the number of points.
@@ -239,9 +75,4 @@ function globeFindPointByPolarHalfCircle(out, globe, centerLong, centerLat, radi
239
75
  offset -= 2;
240
76
  }
241
77
  }
242
- export {
243
- // createTemplate,
244
- // increasePopulation,
245
- // interpolation,
246
- // createCummulativeTemplate,
247
- createCummulativeTemplateStash, globeFindPointByPolar, globeFindPointByPolarHalfCircle };
78
+ export { createCummulativeTemplateStash, globeFindPointByPolar, globeFindPointByPolarHalfCircle };
package/Math/circle.js CHANGED
@@ -29,30 +29,5 @@ function createCircleClosestAzimuthAngleProperties(circle) {
29
29
  normal: normal,
30
30
  northPointProjectedToOriginPlaneNormalized: N,
31
31
  };
32
- // const distance = normal[2]; //dot(normal, [0, 0, 1] as Vec3)
33
- // const N: Vec3 = [0, 0, 0];
34
- // if (Math.abs(distance) < 1e-6) {
35
- // N[0] = -1;
36
- // N[1] = 0;
37
- // N[2] = 0;
38
- // } else {
39
- // // TODO: add cases for 8 parts of the sphere
40
- // copy(N, normal);
41
- // multiplyScalar(N, N, distance);
42
- // if (N[2] >= 0) {
43
- // N[0] = -N[0];
44
- // N[1] = -N[1];
45
- // N[2] = 1 - N[2];
46
- // } else {
47
- // N[2] = -N[2];
48
- // N[0] = -N[0];
49
- // N[1] = -N[1];
50
- // }
51
- // }
52
- // normalize(N, N);
53
- // return {
54
- // normal: normal,
55
- // northPointProjectedToOriginPlaneNormalized: N,
56
- // }
57
32
  }
58
33
  export { closestAzimuthAngle, createCircleClosestAzimuthAngleProperties };
package/Math/vec3.js CHANGED
@@ -85,7 +85,7 @@ function equals(a, b) {
85
85
  Math.abs(a[2] - b[2]) < EPSILON);
86
86
  }
87
87
  function fromUnitVectorToLongLat(out, a) {
88
- const len = length(a); // TODO Might drop length check
88
+ const len = length(a);
89
89
  if (len === 0) {
90
90
  throw new Error('Cannot convert a zero vector to unit vector');
91
91
  }
@@ -335,7 +335,7 @@ class PointGlowLineToEarthPlugin {
335
335
  });
336
336
  }
337
337
  _doesChanged() {
338
- return this._cameraBlockTotem.isMoved() || this._parametersChanged; // TODO: implement
338
+ return this.globe.api_IsScreenMoving();
339
339
  }
340
340
  _changed() {
341
341
  this._parametersChanged = true;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pirireis/webglobeplugins",
3
- "version": "0.15.21-alpha",
3
+ "version": "0.15.24",
4
4
  "main": "index.js",
5
5
  "author": "Toprak Nihat Deniz Ozturk",
6
6
  "license": "MIT",
@@ -14,7 +14,7 @@ const _0vec3 = /* @__PURE__ */ [0, 0, 0];
14
14
  * @typedef {Array<Point>, rgba, trackID} Track
15
15
  */
16
16
  class PointTracksPlugin {
17
- constructor(id, { pointSize = 2, hoveredPointSize = 4, selectionPointFilling = 4, opacity = 1.0, objectStoreExtraParameters = ["long", "lat", "height"], initialCapacity = 10000000 } = {}) {
17
+ constructor(id, { pointSize = 2, hoveredPointSize = 4, selectionPointFilling = 4, opacity = 1.0, objectStoreExtraParameters = ["long", "lat", "height"], initialCapacity = 1000 } = {}) {
18
18
  this.id = id;
19
19
  this._isFreed = false;
20
20
  this._pointProgram = null;
@@ -25,7 +25,7 @@ class PointTracksPlugin {
25
25
  this._selectedID = -1;
26
26
  this._selectedObj = null;
27
27
  this._tracksToPointsMap = new Map(); // one to many
28
- this._opacity = opacity;
28
+ this._opacity = opacity ? opacity : 1.0;
29
29
  this.program = null;
30
30
  this._lastWH = { w: 0, h: 0 };
31
31
  this._focusParams = { on: false, length: 0, elementBuffer: null, trackIDs: [] };
@@ -34,11 +34,11 @@ class PointTracksPlugin {
34
34
  selectionPointFilling: selectionPointFilling ? selectionPointFilling : 4,
35
35
  hoveredPointSize: hoveredPointSize ? hoveredPointSize : 4
36
36
  };
37
- this._objectStoreExtraParameters = objectStoreExtraParameters;
37
+ this._objectStoreExtraParameters = objectStoreExtraParameters ? objectStoreExtraParameters : [];
38
38
  this._objectStoreExtraParametersFiltered = objectStoreExtraParameters.filter(param => {
39
39
  return !["long", "lat", "height", "ID", "trackID"].includes(param);
40
40
  });
41
- this._bufferOrchestrator = new BufferOrchestrator({ capacity: initialCapacity });
41
+ this._bufferOrchestrator = new BufferOrchestrator({ capacity: initialCapacity ? initialCapacity : 1000 });
42
42
  }
43
43
  init(globe, gl) {
44
44
  this.globe = globe;
@@ -144,7 +144,7 @@ class PointTracksPlugin {
144
144
  * @returns
145
145
  */
146
146
  insertBulk(tracks) {
147
- this._fillTracksToPointsMap(tracks); // TODO error should be at the top
147
+ this._fillTracksToPointsMap(tracks);
148
148
  const flattenedPoints = tracks.map(trackToFlatPoints, this._objectStoreExtraParametersFiltered).flat();
149
149
  const currentLoad = this._bufferOrchestrator.length;
150
150
  if (currentLoad + flattenedPoints.length >= 2147483647) {
@@ -224,7 +224,6 @@ class PointTracksPlugin {
224
224
  return;
225
225
  this._isFreed = true;
226
226
  this._pickerDisplayer.free();
227
- this._tracksToPointMap.clear();
228
227
  PointOnGlobeProgramCache.release(this.globe);
229
228
  this.gl.deleteBuffer(this._focusParams.elementBuffer);
230
229
  this._bufferManagersMap.forEach(({ bufferManager, adaptor }) => bufferManager.free());
@@ -8,7 +8,6 @@ import { attributeLoader } from "../../util/gl-util/buffer/attribute-loader";
8
8
  * This program draws line between points provided from the first and second buffer.
9
9
  * draw method gl.drawArraysInstanced( gl.POINTS, 0,2, lineCount);
10
10
  * */
11
- // TODO: find better way to eleminate edge case distance(posA, posB) > 37000000.0
12
11
  const vertexShaderSource = `#version 300 es
13
12
  precision highp float;
14
13
  ${CameraUniformBlockString}
@@ -100,7 +100,6 @@ class Logic {
100
100
  const vao = gl.createVertexArray();
101
101
  const divisor = 1;
102
102
  gl.bindVertexArray(vao);
103
- // TODO constants to escape values
104
103
  attributeLoader(gl, pos3DObj, 0, 3, { divisor });
105
104
  attributeLoader(gl, radiusObj, 1, 1, { divisor, escapeValues: [-1] });
106
105
  attributeLoader(gl, colorObj, 2, 4, { divisor, escapeValues: [-1, -1, -1, -1] });
@@ -1,6 +1,7 @@
1
1
  import { globeProgramCache } from "../programcache";
2
2
  import { fromLongLatToUnitVector } from "../../Math/vec3";
3
3
  import { RADIANS } from "../../Math/methods";
4
+ import { GlobeChangeObserver } from "./globe-changes";
4
5
  export const CameraUniformBlockString = `
5
6
  layout(std140) uniform CameraUniformBlock {
6
7
  mat4 view; // 64 bytes 0
@@ -29,6 +30,7 @@ export class CameraUniformBlockTotem {
29
30
  _isMovedParams;
30
31
  _normalizedCameraVector = [0, 0, 0]; // Normalized camera vector
31
32
  // _frustumPlanes: any; // Uncomment and type if used
33
+ _globeChangeObserver = null;
32
34
  constructor() {
33
35
  this.id = "CameraUniformBlockTotem";
34
36
  this.description =
@@ -51,6 +53,7 @@ export class CameraUniformBlockTotem {
51
53
  this.ubo = this._createUBO();
52
54
  this.traslateFloat32 = new Float32Array(3);
53
55
  this.mapWHFloat32 = new Float32Array(2);
56
+ this._globeChangeObserver = new GlobeChangeObserver(globe);
54
57
  this.setGeometry();
55
58
  this.resize();
56
59
  }
@@ -86,6 +89,7 @@ export class CameraUniformBlockTotem {
86
89
  const ubo = this.ubo;
87
90
  const mapWHFloat32 = this.mapWHFloat32;
88
91
  const globe = this.globe;
92
+ this._globeChangeObserver?.checkChanges();
89
93
  gl.bindBuffer(gl.UNIFORM_BUFFER, ubo);
90
94
  {
91
95
  // view, projection, translate
@@ -196,6 +200,9 @@ export class CameraUniformBlockTotem {
196
200
  fromLongLatToUnitVector(result, [CenterLong * RADIANS, CenterLat * RADIANS]);
197
201
  return result;
198
202
  }
203
+ getGlobeChanges() {
204
+ return this._globeChangeObserver?.getChanges();
205
+ }
199
206
  free() {
200
207
  const gl = this.gl;
201
208
  const ubo = this.ubo;
@@ -1,13 +1,13 @@
1
1
  import { globeProgramCache } from "../programcache";
2
- export const WebGlobeInfoUniformBlockString = `
3
- layout(std140) uniform WebGlobeInfo {
4
- vec2 canvas_resolution;
5
- vec2 mouse_radian_long_lat;
6
- vec2 mouse_pixel_xy;
7
- float north_angle;
8
- float world_tilt;
9
- float earth_distance;
10
- };
2
+ export const WebGlobeInfoUniformBlockString = `
3
+ layout(std140) uniform WebGlobeInfo {
4
+ vec2 canvas_resolution;
5
+ vec2 mouse_radian_long_lat;
6
+ vec2 mouse_pixel_xy;
7
+ float north_angle;
8
+ float world_tilt;
9
+ float earth_distance;
10
+ };
11
11
  `;
12
12
  export default class CanvasWebGlobeInfo {
13
13
  id;
@@ -12,11 +12,12 @@ export class GlobeChangeObserver {
12
12
  };
13
13
  lastElevationCoefficient = NaN;
14
14
  changes = {
15
- geometryChanged: false,
16
- lookChanged: false,
17
- lodChanged: false,
18
- worldWHChanged: false,
19
- elevationCoefficientChanged: false
15
+ geometry: false,
16
+ look: false,
17
+ lod: false,
18
+ lod2DWheel: false,
19
+ elevationScale: false,
20
+ screenMoved: false
20
21
  };
21
22
  constructor(globe) {
22
23
  this.globe = globe;
@@ -27,24 +28,30 @@ export class GlobeChangeObserver {
27
28
  this.lastElevationCoefficient = globe.api_GetZScale();
28
29
  }
29
30
  checkChanges() {
30
- const currentGeometry = this.globe.api_GetCurrentGeometry();
31
- const currentLook = this.globe.api_GetCurrentLookInfo();
32
- const currentLOD = this.globe.api_GetCurrentLODWithDecimal();
33
- const currentWorldWH = this.globe.api_GetCurrentWorldWH();
34
- this.changes.geometryChanged = (this.lastGeometry !== currentGeometry);
35
- this.changes.lookChanged = (this.lastLook.CenterLong !== currentLook.CenterLong ||
31
+ const globe = this.globe;
32
+ const currentGeometry = globe.api_GetCurrentGeometry();
33
+ const currentLook = globe.api_GetCurrentLookInfo();
34
+ const currentLOD = globe.api_GetCurrentLODWithDecimal();
35
+ const currentWorldWH = globe.api_GetCurrentWorldWH();
36
+ this.changes.geometry = (this.lastGeometry !== currentGeometry);
37
+ this.changes.look = (this.lastLook.CenterLong !== currentLook.CenterLong ||
36
38
  this.lastLook.CenterLat !== currentLook.CenterLat ||
37
39
  this.lastLook.Distance !== currentLook.Distance ||
38
40
  this.lastLook.Tilt !== currentLook.Tilt ||
39
- this.lastLook.NorthAng !== currentLook.NorthAng);
40
- this.changes.lodChanged = (this.lastLOD !== currentLOD);
41
- this.changes.worldWHChanged = (this.lastWorldWH.width !== currentWorldWH.width ||
41
+ this.lastLook.NorthAng !== currentLook.NorthAng ||
42
+ this.lastWorldWH.width !== currentWorldWH.width ||
42
43
  this.lastWorldWH.height !== currentWorldWH.height);
44
+ this.changes.lod = (this.lastLOD !== currentLOD);
45
+ this.changes.lod2DWheel = (!globe.api_IsScreenMoving() && this.changes.lod);
43
46
  // Update last known states
44
47
  this.lastGeometry = currentGeometry;
45
48
  this.lastLook = currentLook;
46
49
  this.lastLOD = currentLOD;
47
50
  this.lastWorldWH = currentWorldWH;
51
+ this.changes.screenMoved = (this.changes.geometry ||
52
+ this.changes.look ||
53
+ this.changes.lod ||
54
+ this.changes.lod2DWheel);
48
55
  }
49
56
  getChanges() {
50
57
  return this.changes;
@@ -216,7 +216,6 @@ export class BearingLinePlugin {
216
216
  this.drawOptions.drawAngleRing = drawAngleRing;
217
217
  this.globe.DrawRender();
218
218
  }
219
- // TODO:
220
219
  updatePartial(items, { textWriterIDs } = {}) {
221
220
  if (this._freed) {
222
221
  throw new Error("Plugin has been freed, cannot update item.");
@@ -436,10 +435,8 @@ export class BearingLinePlugin {
436
435
  this.linePlugin.draw3D();
437
436
  this.linePluginBL.draw3D();
438
437
  }
439
- if (this.drawOptions.drawAngleRing) {
440
- for (const textWriter of this._textWritersMap.values()) {
441
- textWriter.draw();
442
- }
438
+ for (const textWriter of this._textWritersMap.values()) {
439
+ textWriter.draw();
443
440
  }
444
441
  }
445
442
  free() {
@@ -1,7 +1,3 @@
1
- /**
2
- * set and get node data
3
- * node indexes;
4
- */
5
1
  export class ChainListMap {
6
2
  _chainMap;
7
3
  _chainSideProperties;
@@ -98,7 +94,7 @@ export class ChainListMap {
98
94
  });
99
95
  }
100
96
  this._chainMap.delete(chainKey);
101
- this._chainSideProperties.delete(chainKey); // TODO: this might be this way but adding this know can cause side effects
97
+ this._chainSideProperties.delete(chainKey);
102
98
  for (const key of keys)
103
99
  this._indexMap.delete(key);
104
100
  return keys;
@@ -177,10 +173,9 @@ export class ChainListMap {
177
173
  memoryProperties[key] = value;
178
174
  });
179
175
  }
180
- // TODO: bad name clean up, need to check on frontend
181
- getNodeProperties(chainKey) {
182
- return this._chainSideProperties.get(chainKey);
183
- }
176
+ // getNodeProperties(chainKey: string): ChainProperties | undefined {
177
+ // return this._chainSideProperties.get(chainKey);
178
+ // }
184
179
  getChainProperties(chainKey) {
185
180
  return this._chainSideProperties.get(chainKey);
186
181
  }
@@ -158,12 +158,14 @@ export class CircleLineChainPlugin {
158
158
  this.globe?.DrawRender();
159
159
  }
160
160
  setOpacities(opacities) {
161
- // TODO: Check opacities
161
+ if (this._freed) {
162
+ console.warn("CircleLineChainPlugin is freed, cannot set opacities.");
163
+ return;
164
+ }
162
165
  this._opacities = {
163
166
  ...this._opacities,
164
167
  ...opacities
165
168
  };
166
- // set Opacities of plugins
167
169
  this.globe?.DrawRender();
168
170
  }
169
171
  setElevationMode(mode) {
@@ -7,10 +7,10 @@
7
7
  // altitude: rangeRing.altitude,
8
8
  // };
9
9
  // }
10
- const keyAdapter = (centerID, rangeID) => {
10
+ export const keyAdapter = (centerID, rangeID) => {
11
11
  return `${centerID}-${rangeID}`;
12
12
  };
13
- export const allKeysAdapter = (rangeRing) => {
13
+ export const allCircleKeysAdapter = (rangeRing) => {
14
14
  const result = new Array(rangeRing.rings.length);
15
15
  for (let i = 0; i < rangeRing.rings.length; i++) {
16
16
  result[i] = keyAdapter(rangeRing.centerID, rangeRing.rings[i].ringID);
@@ -56,20 +56,36 @@ export const rangeRingToArcInputAdapter = (globe, rangeRingInput) => {
56
56
  }
57
57
  return result;
58
58
  };
59
+ export function createColorRatios(color, stepAngle, colorFade = 0.4) {
60
+ const angleCount = Math.ceil(360 / stepAngle) * 2;
61
+ let angleLeft = 360;
62
+ const result = new Array(angleCount);
63
+ for (let i = 0; i < angleCount; i++) {
64
+ const currentAngle = Math.min(stepAngle, angleLeft);
65
+ angleLeft -= currentAngle;
66
+ result[i * 2] = {
67
+ color: [0, 0, 0, 0],
68
+ ratio: 1,
69
+ };
70
+ const colorRatio = {
71
+ // color: i % 2 === 0 ? color : [color[0] * colorFade, color[1] * colorFade, color[2] * colorFade, color[3]] as Color,
72
+ color: i % 2 === 0 ? color : [1 - color[0] * colorFade, 1 - color[1] * colorFade, 1 - color[2] * colorFade, color[3]],
73
+ ratio: currentAngle - 1
74
+ };
75
+ result[i * 2 + 1] = colorRatio;
76
+ }
77
+ return result;
78
+ }
59
79
  export const padding1DegreeInputAdapter = (bearingLine) => {
60
- const { long, lat, rgba, altitude = 0, rings } = bearingLine;
80
+ const { long, lat, rgba, altitude = 0, rings, stepAngle } = bearingLine;
61
81
  const result = new Array(rings.length);
62
82
  for (let i = 0; i < rings.length; i++) {
63
83
  const ring = rings[i];
64
84
  result[i] = {
65
85
  key: keyAdapter(bearingLine.centerID, ring.ringID),
66
86
  center: [long, lat],
67
- outerRadius: ring.radius,
68
- colorsRatios: [{
69
- color: rgba,
70
- ratio: 360,
71
- }
72
- ],
87
+ radius: ring.radius,
88
+ colorsRatios: createColorRatios(rgba, stepAngle, 0.5),
73
89
  heightFromGroundIn3D: altitude,
74
90
  };
75
91
  }