@pirireis/webglobeplugins 0.17.1 → 1.0.3

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 (67) hide show
  1. package/Math/haversine.js +22 -0
  2. package/Math/methods.js +15 -2
  3. package/Math/tessellation/methods.js +4 -1
  4. package/Math/tessellation/nearest-value-padding.js +112 -0
  5. package/Math/tessellation/spherical-triangle-area.js +99 -0
  6. package/Math/tessellation/tile-merger.js +346 -215
  7. package/Math/tessellation/triangle-tessellation.js +381 -9
  8. package/Math/vec3.js +4 -0
  9. package/Math/xyz-tile.js +18 -0
  10. package/altitude-locator/plugin.js +1 -2
  11. package/investigation-tools/draw/tiles/adapters.js +2 -2
  12. package/investigation-tools/draw/tiles/tiles.js +2 -2
  13. package/package.json +1 -1
  14. package/programs/helpers/fadeaway.js +6 -1
  15. package/programs/point-on-globe/square-pixel-point.js +1 -0
  16. package/programs/polygon-on-globe/texture-dem-triangles.js +94 -116
  17. package/programs/totems/camera-totem-attactment-interface.js +1 -0
  18. package/programs/totems/camerauniformblock.js +33 -22
  19. package/programs/totems/dem-textures-manager.js +265 -0
  20. package/programs/vectorfields/logics/drawrectangleparticles.js +51 -18
  21. package/programs/vectorfields/logics/{ubo-new.js → particle-ubo.js} +5 -14
  22. package/programs/vectorfields/logics/pixelbased.js +42 -36
  23. package/programs/vectorfields/pingpongbuffermanager.js +34 -8
  24. package/semiplugins/shape-on-terrain/terrain-polygon/adapters.js +55 -0
  25. package/semiplugins/shape-on-terrain/terrain-polygon/data/cache.js +102 -0
  26. package/semiplugins/shape-on-terrain/terrain-polygon/data/index-polygon-map.js +45 -0
  27. package/semiplugins/shape-on-terrain/terrain-polygon/data/manager.js +4 -0
  28. package/semiplugins/shape-on-terrain/terrain-polygon/data/master-worker.js +177 -0
  29. package/semiplugins/shape-on-terrain/terrain-polygon/data/polygon-to-triangles.js +100 -0
  30. package/semiplugins/shape-on-terrain/terrain-polygon/data/random.js +121 -0
  31. package/semiplugins/shape-on-terrain/terrain-polygon/data/types.js +1 -0
  32. package/semiplugins/shape-on-terrain/terrain-polygon/data/worker-contact.js +63 -0
  33. package/semiplugins/shape-on-terrain/terrain-polygon/data/worker.js +125 -0
  34. package/semiplugins/shape-on-terrain/terrain-polygon/terrain-polygon.js +219 -0
  35. package/semiplugins/shape-on-terrain/terrain-polygon/types.js +8 -0
  36. package/semiplugins/shell/bbox-renderer/logic.js +18 -58
  37. package/semiplugins/shell/bbox-renderer/object.js +19 -9
  38. package/tracks/point-heat-map/point-to-heat-map-flow.js +1 -1
  39. package/tracks/point-tracks/plugin.js +13 -6
  40. package/tracks/timetracks/program-line-strip.js +1 -1
  41. package/util/account/single-attribute-buffer-management/buffer-manager.js +5 -3
  42. package/util/account/single-attribute-buffer-management/buffer-orchestrator.js +2 -2
  43. package/util/gl-util/uniform-block/manager.js +20 -10
  44. package/util/helper-methods.js +8 -0
  45. package/util/picking/fence.js +4 -2
  46. package/util/picking/picker-displayer.js +51 -9
  47. package/util/programs/draw-texture-on-canvas.js +18 -15
  48. package/util/shaderfunctions/geometrytransformations.js +67 -1
  49. package/vectorfield/waveparticles/plugin.js +241 -116
  50. package/vectorfield/wind/adapters/image-to-fields.js +61 -0
  51. package/vectorfield/wind/adapters/types.js +1 -0
  52. package/vectorfield/wind/imagetovectorfieldandmagnitude.js +6 -9
  53. package/vectorfield/wind/plugin-persistant copy.js +364 -0
  54. package/vectorfield/wind/plugin-persistant.js +375 -0
  55. package/vectorfield/wind/plugin.js +1 -1
  56. package/Math/tessellation/earcut/adapters.js +0 -37
  57. package/Math/tessellation/hybrid-triangle-tessellation-meta.js +0 -123
  58. package/Math/tessellation/shred-input.js +0 -18
  59. package/Math/tessellation/tiler.js +0 -50
  60. package/Math/tessellation/triangle-tessellation-meta.js +0 -523
  61. package/programs/polygon-on-globe/texture-dem-triangle-test-plugin-triangle.js +0 -328
  62. package/programs/vectorfields/logics/drawrectangleparticles1.js +0 -112
  63. package/semiplugins/shape-on-terrain/terrain-cover/texture-dem-cover.js +0 -1
  64. package/util/gl-util/uniform-block/types.js +0 -1
  65. package/util/webglobe/index.js +0 -2
  66. /package/Math/tessellation/{zoom-catch.js → constants.js} +0 -0
  67. /package/util/{webglobe/gldefaultstates.js → globe-default-gl-states.js} +0 -0
