@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.
- package/Math/angle-calculation.js +1 -0
- package/Math/contour/quadtreecontours.js +300 -0
- package/Math/finite-line-2d.js +58 -0
- package/Math/tessellation/hybrid-triangle-tessellation-meta.js +123 -0
- package/Math/tessellation/tile-merger.js +56 -0
- package/Math/tessellation/triangle-tessellation-meta.js +178 -32
- package/Math/tessellation/triangle-tessellation.js +5 -1
- package/compass-rose/compass-text-writer.js +39 -33
- package/constants.js +3 -0
- package/{util/heatwavedatamanager → heatwave}/datamanager.js +1 -1
- package/heatwave/{plugins/heatwaveglobeshell.js → heatwave.js} +8 -6
- package/heatwave/index.js +5 -3
- package/heatwave/{isobar/plugin.js → isobar.js} +6 -5
- package/{util/heatwavedatamanager → heatwave}/texture-point-sampler.js +24 -3
- package/package.json +4 -2
- package/programs/arrowfield/{object.js → arrow-field.js} +1 -1
- package/programs/arrowfield/logic.js +1 -1
- package/programs/data2legend/density-to-legend.js +24 -29
- package/programs/data2legend/point-to-density-texture.js +14 -17
- package/programs/float2legendwithratio/logic.js +2 -2
- package/programs/float2legendwithratio/object.js +1 -1
- package/programs/helpers/{blender/program.js → blender.js} +1 -1
- package/programs/helpers/{fadeaway/logic.js → fadeaway.js} +11 -2
- package/programs/index.js +20 -9
- package/programs/line-on-globe/circle-accurate-3d.js +12 -14
- package/programs/line-on-globe/circle-accurate-flat.js +0 -1
- package/programs/line-on-globe/degree-padding-around-circle-3d.js +13 -15
- package/programs/line-on-globe/lines-color-instanced-flat.js +15 -18
- package/programs/line-on-globe/naive-accurate-flexible.js +0 -1
- package/programs/picking/pickable-polygon-renderer.js +1 -1
- package/programs/picking/pickable-renderer.js +2 -2
- package/programs/point-on-globe/element-globe-surface-glow.js +2 -2
- package/programs/point-on-globe/element-point-glow.js +1 -1
- package/programs/point-on-globe/square-pixel-point.js +1 -1
- package/programs/polygon-on-globe/texture-dem-triangle-test-plugin-triangle.js +32 -6
- package/programs/polygon-on-globe/texture-dem-triangles.js +32 -5
- package/programs/rings/partial-ring/piece-of-pie.js +26 -29
- package/programs/totems/camerauniformblock.js +31 -42
- package/programs/two-d/pixel-padding-for-compass.js +14 -24
- package/programs/vectorfields/logics/drawrectangleparticles.js +1 -2
- package/programs/vectorfields/logics/pixelbased.js +1 -2
- package/programs/vectorfields/pingpongbuffermanager.js +1 -1
- package/range-tools-on-terrain/bearing-line/adapters.js +1 -1
- package/range-tools-on-terrain/circle-line-chain/adapters.js +0 -5
- package/range-tools-on-terrain/circle-line-chain/plugin.js +1 -1
- package/range-tools-on-terrain/range-ring/plugin.js +4 -6
- package/semiplugins/lightweight/line-plugin.js +0 -1
- package/semiplugins/shape-on-terrain/arc-plugin.js +0 -2
- package/semiplugins/shape-on-terrain/circle-plugin.js +2 -2
- package/semiplugins/shape-on-terrain/padding-1-degree.js +1 -1
- package/semiplugins/shell/bbox-renderer/index.js +2 -0
- package/{programs/globeshell/wiggle → semiplugins/shell/bbox-renderer}/logic.js +101 -102
- package/{programs/globeshell/wiggle → semiplugins/shell/bbox-renderer}/object.js +6 -7
- package/semiplugins/utility/container-plugin.js +94 -0
- package/semiplugins/utility/object-pass-container-plugin.js +80 -0
- package/{point-heat-map → tracks/point-heat-map}/adaptors/timetracksplugin-format-to-this.js +1 -1
- package/{point-heat-map → tracks/point-heat-map}/plugin-webworker.js +3 -3
- package/{point-heat-map → tracks/point-heat-map}/point-to-heat-map-flow.js +11 -14
- package/{point-tracks → tracks/point-tracks}/plugin.js +5 -5
- package/{timetracks → tracks/timetracks}/adaptors-line-strip.js +1 -1
- package/{timetracks → tracks/timetracks}/program-line-strip.js +49 -49
- package/{timetracks → tracks/timetracks}/programpoint-line-strip.js +16 -13
- package/types.js +6 -0
- package/util/account/bufferoffsetmanager.js +1 -1
- package/util/account/single-attribute-buffer-management/buffer-orchestrator.js +9 -95
- package/util/gl-util/uniform-block/manager.js +0 -1
- package/util/gl-util/uniform-block/types.js +0 -7
- package/util/index.js +10 -13
- package/util/picking/fence.js +16 -18
- package/util/picking/picker-displayer.js +4 -6
- package/util/programs/{shapesonglobe.js → draw-from-pixel-coords.js} +4 -7
- package/util/programs/draw-texture-on-canvas.js +1 -1
- package/util/programs/texturetoglobe.js +3 -3
- package/util/webglobe/rasteroverlay.js +1 -0
- package/vectorfield/arrowfield/index.js +3 -0
- package/{arrowfield → vectorfield/arrowfield}/plugin.js +2 -2
- package/{waveparticles → vectorfield/waveparticles}/plugin.js +12 -12
- package/{wind → vectorfield/wind}/index.js +1 -1
- package/{wind → vectorfield/wind}/plugin.js +32 -32
- package/write-text/attached-text-writer.js +9 -1
- package/write-text/context-text3.js +0 -1
- package/write-text/objectarraylabels/index.js +2 -0
- package/Math/tessellation/tessellation-algorithm.js +0 -67
- package/arrowfield/index.js +0 -3
- package/bearing-line/index.js +0 -2
- package/bearing-line/plugin.js +0 -444
- package/circle-line-chain/chain-list-map.js +0 -201
- package/circle-line-chain/plugin.js +0 -411
- package/circle-line-chain/util.js +0 -1
- package/compassrose/compassrose.js +0 -293
- package/compassrose/index.js +0 -2
- package/index.js +0 -12
- package/partialrings/buffer-manager.js +0 -75
- package/partialrings/index.js +0 -2
- package/partialrings/plugin.js +0 -128
- package/partialrings/program.js +0 -279
- package/programs/arrowfield/index.js +0 -2
- package/programs/globe-util/is-globe-moved.js +0 -19
- package/programs/globeshell/index.js +0 -2
- package/programs/globeshell/wiggle/index.js +0 -2
- package/programs/helpers/blender/index.js +0 -1
- package/programs/helpers/fadeaway/index.js +0 -2
- package/programs/helpers/fadeaway/object.js +0 -14
- package/programs/helpers/index.js +0 -2
- package/programs/rings/distancering/circleflatprogram.js +0 -116
- package/programs/rings/distancering/circlepaddingfreeangleprogram.js +0 -326
- package/programs/rings/distancering/circlepaddysharedbuffer.js +0 -368
- package/programs/rings/distancering/index.js +0 -6
- package/programs/rings/distancering/paddyflatprogram.js +0 -127
- package/programs/rings/distancering/paddyflatprogram2d.js +0 -129
- package/programs/rings/distancering/paddyflatprogram3d.js +0 -128
- package/programs/two-d/pixel-circle.js +0 -1
- package/programs/vectorfields/index.js +0 -3
- package/rangerings/enum.js +0 -2
- package/rangerings/index.js +0 -5
- package/rangerings/plugin.js +0 -543
- package/rangerings/rangeringangletext.js +0 -326
- package/rangerings/ring-account.js +0 -112
- package/timetracks/index.js +0 -1
- package/util/build-strategy/general-strategy.js +0 -62
- package/util/gl-util/uniform-block/shader.js +0 -1
- package/util/heatwavedatamanager/index.js +0 -2
- package/util/heatwavedatamanager/pointcoordsmeta.js +0 -22
- package/util/jshelpers/data-filler.js +0 -17
- package/util/jshelpers/equality.js +0 -18
- package/util/jshelpers/index.js +0 -2
- package/util/jshelpers/timefilters.js +0 -30
- package/util/programs/index.js +0 -1
- package/util/surface-line-data/arc-bboxes.js +0 -25
- package/util/surface-line-data/arcs-to-cuts.js +0 -50
- package/util/surface-line-data/cut-arc.js +0 -1
- package/util/surface-line-data/flow.js +0 -28
- package/util/surface-line-data/rbush-manager.js +0 -1
- package/util/surface-line-data/types.js +0 -1
- package/util/surface-line-data/web-worker.js +0 -1
- package/write-text/context-text3old.js +0 -152
- package/write-text/index.js +0 -1
- package/write-text/writer-plugin.js +0 -8
- /package/{heatwave/isobar/quadtreecontours.js → Math/contour/quadtreecontours1.js} +0 -0
- /package/pin/{pin-object-array.js → pin-object-array1.js} +0 -0
- /package/pin/{pin-point-totem.js → pin-point-totem1.js} +0 -0
- /package/{circle-line-chain/init.js → programs/polygon-on-globe/partial-tesselation.js} +0 -0
- /package/{point-heat-map → tracks/point-heat-map}/index.js +0 -0
- /package/{point-tracks → tracks/point-tracks}/key-methods.js +0 -0
- /package/{timetracks → tracks/timetracks}/plugin-line-strip.js +0 -0
- /package/{arrowfield → vectorfield/arrowfield}/adaptor.js +0 -0
- /package/{waveparticles → vectorfield/waveparticles}/adaptor.js +0 -0
- /package/{waveparticles → vectorfield/waveparticles}/index.js +0 -0
- /package/{wind → vectorfield/wind}/imagetovectorfieldandmagnitude.js +0 -0
- /package/{wind → vectorfield/wind}/vectorfieldimage.js +0 -0
- /package/write-text/{context-text.js → context-textDELETE.js} +0 -0
- /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 =
|
|
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
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
longLatPoints.push(...
|
|
247
|
-
|
|
248
|
-
|
|
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
|
-
|
|
262
|
-
|
|
263
|
-
|
|
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(
|
|
268
|
-
points.push(...p1);
|
|
269
|
-
longLatPoints.push(...
|
|
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(
|
|
296
|
-
const result = [];
|
|
291
|
+
function filterDuplicate(points) {
|
|
292
|
+
const result = [points[0]];
|
|
297
293
|
let dublicate = false;
|
|
298
|
-
for (let i =
|
|
294
|
+
for (let i = 1; i < points.length; i++) {
|
|
299
295
|
for (let j = 0; j < result.length; j++) {
|
|
300
|
-
if (equals(
|
|
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(
|
|
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
|
-
|
|
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
|
-
|
|
2
|
-
|
|
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',
|
|
27
|
-
hollowColor: '#000000',
|
|
28
|
-
size: 12,
|
|
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',
|
|
35
|
-
hollowColor: '#000000',
|
|
36
|
-
size: 14,
|
|
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
|
|
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(
|
|
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();
|
|
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
|
|
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:
|
|
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:
|
|
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
|
|
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
|
|
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 {
|
|
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,7 +1,9 @@
|
|
|
1
|
-
import { getColorRampModed
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
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
|
|
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
|
|
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
|
|
2
|
-
import {
|
|
3
|
-
|
|
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 {
|
|
2
|
-
import
|
|
3
|
-
import
|
|
4
|
-
import
|
|
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
|
|
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
|
-
|
|
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 [
|
|
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 [
|
|
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.
|
|
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
|
|
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
|
} = {}) {
|