@pirireis/webglobeplugins 0.16.7 → 0.17.0

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 (152) hide show
  1. package/Math/angle-calculation.js +1 -0
  2. package/Math/contour/quadtreecontours.js +300 -0
  3. package/Math/finite-line-2d.js +58 -0
  4. package/Math/tessellation/hybrid-triangle-tessellation-meta.js +123 -0
  5. package/Math/tessellation/tile-merger.js +56 -0
  6. package/Math/tessellation/triangle-tessellation-meta.js +178 -32
  7. package/Math/tessellation/triangle-tessellation.js +5 -1
  8. package/compass-rose/compass-text-writer.js +39 -33
  9. package/constants.js +3 -0
  10. package/{util/heatwavedatamanager → heatwave}/datamanager.js +1 -1
  11. package/heatwave/{plugins/heatwaveglobeshell.js → heatwave.js} +8 -6
  12. package/heatwave/index.js +5 -3
  13. package/heatwave/{isobar/plugin.js → isobar.js} +6 -5
  14. package/{util/heatwavedatamanager → heatwave}/texture-point-sampler.js +24 -3
  15. package/package.json +4 -2
  16. package/programs/arrowfield/{object.js → arrow-field.js} +1 -1
  17. package/programs/arrowfield/logic.js +1 -1
  18. package/programs/data2legend/density-to-legend.js +24 -29
  19. package/programs/data2legend/point-to-density-texture.js +14 -17
  20. package/programs/float2legendwithratio/logic.js +2 -2
  21. package/programs/float2legendwithratio/object.js +1 -1
  22. package/programs/helpers/{blender/program.js → blender.js} +1 -1
  23. package/programs/helpers/{fadeaway/logic.js → fadeaway.js} +11 -2
  24. package/programs/index.js +20 -9
  25. package/programs/line-on-globe/circle-accurate-3d.js +12 -14
  26. package/programs/line-on-globe/circle-accurate-flat.js +0 -1
  27. package/programs/line-on-globe/degree-padding-around-circle-3d.js +13 -15
  28. package/programs/line-on-globe/lines-color-instanced-flat.js +15 -18
  29. package/programs/line-on-globe/naive-accurate-flexible.js +0 -1
  30. package/programs/picking/pickable-polygon-renderer.js +1 -1
  31. package/programs/picking/pickable-renderer.js +2 -2
  32. package/programs/point-on-globe/element-globe-surface-glow.js +2 -2
  33. package/programs/point-on-globe/element-point-glow.js +1 -1
  34. package/programs/point-on-globe/square-pixel-point.js +1 -1
  35. package/programs/polygon-on-globe/texture-dem-triangle-test-plugin-triangle.js +32 -6
  36. package/programs/polygon-on-globe/texture-dem-triangles.js +32 -5
  37. package/programs/rings/partial-ring/piece-of-pie.js +26 -29
  38. package/programs/totems/camerauniformblock.js +31 -42
  39. package/programs/two-d/pixel-padding-for-compass.js +14 -24
  40. package/programs/vectorfields/logics/drawrectangleparticles.js +1 -2
  41. package/programs/vectorfields/logics/pixelbased.js +1 -2
  42. package/programs/vectorfields/pingpongbuffermanager.js +1 -1
  43. package/range-tools-on-terrain/bearing-line/adapters.js +1 -1
  44. package/range-tools-on-terrain/circle-line-chain/adapters.js +0 -5
  45. package/range-tools-on-terrain/circle-line-chain/plugin.js +1 -1
  46. package/range-tools-on-terrain/range-ring/plugin.js +4 -6
  47. package/semiplugins/lightweight/line-plugin.js +0 -1
  48. package/semiplugins/shape-on-terrain/arc-plugin.js +0 -2
  49. package/semiplugins/shape-on-terrain/circle-plugin.js +2 -2
  50. package/semiplugins/shape-on-terrain/padding-1-degree.js +1 -1
  51. package/semiplugins/shell/bbox-renderer/index.js +2 -0
  52. package/{programs/globeshell/wiggle → semiplugins/shell/bbox-renderer}/logic.js +101 -102
  53. package/{programs/globeshell/wiggle → semiplugins/shell/bbox-renderer}/object.js +6 -7
  54. package/semiplugins/utility/container-plugin.js +94 -0
  55. package/semiplugins/utility/object-pass-container-plugin.js +80 -0
  56. package/{point-heat-map → tracks/point-heat-map}/adaptors/timetracksplugin-format-to-this.js +1 -1
  57. package/{point-heat-map → tracks/point-heat-map}/plugin-webworker.js +3 -3
  58. package/{point-heat-map → tracks/point-heat-map}/point-to-heat-map-flow.js +11 -14
  59. package/{point-tracks → tracks/point-tracks}/plugin.js +5 -5
  60. package/{timetracks → tracks/timetracks}/adaptors-line-strip.js +1 -1
  61. package/{timetracks → tracks/timetracks}/program-line-strip.js +49 -49
  62. package/{timetracks → tracks/timetracks}/programpoint-line-strip.js +16 -13
  63. package/types.js +6 -0
  64. package/util/account/bufferoffsetmanager.js +1 -1
  65. package/util/account/single-attribute-buffer-management/buffer-orchestrator.js +9 -95
  66. package/util/gl-util/uniform-block/manager.js +0 -1
  67. package/util/gl-util/uniform-block/types.js +0 -7
  68. package/util/index.js +10 -13
  69. package/util/picking/fence.js +16 -18
  70. package/util/picking/picker-displayer.js +4 -6
  71. package/util/programs/{shapesonglobe.js → draw-from-pixel-coords.js} +4 -7
  72. package/util/programs/draw-texture-on-canvas.js +1 -1
  73. package/util/programs/texturetoglobe.js +3 -3
  74. package/util/webglobe/rasteroverlay.js +1 -0
  75. package/vectorfield/arrowfield/index.js +3 -0
  76. package/{arrowfield → vectorfield/arrowfield}/plugin.js +2 -2
  77. package/{waveparticles → vectorfield/waveparticles}/plugin.js +12 -12
  78. package/{wind → vectorfield/wind}/index.js +1 -1
  79. package/{wind → vectorfield/wind}/plugin.js +32 -32
  80. package/write-text/attached-text-writer.js +9 -1
  81. package/write-text/context-text3.js +0 -1
  82. package/write-text/objectarraylabels/index.js +2 -0
  83. package/Math/tessellation/tessellation-algorithm.js +0 -67
  84. package/arrowfield/index.js +0 -3
  85. package/bearing-line/index.js +0 -2
  86. package/bearing-line/plugin.js +0 -444
  87. package/circle-line-chain/chain-list-map.js +0 -201
  88. package/circle-line-chain/plugin.js +0 -411
  89. package/circle-line-chain/util.js +0 -1
  90. package/compassrose/compassrose.js +0 -293
  91. package/compassrose/index.js +0 -2
  92. package/index.js +0 -12
  93. package/partialrings/buffer-manager.js +0 -75
  94. package/partialrings/index.js +0 -2
  95. package/partialrings/plugin.js +0 -128
  96. package/partialrings/program.js +0 -279
  97. package/programs/arrowfield/index.js +0 -2
  98. package/programs/globe-util/is-globe-moved.js +0 -19
  99. package/programs/globeshell/index.js +0 -2
  100. package/programs/globeshell/wiggle/index.js +0 -2
  101. package/programs/helpers/blender/index.js +0 -1
  102. package/programs/helpers/fadeaway/index.js +0 -2
  103. package/programs/helpers/fadeaway/object.js +0 -14
  104. package/programs/helpers/index.js +0 -2
  105. package/programs/rings/distancering/circleflatprogram.js +0 -116
  106. package/programs/rings/distancering/circlepaddingfreeangleprogram.js +0 -326
  107. package/programs/rings/distancering/circlepaddysharedbuffer.js +0 -368
  108. package/programs/rings/distancering/index.js +0 -6
  109. package/programs/rings/distancering/paddyflatprogram.js +0 -127
  110. package/programs/rings/distancering/paddyflatprogram2d.js +0 -129
  111. package/programs/rings/distancering/paddyflatprogram3d.js +0 -128
  112. package/programs/two-d/pixel-circle.js +0 -1
  113. package/programs/vectorfields/index.js +0 -3
  114. package/rangerings/enum.js +0 -2
  115. package/rangerings/index.js +0 -5
  116. package/rangerings/plugin.js +0 -543
  117. package/rangerings/rangeringangletext.js +0 -326
  118. package/rangerings/ring-account.js +0 -112
  119. package/timetracks/index.js +0 -1
  120. package/util/build-strategy/general-strategy.js +0 -62
  121. package/util/gl-util/uniform-block/shader.js +0 -1
  122. package/util/heatwavedatamanager/index.js +0 -2
  123. package/util/heatwavedatamanager/pointcoordsmeta.js +0 -22
  124. package/util/jshelpers/data-filler.js +0 -17
  125. package/util/jshelpers/equality.js +0 -18
  126. package/util/jshelpers/index.js +0 -2
  127. package/util/jshelpers/timefilters.js +0 -30
  128. package/util/programs/index.js +0 -1
  129. package/util/surface-line-data/arc-bboxes.js +0 -25
  130. package/util/surface-line-data/arcs-to-cuts.js +0 -50
  131. package/util/surface-line-data/cut-arc.js +0 -1
  132. package/util/surface-line-data/flow.js +0 -28
  133. package/util/surface-line-data/rbush-manager.js +0 -1
  134. package/util/surface-line-data/types.js +0 -1
  135. package/util/surface-line-data/web-worker.js +0 -1
  136. package/write-text/context-text3old.js +0 -152
  137. package/write-text/index.js +0 -1
  138. package/write-text/writer-plugin.js +0 -8
  139. /package/{heatwave/isobar/quadtreecontours.js → Math/contour/quadtreecontours1.js} +0 -0
  140. /package/pin/{pin-object-array.js → pin-object-array1.js} +0 -0
  141. /package/pin/{pin-point-totem.js → pin-point-totem1.js} +0 -0
  142. /package/{circle-line-chain/init.js → programs/polygon-on-globe/partial-tesselation.js} +0 -0
  143. /package/{point-heat-map → tracks/point-heat-map}/index.js +0 -0
  144. /package/{point-tracks → tracks/point-tracks}/key-methods.js +0 -0
  145. /package/{timetracks → tracks/timetracks}/plugin-line-strip.js +0 -0
  146. /package/{arrowfield → vectorfield/arrowfield}/adaptor.js +0 -0
  147. /package/{waveparticles → vectorfield/waveparticles}/adaptor.js +0 -0
  148. /package/{waveparticles → vectorfield/waveparticles}/index.js +0 -0
  149. /package/{wind → vectorfield/wind}/imagetovectorfieldandmagnitude.js +0 -0
  150. /package/{wind → vectorfield/wind}/vectorfieldimage.js +0 -0
  151. /package/write-text/{context-text.js → context-textDELETE.js} +0 -0
  152. /package/{heatwave/isobar → write-text/objectarraylabels}/objectarraylabels.js +0 -0