@@ -0,0 +1,375 @@
1
+ /**
2
+ * Author: Toprak Nihat Deniz Ozturk
3
+ */
4
+ import { imageToFields } from "./adapters/image-to-fields";
5
+ import ParticlePlugin from "../waveparticles/plugin";
6
+ import { createImageFromBase64 } from "../../util/webglobjectbuilders";
7
+ import { TexturePointSampler } from "../../heatwave/texture-point-sampler";
8
+ import imageToMagnitude, { imageToRadianAngle } from "./imagetovectorfieldandmagnitude";
9
+ import { isBoolean } from "../../util/check/typecheck";
10
+ const windyLegendData = {
11
+ thresholds: [0, 3, 3, 5, 5, 7, 10, 10, 13, 15, 15, 17, 20, 20, 25, 25, 30],
12
+ values: [
13
+ "#6271B8",
14
+ "#6271B8",
15
+ "#6271B8",
16
+ "#6271B8",
17
+ "#3D6EA3",
18
+ "#4A94AA",
19
+ "#4A9294",
20
+ "#4D8E7C",
21
+ "#4CA44C",
22
+ "#67A436",
23
+ "#A28740",
24
+ "#A26D5C",
25
+ "#8D3F5C",
26
+ "#974B91",
27
+ "#5F64A0",
28
+ "#5B88A1",
29
+ "#5B88A1"
30
+ ]
31
+ };
32
+ export default class WindPlugin {
33
+ id;
34
+ globe;
35
+ gl = null;
36
+ particlePlugin;
37
+ windMetadata;
38
+ _legendData;
39
+ options;
40
+ windData;
41
+ _height;
42
+ _speedFactor;
43
+ _dropRate;
44
+ texturePointSampler;
45
+ texturePointSamplerAngle;
46
+ /**
47
+ * @param id - Plugin identifier
48
+ * @param windDataMeta - Wind data metadata
49
+ * @param windDataMeta.width - image width
50
+ * @param windDataMeta.height - image height
51
+ * @param windDataMeta.bbox - bounding box [minLon, minLat, maxLon, maxLat]
52
+ * @param options - Plugin options
53
+ * @param options.fadeOpacity - how fast the particle trails fade on each frame | between 0 - 1 | default 0.746
54
+ * @param options.speedFactor - how fast the particles move | between 0 - 1 | default 0.6
55
+ * @param options.dropRate - how often the particles move to a random place | between 0 - 1 | default 0.007
56
+ * @param options.dropRateBump - drop rate increase relative to individual particle speed
57
+ * @param options.baseOpacity - opacity of drawn particle trails | between 0 - 1 | default 1.0
58
+ * @param options.wingSize - wing size of particle arrow | positive number | default 7.0
59
+ * @param options.tailSize - tail size of particle arrow | positive number | default 1.0
60
+ * @param options.minSpeed - minimum speed threshold | positive number | default 0.0
61
+ * @param options.maxSpeed - maximum speed threshold | positive number | default 1000.0
62
+ * @param options.height - height of the particles | number | default 0.0
63
+ * @param options.numParticles - number of particles | positive integer | default 40000
64
+ * @param options.legendData - legend data for color mapping
65
+ */
66
+ constructor(id, windDataMeta, options = {}) {
67
+ this.id = id;
68
+ this.windMetadata = windDataMeta;
69
+ this._legendData = options.legendData || windyLegendData;
70
+ this.options = {
71
+ fadeOpacity: options.fadeOpacity ?? 0.746,
72
+ speedFactor: options.speedFactor ?? 0.6,
73
+ dropRate: options.dropRate ?? 0.007,
74
+ dropRateBump: options.dropRateBump ?? 0.001,
75
+ baseOpacity: options.baseOpacity ?? 1.0,
76
+ wingSize: options.wingSize ?? 7.0,
77
+ tailSize: options.tailSize ?? 1.0,
78
+ minSpeed: options.minSpeed ?? 0.0,
79
+ maxSpeed: options.maxSpeed ?? 1000.0,
80
+ height: options.height ?? 0.0,
81
+ numParticles: options.numParticles ?? 40000,
82
+ legendData: this._legendData
83
+ };
84
+ this.windData = null;
85
+ this._height = this.options.height;
86
+ this._speedFactor = this.options.speedFactor;
87
+ this._dropRate = this.options.dropRate;
88
+ }
89
+ // Globe plugin init method
90
+ init(globe, gl) {
91
+ this.globe = globe;
92
+ this.gl = gl;
93
+ // Initialize the particle plugin with appropriate options
94
+ const { bbox, width, height, flipY } = this.windMetadata;
95
+ this.particlePlugin = new ParticlePlugin(`${this.id}_particles`, {
96
+ dataWidth: width,
97
+ dataHeight: height,
98
+ fadeOpacity: this.options.fadeOpacity,
99
+ opacity: this.options.baseOpacity,
100
+ speed: this._speedFactor,
101
+ dropRate: this._dropRate,
102
+ height: this._height,
103
+ minLon: bbox[0],
104
+ minLat: bbox[1] < -85 ? -85 : bbox[1],
105
+ maxLon: bbox[2],
106
+ maxLat: bbox[3] > 85 ? 85 : bbox[3],
107
+ particleCount: this.options.numParticles,
108
+ flipY: flipY ?? true,
109
+ useColorTexture: false, // TODO: under test.. make it true later
110
+ useSpeedTexture: true,
111
+ minSpeedThreshold: this.options.minSpeed,
112
+ maxSpeedThreshold: this.options.maxSpeed,
113
+ tailSize: this.options.tailSize,
114
+ wingSize: this.options.wingSize
115
+ });
116
+ this.particlePlugin.init(globe, gl);
117
+ // apply initial speed thresholds from options
118
+ this.particlePlugin.setSpeedThresholds(this.options.minSpeed, this.options.maxSpeed);
119
+ }
120
+ draw3D() {
121
+ if (this.particlePlugin) {
122
+ this.particlePlugin.draw3D();
123
+ }
124
+ }
125
+ free() {
126
+ if (this.particlePlugin) {
127
+ this.particlePlugin.free();
128
+ }
129
+ if (this.texturePointSampler) {
130
+ this.texturePointSampler = undefined;
131
+ }
132
+ if (this.texturePointSamplerAngle) {
133
+ this.texturePointSamplerAngle = undefined;
134
+ }
135
+ }
136
+ // ===== Wind Data Management =====
137
+ /**
138
+ * Set wind data from base64 encoded image
139
+ * @param windData - Wind data object
140
+ * @param windData.image - base64 encoded image
141
+ * @param windData.width - image width
142
+ * @param windData.height - image height
143
+ * @param windData.uMin - minimum u value
144
+ * @param windData.vMin - minimum v value
145
+ * @param windData.uMax - maximum u value
146
+ * @param windData.vMax - maximum v value
147
+ * @param windData.bbox - bounding box [minLon, minLat, maxLon, maxLat]
148
+ */
149
+ setWindDataWithImageBase64(windData) {
150
+ const image = createImageFromBase64(windData.image);
151
+ image.onload = () => {
152
+ const fullWindData = {
153
+ image: image,
154
+ uMin: windData.uMin,
155
+ vMin: windData.vMin,
156
+ uMax: windData.uMax,
157
+ vMax: windData.vMax
158
+ };
159
+ this.setWind(fullWindData);
160
+ };
161
+ }
162
+ /**
163
+ * Set wind data from HTMLImageElement
164
+ */
165
+ setWind(windData) {
166
+ this.windData = windData;
167
+ if (!this.particlePlugin) {
168
+ return;
169
+ }
170
+ // Convert wind image to vector field, speed field, and color field
171
+ const { vectorFieldData, speedFieldData, colorFieldData } = imageToFields(windData, this._legendData);
172
+ // Update the particle plugin with the new data
173
+ this.particlePlugin.setVectorFieldData(vectorFieldData, {
174
+ dataWidth: windData.image.width,
175
+ dataHeight: windData.image.height,
176
+ flipY: this.windMetadata.flipY
177
+ });
178
+ this.particlePlugin.setSpeedField(speedFieldData);
179
+ this.particlePlugin.setColorField(colorFieldData);
180
+ // Update texture point samplers if they exist
181
+ this._setCoorcinatesDataCalculatorData();
182
+ }
183
+ // ===== Legend and Color Management =====
184
+ /**
185
+ * Set legend data for color mapping
186
+ * @param legendData - Legend data object
187
+ * @param legendData.thresholds - list of speed thresholds
188
+ * @param legendData.values - list of colors in hex format like #ff0000
189
+ */
190
+ setLegend(legendData) {
191
+ this._legendData = legendData;
192
+ // If wind data is already set, re-process to update colors
193
+ if (this.windData && this.particlePlugin) {
194
+ const { vectorFieldData, speedFieldData, colorFieldData } = imageToFields(this.windData, this._legendData);
195
+ this.particlePlugin.setColorField(colorFieldData);
196
+ }
197
+ }
198
+ setFlipY(flipY) {
199
+ isBoolean(flipY);
200
+ this.windMetadata.flipY = flipY;
201
+ if (this.particlePlugin && this.windData) {
202
+ this.setWind(this.windData);
203
+ }
204
+ }
205
+ setDrawTextureMaxPixelOnDimension(value) {
206
+ if (this.particlePlugin) {
207
+ this.particlePlugin.setDrawTextureMaxPixelOnDimension(value);
208
+ }
209
+ }
210
+ // ===== Property Setters =====
211
+ set height(value) {
212
+ this._height = value;
213
+ if (this.particlePlugin) {
214
+ this.particlePlugin.setHeight(value);
215
+ }
216
+ }
217
+ get height() {
218
+ return this._height;
219
+ }
220
+ set minSpeed(value) {
221
+ this.options.minSpeed = value;
222
+ if (this.particlePlugin) {
223
+ this.particlePlugin.setMinSpeedThreshold(value);
224
+ }
225
+ }
226
+ get minSpeed() {
227
+ return this.options.minSpeed;
228
+ }
229
+ set maxSpeed(value) {
230
+ this.options.maxSpeed = value;
231
+ if (this.particlePlugin) {
232
+ this.particlePlugin.setMaxSpeedThreshold(value);
233
+ }
234
+ }
235
+ get maxSpeed() {
236
+ return this.options.maxSpeed;
237
+ }
238
+ set fadeOpacity(value) {
239
+ this.options.fadeOpacity = value;
240
+ if (this.particlePlugin) {
241
+ this.particlePlugin.setFadeOpacity(value);
242
+ }
243
+ }
244
+ get fadeOpacity() {
245
+ return this.options.fadeOpacity;
246
+ }
247
+ set speedFactor(value) {
248
+ this._speedFactor = value;
249
+ if (this.particlePlugin) {
250
+ this.particlePlugin.setParticleSpeed(value);
251
+ }
252
+ }
253
+ get speedFactor() {
254
+ return this._speedFactor;
255
+ }
256
+ set dropRate(value) {
257
+ this._dropRate = value;
258
+ if (this.particlePlugin) {
259
+ this.particlePlugin.setDropRate(value);
260
+ }
261
+ }
262
+ get dropRate() {
263
+ return this._dropRate;
264
+ }
265
+ set dropRateBump(value) {
266
+ this.options.dropRateBump = value;
267
+ // Note: ParticlePlugin doesn't have dropRateBump parameter
268
+ // This would need to be added to ParticlePlugin if needed
269
+ }
270
+ get dropRateBump() {
271
+ return this.options.dropRateBump;
272
+ }
273
+ set baseOpacity(value) {
274
+ this.options.baseOpacity = value;
275
+ if (this.particlePlugin) {
276
+ this.particlePlugin.setOpacity(value);
277
+ }
278
+ }
279
+ get baseOpacity() {
280
+ return this.options.baseOpacity;
281
+ }
282
+ set numParticles(value) {
283
+ this.options.numParticles = value;
284
+ if (this.particlePlugin) {
285
+ this.particlePlugin.setParticleCount(value);
286
+ }
287
+ }
288
+ get numParticles() {
289
+ return this.options.numParticles;
290
+ }
291
+ /**
292
+ * Set wing and tail size for particle arrows
293
+ */
294
+ setParticleDimensions(tail, wing) {
295
+ this.options.tailSize = tail;
296
+ this.options.wingSize = wing;
297
+ if (this.particlePlugin) {
298
+ this.particlePlugin.setParticleDimensions(tail, wing);
299
+ }
300
+ }
301
+ /**
302
+ * Set particle color (used when not using color field)
303
+ */
304
+ setParticleColor(color) {
305
+ if (this.particlePlugin) {
306
+ this.particlePlugin.setParticleColor(color);
307
+ }
308
+ }
309
+ /**
310
+ * Set bounding box
311
+ */
312
+ setBBox(bbox) {
313
+ // rescale
314
+ if (this.particlePlugin) {
315
+ this.particlePlugin.setBBox({
316
+ minLon: bbox.minLon,
317
+ minLat: bbox.minLat < -85 ? -85 : bbox.minLat,
318
+ maxLon: bbox.maxLon,
319
+ maxLat: bbox.maxLat > 85 ? 85 : bbox.maxLat
320
+ });
321
+ }
322
+ // Update metadata
323
+ this.windMetadata.bbox = [bbox.minLon, bbox.minLat, bbox.maxLon, bbox.maxLat];
324
+ }
325
+ // ===== Texture Point Sampler (for backward compatibility) =====
326
+ /**
327
+ * Get texture point sampler for magnitude or angle
328
+ * @param type - 'magnitude' or 'angle'
329
+ */
330
+ getTexturePointSampler(type = 'magnitude') {
331
+ if (type === 'magnitude') {
332
+ if (!this.texturePointSampler) {
333
+ this._createTexturePointSampler();
334
+ this._setCoorcinatesDataCalculatorData();
335
+ }
336
+ return this.texturePointSampler;
337
+ }
338
+ else if (type === 'angle') {
339
+ if (!this.texturePointSamplerAngle) {
340
+ this._createTexturePointSamplerAngle();
341
+ this._setCoorcinatesDataCalculatorData();
342
+ }
343
+ return this.texturePointSamplerAngle;
344
+ }
345
+ else {
346
+ throw new Error(`WindPlugin.getTexturePointSampler: type must be either 'magnitude' or 'angle'.`);
347
+ }
348
+ }
349
+ _createTexturePointSamplerAngle() {
350
+ const { bbox, width, height } = this.windMetadata;
351
+ this.texturePointSamplerAngle = new TexturePointSampler(bbox, width, height);
352
+ }
353
+ _createTexturePointSampler() {
354
+ const { bbox, width, height } = this.windMetadata;
355
+ this.texturePointSampler = new TexturePointSampler(bbox, width, height);
356
+ }
357
+ _setCoorcinatesDataCalculatorData() {
358
+ if (!this.windData) {
359
+ return;
360
+ }
361
+ const windDataWithDimensions = {
362
+ ...this.windData,
363
+ width: this.windData.image.width,
364
+ height: this.windData.image.height
365
+ };
366
+ if (this.texturePointSamplerAngle) {
367
+ const angle = imageToRadianAngle(windDataWithDimensions);
368
+ this.texturePointSamplerAngle.updateTextureData(0, angle, angle);
369
+ }
370
+ if (this.texturePointSampler) {
371
+ const magnitude = imageToMagnitude(windDataWithDimensions);
372
+ this.texturePointSampler.updateTextureData(0, magnitude, magnitude);
373
+ }
374
+ }
375
+ }
@@ -2,7 +2,7 @@
2
2
  * Author: Toprak Nihat Deniz Ozturk
