@pirireis/webglobeplugins 0.17.1 → 1.0.2
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 → angle-calculation.ts} +18 -14
- package/Math/{arc-cdf-points.js → arc-cdf-points.ts} +329 -272
- package/Math/{arc-generate-points-exponantial.js → arc-generate-points-exponantial.ts} +299 -254
- package/Math/{arc.js → arc.ts} +421 -292
- package/Math/bounds/line-bbox.js +225 -186
- package/Math/{circle-cdf-points.js → circle-cdf-points.ts} +143 -78
- package/Math/{circle.js → circle.ts} +49 -33
- package/Math/{constants.js → constants.ts} +12 -4
- package/Math/contour/{quadtreecontours.js → quadtreecontours.ts} +371 -300
- package/Math/contour/quadtreecontours1.js +336 -298
- package/Math/{finite-line-2d.js → finite-line-2d.ts} +68 -58
- package/Math/haversine.ts +33 -0
- package/Math/index.js +0 -1
- package/Math/juction/{arc-plane.js → arc-plane.ts} +203 -143
- package/Math/juction/{line-sphere.js → line-sphere.ts} +32 -22
- package/Math/juction/{plane-plane.js → plane-plane.ts} +62 -53
- package/Math/{line.js → line.ts} +84 -52
- package/Math/matrix4.ts +0 -0
- package/Math/mesh/mapbox-delaunay.d.ts +74 -0
- package/Math/{methods.js → methods.ts} +182 -113
- package/Math/{plane.js → plane.ts} +92 -56
- package/Math/{quaternion.js → quaternion.ts} +128 -106
- package/Math/roadmap.md +10 -0
- package/Math/templete-shapes/{grid-visually-equal.js → grid-visually-equal.ts} +118 -65
- package/Math/tessellation/constants.ts +1 -0
- package/Math/tessellation/methods.ts +79 -0
- package/Math/tessellation/nearest-value-padding.ts +147 -0
- package/Math/tessellation/roadmap.md +48 -0
- package/Math/tessellation/spherical-triangle-area.ts +127 -0
- package/Math/tessellation/tile-merger.ts +578 -0
- package/Math/tessellation/triangle-tessellation.ts +533 -0
- package/Math/tessellation/types.ts +1 -0
- package/Math/types.ts +68 -0
- package/Math/utils.js +3 -2
- package/Math/{vec3.js → vec3.ts} +227 -151
- package/Math/xyz-tile.ts +26 -0
- package/algorithms/search-binary.js +14 -16
- package/altitude-locator/adaptors.js +0 -1
- package/altitude-locator/keymethod.js +0 -1
- package/altitude-locator/plugin.js +445 -345
- package/altitude-locator/types.js +26 -21
- package/compass-rose/compass-rose-padding-flat.js +274 -230
- package/compass-rose/{compass-text-writer.js → compass-text-writer.ts} +210 -155
- package/compass-rose/index.js +3 -3
- package/{constants.js → constants.ts} +8 -6
- package/heatwave/datamanager.js +168 -149
- package/heatwave/heatwave.js +261 -206
- package/heatwave/index.js +5 -5
- package/heatwave/isobar.js +340 -303
- package/heatwave/{texture-point-sampler.js → texture-point-sampler.ts} +220 -187
- package/investigation-tools/draw/tiles/adapters.ts +133 -0
- package/investigation-tools/draw/tiles/{tiles.js → tiles.ts} +162 -128
- package/jest.config.js +6 -7
- package/package.json +1 -1
- package/pin/pin-object-array1.js +381 -300
- package/pin/pin-point-totem1.js +77 -60
- package/programs/arrowfield/arrow-field.js +89 -60
- package/programs/arrowfield/logic.js +173 -141
- package/programs/data2legend/density-to-legend.js +86 -68
- package/programs/data2legend/point-to-density-texture.js +84 -67
- package/programs/float2legendwithratio/index.js +3 -2
- package/programs/float2legendwithratio/logic.js +144 -118
- package/programs/float2legendwithratio/object.js +141 -104
- package/programs/helpers/blender.js +73 -58
- package/programs/helpers/{fadeaway.js → fadeaway.ts} +73 -55
- package/programs/index.js +19 -20
- package/programs/line-on-globe/circle-accurate-3d.js +112 -85
- package/programs/line-on-globe/circle-accurate-flat.js +200 -148
- package/programs/line-on-globe/degree-padding-around-circle-3d.js +134 -102
- package/programs/line-on-globe/index.js +0 -1
- package/programs/line-on-globe/lines-color-instanced-flat.js +99 -80
- package/programs/line-on-globe/linestrip/data.ts +29 -0
- package/programs/line-on-globe/linestrip/{linestrip.js → linestrip.ts} +152 -93
- package/programs/line-on-globe/{naive-accurate-flexible.js → naive-accurate-flexible.ts} +175 -126
- package/programs/line-on-globe/util.js +8 -5
- package/programs/picking/pickable-polygon-renderer.js +129 -98
- package/programs/picking/pickable-renderer.js +130 -98
- package/programs/point-on-globe/element-globe-surface-glow.js +122 -93
- package/programs/point-on-globe/element-point-glow.js +114 -80
- package/programs/point-on-globe/square-pixel-point.js +139 -120
- package/programs/polygon-on-globe/roadmap.md +8 -0
- package/programs/polygon-on-globe/texture-dem-triangles.ts +290 -0
- package/programs/{programcache.js → programcache.ts} +134 -126
- package/programs/rings/index.js +1 -1
- package/programs/rings/partial-ring/{piece-of-pie.js → piece-of-pie.ts} +222 -152
- package/programs/totems/camera-totem-attactment-interface.ts +4 -0
- package/programs/totems/{camerauniformblock.js → camerauniformblock.ts} +326 -230
- package/programs/totems/{canvas-webglobe-info.js → canvas-webglobe-info.ts} +147 -132
- package/programs/totems/dem-textures-manager.ts +368 -0
- package/programs/totems/{globe-changes.js → globe-changes.ts} +79 -59
- package/programs/totems/gpu-selection-uniform-block.js +127 -99
- package/programs/totems/{index.js → index.ts} +2 -2
- package/programs/two-d/pixel-padding-for-compass.js +101 -87
- package/programs/util.js +19 -14
- package/programs/vectorfields/logics/{constants.js → constants.ts} +5 -4
- package/programs/vectorfields/logics/drawrectangleparticles.ts +182 -0
- package/programs/vectorfields/logics/index.js +4 -2
- package/programs/vectorfields/logics/particle-ubo.ts +23 -0
- package/programs/vectorfields/logics/{pixelbased.js → pixelbased.ts} +119 -84
- package/programs/vectorfields/logics/ubo.js +57 -51
- package/programs/vectorfields/{pingpongbuffermanager.js → pingpongbuffermanager.ts} +113 -73
- package/publish.bat +62 -0
- package/range-tools-on-terrain/bearing-line/{adapters.js → adapters.ts} +154 -114
- package/range-tools-on-terrain/bearing-line/{plugin.js → plugin.ts} +569 -457
- package/range-tools-on-terrain/bearing-line/types.ts +65 -0
- package/range-tools-on-terrain/circle-line-chain/{adapters.js → adapters.ts} +104 -85
- package/range-tools-on-terrain/circle-line-chain/{chain-list-map.js → chain-list-map.ts} +446 -382
- package/range-tools-on-terrain/circle-line-chain/{plugin.js → plugin.ts} +607 -464
- package/range-tools-on-terrain/circle-line-chain/types.ts +43 -0
- package/range-tools-on-terrain/range-ring/{adapters.js → adapters.ts} +114 -93
- package/range-tools-on-terrain/range-ring/{enum.js → enum.ts} +2 -2
- package/range-tools-on-terrain/range-ring/{plugin.js → plugin.ts} +444 -377
- package/range-tools-on-terrain/range-ring/rangeringangletext.ts +396 -0
- package/range-tools-on-terrain/range-ring/types.ts +30 -0
- package/semiplugins/interface.ts +14 -0
- package/semiplugins/lightweight/{line-plugin.js → line-plugin.ts} +342 -221
- package/semiplugins/lightweight/{piece-of-pie-plugin.js → piece-of-pie-plugin.ts} +275 -200
- package/semiplugins/shape-on-terrain/{arc-plugin.js → arc-plugin.ts} +616 -481
- package/semiplugins/shape-on-terrain/{circle-plugin.js → circle-plugin.ts} +588 -444
- package/semiplugins/shape-on-terrain/goal.md +12 -0
- package/semiplugins/shape-on-terrain/{padding-1-degree.js → padding-1-degree.ts} +713 -539
- package/semiplugins/shape-on-terrain/terrain-polygon/adapters.ts +69 -0
- package/semiplugins/shape-on-terrain/terrain-polygon/data/cache-shortcuts.md +20 -0
- package/semiplugins/shape-on-terrain/terrain-polygon/data/cache.ts +149 -0
- package/semiplugins/shape-on-terrain/terrain-polygon/data/index-polygon-map.ts +58 -0
- package/semiplugins/shape-on-terrain/terrain-polygon/data/manager.ts +4 -0
- package/semiplugins/shape-on-terrain/terrain-polygon/data/master-worker.js +196 -0
- package/semiplugins/shape-on-terrain/terrain-polygon/data/master-worker.ts +209 -0
- package/semiplugins/shape-on-terrain/terrain-polygon/data/polygon-to-triangles.ts +144 -0
- package/semiplugins/shape-on-terrain/terrain-polygon/data/random.ts +165 -0
- package/semiplugins/shape-on-terrain/terrain-polygon/data/readme.md +5 -0
- package/semiplugins/shape-on-terrain/terrain-polygon/data/types.ts +37 -0
- package/semiplugins/shape-on-terrain/terrain-polygon/data/worker-contact.ts +81 -0
- package/semiplugins/shape-on-terrain/terrain-polygon/data/worker.js +146 -0
- package/semiplugins/shape-on-terrain/terrain-polygon/notes.md +90 -0
- package/semiplugins/shape-on-terrain/terrain-polygon/terrain-polygon.ts +265 -0
- package/semiplugins/shape-on-terrain/terrain-polygon/types.ts +69 -0
- package/semiplugins/shell/bbox-renderer/index.ts +2 -0
- package/semiplugins/shell/bbox-renderer/{logic.js → logic.ts} +273 -249
- package/semiplugins/shell/bbox-renderer/object.ts +129 -0
- package/semiplugins/type.ts +8 -0
- package/semiplugins/utility/{container-plugin.js → container-plugin.ts} +126 -94
- package/semiplugins/utility/{object-pass-container-plugin.js → object-pass-container-plugin.ts} +101 -80
- package/shaders/fragment-toy/firework.js +1 -1
- package/shaders/fragment-toy/singularity.js +5 -2
- package/terrain-plugin.mmd +83 -0
- package/tests/Math/arc-sampling-test.js +367 -0
- package/tests/Math/arc-sampling-test.ts +429 -0
- package/tests/Math/arc.test.ts +77 -0
- package/tests/Math/junction/arc-limit.test.ts +7 -0
- package/tests/Math/junction/arc-plane-points.test.ts +196 -0
- package/tests/Math/junction/arc-plane.test.ts +172 -0
- package/tests/Math/junction/line-sphere.test.ts +127 -0
- package/tests/Math/junction/plane-plane.test.ts +91 -0
- package/tests/Math/plane-test.ts +17 -0
- package/tests/Math/plane.test.ts +43 -0
- package/tests/Math/vec3.test.ts +33 -0
- package/tracks/point-heat-map/adaptors/timetracksplugin-format-to-this.js +78 -63
- package/tracks/point-heat-map/index.js +0 -1
- package/tracks/point-heat-map/plugin-webworker.js +148 -121
- package/tracks/point-heat-map/point-to-heat-map-flow.js +150 -121
- package/tracks/point-heat-map/readme.md +15 -0
- package/tracks/point-tracks/key-methods.js +3 -2
- package/tracks/point-tracks/plugin.js +487 -394
- package/tracks/timetracks/adaptors-line-strip.js +79 -65
- package/tracks/timetracks/plugin-line-strip.js +295 -240
- package/tracks/timetracks/program-line-strip.js +495 -411
- package/tracks/timetracks/programpoint-line-strip.js +137 -109
- package/tracks/timetracks/readme.md +1 -0
- package/tsconfig.json +22 -0
- package/types/@pirireis/webglobe.d.ts +102 -0
- package/types/delaunator.d.ts +40 -0
- package/types/earcut.d.ts +11 -0
- package/types/rbush.d.ts +57 -0
- package/types.ts +319 -0
- package/util/account/bufferoffsetmanager.js +209 -176
- package/util/account/create-buffermap-orchastration.ts +85 -0
- package/util/account/index.js +6 -3
- package/util/account/single-attribute-buffer-management/{buffer-manager.js → buffer-manager.ts} +151 -117
- package/util/account/single-attribute-buffer-management/{buffer-orchestrator.js → buffer-orchestrator.ts} +238 -212
- package/util/account/single-attribute-buffer-management/{buffer-orchestrator1.js → buffer-orchestrator1.ts} +184 -159
- package/util/account/single-attribute-buffer-management/{index.js → index.ts} +11 -4
- package/util/account/single-attribute-buffer-management/{object-store.js → object-store.ts} +76 -55
- package/util/account/single-attribute-buffer-management/types.ts +43 -0
- package/util/account/util.js +22 -18
- package/util/algorithms/index.js +0 -1
- package/util/algorithms/search-binary.js +26 -25
- package/util/build-strategy/{static-dynamic.js → static-dynamic.ts} +50 -41
- package/util/check/index.js +0 -1
- package/util/check/typecheck.ts +74 -0
- package/util/{frame-counter-trigger.js → frame-counter-trigger.ts} +99 -84
- package/util/geometry/{index.js → index.ts} +155 -121
- package/util/gl-util/buffer/{attribute-loader.js → attribute-loader.ts} +84 -62
- package/util/gl-util/buffer/{index.js → index.ts} +6 -3
- package/util/gl-util/draw-options/{methods.js → methods.ts} +47 -32
- package/util/gl-util/uniform-block/{manager.js → manager.ts} +232 -190
- package/util/{webglobe/gldefaultstates.js → globe-default-gl-states.ts} +5 -4
- package/util/helper-methods.ts +9 -0
- package/util/index.js +9 -10
- package/util/interpolation/index.js +0 -1
- package/util/interpolation/timetrack/index.js +9 -2
- package/util/interpolation/timetrack/timetrack-interpolator.js +94 -79
- package/util/interpolation/timetrack/web-worker.js +51 -46
- package/util/picking/{fence.js → fence.ts} +47 -41
- package/util/picking/picker-displayer.ts +226 -0
- package/util/programs/draw-from-pixel-coords.js +201 -164
- package/util/programs/{draw-texture-on-canvas.js → draw-texture-on-canvas.ts} +92 -67
- package/util/programs/supersampletotextures.js +130 -97
- package/util/programs/texturetoglobe.js +153 -128
- package/util/shaderfunctions/{geometrytransformations.js → geometrytransformations.ts} +169 -41
- package/util/shaderfunctions/index.js +2 -2
- package/util/shaderfunctions/nodata.js +4 -2
- package/util/shaderfunctions/noisefunctions.js +10 -7
- package/util/{webglobjectbuilders.js → webglobjectbuilders.ts} +446 -358
- package/vectorfield/arrowfield/adaptor.js +11 -11
- package/vectorfield/arrowfield/index.js +3 -3
- package/vectorfield/arrowfield/plugin.js +128 -83
- package/vectorfield/waveparticles/adaptor.js +16 -15
- package/vectorfield/waveparticles/index.js +3 -3
- package/vectorfield/waveparticles/plugin.ts +506 -0
- package/vectorfield/wind/adapters/image-to-fields.ts +74 -0
- package/vectorfield/wind/adapters/types.ts +12 -0
- package/vectorfield/wind/{imagetovectorfieldandmagnitude.js → imagetovectorfieldandmagnitude.ts} +78 -56
- package/vectorfield/wind/index.js +5 -5
- package/vectorfield/wind/plugin-persistant copy.ts +461 -0
- package/vectorfield/wind/plugin-persistant.ts +483 -0
- package/vectorfield/wind/plugin.js +883 -685
- package/vectorfield/wind/vectorfieldimage.js +27 -23
- package/write-text/{context-text-bulk.js → context-text-bulk.ts} +285 -200
- package/write-text/context-text3.ts +252 -0
- package/write-text/{context-text4.js → context-text4.ts} +231 -146
- package/write-text/context-textDELETE.js +125 -94
- package/write-text/objectarraylabels/{index.js → index.ts} +2 -2
- package/write-text/objectarraylabels/objectarraylabels.d.ts +72 -0
- package/write-text/objectarraylabels/objectarraylabels.js +247 -200
- package/Math/matrix4.js +0 -1
- package/Math/tessellation/earcut/adapters.js +0 -37
- package/Math/tessellation/hybrid-triangle-tessellation-meta.js +0 -123
- package/Math/tessellation/methods.js +0 -46
- package/Math/tessellation/shred-input.js +0 -18
- package/Math/tessellation/tile-merger.js +0 -298
- package/Math/tessellation/tiler.js +0 -50
- package/Math/tessellation/triangle-tessellation-meta.js +0 -523
- package/Math/tessellation/triangle-tessellation.js +0 -14
- package/Math/tessellation/types.js +0 -1
- package/Math/tessellation/zoom-catch.js +0 -1
- package/Math/types.js +0 -1
- package/investigation-tools/draw/tiles/adapters.js +0 -67
- package/programs/line-on-globe/linestrip/data.js +0 -4
- package/programs/polygon-on-globe/texture-dem-triangle-test-plugin-triangle.js +0 -328
- package/programs/polygon-on-globe/texture-dem-triangles.js +0 -268
- package/programs/vectorfields/logics/drawrectangleparticles.js +0 -114
- package/programs/vectorfields/logics/drawrectangleparticles1.js +0 -112
- package/programs/vectorfields/logics/ubo-new.js +0 -25
- package/range-tools-on-terrain/bearing-line/types.js +0 -1
- package/range-tools-on-terrain/circle-line-chain/types.js +0 -1
- package/range-tools-on-terrain/range-ring/rangeringangletext.js +0 -331
- package/range-tools-on-terrain/range-ring/types.js +0 -9
- package/semiplugins/interface.js +0 -1
- package/semiplugins/shape-on-terrain/terrain-cover/texture-dem-cover.js +0 -1
- package/semiplugins/shell/bbox-renderer/index.js +0 -2
- package/semiplugins/shell/bbox-renderer/object.js +0 -65
- package/semiplugins/type.js +0 -1
- package/types.js +0 -19
- package/util/account/create-buffermap-orchastration.js +0 -39
- package/util/account/single-attribute-buffer-management/types.js +0 -1
- package/util/check/typecheck.js +0 -66
- package/util/gl-util/uniform-block/types.js +0 -1
- package/util/picking/picker-displayer.js +0 -134
- package/util/webglobe/index.js +0 -2
- package/vectorfield/waveparticles/plugin.js +0 -290
- package/write-text/context-text3.js +0 -167
|
@@ -0,0 +1,483 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Author: Toprak Nihat Deniz Ozturk
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { Globe } from "../../types";
|
|
6
|
+
import { imageToFields } from "./adapters/image-to-fields";
|
|
7
|
+
import ParticlePlugin from "../waveparticles/plugin";
|
|
8
|
+
import { createImageFromBase64 } from "../../util/webglobjectbuilders";
|
|
9
|
+
import { TexturePointSampler } from "../../heatwave/texture-point-sampler";
|
|
10
|
+
import imageToMagnitude, { imageToRadianAngle } from "./imagetovectorfieldandmagnitude";
|
|
11
|
+
import { WindData, LegendData } from "./adapters/types.js";
|
|
12
|
+
import { isBoolean } from "../../util/check/typecheck";
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Shader Documentation:
|
|
16
|
+
* * Vector field escape value
|
|
17
|
+
* texture2D(u_wind, pos).rg == vec2(0.0, 0.0) is used as escape value.
|
|
18
|
+
* In sea wind maps, land areas have rg values of 0.0.
|
|
19
|
+
* The probability of a real particle having rg == vec2(0.0, 0.0) is low.
|
|
20
|
+
* Must have lowest value in both horizontal and vertical dimensions.
|
|
21
|
+
*/
|
|
22
|
+
|
|
23
|
+
type WindDataMeta = {
|
|
24
|
+
width: number;
|
|
25
|
+
height: number;
|
|
26
|
+
bbox: number[]; // [minLon, minLat, maxLon, maxLat]
|
|
27
|
+
flipY?: boolean;
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
type WindPluginOptions = {
|
|
31
|
+
fadeOpacity?: number;
|
|
32
|
+
speedFactor?: number;
|
|
33
|
+
dropRate?: number;
|
|
34
|
+
dropRateBump?: number;
|
|
35
|
+
baseOpacity?: number;
|
|
36
|
+
wingSize?: number;
|
|
37
|
+
tailSize?: number;
|
|
38
|
+
minSpeed?: number;
|
|
39
|
+
maxSpeed?: number;
|
|
40
|
+
height?: number;
|
|
41
|
+
numParticles?: number;
|
|
42
|
+
legendData?: LegendData;
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
const windyLegendData: LegendData = {
|
|
46
|
+
thresholds: [0, 3, 3, 5, 5, 7, 10, 10, 13, 15, 15, 17, 20, 20, 25, 25, 30],
|
|
47
|
+
values: [
|
|
48
|
+
"#6271B8",
|
|
49
|
+
"#6271B8",
|
|
50
|
+
"#6271B8",
|
|
51
|
+
"#6271B8",
|
|
52
|
+
"#3D6EA3",
|
|
53
|
+
"#4A94AA",
|
|
54
|
+
"#4A9294",
|
|
55
|
+
"#4D8E7C",
|
|
56
|
+
"#4CA44C",
|
|
57
|
+
"#67A436",
|
|
58
|
+
"#A28740",
|
|
59
|
+
"#A26D5C",
|
|
60
|
+
"#8D3F5C",
|
|
61
|
+
"#974B91",
|
|
62
|
+
"#5F64A0",
|
|
63
|
+
"#5B88A1",
|
|
64
|
+
"#5B88A1"
|
|
65
|
+
]
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
export default class WindPlugin {
|
|
69
|
+
public id: string;
|
|
70
|
+
public globe!: Globe;
|
|
71
|
+
private gl: WebGL2RenderingContext | null = null;
|
|
72
|
+
private particlePlugin!: ParticlePlugin;
|
|
73
|
+
private windMetadata: WindDataMeta;
|
|
74
|
+
private _legendData: LegendData;
|
|
75
|
+
private options: WindPluginOptions;
|
|
76
|
+
private windData: WindData | null;
|
|
77
|
+
private _height: number;
|
|
78
|
+
private _speedFactor: number;
|
|
79
|
+
private _dropRate: number;
|
|
80
|
+
private texturePointSampler?: TexturePointSampler;
|
|
81
|
+
private texturePointSamplerAngle?: TexturePointSampler;
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* @param id - Plugin identifier
|
|
85
|
+
* @param windDataMeta - Wind data metadata
|
|
86
|
+
* @param windDataMeta.width - image width
|
|
87
|
+
* @param windDataMeta.height - image height
|
|
88
|
+
* @param windDataMeta.bbox - bounding box [minLon, minLat, maxLon, maxLat]
|
|
89
|
+
* @param options - Plugin options
|
|
90
|
+
* @param options.fadeOpacity - how fast the particle trails fade on each frame | between 0 - 1 | default 0.746
|
|
91
|
+
* @param options.speedFactor - how fast the particles move | between 0 - 1 | default 0.6
|
|
92
|
+
* @param options.dropRate - how often the particles move to a random place | between 0 - 1 | default 0.007
|
|
93
|
+
* @param options.dropRateBump - drop rate increase relative to individual particle speed
|
|
94
|
+
* @param options.baseOpacity - opacity of drawn particle trails | between 0 - 1 | default 1.0
|
|
95
|
+
* @param options.wingSize - wing size of particle arrow | positive number | default 7.0
|
|
96
|
+
* @param options.tailSize - tail size of particle arrow | positive number | default 1.0
|
|
97
|
+
* @param options.minSpeed - minimum speed threshold | positive number | default 0.0
|
|
98
|
+
* @param options.maxSpeed - maximum speed threshold | positive number | default 1000.0
|
|
99
|
+
* @param options.height - height of the particles | number | default 0.0
|
|
100
|
+
* @param options.numParticles - number of particles | positive integer | default 40000
|
|
101
|
+
* @param options.legendData - legend data for color mapping
|
|
102
|
+
*/
|
|
103
|
+
constructor(
|
|
104
|
+
id: string,
|
|
105
|
+
windDataMeta: WindDataMeta,
|
|
106
|
+
options: WindPluginOptions = {}
|
|
107
|
+
) {
|
|
108
|
+
this.id = id;
|
|
109
|
+
this.windMetadata = windDataMeta;
|
|
110
|
+
this._legendData = options.legendData || windyLegendData;
|
|
111
|
+
|
|
112
|
+
this.options = {
|
|
113
|
+
fadeOpacity: options.fadeOpacity ?? 0.746,
|
|
114
|
+
speedFactor: options.speedFactor ?? 0.6,
|
|
115
|
+
dropRate: options.dropRate ?? 0.007,
|
|
116
|
+
dropRateBump: options.dropRateBump ?? 0.001,
|
|
117
|
+
baseOpacity: options.baseOpacity ?? 1.0,
|
|
118
|
+
wingSize: options.wingSize ?? 7.0,
|
|
119
|
+
tailSize: options.tailSize ?? 1.0,
|
|
120
|
+
minSpeed: options.minSpeed ?? 0.0,
|
|
121
|
+
maxSpeed: options.maxSpeed ?? 1000.0,
|
|
122
|
+
height: options.height ?? 0.0,
|
|
123
|
+
numParticles: options.numParticles ?? 40000,
|
|
124
|
+
legendData: this._legendData
|
|
125
|
+
};
|
|
126
|
+
|
|
127
|
+
this.windData = null;
|
|
128
|
+
this._height = this.options.height!;
|
|
129
|
+
this._speedFactor = this.options.speedFactor!;
|
|
130
|
+
this._dropRate = this.options.dropRate!;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
// Globe plugin init method
|
|
134
|
+
init(globe: Globe, gl: WebGL2RenderingContext): void {
|
|
135
|
+
this.globe = globe;
|
|
136
|
+
this.gl = gl;
|
|
137
|
+
|
|
138
|
+
// Initialize the particle plugin with appropriate options
|
|
139
|
+
const { bbox, width, height, flipY } = this.windMetadata;
|
|
140
|
+
|
|
141
|
+
this.particlePlugin = new ParticlePlugin(
|
|
142
|
+
`${this.id}_particles`,
|
|
143
|
+
{
|
|
144
|
+
dataWidth: width,
|
|
145
|
+
dataHeight: height,
|
|
146
|
+
fadeOpacity: this.options.fadeOpacity,
|
|
147
|
+
opacity: this.options.baseOpacity,
|
|
148
|
+
speed: this._speedFactor,
|
|
149
|
+
dropRate: this._dropRate,
|
|
150
|
+
height: this._height,
|
|
151
|
+
minLon: bbox[0],
|
|
152
|
+
minLat: bbox[1] < -85 ? -85 : bbox[1],
|
|
153
|
+
maxLon: bbox[2],
|
|
154
|
+
maxLat: bbox[3] > 85 ? 85 : bbox[3],
|
|
155
|
+
particleCount: this.options.numParticles,
|
|
156
|
+
flipY: flipY ?? true,
|
|
157
|
+
useColorTexture: false, // TODO: under test.. make it true later
|
|
158
|
+
useSpeedTexture: true,
|
|
159
|
+
minSpeedThreshold: this.options.minSpeed,
|
|
160
|
+
maxSpeedThreshold: this.options.maxSpeed,
|
|
161
|
+
tailSize: this.options.tailSize!,
|
|
162
|
+
wingSize: this.options.wingSize!
|
|
163
|
+
}
|
|
164
|
+
);
|
|
165
|
+
|
|
166
|
+
this.particlePlugin.init(globe, gl);
|
|
167
|
+
// apply initial speed thresholds from options
|
|
168
|
+
this.particlePlugin.setSpeedThresholds(this.options.minSpeed!, this.options.maxSpeed!);
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
draw3D(): void {
|
|
172
|
+
if (this.particlePlugin) {
|
|
173
|
+
this.particlePlugin.draw3D();
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
free(): void {
|
|
178
|
+
if (this.particlePlugin) {
|
|
179
|
+
this.particlePlugin.free();
|
|
180
|
+
}
|
|
181
|
+
if (this.texturePointSampler) {
|
|
182
|
+
this.texturePointSampler = undefined;
|
|
183
|
+
}
|
|
184
|
+
if (this.texturePointSamplerAngle) {
|
|
185
|
+
this.texturePointSamplerAngle = undefined;
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
// ===== Wind Data Management =====
|
|
190
|
+
|
|
191
|
+
/**
|
|
192
|
+
* Set wind data from base64 encoded image
|
|
193
|
+
* @param windData - Wind data object
|
|
194
|
+
* @param windData.image - base64 encoded image
|
|
195
|
+
* @param windData.width - image width
|
|
196
|
+
* @param windData.height - image height
|
|
197
|
+
* @param windData.uMin - minimum u value
|
|
198
|
+
* @param windData.vMin - minimum v value
|
|
199
|
+
* @param windData.uMax - maximum u value
|
|
200
|
+
* @param windData.vMax - maximum v value
|
|
201
|
+
* @param windData.bbox - bounding box [minLon, minLat, maxLon, maxLat]
|
|
202
|
+
*/
|
|
203
|
+
setWindDataWithImageBase64(windData: {
|
|
204
|
+
image: string;
|
|
205
|
+
width: number;
|
|
206
|
+
height: number;
|
|
207
|
+
uMin: number;
|
|
208
|
+
vMin: number;
|
|
209
|
+
uMax: number;
|
|
210
|
+
vMax: number;
|
|
211
|
+
bbox?: number[];
|
|
212
|
+
}): void {
|
|
213
|
+
const image = createImageFromBase64(windData.image);
|
|
214
|
+
image.onload = () => {
|
|
215
|
+
const fullWindData: WindData = {
|
|
216
|
+
image: image,
|
|
217
|
+
uMin: windData.uMin,
|
|
218
|
+
vMin: windData.vMin,
|
|
219
|
+
uMax: windData.uMax,
|
|
220
|
+
vMax: windData.vMax
|
|
221
|
+
};
|
|
222
|
+
this.setWind(fullWindData);
|
|
223
|
+
};
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
/**
|
|
227
|
+
* Set wind data from HTMLImageElement
|
|
228
|
+
*/
|
|
229
|
+
setWind(windData: WindData): void {
|
|
230
|
+
this.windData = windData;
|
|
231
|
+
|
|
232
|
+
if (!this.particlePlugin) {
|
|
233
|
+
return;
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
// Convert wind image to vector field, speed field, and color field
|
|
237
|
+
const { vectorFieldData, speedFieldData, colorFieldData } = imageToFields(
|
|
238
|
+
windData,
|
|
239
|
+
this._legendData
|
|
240
|
+
);
|
|
241
|
+
|
|
242
|
+
// Update the particle plugin with the new data
|
|
243
|
+
this.particlePlugin.setVectorFieldData(vectorFieldData, {
|
|
244
|
+
dataWidth: windData.image.width,
|
|
245
|
+
dataHeight: windData.image.height,
|
|
246
|
+
flipY: this.windMetadata.flipY
|
|
247
|
+
});
|
|
248
|
+
|
|
249
|
+
this.particlePlugin.setSpeedField(speedFieldData);
|
|
250
|
+
this.particlePlugin.setColorField(colorFieldData);
|
|
251
|
+
|
|
252
|
+
// Update texture point samplers if they exist
|
|
253
|
+
this._setCoorcinatesDataCalculatorData();
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
// ===== Legend and Color Management =====
|
|
257
|
+
|
|
258
|
+
/**
|
|
259
|
+
* Set legend data for color mapping
|
|
260
|
+
* @param legendData - Legend data object
|
|
261
|
+
* @param legendData.thresholds - list of speed thresholds
|
|
262
|
+
* @param legendData.values - list of colors in hex format like #ff0000
|
|
263
|
+
*/
|
|
264
|
+
setLegend(legendData: LegendData): void {
|
|
265
|
+
this._legendData = legendData;
|
|
266
|
+
|
|
267
|
+
// If wind data is already set, re-process to update colors
|
|
268
|
+
if (this.windData && this.particlePlugin) {
|
|
269
|
+
const { vectorFieldData, speedFieldData, colorFieldData } = imageToFields(
|
|
270
|
+
this.windData,
|
|
271
|
+
this._legendData
|
|
272
|
+
);
|
|
273
|
+
this.particlePlugin.setColorField(colorFieldData);
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
|
|
278
|
+
setFlipY(flipY: boolean): void {
|
|
279
|
+
isBoolean(flipY);
|
|
280
|
+
this.windMetadata.flipY = flipY;
|
|
281
|
+
if (this.particlePlugin && this.windData) {
|
|
282
|
+
this.setWind(this.windData);
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
|
|
287
|
+
setDrawTextureMaxPixelOnDimension(value: number): void {
|
|
288
|
+
if (this.particlePlugin) {
|
|
289
|
+
this.particlePlugin.setDrawTextureMaxPixelOnDimension(value);
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
// ===== Property Setters =====
|
|
293
|
+
|
|
294
|
+
set height(value: number) {
|
|
295
|
+
this._height = value;
|
|
296
|
+
if (this.particlePlugin) {
|
|
297
|
+
this.particlePlugin.setHeight(value);
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
get height(): number {
|
|
302
|
+
return this._height;
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
set minSpeed(value: number) {
|
|
306
|
+
this.options.minSpeed = value;
|
|
307
|
+
if (this.particlePlugin) {
|
|
308
|
+
this.particlePlugin.setMinSpeedThreshold(value);
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
get minSpeed(): number {
|
|
313
|
+
return this.options.minSpeed!;
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
set maxSpeed(value: number) {
|
|
317
|
+
this.options.maxSpeed = value;
|
|
318
|
+
if (this.particlePlugin) {
|
|
319
|
+
this.particlePlugin.setMaxSpeedThreshold(value);
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
get maxSpeed(): number {
|
|
324
|
+
return this.options.maxSpeed!;
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
set fadeOpacity(value: number) {
|
|
328
|
+
this.options.fadeOpacity = value;
|
|
329
|
+
if (this.particlePlugin) {
|
|
330
|
+
this.particlePlugin.setFadeOpacity(value);
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
get fadeOpacity(): number {
|
|
335
|
+
return this.options.fadeOpacity!;
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
set speedFactor(value: number) {
|
|
339
|
+
this._speedFactor = value;
|
|
340
|
+
if (this.particlePlugin) {
|
|
341
|
+
this.particlePlugin.setParticleSpeed(value);
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
get speedFactor(): number {
|
|
346
|
+
return this._speedFactor;
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
set dropRate(value: number) {
|
|
350
|
+
this._dropRate = value;
|
|
351
|
+
if (this.particlePlugin) {
|
|
352
|
+
this.particlePlugin.setDropRate(value);
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
get dropRate(): number {
|
|
357
|
+
return this._dropRate;
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
set dropRateBump(value: number) {
|
|
361
|
+
this.options.dropRateBump = value;
|
|
362
|
+
// Note: ParticlePlugin doesn't have dropRateBump parameter
|
|
363
|
+
// This would need to be added to ParticlePlugin if needed
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
get dropRateBump(): number {
|
|
367
|
+
return this.options.dropRateBump!;
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
set baseOpacity(value: number) {
|
|
371
|
+
this.options.baseOpacity = value;
|
|
372
|
+
if (this.particlePlugin) {
|
|
373
|
+
this.particlePlugin.setOpacity(value);
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
get baseOpacity(): number {
|
|
378
|
+
return this.options.baseOpacity!;
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
set numParticles(value: number) {
|
|
382
|
+
this.options.numParticles = value;
|
|
383
|
+
if (this.particlePlugin) {
|
|
384
|
+
this.particlePlugin.setParticleCount(value);
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
get numParticles(): number {
|
|
389
|
+
return this.options.numParticles!;
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
/**
|
|
393
|
+
* Set wing and tail size for particle arrows
|
|
394
|
+
*/
|
|
395
|
+
setParticleDimensions(tail: number, wing: number): void {
|
|
396
|
+
this.options.tailSize = tail;
|
|
397
|
+
this.options.wingSize = wing;
|
|
398
|
+
if (this.particlePlugin) {
|
|
399
|
+
this.particlePlugin.setParticleDimensions(tail, wing);
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
/**
|
|
404
|
+
* Set particle color (used when not using color field)
|
|
405
|
+
*/
|
|
406
|
+
setParticleColor(color: number[]): void {
|
|
407
|
+
if (this.particlePlugin) {
|
|
408
|
+
this.particlePlugin.setParticleColor(color);
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
/**
|
|
413
|
+
* Set bounding box
|
|
414
|
+
*/
|
|
415
|
+
setBBox(bbox: { minLon: number; minLat: number; maxLon: number; maxLat: number }): void {
|
|
416
|
+
// rescale
|
|
417
|
+
|
|
418
|
+
if (this.particlePlugin) {
|
|
419
|
+
this.particlePlugin.setBBox({
|
|
420
|
+
minLon: bbox.minLon,
|
|
421
|
+
minLat: bbox.minLat < -85 ? -85 : bbox.minLat,
|
|
422
|
+
maxLon: bbox.maxLon,
|
|
423
|
+
maxLat: bbox.maxLat > 85 ? 85 : bbox.maxLat
|
|
424
|
+
});
|
|
425
|
+
}
|
|
426
|
+
// Update metadata
|
|
427
|
+
this.windMetadata.bbox = [bbox.minLon, bbox.minLat, bbox.maxLon, bbox.maxLat];
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
// ===== Texture Point Sampler (for backward compatibility) =====
|
|
431
|
+
|
|
432
|
+
/**
|
|
433
|
+
* Get texture point sampler for magnitude or angle
|
|
434
|
+
* @param type - 'magnitude' or 'angle'
|
|
435
|
+
*/
|
|
436
|
+
getTexturePointSampler(type: 'magnitude' | 'angle' = 'magnitude'): TexturePointSampler {
|
|
437
|
+
if (type === 'magnitude') {
|
|
438
|
+
if (!this.texturePointSampler) {
|
|
439
|
+
this._createTexturePointSampler();
|
|
440
|
+
this._setCoorcinatesDataCalculatorData();
|
|
441
|
+
}
|
|
442
|
+
return this.texturePointSampler!;
|
|
443
|
+
} else if (type === 'angle') {
|
|
444
|
+
if (!this.texturePointSamplerAngle) {
|
|
445
|
+
this._createTexturePointSamplerAngle();
|
|
446
|
+
this._setCoorcinatesDataCalculatorData();
|
|
447
|
+
}
|
|
448
|
+
return this.texturePointSamplerAngle!;
|
|
449
|
+
} else {
|
|
450
|
+
throw new Error(`WindPlugin.getTexturePointSampler: type must be either 'magnitude' or 'angle'.`);
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
private _createTexturePointSamplerAngle(): void {
|
|
455
|
+
const { bbox, width, height } = this.windMetadata;
|
|
456
|
+
this.texturePointSamplerAngle = new TexturePointSampler(bbox as [number, number, number, number], width, height);
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
private _createTexturePointSampler(): void {
|
|
460
|
+
const { bbox, width, height } = this.windMetadata;
|
|
461
|
+
this.texturePointSampler = new TexturePointSampler(bbox as [number, number, number, number], width, height);
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
private _setCoorcinatesDataCalculatorData(): void {
|
|
465
|
+
if (!this.windData) {
|
|
466
|
+
return;
|
|
467
|
+
}
|
|
468
|
+
const windDataWithDimensions = {
|
|
469
|
+
...this.windData,
|
|
470
|
+
width: this.windData.image.width,
|
|
471
|
+
height: this.windData.image.height
|
|
472
|
+
};
|
|
473
|
+
if (this.texturePointSamplerAngle) {
|
|
474
|
+
const angle = imageToRadianAngle(windDataWithDimensions as any);
|
|
475
|
+
this.texturePointSamplerAngle.updateTextureData(0, angle, angle);
|
|
476
|
+
}
|
|
477
|
+
if (this.texturePointSampler) {
|
|
478
|
+
const magnitude = imageToMagnitude(windDataWithDimensions as any);
|
|
479
|
+
this.texturePointSampler.updateTextureData(0, magnitude, magnitude);
|
|
480
|
+
}
|
|
481
|
+
}
|
|
482
|
+
}
|
|
483
|
+
|