@pirireis/webglobeplugins 0.0.1

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 (82) hide show
  1. package/arrowfield/adaptor.js +11 -0
  2. package/arrowfield/index.js +4 -0
  3. package/arrowfield/plugin.js +128 -0
  4. package/compassrose/compassrose.js +394 -0
  5. package/compassrose/index.js +2 -0
  6. package/heatwavemaps/index.js +4 -0
  7. package/heatwavemaps/isobar/objectarraylabels.js +247 -0
  8. package/heatwavemaps/isobar/plugin.js +337 -0
  9. package/heatwavemaps/isobar/quadtreecontours.js +338 -0
  10. package/heatwavemaps/plugins/heatwaveglobeshell.js +257 -0
  11. package/index.js +8 -0
  12. package/package.json +7 -0
  13. package/programs/arrowfield/index.js +2 -0
  14. package/programs/arrowfield/logic.js +284 -0
  15. package/programs/arrowfield/object.js +89 -0
  16. package/programs/float2legendwithratio/index.js +3 -0
  17. package/programs/float2legendwithratio/logic.js +189 -0
  18. package/programs/float2legendwithratio/object.js +132 -0
  19. package/programs/globeshell/index.js +2 -0
  20. package/programs/globeshell/noise/noises.js +0 -0
  21. package/programs/globeshell/wiggle/index.js +6 -0
  22. package/programs/globeshell/wiggle/logic.js +374 -0
  23. package/programs/globeshell/wiggle/object.js +94 -0
  24. package/programs/helpers/blender/index.js +0 -0
  25. package/programs/helpers/blender/program.js +91 -0
  26. package/programs/helpers/fadeaway/index.js +3 -0
  27. package/programs/helpers/fadeaway/logic.js +76 -0
  28. package/programs/helpers/fadeaway/object.js +20 -0
  29. package/programs/helpers/index.js +2 -0
  30. package/programs/index.js +21 -0
  31. package/programs/programcache.js +119 -0
  32. package/programs/rings/distancering/circleflatprogram.js +135 -0
  33. package/programs/rings/distancering/circlepaddysharedbuffer.js +502 -0
  34. package/programs/rings/distancering/index.js +5 -0
  35. package/programs/rings/distancering/paddyflatprogram.js +131 -0
  36. package/programs/rings/distancering/shader.js +0 -0
  37. package/programs/rings/index.js +9 -0
  38. package/programs/totems/camerauniformblock.js +129 -0
  39. package/programs/totems/index.js +2 -0
  40. package/programs/util.js +17 -0
  41. package/programs/vectorfields/index.js +3 -0
  42. package/programs/vectorfields/logics/drawrectangleparticles.js +125 -0
  43. package/programs/vectorfields/logics/index.js +5 -0
  44. package/programs/vectorfields/logics/pixelbased.js +161 -0
  45. package/programs/vectorfields/logics/ubo.js +64 -0
  46. package/programs/vectorfields/pingpongbuffermanager.js +80 -0
  47. package/rangerings/index.js +3 -0
  48. package/rangerings/rangerings.js +88 -0
  49. package/timetracks/adaptors.js +133 -0
  50. package/timetracks/index.js +3 -0
  51. package/timetracks/plugin.js +304 -0
  52. package/timetracks/program.js +850 -0
  53. package/timetracks/programpoint.js +168 -0
  54. package/util/datamanager/datamanager.js +168 -0
  55. package/util/datamanager/index.js +3 -0
  56. package/util/datamanager/pointcoordinatesdatacalculator.js +133 -0
  57. package/util/datamanager/pointcoordsmeta.js +22 -0
  58. package/util/geometry/geodatafromtexture.js +52 -0
  59. package/util/geometry/index.js +44 -0
  60. package/util/index.js +13 -0
  61. package/util/jshelpers/index.js +1 -0
  62. package/util/jshelpers/timefilters.js +32 -0
  63. package/util/jshelpers/timemethods.js +19 -0
  64. package/util/programs/index.js +2 -0
  65. package/util/programs/shapesonglobe.js +248 -0
  66. package/util/programs/supersampletotextures.js +142 -0
  67. package/util/programs/texturetoglobe.js +203 -0
  68. package/util/shaderfunctions/geometrytransformations.js +129 -0
  69. package/util/shaderfunctions/index.js +2 -0
  70. package/util/shaderfunctions/nodata.js +10 -0
  71. package/util/shaderfunctions/noisefunctions.js +44 -0
  72. package/util/webglobe/gldefaultstates.js +4 -0
  73. package/util/webglobe/index.js +2 -0
  74. package/util/webglobe/rasteroverlay.js +96 -0
  75. package/util/webglobjectbuilders.js +256 -0
  76. package/waveparticles/adaptor.js +16 -0
  77. package/waveparticles/index.js +4 -0
  78. package/waveparticles/plugin.js +281 -0
  79. package/wind/imagetovectorfieldandmagnitude.js +39 -0
  80. package/wind/index.js +7 -0
  81. package/wind/plugin.js +1032 -0
  82. package/wind/vectorfieldimage.js +27 -0