3
3
  */
4
4
  import { createImageFromBase64, createProgramWrapper, createTexture, createBuffer, bindAttribute, bindFramebuffer, bindTexture, getColorRamp } from "../../util/webglobjectbuilders";
5
- import { defaultblendfunction } from "../../util/webglobe/gldefaultstates";
5
+ import { defaultblendfunction } from "../../util/globe-default-gl-states";
6
6
  import imageToMagnitude, { imageToRadianAngle } from "./imagetovectorfieldandmagnitude";
7
7
  import { TexturePointSampler } from "../../heatwave/texture-point-sampler";
8
8
  /**
@@ -1,37 +0,0 @@
1
- function geoJSONToEarcut(geojson) {
2
- const vertices = [];
3
- const holes = [];
4
- const dimensions = 2; // Assuming 2D coordinates (longitude, latitude)
5
- let holeIndex = 0;
6
- if (geojson.type !== 'FeatureCollection') {
7
- throw new Error('Invalid GeoJSON: Expected FeatureCollection');
8
- }
9
- const features = geojson.features;
10
- function processPolygon(coordinates) {
11
- for (let i = 0; i < coordinates.length; i++) {
12
- if (i > 0) {
13
- holeIndex += coordinates[i - 1].length;
14
- holes.push(holeIndex);
15
- }
16
- for (const coord of coordinates[i]) {
17
- vertices.push(coord[0], coord[1]);
18
- }
19
- }
20
- }
21
- function processMultiPolygon(coordinates) {
22
- for (const polygon of coordinates) {
23
- processPolygon(polygon);
24
- }
25
- }
26
- for (const feature of features) {
27
- const geometry = feature.geometry;
28
- if (geometry.type === 'Polygon') {
29
- processPolygon(geometry.coordinates);
30
- }
31
- else if (geometry.type === 'MultiPolygon') {
32
- processMultiPolygon(geometry.coordinates);
33
- }
34
- }
35
- return { vertices, holes, dimensions };
36
- }
37
- export { geoJSONToEarcut };
@@ -1,123 +0,0 @@
1
- /**
2
- * @author Toprak Ozturk
3
- */
4
- import { equals, fromLongLatToUnitVector, fromUnitVectorToLongLat } from "../vec3";
5
- import { pointsOnArc } from "../juction/arc-plane";
6
- import { junctionVerticalOrHorizontalLines } from "../finite-line-2d";
7
- // TODO:get rid of embedded lists. always flat list
8
- const TILE_DEM_VERTEX_COUNT = 5; // 5x5 grid for DEM
9
- const TILE_DEM_STEPCOUNT = TILE_DEM_VERTEX_COUNT - 1; // 4 inner divisions in each dimension
10
- var EdgeType;
11
- (function (EdgeType) {
12
- EdgeType[EdgeType["ARC"] = 0] = "ARC";
13
- EdgeType[EdgeType["LINEAR"] = 1] = "LINEAR";
14
- })(EdgeType || (EdgeType = {}));
15
- const _tempVec2 = /*@__PURE__*/ [0, 0];
16
- const _plane = /*@__PURE__*/ { normal: [0, 0, 0], distance: 0 };
17
- const _resultPoints = /*@__PURE__*/ [[0, 0, 0], [0, 0, 0]];
18
- /**
19
- *
20
- * @param triangleMeta
21
- * @param zoom
22
- * @param angle
23
- * @param dimension false for longitude (meridian) true for latitude (parallel)
24
- */
25
- function getPoints(triangleMeta, angle, dimension) {
26
- // console.log("getPoints called with angle:", angle * 180 / Math.PI, "dimension:", dimension ? 'latitude' : 'longitude');
27
- // find which arcs are cut by plane
28
- const radians = angle;
29
- if (dimension) {
30
- _plane.normal[0] = 0;
31
- _plane.normal[1] = 0;
32
- _plane.normal[2] = 1;
33
- _plane.distance = Math.sin(radians);
34
- }
35
- else {
36
- _plane.normal[0] = Math.sin(radians);
37
- _plane.normal[1] = -Math.cos(radians);
38
- _plane.normal[2] = 0;
39
- _plane.distance = 0;
40
- }
41
- let result = [];
42
- // Add debugging
43
- let resultsFromDistinctEdges = 0;
44
- for (let i = 0; i < 3; i++) {
45
- const edgeType = triangleMeta.edgeTypes[i];
46
- const edge = triangleMeta.edges[i];
47
- const coordIndex = dimension ? 1 : 0;
48
- const minCoord = edge.bbox.min[coordIndex];
49
- const maxCoord = edge.bbox.max[coordIndex];
50
- if (minCoord > angle || maxCoord < angle) {
51
- continue; // edge is out of range
52
- }
53
- let count = 0;
54
- if (edgeType === EdgeType.ARC) {
55
- count = pointsOnArc(edge, _plane, _resultPoints);
56
- if (count === 1) {
57
- fromUnitVectorToLongLat(_tempVec2, _resultPoints[0]);
58
- result.push([[..._resultPoints[0]], [..._tempVec2]]);
59
- }
60
- else if (count === 2) {
61
- // throw new Error('Unexpected 2 cut points on arc, should be max 1'); // TODO DELETE this line later
62
- fromUnitVectorToLongLat(_tempVec2, _resultPoints[0]);
63
- result.push([[..._resultPoints[0]], [..._tempVec2]]);
64
- fromUnitVectorToLongLat(_tempVec2, _resultPoints[1]);
65
- result.push([[..._resultPoints[1]], [..._tempVec2]]); // TODO: this is a fix for a bug, need to investigate later
66
- }
67
- }
68
- else {
69
- // linear line
70
- count = junctionVerticalOrHorizontalLines(_tempVec2, edge.line, angle, dimension);
71
- if (count === 1) {
72
- fromLongLatToUnitVector(_resultPoints[0], _tempVec2);
73
- result.push([[..._resultPoints[0]], [..._tempVec2]]);
74
- }
75
- }
76
- resultsFromDistinctEdges += 1;
77
- }
78
- if (resultsFromDistinctEdges === 3) {
79
- result = filterDuplicate(result);
80
- }
81
- if (result.length !== 2 && result.length !== 4) {
82
- // TODO: THERE is a case where 4 points are found.
83
- // this happens when two arcs has limit and share space in Z dimension
84
- console.log("ERROR");
85
- const text = 'Angle:' + angle + ' dimension:' + (dimension ? 'latitude' : 'longitude') + "\n" +
86
- 'Result points count:' + result.length + "\n" +
87
- "bbox:" + triangleMeta.bbox.min[0] * 180 / Math.PI + ", " + triangleMeta.bbox.min[1] * 180 / Math.PI + ", " + triangleMeta.bbox.max[0] * 180 / Math.PI + ", " + triangleMeta.bbox.max[1] * 180 / Math.PI + "\n";
88
- for (let res of result) {
89
- const ll = res[1];
90
- console.log("Point: " + ll[0] * 180 / Math.PI + ", " + ll[1] * 180 / Math.PI + "\n");
91
- }
92
- throw new Error(`Unexpected cut count for tile cut, got: ${result.length}, angle: ${angle * 180 / Math.PI}, dimension: ${dimension ? 'latitude' : 'longitude'} \n` + text);
93
- }
94
- // TODO: i want to see it delete later
95
- if (result.length === 4) {
96
- console.warn("Warning: 4 cut points found on triangle for angle:", angle * 180 / Math.PI, "dimension:", dimension ? 'latitude' : 'longitude', "points:", result);
97
- }
98
- result.sort((a, b) => {
99
- if (dimension) {
100
- return a[1][0] - b[1][0]; // sort by y for longitude cuts
101
- }
102
- else {
103
- return a[1][1] - b[1][1]; // sort by x for latitude cuts
104
- }
105
- });
106
- return result;
107
- }
108
- function filterDuplicate(points) {
109
- const result = [points[0]];
110
- let dublicate = false;
111
- for (let i = 1; i < points.length; i++) {
112
- for (let j = 0; j < result.length; j++) {
113
- if (equals(points[i][0], result[j][0])) {
114
- dublicate = true;
115
- break;
116
- }
117
- }
118
- if (!dublicate) {
119
- result.push(points[i]);
120
- }
121
- }
122
- return result;
123
- }
@@ -1,18 +0,0 @@
1
- import earcut from "earcut";
2
- import { createTriangleTessellationMeta } from "./triangle-tessellation-meta";
3
- function shredInput(vertices, holes, zoomLevel) {
4
- const result = [];
5
- const triangles = earcut(vertices, holes, 2);
6
- for (let i = 0; i < triangles.length; i += 3) {
7
- const idx1 = triangles[i] * 2;
8
- const idx2 = triangles[i + 1] * 2;
9
- const idx3 = triangles[i + 2] * 2;
10
- const p1 = [vertices[idx1], vertices[idx1 + 1]];
11
- const p2 = [vertices[idx2], vertices[idx2 + 1]];
12
- const p3 = [vertices[idx3], vertices[idx3 + 1]];
13
- const triangleMeta = createTriangleTessellationMeta(p1, p2, p3);
14
- result.push(triangleMeta);
15
- }
16
- // cut triangles into smaller pieces based on zoom level...
17
- return result;
18
- }
@@ -1,50 +0,0 @@
1
- "use strict";
2
- // /**
3
- // * Find length in x and y for a tile in given zoom level (in wgs84)
4
- // * Find tile cuts for given line represented by two points
5
- // * Find inner position of point in tile
6
- // *
7
- // */
8
- // import { LongLat } from "../../types";
9
- // export function tileLength(zoom: number): LongLat {
10
- // const tileSize = 256; // in pixels
11
- // const worldSize = tileSize * Math.pow(2, zoom);
12
- // const latLength = 180 / worldSize;
13
- // const lonLength = 360 / worldSize;
14
- // return [lonLength, latLength];
15
- // }
16
- // // export function tileCuts(p1: LongLat, p2: LongLat, zoom: number): LongLat[] {
17
- // // const cuts: LongLat[] = [];
18
- // // const tileSize = 256;
19
- // // const worldSize = tileSize * Math.pow(2, zoom);
20
- // // const latLength = 180 / worldSize;
21
- // // const lonLength = 360 / worldSize;
22
- // // const x1 = (p1[0] + 180) / lonLength;
23
- // // const y1 = (90 - p1[1]) / latLength;
24
- // // const x2 = (p2[0] + 180) / lonLength;
25
- // // const y2 = (90 - p2[1]) / latLength;
26
- // // const dx = x2 - x1;
27
- // // const dy = y2 - y1;
28
- // // const steps = Math.max(Math.abs(dx), Math.abs(dy));
29
- // // const xStep = dx / steps;
30
- // // const yStep = dy / steps;
31
- // // let x = x1;
32
- // // let y = y1;
33
- // // for (let i = 0; i <= steps; i++) {
34
- // // const tileX = Math.floor(x);
35
- // // const tileY = Math.floor(y);
36
- // // const cutX = tileX * lonLength - 180;
37
- // // const cutY = 90 - tileY * latLength;
38
- // // const cut: LongLat = [cutX, cutY];
39
- // // if (cuts.length === 0 || (cuts[cuts.length - 1][0] !== cut[0] || cuts[cuts.length - 1][1] !== cut[1])) {
40
- // // cuts.push(cut);
41
- // // }
42
- // // x += xStep;
43
- // // y += yStep;
44
- // // }
45
- // // return cuts;
46
- // // }
47
- // // function fillTriangle(p1: LongLat, p2: LongLat, p3: LongLat, zoom: number): {positions:LongLat[], indices:number[]} {
48
- // // // this function fills the triangle triangle iteratively
49
- // // //
50
- // // }