@@ -118,7 +118,7 @@ function showMeta(triangleMeta) {
118
118
  * @param angle
119
119
  * @param dimension false for longitude (meridian) true for latitude (parallel)
120
120
  */
121
- function getPoints(triangleMeta, angle, dimension) {
121
+ export function getPoints(triangleMeta, angle, dimension) {
122
122
  // console.log("getPoints called with angle:", angle * 180 / Math.PI, "dimension:", dimension ? 'latitude' : 'longitude');
123
123
  // find which arcs are cut by plane
124
124
  const radians = angle;
@@ -147,12 +147,12 @@ function getPoints(triangleMeta, angle, dimension) {
147
147
  }
148
148
  const count = pointsOnArc(arc, _plane, _resultPoints);
149
149
  if (count === 1) {
150
- result.push([..._resultPoints[0]]);
150
+ result.push([[..._resultPoints[0]], vec3ToLongLatRadians(_resultPoints[0])]);
151
151
  }
152
152
  else if (count === 2) {
153
153
  // throw new Error('Unexpected 2 cut points on arc, should be max 1'); // TODO DELETE this line later
154
- result.push([..._resultPoints[0]]);
155
- result.push([..._resultPoints[1]]); // TODO: this is a fix for a bug, need to investigate later
154
+ result.push([[..._resultPoints[0]], vec3ToLongLatRadians(_resultPoints[0])]);
155
+ result.push([[..._resultPoints[1]], vec3ToLongLatRadians(_resultPoints[1])]); // TODO: this is a fix for a bug, need to investigate later
156
156
  }
157
157
  resultsFromDistinctArcs += 1;
158
158
  }
@@ -168,7 +168,7 @@ function getPoints(triangleMeta, angle, dimension) {
168
168
  "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";
169
169
  showMeta(triangleMeta);
170
170
  for (let res of result) {
171
- const ll = vec3ToLongLatRadians(res);
171
+ const ll = res[1];
172
172
  console.log("Point: " + ll[0] * 180 / Math.PI + ", " + ll[1] * 180 / Math.PI + "\n");
173
173
  }
174
174
  throw new Error(`Unexpected cut count for tile cut, got: ${result.length}, angle: ${angle * 180 / Math.PI}, dimension: ${dimension ? 'latitude' : 'longitude'} \n` + text);
@@ -179,10 +179,10 @@ function getPoints(triangleMeta, angle, dimension) {
179
179
  }
180
180
  result.sort((a, b) => {
181
181
  if (dimension) {
182
- return a[1] - b[1]; // sort by y for longitude cuts
182
+ return a[0][1] - b[0][1]; // sort by y for longitude cuts
183
183
  }
184
184
  else {
185
- return a[0] - b[0]; // sort by x for latitude cuts
185
+ return a[1][0] - b[1][0]; // sort by x for latitude cuts
186
186
  }
187
187
  });
188
188
  return result;
@@ -239,15 +239,13 @@ export function getAllPoints(triangleMeta, zoom, innerCuts = TILE_DEM_STEPCOUNT)
239
239
  for (let i = 0; i < concurances.length; i += 2) {
240
240
  const p0 = concurances[i];
241
241
  const p1 = concurances[i + 1];
242
- points.push(...p0);
243
- points.push(...p1);
244
- const p0LongLat = vec3ToLongLatRadians(p0);
245
- const p1LongLat = vec3ToLongLatRadians(p1);
246
- longLatPoints.push(...p0LongLat);
247
- longLatPoints.push(...p1LongLat);
248
- fillBetweenInParallels(lat, p0LongLat, p1LongLat, lonLengthRadian, points, longLatPoints);
249
- if (length(p0) < 0.99 || length(p1) < 0.99 || length(p0) > 1.01 || length(p1) > 1.01) {
250
- console.warn("Warning: Cut point is not on unit sphere!", length(p0), length(p1));
242
+ points.push(...p0[0]);
243
+ longLatPoints.push(...p0[1]);
244
+ fillBetweenInParallels(lat, p0[1], p1[1], lonLengthRadian, points, longLatPoints);
245
+ points.push(...p1[0]);
246
+ longLatPoints.push(...p1[1]);
247
+ if (length(p0[0]) < 0.99 || length(p1[0]) < 0.99 || length(p0[0]) > 1.01 || length(p1[0]) > 1.01) {
248
+ console.warn("Warning: Cut point is not on unit sphere!", length(p0[0]), length(p1[0]));
251
249
  }
252
250
  }
253
251
  currentY -= latInnerStep;
@@ -258,15 +256,13 @@ export function getAllPoints(triangleMeta, zoom, innerCuts = TILE_DEM_STEPCOUNT)
258
256
  currentLong += lonLengthRadian; // since start point is already added
259
257
  while (currentLong < endMeridianRadian) {
260
258
  const [p0, p1] = getPoints(triangleMeta, currentLong, false);
261
- const p0LongLat = vec3ToLongLatRadians(p0);
262
- const p1LongLat = vec3ToLongLatRadians(p1);
263
- if (!isOnTileEdge(p0LongLat, zoom)) {
264
- points.push(...p0);
265
- longLatPoints.push(...p0LongLat);
259
+ if (!isOnTileEdge(p0[1], zoom)) {
260
+ points.push(...p0[0]);
261
+ longLatPoints.push(...p0[1]);
266
262
  }
267
- if (!isOnTileEdge(p1LongLat, zoom)) {
268
- points.push(...p1);
269
- longLatPoints.push(...p1LongLat);
263
+ if (!isOnTileEdge(p1[1], zoom)) {
264
+ points.push(...p1[0]);
265
+ longLatPoints.push(...p1[1]);
270
266
  }
271
267
  currentLong += lonLengthRadian;
272
268
  }
@@ -274,7 +270,7 @@ export function getAllPoints(triangleMeta, zoom, innerCuts = TILE_DEM_STEPCOUNT)
274
270
  let indices = delaunator.triangles;
275
271
  const edgeIndexes = shellPoints.map((e, index) => index * 2); // edge points are always first points in list
276
272
  indices = filteroutEdgeConnections(indices, edgeIndexes);
277
- rotateIndices(indices);
273
+ // rotateIndices(indices);
278
274
  return { vec3s: new Float32Array(points), longLats: new Float32Array(longLatPoints), indices: indices };
279
275
  }
280
276
  function fillBetweenInParallels(lat, p1, p2, step, fillVec3Arr, longLatPoints) {
@@ -292,18 +288,18 @@ function fillBetweenInParallels(lat, p1, p2, step, fillVec3Arr, longLatPoints) {
292
288
  current += step;
293
289
  }
294
290
  }
295
- function filterDuplicate(vec3s) {
296
- const result = [];
291
+ function filterDuplicate(points) {
292
+ const result = [points[0]];
297
293
  let dublicate = false;
298
- for (let i = 0; i < vec3s.length; i++) {
294
+ for (let i = 1; i < points.length; i++) {
299
295
  for (let j = 0; j < result.length; j++) {
300
- if (equals(vec3s[i], result[j])) {
296
+ if (equals(points[i][0], result[j][0])) {
301
297
  dublicate = true;
302
298
  break;
303
299
  }
304
300
  }
305
301
  if (!dublicate) {
306
- result.push(vec3s[i]);
302
+ result.push(points[i]);
307
303
  }
308
304
  }
309
305
  return result;
@@ -366,5 +362,155 @@ function shredTriangleTessellationMeta(triangleMeta, zoomLevel) {
366
362
  *
367
363
  * still all triangles should have some sort of cached tessellation to fast render on rapit earth rotation
368
364
  */
369
- // function partialTessellation(triangleMeta: TriangleTessellationMeta, limits: BBox[], zoomLevel: number, innerCuts: number): { vec3s: Float32Array, longLats: Float32Array, indices: Uint32Array } {
370
- // }
365
+ /**
366
+ * Creates a mesh for a spherical triangle, tessellated only within the
367
+ * regions specified by the `limits` array.
368
+ *
369
+ * @param triangleMeta The metadata for the spherical triangle.
370
+ * @param limits An array of bounding boxes and their associated zoom levels to tessellate.
371
+ * @param innerCuts The number of subdivisions within each tile (e.g., TILE_DEM_STEPCOUNT).
372
+ * @returns A set of arrays (vec3s, longLats, indices) representing the partial mesh.
373
+ */
374
+ export function partialTessellation(triangleMeta, limits, innerCuts) {
375
+ // TODO: pointMap can be local variable and cleaned after function call to avoid reinitialization overhead
376
+ const pointMap = new Map(); // Key: "lon|lat", Value: index
377
+ const allVec3s = [];
378
+ const allLongLats = [];
379
+ let pointCounter = 0;
380
+ /**
381
+ * Precision for coordinate keys in the map. 1e-12 radians is
382
+ * extremely small (sub-millimeter on Earth's surface) and avoids
383
+ * floating point inaccuracies causing duplicate points.
384
+ */
385
+ const KEY_PRECISION = 10;
386
+ /**
387
+ * Adds a point to the vertex arrays if it doesn't already exist.
388
+ * Returns the index of the point (new or existing).
389
+ */
390
+ const addPoint = (longLat, vec3) => {
391
+ const key = `${longLat[0].toPrecision(KEY_PRECISION)}|${longLat[1].toPrecision(KEY_PRECISION)}`;
392
+ let index = pointMap.get(key);
393
+ if (index !== undefined) {
394
+ return index; // Point already exists
395
+ }
396
+ // Point is new, add it
397
+ const v3 = vec3 || createUnitVectorFromLongLat(longLat);
398
+ allVec3s.push(...v3);
399
+ allLongLats.push(...longLat);
400
+ index = pointCounter++;
401
+ pointMap.set(key, index);
402
+ return index;
403
+ };
404
+ // 1. Add triangle's "shell" (for Delaunay) and "edge" (vertices/limits) points
405
+ // These points constrain the triangulation.
406
+ const shellPointIndices = [];
407
+ const edgePoints = getEdgePoints(triangleMeta);
408
+ // Assuming shellPoints and edgePoints have the same length and correspond
409
+ const shellPointCount = Math.min(triangleMeta.shellPoints.length, edgePoints.length);
410
+ for (let i = 0; i < shellPointCount; i++) {
411
+ // Add the "shell" point (for Delaunay stability)
412
+ shellPointIndices.push(addPoint(triangleMeta.shellPoints[i]));
413
+ // Add the actual "edge" point (triangle vertex or limit point)
414
+ addPoint(vec3ToLongLatRadians(edgePoints[i]), edgePoints[i]);
415
+ }
416
+ // 2. Iterate through each tile limit
417
+ for (const { bbox: tileBBox, zoom } of limits) {
418
+ // 2a. Calculate the intersection BBOX (the area we'll work on)
419
+ const workBBox = {
420
+ min: [
421
+ Math.max(triangleMeta.bbox.min[0], tileBBox.min[0]),
422
+ Math.max(triangleMeta.bbox.min[1], tileBBox.min[1])
423
+ ],
424
+ max: [
425
+ Math.min(triangleMeta.bbox.max[0], tileBBox.max[0]),
426
+ Math.min(triangleMeta.bbox.max[1], tileBBox.max[1])
427
+ ],
428
+ };
429
+ // If the intersection is invalid (no overlap), skip this tile
430
+ if (workBBox.min[0] >= workBBox.max[0] || workBBox.min[1] >= workBBox.max[1]) {
431
+ continue;
432
+ }
433
+ // 2b. Calculate grid steps for this tile's zoom
434
+ const tileCount = TILE_COUNTS[zoom];
435
+ const lonStep = (2 * Math.PI) / tileCount / innerCuts;
436
+ const latStep = 1.0 / innerCuts; // This is in tileY units
437
+ // 2c. Generate Latitude (Parallel) Points
438
+ const startTileY = latToTileY(workBBox.max[1], zoom); // max lat -> min tileY
439
+ const endTileY = latToTileY(workBBox.min[1], zoom); // min lat -> max tileY
440
+ let currentY = Math.ceil(startTileY / latStep) * latStep;
441
+ if (currentY < startTileY - 1e-9)
442
+ currentY += latStep; // Ensure we start inside or on edge
443
+ while (currentY <= endTileY + 1e-9) {
444
+ const lat = tileYtoLat(currentY, zoom);
445
+ // Skip if rounding put us slightly outside the work box
446
+ if (lat < workBBox.min[1] - 1e-9 || lat > workBBox.max[1] + 1e-9) {
447
+ currentY += latStep;
448
+ continue;
449
+ }
450
+ // Find where this latitude line intersects the triangle
451
+ const intersections = getPoints(triangleMeta, lat, true);
452
+ for (let i = 0; i < intersections.length; i += 2) {
453
+ const p0 = intersections[i]; // [Vec3, LongLatRadian]
454
+ const p1 = intersections[i + 1];
455
+ // Find the segment of this latitude line that is *inside* both
456
+ // the triangle (p0-p1) AND the tile BBOX (workBBox)
457
+ const triMinLon = Math.min(p0[1][0], p1[1][0]);
458
+ const triMaxLon = Math.max(p0[1][0], p1[1][0]);
459
+ const segMinLon = Math.max(workBBox.min[0], triMinLon);
460
+ const segMaxLon = Math.min(workBBox.max[0], triMaxLon);
461
+ // If this clipped segment is valid, generate points
462
+ if (segMinLon < segMaxLon - 1e-9) {
463
+ // Add the exact start and end points of the clipped segment
464
+ addPoint([segMinLon, lat]);
465
+ addPoint([segMaxLon, lat]);
466
+ // Add fill points *between* them
467
+ let currentLon = Math.ceil(segMinLon / lonStep) * lonStep;
468
+ if (currentLon < segMinLon - 1e-9)
469
+ currentLon += lonStep;
470
+ while (currentLon < segMaxLon - 1e-9) {
471
+ addPoint([currentLon, lat]);
472
+ currentLon += lonStep;
473
+ }
474
+ }
475
+ }
476
+ currentY += latStep;
477
+ }
478
+ // 2d. Generate Longitude (Meridian) Points
479
+ const startLon = workBBox.min[0];
480
+ const endLon = workBBox.max[0];
481
+ let currentLon = Math.ceil(startLon / lonStep) * lonStep;
482
+ if (currentLon < startLon - 1e-9)
483
+ currentLon += lonStep;
484
+ while (currentLon <= endLon + 1e-9) {
485
+ // Find where this longitude line intersects the triangle
486
+ const intersections = getPoints(triangleMeta, currentLon, false);
487
+ for (const p of intersections) {
488
+ const pLongLat = p[1];
489
+ // Check if this point is inside the *workBBox*
490
+ if (pLongLat[1] >= workBBox.min[1] - 1e-9 &&
491
+ pLongLat[1] <= workBBox.max[1] + 1e-9) {
492
+ addPoint(pLongLat, p[0]);
493
+ }
494
+ }
495
+ currentLon += lonStep;
496
+ }
497
+ } // End loop over limits
498
+ // 3. Triangulate
499
+ // We must have at least 3 points to make a triangle
500
+ if (pointCounter < 3) {
501
+ return {
502
+ vec3s: new Float32Array(),
503
+ longLats: new Float32Array(),
504
+ indices: new Uint32Array(),
505
+ };
506
+ }
507
+ const delaunator = new Delaunator(allLongLats);
508
+ let indices = delaunator.triangles;
509
+ // 4. Filter out triangles connected to the "shell" points
510
+ indices = filteroutEdgeConnections(indices, shellPointIndices);
511
+ return {
512
+ vec3s: new Float32Array(allVec3s),
513
+ longLats: new Float32Array(allLongLats),
514
+ indices: indices,
515
+ };
516
+ }
@@ -2,9 +2,13 @@
2
2
  * @author Toprak Ozturk
3
3
  *
4
4
  */
5
- import { createTriangleTessellationMeta, getAllPoints } from "./triangle-tessellation-meta";
5
+ import { createTriangleTessellationMeta, getAllPoints, partialTessellation } from "./triangle-tessellation-meta";
6
6
  export function test1(zoomLevel, p1, p2, p3) {
7
7
  const triangleMeta = createTriangleTessellationMeta(p1, p2, p3);
8
8
  const { vec3s, longLats, indices } = getAllPoints(triangleMeta, zoomLevel);
9
9
  return { vec3s, longLats, indices };
10
10
  }
11
+ export function partialTest(bboxZooms, p1, p2, p3) {
12
+ const triangleMeta = createTriangleTessellationMeta(p1, p2, p3);
13
+ return partialTessellation(triangleMeta, bboxZooms, 5);
14
+ }
@@ -1,17 +1,5 @@
1
- import { CSZMode, CSMeasureTextPositionTypes } from "@pirireis/webglobe";
2
- // const defaultStyle = {
3
- // textFont: {
4
- // name: 'Arial',
5
- // textColor: '#FFFFFF', // beyaz
6
- // hollowColor: '#000000', // siyah
7
- // size: 12, // piksel
8
- // hollow: true,
9
- // bold: true,
10
- // italic: false,
11
- // },
12
- // opacity: 1.0,
13
- // zMode: CSZMode.Z_GROUND_PERVERTEX,
14
- // }
1
+ // filepath: d:\webglobeplugins\webglobePlugin\src\webglobeplugins\compass-rose\compass-text-writer.ts
2
+ import { CSMeasureTextPositionTypes } from "@pirireis/webglobe";
15
3
  /**
16
4
  * TODOs:
17
5
  * 1) update all if initials change (propably need a context and a callback to iterate over data)
@@ -21,19 +9,32 @@ import { CSZMode, CSMeasureTextPositionTypes } from "@pirireis/webglobe";
21
9
  const yGapFit = -2;
22
10
  const xGapFit = -5;
23
11
  export class PixelPaddingCompassTextWriter {
12
+ globe;
13
+ itemMap;
14
+ font;
15
+ northFont;
16
+ doDraw;
17
+ angle;
18
+ angles;
19
+ texts;
20
+ positions;
21
+ _lastNorthAngle;
22
+ offsets;
23
+ keyAdaptor;
24
+ opacity;
24
25
  constructor(globe, { font = {
25
26
  name: 'Arial',
26
- textColor: '#FFFFFF', // beyaz
27
- hollowColor: '#000000', // siyah
28
- size: 12, // piksel
27
+ textColor: '#FFFFFF',
28
+ hollowColor: '#000000',
29
+ size: 12,
29
30
  hollow: true,
30
31
  bold: true,
31
32
  italic: false,
32
33
  }, northFont = {
33
34
  name: 'Arial',
34
- textColor: '#BB0000', // beyaz
35
- hollowColor: '#000000', // siyah
36
- size: 14, // piksel
35
+ textColor: '#BB0000',
36
+ hollowColor: '#000000',
37
+ size: 14,
37
38
  hollow: true,
38
39
  bold: true,
39
40
  italic: false,
@@ -56,17 +57,16 @@ export class PixelPaddingCompassTextWriter {
56
57
  this.positions.push(null);
57
58
  }
58
59
  this.angles.push(currentAngle);
59
- if (currentAngle == 0) {
60
+ if (currentAngle === 0) {
60
61
  this.texts.push("K");
61
62
  }
62
63
  else {
63
- // to string 3 chars fill left with 0
64
64
  this.texts.push(currentAngle.toString().padStart(3, '0'));
65
65
  }
66
66
  currentAngle += this.angle;
67
67
  }
68
68
  this._lastNorthAngle = globe.api_GetCurrentLookInfo()["NorthAng"] * (Math.PI / 180);
69
- this.offsets = this.__offset(this._lastNorthAngle);
69
+ this.offsets = this.__offset();
70
70
  }
71
71
  setKeyAdaptor(adaptor) {
72
72
  this.keyAdaptor = adaptor;
@@ -86,7 +86,6 @@ export class PixelPaddingCompassTextWriter {
86
86
  _checkSetOffsets() {
87
87
  const { globe } = this;
88
88
  const newAngle = globe.api_GetCurrentLookInfo()["NorthAng"] * (Math.PI / 180);
89
- ;
90
89
  if (newAngle !== this._lastNorthAngle) {
91
90
  this._lastNorthAngle = newAngle;
92
91
  this.offsets = this.__offset();
@@ -96,42 +95,49 @@ export class PixelPaddingCompassTextWriter {
96
95
  if (!this.doDraw)
97
96
  return;
98
97
  const { globe, font, opacity: opacity_, northFont, itemMap, texts, angles, positions } = this;
99
- this._checkSetOffsets(); // zMode: CSZMode.Z_GROUND_PERVERTEX,
98
+ this._checkSetOffsets();
100
99
  const offsets = this.offsets;
101
100
  for (const [key, { center, radius, opacity = null }] of itemMap) {
102
- const o = opacity === null ? opacity_ : opacity * opacity_;
103
- if (center.x !== null && center.y !== null) {
101
+ const o = opacity === null ? (opacity_ ?? 1.0) : opacity * (opacity_ ?? 1.0);
102
+ if (center && radius !== undefined) {
103
+ const { x, y } = center;
104
+ if (x === null || y === null)
105
+ continue;
104
106
  offsets.forEach(({ offsetX, offsetY }, i) => {
105
107
  const text = texts[i];
106
108
  const angle = angles[i];
107
109
  font.position = positions[i];
108
110
  if (angle === 0) {
109
- globe.api_DrawContextTextMultiLine(text, northFont, o, { x: center.x + offsetX * radius + xGapFit, y: center.y + offsetY * radius + yGapFit });
111
+ globe.api_DrawContextTextMultiLine(text, northFont, o, { x: x + offsetX * radius + xGapFit, y: y + offsetY * radius + yGapFit });
110
112
  }
111
113
  else {
112
- globe.api_DrawContextTextMultiLine(text, font, o, { x: center.x + offsetX * radius + xGapFit, y: center.y + offsetY * radius + yGapFit });
114
+ globe.api_DrawContextTextMultiLine(text, font, o, { x: x + offsetX * radius + xGapFit, y: y + offsetY * radius + yGapFit });
113
115
  }
114
116
  });
115
117
  }
116
118
  }
117
119
  }
118
- insertTextItem(key, x, y, radius = undefined) {
120
+ insertTextItem(key, x, y, radius) {
119
121
  const item = this.getItem(key);
120
122
  item.center = { x, y };
121
123
  if (radius === undefined)
122
124
  return;
123
- if (item.radius != undefined && item.radius === radius)
125
+ if (item.radius !== undefined && item.radius === radius)
124
126
  return;
125
127
  item.radius = radius;
126
128
  }
127
129
  getItem(key) {
128
- if (!this.itemMap.has(key))
130
+ if (!this.itemMap.has(key)) {
129
131
  this.itemMap.set(key, {});
132
+ }
130
133
  return this.itemMap.get(key);
131
134
  }
132
135
  __calculateOffset(angle) {
133
136
  const rAngle = (angle - 90) * (Math.PI / 180);
134
- return { offsetX: Math.cos(rAngle + this._lastNorthAngle), offsetY: Math.sin(rAngle + this._lastNorthAngle) };
137
+ return {
138
+ offsetX: Math.cos(rAngle + this._lastNorthAngle),
139
+ offsetY: Math.sin(rAngle + this._lastNorthAngle)
140
+ };
135
141
  }
136
142
  __offset() {
137
143
  const angle = this.angle;
package/constants.js CHANGED
@@ -1,3 +1,6 @@
1
+ export const CSRenderPassPluginKeys = ["supportNormalPass",
2
+ "supportSelectedPass",
3
+ "supportEditingPass"];
1
4
  export const GLOBE_DEFAULT_MIN_LOD = 2;
2
5
  export const GLOBE_DEFAULT_MAX_LOD = 25;
3
6
  export const POLE2 = 12756274.0;
@@ -2,7 +2,7 @@
2
2
  * todo:
3
3
  * data must be processed before being set to the cache
4
4
  */
5
- export default class DataManager {
5
+ export class DataManager {
6
6
  /**
7
7
  *
8
8
  * @param {Array<number>} timeEpocs | array of time epocs
@@ -1,7 +1,9 @@
1
- import { getColorRampModed, DataManager, } from "../../util/index";
2
- import { TexturePointSampler } from "../../util/heatwavedatamanager/texture-point-sampler";
3
- import { GlobeShellWiggle, Float2LegendWithRatio } from "../../programs";
4
- import { opacityCheck } from "../../util/check/typecheck";
1
+ import { getColorRampModed } from "../util/webglobjectbuilders";
2
+ import { DataManager } from "./datamanager";
3
+ import { TexturePointSampler } from "./texture-point-sampler";
4
+ import { BBOXGlobeShell } from "../semiplugins/shell/bbox-renderer";
5
+ import { Float2LegendWithRatio } from "../programs/float2legendwithratio";
6
+ import { opacityCheck } from "../util/check/typecheck";
5
7
  /**
6
8
  * @param id : string
7
9
  * @param dataManager : DataManager
@@ -9,7 +11,7 @@ import { opacityCheck } from "../../util/check/typecheck";
9
11
  * @param dataWidthHeight : {width: number, height: number}
10
12
  * @param options : {bbox: number[], minMaxEdges: {min: number, max: number}, escapeValue: number, resolution: number[], meshPartition: number[]}
11
13
  */
12
- export default class HeatWaveGlobeShellPlugin {
14
+ export class HeatWavePlugin {
13
15
  constructor(id, dataManager, colorRampData, dataWidthHeight, { bbox = [-180, -90, 180, 90], minMaxEdges = { min: -99999, max: 99999 }, escapeValue = 99999, resolution = [2056, 2056], yFlip = true, } = {}) {
14
16
  this.id = id;
15
17
  this.dataManager = dataManager;
@@ -152,7 +154,7 @@ export default class HeatWaveGlobeShellPlugin {
152
154
  this.setEscapeValue(this._escapeValue);
153
155
  }
154
156
  _init(globe, gl) {
155
- this.globeShell = new GlobeShellWiggle(gl, globe, {
157
+ this.globeShell = new BBOXGlobeShell(gl, globe, {
156
158
  minLon: this._bbox[0],
157
159
  minLat: this._bbox[1],
158
160
  maxLon: this._bbox[2],
package/heatwave/index.js CHANGED
@@ -1,3 +1,5 @@
1
- import HeatWavePlugin from './plugins/heatwaveglobeshell';
2
- import { IsobarRasterToVector } from './isobar/plugin';
3
- export { HeatWavePlugin, IsobarRasterToVector };
1
+ import { DataManager } from "./datamanager.js";
2
+ import { HeatWavePlugin } from "./heatwave.js";
3
+ import { IsobarRasterToVector } from "./isobar.js";
4
+ import { TexturePointSampler } from "./texture-point-sampler";
5
+ export { DataManager, HeatWavePlugin, IsobarRasterToVector, TexturePointSampler };
@@ -1,7 +1,8 @@
1
- import { ShapesOnGlobeProgram, latLongToPixelXY } from "../../util";
2
- import ContourMipmap, { scaleParameters } from "./quadtreecontours";
3
- import ObjectArrayLabels from "./objectarraylabels";
4
- import { isBoolean, opacityCheck } from "../../util/check/typecheck";
1
+ import { DrawFromPixelCoords, } from "../util/programs/draw-from-pixel-coords";
2
+ import { latLongToPixelXY } from "../util/geometry/index";
3
+ import ContourMipmap, { scaleParameters } from "../Math/contour/quadtreecontours";
4
+ import ObjectArrayLabels from "../write-text/objectarraylabels";
5
+ import { isBoolean, opacityCheck } from "../util/check/typecheck";
5
6
  export class IsobarRasterToVector {
6
7
  /**
7
8
  * @typedef {Object} IsobarData
@@ -151,7 +152,7 @@ export class IsobarRasterToVector {
151
152
  init(globe, gl) {
152
153
  this.gl = gl;
153
154
  this.globe = globe;
154
- this.program = new ShapesOnGlobeProgram(gl, globe, 'line_strip');
155
+ this.program = new DrawFromPixelCoords(gl, globe, 'line_strip');
155
156
  if (this._isLabelsOn) {
156
157
  this._createLabelsLayer();
157
158
  this._labelsLayer.addToMap();
@@ -1,4 +1,25 @@
1
- import PointCoordsMeta from "./pointcoordsmeta";
1
+ class PointCoordsMeta {
2
+ _bbox;
3
+ _width;
4
+ _height;
5
+ _xRatio;
6
+ _yRatio;
7
+ constructor(bbox, width, height) {
8
+ this._bbox = bbox;
9
+ this._width = width;
10
+ this._height = height;
11
+ this._xRatio = this._width / (this._bbox[2] - this._bbox[0]);
12
+ this._yRatio = this._height / (this._bbox[3] - this._bbox[1]);
13
+ }
14
+ getFlooredIndex(long, lat) {
15
+ let x = (long - this._bbox[0]) * this._xRatio;
16
+ let y = (this._bbox[3] - lat) * this._yRatio;
17
+ x = x > 0 ? x - 1 : 0;
18
+ y = y > 0 ? y - 1 : 0;
19
+ const index = Math.floor(y) * this._width + Math.floor(x);
20
+ return index;
21
+ }
22
+ }
2
23
  const pointObject = (long, lat, posIndex, callback) => {
3
24
  return { long, lat, posIndex, callback };
4
25
  };
@@ -103,7 +124,7 @@ export class TexturePointSampler {
103
124
  }
104
125
  flush(callEmptyCallback = false) {
105
126
  if (callEmptyCallback) {
106
- for (const [key, { callback }] of this._pointObjects.entries()) {
127
+ for (const [, { callback }] of this._pointObjects.entries()) {
107
128
  callback(null, null, null);
108
129
  }
109
130
  }
@@ -141,7 +162,7 @@ export class TexturePointSampler {
141
162
  }
142
163
  }
143
164
  else {
144
- for (const [key, { callback }] of this._pointObjects.entries()) {
165
+ for (const [, { callback }] of this._pointObjects.entries()) {
145
166
  callback(null, null, null);
146
167
  }
147
168
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pirireis/webglobeplugins",
3
- "version": "0.16.7",
3
+ "version": "0.17.0",
4
4
  "main": "index.js",
5
5
  "author": "Toprak Nihat Deniz Ozturk",
6
6
  "license": "MIT",
@@ -8,9 +8,11 @@
8
8
  "build": "tsc"
9
9
  },
10
10
  "dependencies": {
11
- "@pirireis/webglobe": "^6.2.22",
12
11
  "delaunator": "^5.0.1",
13
12
  "earcut": "^3.0.2",
14
13
  "rbush": "^4.0.1"
14
+ },
15
+ "peerDependencies": {
16
+ "@pirireis/webglobe": "^6.2.22"
15
17
  }
16
18
  }
@@ -4,7 +4,7 @@
4
4
  import Logic from './logic';
5
5
  import { globeProgramCache } from '../programcache';
6
6
  import { longlatbbox2normalbbox } from "../util";
7
- export default class ArrowField {
7
+ export class ArrowField {
8
8
  constructor(gl, globe, { minLon = -180, maxLon = 180, minLat = -90, maxLat = 90, height = 0, opacity = 1, color = [0.04, 0.2, 0.8], targetWidth = 100, targetHeight = 100, dataWidth = null, dataHeight = null, tailLengthRatio = 1, wingLengthRatio = 0.5, noDataValue = null,
9
9
  // maxMagnitude = null
10
10
  } = {}) {
@@ -1,4 +1,4 @@
1
- import { createProgram } from "../../util";
1
+ import { createProgram } from "../../util/webglobjectbuilders";
2
2
  import { globeProgramCache } from "../programcache";
3
3
  import { CameraUniformBlockTotem } from "../totems";
4
4
  const arrowVertexShader = `#version 300 es