@@ -0,0 +1,247 @@
1
+ import {
2
+ CSGlobe,
3
+ CSIconTypes,
4
+ CSObjectTypes,
5
+ CSObjectArrayUpdateTypes,
6
+ } from "@pirireis/webglobe";
7
+
8
+ /**
9
+ * @typedef {Object} IconPayload
10
+ * @property {string} app6DCode
11
+ * @property {string} accsCode
12
+ */
13
+
14
+ /**
15
+ * @typedef {IconPayload & Object.<string, any>} PointPayload
16
+ */
17
+
18
+ /**
19
+ * @typedef {Object} CanChangeOptions
20
+ * @property {boolean} [attribs=false]
21
+ * @property {boolean} [icon=false]
22
+ * @property {boolean} [label=false]
23
+ * @property {boolean} [heading=false]
24
+ */
25
+
26
+ /**
27
+ * @typedef {Object} PointObjectArray
28
+ * @property {number[]} coords [longitude1, latitude1, longitude2, latitude2, ....]
29
+ * @property {number[]} coordsZ [z1, z2, ....]
30
+ * @property {PointPayload[]} attribs
31
+ */
32
+
33
+ class ObjectArrayLabels {
34
+ /**
35
+ * @param {number | string} id
36
+ * @param {CSGlobe} globe
37
+ */
38
+ constructor(id, globe, labelStyle = null) {
39
+ this.id = id;
40
+ this.setGlobe(globe);
41
+
42
+ this.data = [
43
+ {
44
+ coords: [],
45
+ coordsZ: [],
46
+ attribs: [],
47
+ },
48
+ ];
49
+
50
+ this.primaryKey = "id";
51
+
52
+ this.objectType = CSObjectTypes.POINT;
53
+ this.filter = null;
54
+ this.bbox = null;
55
+ this.startLod = 2;
56
+ this.endLod = 19;
57
+ this.query = true;
58
+ this.reportObj = function (values, mouseEvent) { };
59
+ this._idCollector = new Set();
60
+ this._setStyle(labelStyle);
61
+ }
62
+
63
+
64
+
65
+ _setStyle(labelStyle) {
66
+ this.style = this.globe.ObjectArray.GetDefaultStyle();
67
+
68
+ if (labelStyle) {
69
+ this.style.labels[0] = labelStyle;
70
+ } else {
71
+ this.style.labels[0].vAlignment = 2 // dikey olarak tam noktanın ortası
72
+ this.style.labels[0].hAlignment = 2 // yatay olarak tam noktanın ortası
73
+ this.style.labels[0].size = 11;
74
+ this.style.labels[0].drawAlways = true;
75
+ this.style.labels[0].fontFamily.name = "arial";
76
+ this.style.labels[0].fontFamily.bold = false;
77
+ this.style.labels[0].fontFamily.hollow = true;
78
+ this.style.labels[0].fontFamily.hollowWidth = 1;
79
+ this.style.labels[0].fontFamily.hollowOpacity = 1;
80
+ }
81
+
82
+ this.style.labels[0].text = "${value}";
83
+ this.style.fidKey = this.primaryKey;
84
+
85
+ this.style.iconType = CSIconTypes.NOICON; // milIcon ekleyebilmek için icon tipi MAP olmalı
86
+ }
87
+ /**
88
+ * @param {CSGlobe} [globe]
89
+ */
90
+ setGlobe(globe) {
91
+ if (!globe) return;
92
+ this.globe = globe;
93
+ }
94
+
95
+ addToMap() {
96
+ this.globe.ObjectArray.Add(this);
97
+ }
98
+
99
+ removeFromMap() {
100
+ this.flush();
101
+ this.globe.ObjectArray.Delete(this.id);
102
+ }
103
+
104
+ /**
105
+ * Haritaya kullanılacak veriyi verir. Her çağrıldığında tüm hesaplamalar yeniden yapılır
106
+ * @param {PointObjectArray} data
107
+ */
108
+ setData(data) {
109
+ this.globe.ObjectArray.SetData(this, [data]);
110
+ }
111
+
112
+ /**
113
+ * @param {PointObjectArray} data
114
+ * @param {CSObjectArrayUpdateTypes} operation
115
+ * @param {CanChangeOptions} [canChange]
116
+ */
117
+ updateData(data, operation, canChange) {
118
+ this.globe.ObjectArray.UpdateData(this, operation, [data], canChange);
119
+ }
120
+
121
+ flush() {
122
+ const deleteBucket = {
123
+ coords: [],
124
+ coordsZ: [],
125
+ attribs: [],
126
+ };
127
+ this.setData(deleteBucket);
128
+ this._idCollector = new Set();
129
+ }
130
+
131
+ /**
132
+ * Haritaya kullanılacak veriyi verir. Her çağrıldığında tüm hesaplamalar yeniden yapılmaz, ancak ön hesaplama maliyeti vardır
133
+ * @param {PointObjectArray} data
134
+ */
135
+ setControlledData(data) {
136
+ const paritalData = {
137
+ add: {
138
+ coords: [],
139
+ coordsZ: [],
140
+ attribs: [],
141
+ },
142
+ update: {
143
+ coords: [],
144
+ coordsZ: [],
145
+ attribs: [],
146
+ },
147
+ delete: {
148
+ coords: [],
149
+ coordsZ: [],
150
+ attribs: [],
151
+ },
152
+ canChange: {
153
+ // Tüm değişimler gözardı edilecek
154
+ attribs: false,
155
+ icon: false,
156
+ label: false,
157
+ heading: false,
158
+ },
159
+ };
160
+ // İlk toplu ekleme adımı
161
+ if (this._idCollector.size === 0) {
162
+ this.setData(data);
163
+
164
+ // Eklenen id'ler set edildi
165
+ for (let i = 0; i < data.attribs.length; i++) {
166
+ const currentPayload = data.attribs[i];
167
+ const id = currentPayload[this.primaryKey];
168
+
169
+ this._idCollector.add(id);
170
+ }
171
+
172
+ return;
173
+ }
174
+
175
+ /** @type {Set<string>} */
176
+ const dataIds = new Set();
177
+
178
+ for (let i = 0; i < data.attribs.length; i++) {
179
+ const currentPayload = data.attribs[i];
180
+ const id = currentPayload[this.primaryKey];
181
+
182
+ let bucket = paritalData.add;
183
+
184
+ dataIds.add(id);
185
+
186
+ if (this._idCollector.has(id)) {
187
+ bucket = paritalData.update;
188
+ } else {
189
+ this._idCollector.add(id);
190
+ }
191
+
192
+ bucket.coords.push(data.coords[2 * i], data.coords[2 * i + 1]);
193
+ bucket.coordsZ.push(data.coordsZ[i]);
194
+ bucket.attribs.push(currentPayload);
195
+ }
196
+
197
+ // Artık varolmayan elemenları sil
198
+ const deleteBucket = paritalData.delete;
199
+ this._idCollector.forEach((id) => {
200
+ if (!dataIds.has(id)) {
201
+ this._idCollector.delete(id);
202
+
203
+ deleteBucket.coords.push(0, 0);
204
+ deleteBucket.coordsZ.push(0);
205
+ deleteBucket.attribs.push({
206
+ [this.primaryKey]: id,
207
+ });
208
+ }
209
+ });
210
+
211
+ if (paritalData.add.coords.length > 0) {
212
+ this.updateData(paritalData.add, CSObjectArrayUpdateTypes.ADD);
213
+ }
214
+
215
+ if (paritalData.update.coords.length > 0) {
216
+ this.updateData(
217
+ paritalData.update,
218
+ CSObjectArrayUpdateTypes.UPDATE,
219
+ paritalData.canChange
220
+ );
221
+ }
222
+
223
+ if (paritalData.delete.coords.length > 0) {
224
+ this.updateData(paritalData.delete, CSObjectArrayUpdateTypes.DELETE);
225
+ }
226
+ }
227
+
228
+
229
+ setPrimarykey(key) {
230
+ this.primaryKey = key;
231
+ }
232
+
233
+ setSymbolSet(symbolSet) {
234
+ this.symbolSet = symbolSet;
235
+ }
236
+
237
+ getLabelStyle() {
238
+ return this.style.labels[0];
239
+ }
240
+
241
+ setLabelStyle(style) {
242
+ this.style.labels[0] = style;
243
+
244
+ }
245
+ }
246
+
247
+ export default ObjectArrayLabels;
@@ -0,0 +1,337 @@
1
+ import { ShapesOnGlobeProgram, latLongToPixelXY } from "../../util";
2
+
3
+ import ContourMipmap, { scaleParameters } from "./quadtreecontours";
4
+
5
+ import ObjectArrayLabels from "./objectarraylabels";
6
+
7
+
8
+
9
+ export class IsobarRasterToVector {
10
+
11
+
12
+ /**
13
+ * @typedef {Object} IsobarData
14
+ * @property {number} threshold
15
+ * @property {[number, number, number]} color | rgb color
16
+ * @property {string} label
17
+ *
18
+ * @param {*} id
19
+ * @param {Array<IsobarData>} isabors
20
+ * @param {number} width
21
+ * @param {number} height
22
+ * @param {Object} options
23
+ * @param {boolean} options.xFlip
24
+ * @param {boolean} options.yFlip
25
+ * @param {boolean} options.isOn
26
+ * @param {boolean} options.isLabelsOn
27
+ * @param {Object} options.labelStyle
28
+ */
29
+ constructor(id, dataManager, isobars, width, height, [minLon, minLat, maxLon, maxLat] = [-180, -90, 180, 90], { xFlip = false, yFlip = true, isOn = true, isLabelsOn = true, labelStyle = null, maxMipmapLevel = null } = {}) {
30
+ this.id = id;
31
+ this._isobarsCheckAndComplete(isobars);
32
+ this.isobars = isobars;
33
+ this.contourMipmap = null;
34
+ this.width = width;
35
+ this.height = height;
36
+ this.xFlip = xFlip;
37
+ this.yFlip = yFlip;
38
+ this.bbox = [minLon, minLat, maxLon, maxLat];
39
+ this.dataManager = dataManager;
40
+
41
+ this._transformationMethod = getTransformationMethod(xFlip, yFlip, width, height, minLon, minLat, maxLon, maxLat);
42
+ this._isOn = isOn;
43
+ this._isLabelsOn = isLabelsOn;
44
+ this._labelsLayer = null;
45
+ this._labelsLayerId = id + '_isobar-labels';
46
+ this._lineStrignRanges = [];
47
+ this._transpos = new Float32Array(3);
48
+ this._maxMipmapLevel = maxMipmapLevel;
49
+ this._labelStyle = labelStyle;
50
+
51
+ // this._transformationMethod = null;
52
+ }
53
+
54
+ // API
55
+
56
+ setData(data, on = false) {
57
+ if (!data) return;
58
+ this._data = data;
59
+ if (on) this._isOn = true;
60
+ if (this._isOn) this._calculateAll(data);
61
+ }
62
+
63
+ on() {
64
+ this._isOn = true;
65
+ if (this._data) this._calculateAll(this._data);
66
+ }
67
+
68
+ off() {
69
+ this._isOn = false;
70
+ this.clean();
71
+ }
72
+
73
+
74
+ clean() {
75
+ this.flush();
76
+ this.globe.DrawRender();
77
+ }
78
+
79
+ setFlip(xFlip, yFlip) {
80
+ if (this.xFlip === xFlip && this.yFlip === yFlip) return;
81
+ this.xFlip = xFlip;
82
+ this.yFlip = yFlip;
83
+ const [minLon, minLat, maxLon, maxLat] = this.bbox;
84
+ const { width, height } = this
85
+ this._transformationMethod = getTransformationMethod(xFlip, yFlip, width, height, minLon, minLat, maxLon, maxLat);
86
+ this._calculateLines();
87
+ this.globe.DrawRender();
88
+ }
89
+
90
+ setBoundingBox([minLon, minLat, maxLon, maxLat]) {
91
+ this.bbox = [minLon, minLat, maxLon, maxLat];
92
+ const { width, height, xFlip, yFlip } = this;
93
+ this._transformationMethod = getTransformationMethod(xFlip, yFlip, width, height, minLon, minLat, maxLon, maxLat);
94
+ this._calculateLines();
95
+ this.globe.DrawRender();
96
+ }
97
+
98
+
99
+ setIsLabelsOn(isLabelsOn) {
100
+ if (this._isLabelsOn === isLabelsOn) return;
101
+ this._isLabelsOn = isLabelsOn;
102
+ if (!isLabelsOn) {
103
+ this._labelsLayer.removeFromMap();
104
+ } else {
105
+ if (this._labelsLayer === null) this._createLabelsLayer();
106
+ this._labelsLayer.addToMap();
107
+ this._createBufferData();
108
+ }
109
+ }
110
+
111
+ getIsobars() {
112
+ return this.isobars;
113
+ }
114
+
115
+ setIsobars(isobars) {
116
+ this._isobarsCheckAndComplete(isobars);
117
+ this.isobars = isobars;
118
+ this._calculateLines();
119
+ this.globe.DrawRender();
120
+ }
121
+
122
+ setWidthHeight(width, height) {
123
+ this.width = width;
124
+ this.height = height;
125
+ const { xFlip, yFlip } = this;
126
+ const [minLon, minLat, maxLon, maxLat] = this.bbox;
127
+ this._transformationMethod = getTransformationMethod(xFlip, yFlip, width, height, minLon, minLat, maxLon, maxLat);
128
+ this._calculateLines();
129
+ this.globe.DrawRender();
130
+ }
131
+
132
+
133
+ getLabelStyle() {
134
+ return this._labelsLayer.getLabelStyle();
135
+ }
136
+
137
+ setOpacity(opacity) {
138
+ if (opacity < 0 || opacity > 1) throw new Error("Opacity must be between 0 and 1");
139
+ this.program.setOpacity(opacity);
140
+ }
141
+
142
+
143
+ setLabelStyle(style) {
144
+ this._labelStyle = style;
145
+ if (this._labelsLayer) this._labelsLayer.setLabelStyle(style);
146
+ const lastState = this._isLabelsOn;
147
+ this.setIsLabelsOn(false);
148
+ this.setIsLabelsOn(lastState);
149
+ if (lastState) this._createBufferData();
150
+ }
151
+
152
+ setMaxMipmapLevel(maxMipmapLevel = null) {
153
+ this._maxMipmapLevel = maxMipmapLevel;
154
+ this._calculateLines();
155
+ this.globe.DrawRender();
156
+ }
157
+
158
+
159
+ flush() {
160
+ this.program.setBufferData(new Float32Array(0));
161
+ this._lineStrignRanges = [];
162
+ if (this._isLabelsOn) this._labelsLayer.flush();
163
+ }
164
+
165
+ //
166
+ // implicit methods
167
+
168
+ init(globe, gl) {
169
+ this.gl = gl
170
+ this.globe = globe
171
+
172
+ this.program = new ShapesOnGlobeProgram(gl, globe, 'line_strip');
173
+ if (this._isLabelsOn) {
174
+ this._createLabelsLayer();
175
+ this._labelsLayer.addToMap();
176
+ }
177
+
178
+ this.dataManager.register(this.id, (ratio, t1, t2) => {
179
+ if (!t1 || !t2) {
180
+ this.clean();
181
+ return;
182
+ }
183
+ const data = dataMixer(t1, t2, ratio);
184
+ if (this._isOn) this.setData(data);
185
+ });
186
+ }
187
+
188
+
189
+ resize(width, height) {
190
+ this.program.resize(width, height);
191
+ }
192
+
193
+ draw3D(projMatrix, modelviewMatrix, transPos) {
194
+ if (!this._ready) return;
195
+ this._drawContour(projMatrix, modelviewMatrix, transPos);
196
+ }
197
+
198
+ _calculateLines() {
199
+ this._calculateContours();
200
+ this._bufferData = this._createBufferData();
201
+ this.program.setBufferData(this._bufferData);
202
+ }
203
+
204
+ _drawContour(projMatrix, modelviewMatrix, transPos) {
205
+ this.program.draw(projMatrix, modelviewMatrix, transPos, this._lineStrignRanges);
206
+ }
207
+
208
+
209
+
210
+ _calculateIntersections(threshold) {
211
+ const { _transformationMethod } = this;
212
+ const lines = this.contourMipmap.contour([threshold], { maxMipmapLevel: this._maxMipmapLevel }).map(coords => {
213
+ return coords.map(([x, y]) => _transformationMethod(x, y))
214
+ }
215
+ );
216
+ return lines;
217
+ }
218
+
219
+
220
+ _calculateAll(data) {
221
+ this.contourMipmap = new ContourMipmap(data, this.width, this.height);
222
+ this._calculateContours();
223
+ this._bufferData = this._createBufferData();
224
+ this.program.setBufferData(this._bufferData);
225
+
226
+ this.globe.DrawRender();
227
+ this._ready = true;
228
+ }
229
+
230
+ _calculateContours() {
231
+ const { isobars } = this;
232
+ for (const isobar of isobars) {
233
+ const { threshold } = isobar;
234
+ const lines = this._calculateIntersections(threshold);
235
+ isobar.lines = lines;
236
+ }
237
+ }
238
+
239
+
240
+ _isobarsCheckAndComplete(isobars) {
241
+ window.isobars = isobars;
242
+ if (!Array.isArray(isobars)) throw new Error("isobars must be an array");
243
+ if (isobars.length === 0) throw new Error("isobars must contain at least one element");
244
+ for (const isobar of isobars) {
245
+ if (!isobar || typeof isobar !== 'object') throw new Error("isobar must be an object");
246
+ if (typeof isobar.threshold !== 'number') throw new Error("isobar.threshold must be a number");
247
+ if (isobar.color) {
248
+ if (!Array.isArray(isobar.color) || isobar.color.length !== 3) throw new Error("isobar.color must be an array with 3 elements");
249
+ for (const color of isobar.color) {
250
+ if (color < 0 || color > 1) throw new Error("isobar.color elements must be between 0 and 1");
251
+ }
252
+ }
253
+ if (!isobar.color) isobar.color = [1, 1, 1];
254
+ }
255
+ }
256
+
257
+ _createBufferData() {
258
+ const { isobars } = this;
259
+ const pointCount = isobars.reduce((acc, { lines }) => acc + lines.reduce((acc, line) => acc + line.length, 0), 0);
260
+ const bufferData = new Float32Array(pointCount * 6);
261
+
262
+ let index = 0;
263
+ let pointCounter = 0;
264
+ this._lineStrignRanges = [];
265
+
266
+ // gather label data label
267
+ const labelPoints = {
268
+ coords: [],
269
+ coordsZ: [],
270
+ attribs: []
271
+ };
272
+ const { coords, coordsZ, attribs } = labelPoints;
273
+ let fidCounter = 0;
274
+ for (const { lines, color, threshold } of isobars) {
275
+ for (const line of lines) {
276
+ let startIndex = pointCounter;
277
+ for (const [x, y] of line) {
278
+ const pixXY = latLongToPixelXY(y, x)
279
+ bufferData[index++] = pixXY.x;
280
+ bufferData[index++] = pixXY.y;
281
+ bufferData[index++] = color[0];
282
+ bufferData[index++] = color[1];
283
+ bufferData[index++] = color[2];
284
+ bufferData[index++] = 1.0;
285
+ pointCounter++;
286
+ }
287
+
288
+ coords.push(line[0][0], line[0][1]);
289
+ coordsZ.push(0)
290
+ attribs.push({ value: threshold, fid: fidCounter++ })
291
+ this._lineStrignRanges.push([startIndex, pointCounter - startIndex]);
292
+ }
293
+ }
294
+ if (this._isLabelsOn) this._labelsLayer.setData(labelPoints);
295
+
296
+ return bufferData;
297
+ }
298
+
299
+
300
+
301
+ _createLabelsLayer() {
302
+ this._labelsLayer = new ObjectArrayLabels(this._labelsLayerId, this.globe, this._labelStyle);
303
+ }
304
+
305
+ setGeometry() {
306
+ this.program.setGeometry();
307
+ }
308
+
309
+
310
+ free() {
311
+ this.flush();
312
+ this.program.free();
313
+ if (this._isLabelsOn) this._labelsLayer.removeFromMap();
314
+ this.dataManager.unregister(this.id);
315
+ }
316
+
317
+
318
+
319
+ }
320
+
321
+ const getTransformationMethod = (xFlip, yFlip, width, height, minX, minY, maxX, maxY) => {
322
+ const { scaleX, scaleY } = scaleParameters(minX, minY, maxX, maxY, width, height);
323
+ if (xFlip && yFlip) return (x, y) => [maxX - x * scaleX, maxY - y * scaleY];
324
+ if (xFlip && !yFlip) return (x, y) => [maxX - x * scaleX, minY + y * scaleY];
325
+ if (!xFlip && yFlip) return (x, y) => [minX + x * scaleX, maxY - y * scaleY];
326
+ return (x, y) => [minX + x * scaleX, minY + y * scaleY];
327
+ }
328
+
329
+ function dataMixer(data1, data2, ratio) {
330
+ if (!data1 || !data2) return null;
331
+ if (data1.length !== data2.length) throw new Error("Data length mismatch");
332
+ const data = new Float32Array(data1.length);
333
+ for (let i = 0; i < data1.length; i++) {
334
+ data[i] = data1[i] * (1 - ratio) + data2[i] * ratio;
335
+ }
336
+ return data;
337
+ }