autumnplot-gl 4.0.0-beta → 4.1.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 (84) hide show
  1. package/README.md +13 -207
  2. package/dist/812.autumnplot-gl.js +2 -0
  3. package/dist/812.autumnplot-gl.js.map +1 -0
  4. package/dist/983.autumnplot-gl.js +2 -0
  5. package/dist/983.autumnplot-gl.js.map +1 -0
  6. package/dist/autumnplot-gl.js +1 -1
  7. package/dist/autumnplot-gl.js.map +1 -1
  8. package/dist/marchingsquares.wasm +0 -0
  9. package/lib/AutumnTypes.d.ts +38 -5
  10. package/lib/AutumnTypes.js +7 -1
  11. package/lib/Barbs.d.ts +12 -2
  12. package/lib/Barbs.js +9 -0
  13. package/lib/BillboardCollection.d.ts +2 -2
  14. package/lib/BillboardCollection.js +14 -14
  15. package/lib/Color.d.ts +1 -0
  16. package/lib/Color.js +1 -0
  17. package/lib/ColorBar.d.ts +14 -0
  18. package/lib/ColorBar.js +15 -8
  19. package/lib/Colormap.d.ts +9 -1
  20. package/lib/Colormap.js +24 -1
  21. package/lib/Contour.d.ts +26 -1
  22. package/lib/Contour.js +24 -2
  23. package/lib/ContourCreator.worker.d.ts +25 -0
  24. package/lib/{ContourCreator.js → ContourCreator.worker.js} +15 -14
  25. package/lib/Fill.d.ts +31 -11
  26. package/lib/Fill.js +38 -18
  27. package/lib/Hodographs.d.ts +19 -3
  28. package/lib/Hodographs.js +45 -20
  29. package/lib/Map.d.ts +13 -1
  30. package/lib/Map.js +62 -8
  31. package/lib/Paintball.d.ts +14 -5
  32. package/lib/Paintball.js +96 -46
  33. package/lib/PlotComponent.d.ts +9 -3
  34. package/lib/PlotComponent.js +36 -1
  35. package/lib/PlotLayer.d.ts +2 -2
  36. package/lib/PlotLayer.js +2 -2
  37. package/lib/PlotLayer.worker.js +9 -3
  38. package/lib/RawField.d.ts +223 -27
  39. package/lib/RawField.js +413 -59
  40. package/lib/StationPlot.d.ts +78 -11
  41. package/lib/StationPlot.js +113 -30
  42. package/lib/TextCollection.d.ts +5 -0
  43. package/lib/TextCollection.js +82 -9
  44. package/lib/WasmInterface.d.ts +7 -0
  45. package/lib/WasmInterface.js +11 -0
  46. package/lib/WorkerPool.d.ts +8 -0
  47. package/lib/WorkerPool.js +77 -0
  48. package/lib/cpp/marchingsquares.js +127 -13
  49. package/lib/cpp/marchingsquares.wasm +0 -0
  50. package/lib/cpp/marchingsquares_embind.d.ts +16 -3
  51. package/lib/grids/AutoZoom.d.ts +21 -0
  52. package/lib/grids/AutoZoom.js +63 -0
  53. package/lib/grids/DomainBuffer.d.ts +14 -0
  54. package/lib/grids/DomainBuffer.js +16 -0
  55. package/lib/grids/Geostationary.d.ts +35 -0
  56. package/lib/grids/Geostationary.js +47 -0
  57. package/lib/grids/Grid.d.ts +36 -0
  58. package/lib/grids/Grid.js +12 -0
  59. package/lib/grids/GridCoordinates.d.ts +10 -0
  60. package/lib/grids/GridCoordinates.js +64 -0
  61. package/lib/grids/LambertGrid.d.ts +73 -0
  62. package/lib/grids/LambertGrid.js +92 -0
  63. package/lib/grids/PlateCarreeGrid.d.ts +46 -0
  64. package/lib/grids/PlateCarreeGrid.js +55 -0
  65. package/lib/grids/PlateCarreeRotatedGrid.d.ts +53 -0
  66. package/lib/grids/PlateCarreeRotatedGrid.js +65 -0
  67. package/lib/grids/RadarSweepGrid.d.ts +46 -0
  68. package/lib/grids/RadarSweepGrid.js +74 -0
  69. package/lib/grids/StructuredGrid.d.ts +49 -0
  70. package/lib/grids/StructuredGrid.js +103 -0
  71. package/lib/grids/UnstructuredGrid.d.ts +56 -0
  72. package/lib/grids/UnstructuredGrid.js +102 -0
  73. package/lib/index.d.ts +23 -6
  74. package/lib/index.js +18 -8
  75. package/lib/utils.d.ts +11 -2
  76. package/lib/utils.js +63 -1
  77. package/package.json +4 -3
  78. package/dist/110.autumnplot-gl.js +0 -2
  79. package/dist/110.autumnplot-gl.js.map +0 -1
  80. package/lib/ContourCreator.d.ts +0 -22
  81. package/lib/Grid.d.ts +0 -263
  82. package/lib/Grid.js +0 -547
  83. package/lib/ParticleTracer.d.ts +0 -19
  84. package/lib/ParticleTracer.js +0 -37
@@ -0,0 +1,77 @@
1
+ import * as Comlink from 'comlink';
2
+ class WorkerPool_ {
3
+ constructor(workers, init) {
4
+ this.workers = workers.map(wkr => ({ worker: Comlink.wrap(wkr), is_busy: false }));
5
+ if (init) {
6
+ this.workers.forEach(wkr => init(wkr.worker));
7
+ }
8
+ this.queue = new Map();
9
+ }
10
+ call(path, args, callback) {
11
+ const worker_idx = this.workers.map(((w, iw) => [w, iw])).filter(([w, iw]) => !w.is_busy)[0];
12
+ if (worker_idx === undefined) {
13
+ this.enqueue(path, args, callback);
14
+ }
15
+ else {
16
+ const [worker, iw] = worker_idx;
17
+ const dequeueAndStart = () => {
18
+ if (this.queueSize(path) > 0) {
19
+ const queue_data = this.dequeue(path);
20
+ if (queue_data === undefined)
21
+ return;
22
+ this.startRun(worker, path, queue_data.args).then(queue_data.callback).then(dequeueAndStart);
23
+ }
24
+ };
25
+ this.startRun(worker, path, args).then(callback).then(dequeueAndStart);
26
+ }
27
+ }
28
+ enqueue(path, args, callback) {
29
+ const path_str = path.join(".");
30
+ const old_queue = this.queue.get(path_str);
31
+ const new_queue = old_queue ? old_queue : [];
32
+ new_queue.push({ args: args, callback: callback });
33
+ this.queue.set(path_str, new_queue);
34
+ }
35
+ dequeue(path) {
36
+ const path_str = path.join(".");
37
+ const queue = this.queue.get(path_str);
38
+ if (!queue) {
39
+ return undefined;
40
+ }
41
+ const elem = queue.shift();
42
+ this.queue.set(path_str, queue);
43
+ return elem;
44
+ }
45
+ queueSize(path) {
46
+ const path_str = path.join(".");
47
+ const queue = this.queue.get(path_str);
48
+ if (!queue) {
49
+ return 0;
50
+ }
51
+ return queue.length;
52
+ }
53
+ async startRun(worker, path, args) {
54
+ let rem = worker.worker;
55
+ path.forEach(p => rem = rem[p]);
56
+ worker.is_busy = true;
57
+ const ret = await rem(...args);
58
+ worker.is_busy = false;
59
+ return ret;
60
+ }
61
+ }
62
+ function createProxy(pool, path, target) {
63
+ const proxy = new Proxy(target, {
64
+ get(tgt, prop) {
65
+ return createProxy(pool, [...path, prop], () => { });
66
+ },
67
+ apply(tgt, this_arg, func_args) {
68
+ return new Promise((resolve, reject) => pool.call(path, func_args, resolve));
69
+ }
70
+ });
71
+ return proxy;
72
+ }
73
+ function createWorkerPool(workers, init) {
74
+ const pool = new WorkerPool_(workers, init);
75
+ return createProxy(pool, [], () => { });
76
+ }
77
+ export { createWorkerPool };
@@ -40,10 +40,13 @@ var readyPromise = new Promise((resolve, reject) => {
40
40
  // Determine the runtime environment we are in. You can customize this by
41
41
  // setting the ENVIRONMENT setting at compile time (see settings.js).
42
42
 
43
- var ENVIRONMENT_IS_WEB = true;
44
- var ENVIRONMENT_IS_WORKER = false;
45
- var ENVIRONMENT_IS_NODE = false;
46
- var ENVIRONMENT_IS_SHELL = false;
43
+ // Attempt to auto-detect the environment
44
+ var ENVIRONMENT_IS_WEB = typeof window == 'object';
45
+ var ENVIRONMENT_IS_WORKER = typeof importScripts == 'function';
46
+ // N.b. Electron.js environment is simultaneously a NODE-environment, but
47
+ // also a web environment.
48
+ var ENVIRONMENT_IS_NODE = typeof process == 'object' && typeof process.versions == 'object' && typeof process.versions.node == 'string';
49
+ var ENVIRONMENT_IS_SHELL = !ENVIRONMENT_IS_WEB && !ENVIRONMENT_IS_NODE && !ENVIRONMENT_IS_WORKER;
47
50
 
48
51
  if (Module['ENVIRONMENT']) {
49
52
  throw new Error('Module.ENVIRONMENT has been deprecated. To force the environment, use the ENVIRONMENT compile-time option (for example, -sENVIRONMENT=web or -sENVIRONMENT=node)');
@@ -114,7 +117,17 @@ if (ENVIRONMENT_IS_WEB || ENVIRONMENT_IS_WORKER) {
114
117
 
115
118
  {
116
119
  // include: web_or_worker_shell_read.js
117
- readAsync = (url) => {
120
+ if (ENVIRONMENT_IS_WORKER) {
121
+ readBinary = (url) => {
122
+ var xhr = new XMLHttpRequest();
123
+ xhr.open('GET', url, false);
124
+ xhr.responseType = 'arraybuffer';
125
+ xhr.send(null);
126
+ return new Uint8Array(/** @type{!ArrayBuffer} */(xhr.response));
127
+ };
128
+ }
129
+
130
+ readAsync = (url) => {
118
131
  assert(!isFileURI(url), "readAsync does not work with file:// URLs");
119
132
  return fetch(url, { credentials: 'same-origin' })
120
133
  .then((response) => {
@@ -177,8 +190,6 @@ var OPFS = 'OPFS is no longer included by default; build with -lopfs.js';
177
190
 
178
191
  var NODEFS = 'NODEFS is no longer included by default; build with -lnodefs.js';
179
192
 
180
- assert(!ENVIRONMENT_IS_WORKER, 'worker environment detected but not enabled at build time. Add `worker` to `-sENVIRONMENT` to enable.');
181
-
182
193
  assert(!ENVIRONMENT_IS_NODE, 'node environment detected but not enabled at build time. Add `node` to `-sENVIRONMENT` to enable.');
183
194
 
184
195
  assert(!ENVIRONMENT_IS_SHELL, 'shell environment detected but not enabled at build time. Add `shell` to `-sENVIRONMENT` to enable.');
@@ -2386,6 +2397,14 @@ function dbg(...args) {
2386
2397
 
2387
2398
  var __emval_new_array = () => Emval.toHandle([]);
2388
2399
 
2400
+ var __emval_new_array_from_memory_view = (view) => {
2401
+ view = Emval.toValue(view);
2402
+ // using for..loop is faster than Array.from
2403
+ var a = new Array(view.length);
2404
+ for (var i = 0; i < view.length; i++) a[i] = view[i];
2405
+ return Emval.toHandle(a);
2406
+ };
2407
+
2389
2408
 
2390
2409
  var __emval_new_cstring = (v) => Emval.toHandle(getStringOrSymbol(v));
2391
2410
 
@@ -2560,6 +2579,100 @@ function dbg(...args) {
2560
2579
  };
2561
2580
 
2562
2581
 
2582
+ var getCFunc = (ident) => {
2583
+ var func = Module['_' + ident]; // closure exported function
2584
+ assert(func, 'Cannot call unknown function ' + ident + ', make sure it is exported');
2585
+ return func;
2586
+ };
2587
+
2588
+ var writeArrayToMemory = (array, buffer) => {
2589
+ assert(array.length >= 0, 'writeArrayToMemory array must have a length (should be an array or typed array)')
2590
+ HEAP8.set(array, buffer);
2591
+ };
2592
+
2593
+
2594
+
2595
+ var stackAlloc = (sz) => __emscripten_stack_alloc(sz);
2596
+ var stringToUTF8OnStack = (str) => {
2597
+ var size = lengthBytesUTF8(str) + 1;
2598
+ var ret = stackAlloc(size);
2599
+ stringToUTF8(str, ret, size);
2600
+ return ret;
2601
+ };
2602
+
2603
+
2604
+
2605
+
2606
+
2607
+ /**
2608
+ * @param {string|null=} returnType
2609
+ * @param {Array=} argTypes
2610
+ * @param {Arguments|Array=} args
2611
+ * @param {Object=} opts
2612
+ */
2613
+ var ccall = (ident, returnType, argTypes, args, opts) => {
2614
+ // For fast lookup of conversion functions
2615
+ var toC = {
2616
+ 'string': (str) => {
2617
+ var ret = 0;
2618
+ if (str !== null && str !== undefined && str !== 0) { // null string
2619
+ // at most 4 bytes per UTF-8 code point, +1 for the trailing '\0'
2620
+ ret = stringToUTF8OnStack(str);
2621
+ }
2622
+ return ret;
2623
+ },
2624
+ 'array': (arr) => {
2625
+ var ret = stackAlloc(arr.length);
2626
+ writeArrayToMemory(arr, ret);
2627
+ return ret;
2628
+ }
2629
+ };
2630
+
2631
+ function convertReturnValue(ret) {
2632
+ if (returnType === 'string') {
2633
+
2634
+ return UTF8ToString(ret);
2635
+ }
2636
+ if (returnType === 'boolean') return Boolean(ret);
2637
+ return ret;
2638
+ }
2639
+
2640
+ var func = getCFunc(ident);
2641
+ var cArgs = [];
2642
+ var stack = 0;
2643
+ assert(returnType !== 'array', 'Return type should not be "array".');
2644
+ if (args) {
2645
+ for (var i = 0; i < args.length; i++) {
2646
+ var converter = toC[argTypes[i]];
2647
+ if (converter) {
2648
+ if (stack === 0) stack = stackSave();
2649
+ cArgs[i] = converter(args[i]);
2650
+ } else {
2651
+ cArgs[i] = args[i];
2652
+ }
2653
+ }
2654
+ }
2655
+ var ret = func(...cArgs);
2656
+ function onDone(ret) {
2657
+ if (stack !== 0) stackRestore(stack);
2658
+ return convertReturnValue(ret);
2659
+ }
2660
+
2661
+ ret = onDone(ret);
2662
+ return ret;
2663
+ };
2664
+
2665
+
2666
+
2667
+ /**
2668
+ * @param {string=} returnType
2669
+ * @param {Array=} argTypes
2670
+ * @param {Object=} opts
2671
+ */
2672
+ var cwrap = (ident, returnType, argTypes, opts) => {
2673
+ return (...args) => ccall(ident, returnType, argTypes, args, opts);
2674
+ };
2675
+
2563
2676
  var incrementExceptionRefcount = (ptr) => ___cxa_increment_exception_refcount(ptr);
2564
2677
  Module['incrementExceptionRefcount'] = incrementExceptionRefcount;
2565
2678
 
@@ -2570,7 +2683,6 @@ function dbg(...args) {
2570
2683
 
2571
2684
 
2572
2685
 
2573
- var stackAlloc = (sz) => __emscripten_stack_alloc(sz);
2574
2686
 
2575
2687
  var getExceptionMessageCommon = (ptr) => {
2576
2688
  var sp = stackSave();
@@ -2657,6 +2769,8 @@ var wasmImports = {
2657
2769
  /** @export */
2658
2770
  _emval_new_array: __emval_new_array,
2659
2771
  /** @export */
2772
+ _emval_new_array_from_memory_view: __emval_new_array_from_memory_view,
2773
+ /** @export */
2660
2774
  _emval_new_cstring: __emval_new_cstring,
2661
2775
  /** @export */
2662
2776
  _emval_new_object: __emval_new_object,
@@ -2825,6 +2939,8 @@ function invoke_j(index) {
2825
2939
  // include: postamble.js
2826
2940
  // === Auto-generated postamble setup entry stuff ===
2827
2941
 
2942
+ Module['ccall'] = ccall;
2943
+ Module['cwrap'] = cwrap;
2828
2944
  var missingLibrarySymbols = [
2829
2945
  'writeI53ToI64',
2830
2946
  'writeI53ToI64Clamped',
@@ -2873,9 +2989,6 @@ var missingLibrarySymbols = [
2873
2989
  'STACK_ALIGN',
2874
2990
  'POINTER_SIZE',
2875
2991
  'ASSERTIONS',
2876
- 'getCFunc',
2877
- 'ccall',
2878
- 'cwrap',
2879
2992
  'uleb128Encode',
2880
2993
  'sigToWasmTypes',
2881
2994
  'generateFuncType',
@@ -2895,8 +3008,6 @@ var missingLibrarySymbols = [
2895
3008
  'AsciiToString',
2896
3009
  'stringToAscii',
2897
3010
  'stringToNewUTF8',
2898
- 'stringToUTF8OnStack',
2899
- 'writeArrayToMemory',
2900
3011
  'registerKeyEventCallback',
2901
3012
  'maybeCStringToJsString',
2902
3013
  'findEventTarget',
@@ -3074,6 +3185,7 @@ var unexportedSymbols = [
3074
3185
  'dynCall',
3075
3186
  'wasmTable',
3076
3187
  'noExitRuntime',
3188
+ 'getCFunc',
3077
3189
  'freeTableIndexes',
3078
3190
  'functionsInTableMap',
3079
3191
  'setValue',
@@ -3093,6 +3205,8 @@ var unexportedSymbols = [
3093
3205
  'UTF32ToString',
3094
3206
  'stringToUTF32',
3095
3207
  'lengthBytesUTF32',
3208
+ 'stringToUTF8OnStack',
3209
+ 'writeArrayToMemory',
3096
3210
  'JSEvents',
3097
3211
  'specialHTMLTargets',
3098
3212
  'findCanvasEventTarget',
Binary file
@@ -1,10 +1,23 @@
1
1
  // TypeScript bindings for emscripten-generated code. Automatically generated at compile time.
2
2
  declare namespace RuntimeExports {
3
+ let HEAPU8: any;
3
4
  let HEAPF32: any;
4
5
  let HEAPF64: any;
6
+ /**
7
+ * @param {string|null=} returnType
8
+ * @param {Array=} argTypes
9
+ * @param {Arguments|Array=} args
10
+ * @param {Object=} opts
11
+ */
12
+ function ccall(ident: any, returnType?: (string | null) | undefined, argTypes?: any[] | undefined, args?: (IArguments | any[]) | undefined, opts?: any | undefined): any;
13
+ /**
14
+ * @param {string=} returnType
15
+ * @param {Array=} argTypes
16
+ * @param {Object=} opts
17
+ */
18
+ function cwrap(ident: any, returnType?: string | undefined, argTypes?: any[] | undefined, opts?: any | undefined): (...args: any[]) => any;
5
19
  let HEAP_DATA_VIEW: any;
6
20
  let HEAP8: any;
7
- let HEAPU8: any;
8
21
  let HEAP16: any;
9
22
  let HEAPU16: any;
10
23
  let HEAP32: any;
@@ -16,8 +29,8 @@ interface WasmModule {
16
29
  }
17
30
 
18
31
  interface EmbindModule {
19
- makeContoursFloat32(_0: any, _1: any, _2: any, _3: any, _4: any, _5: any): any;
20
- makeContoursFloat16(_0: any, _1: any, _2: any, _3: any, _4: any, _5: any): any;
32
+ makeContoursFloat32(_0: any, _1: any, _2: any, _3: any, _4: any): any;
33
+ makeContoursFloat16(_0: any, _1: any, _2: any, _3: any, _4: any): any;
21
34
  getContourLevelsFloat32(_0: any, _1: number, _2: number, _3: number): any;
22
35
  getContourLevelsFloat16(_0: any, _1: number, _2: number, _3: number): any;
23
36
  }
@@ -0,0 +1,21 @@
1
+ import { WGLBuffer, WGLTexture } from "autumn-wgl";
2
+ import { WebGLAnyRenderingContext } from "../AutumnTypes";
3
+ import { AbstractConstructor, Grid } from "./Grid";
4
+ interface AutoZoomGridIntf {
5
+ getWGLBillboardBuffers(gl: WebGLAnyRenderingContext, thin_fac: number, max_zoom: number): Promise<{
6
+ 'vertices': WGLBuffer;
7
+ 'texcoords': WGLBuffer;
8
+ }>;
9
+ getVectorRotationTexture(gl: WebGLAnyRenderingContext, data_are_earth_relative: boolean): {
10
+ 'rotation': WGLTexture;
11
+ };
12
+ getVectorRotationAtPoint(lon: number, lat: number): number;
13
+ getMinVisibleZoom(thin_fac: number): Uint8Array;
14
+ }
15
+ declare function autoZoomGridMixin<G extends AbstractConstructor<Grid>>(base: G): AbstractConstructor<AutoZoomGridIntf> & G;
16
+ /**
17
+ * Grids of this type can be used with wind barbs, observations, and anything that needs automatic thinning.
18
+ */
19
+ type AutoZoomGrid<T extends Grid = Grid> = InstanceType<ReturnType<typeof autoZoomGridMixin<AbstractConstructor<T>>>>;
20
+ export { autoZoomGridMixin };
21
+ export type { AutoZoomGrid, AutoZoomGridIntf };
@@ -0,0 +1,63 @@
1
+ import { WGLBuffer, WGLTexture } from "autumn-wgl";
2
+ import { Cache } from "../utils";
3
+ import { getGLFormatTypeAlignment, layer_worker } from "../PlotComponent";
4
+ import { Float16Array } from "@petamoriken/float16";
5
+ async function makeWGLBillboardBuffers(gl, grid, thin_fac, map_max_zoom) {
6
+ const { lats: field_lats, lons: field_lons } = grid.getEarthCoords();
7
+ const min_zoom = grid.getMinVisibleZoom(thin_fac);
8
+ const bb_elements = await layer_worker.makeBBElements(field_lats, field_lons, min_zoom, grid.ni, grid.nj, map_max_zoom);
9
+ const vertices = new WGLBuffer(gl, bb_elements['pts'], 2, gl.POINTS, { per_instance: true });
10
+ const texcoords = new WGLBuffer(gl, bb_elements['tex_coords'], 2, gl.POINTS, { per_instance: true });
11
+ return { 'vertices': vertices, 'texcoords': texcoords };
12
+ }
13
+ function makeVectorRotationTexture(gl, grid, data_are_earth_relative) {
14
+ const coords = grid.getEarthCoords();
15
+ const rot_vals = new Float16Array(grid.ni * grid.nj).fill(parseFloat('nan'));
16
+ if (data_are_earth_relative) {
17
+ rot_vals.fill(0);
18
+ }
19
+ else {
20
+ if (!grid.is_conformal) {
21
+ // If the grid is non-conformal, we need a fully general change of basis from grid coordinates to earth coordinates. This is not supported for now, so warn about it.
22
+ console.warn('Vector rotations for non-conformal projections are not supported. The output may look incorrect.');
23
+ }
24
+ for (let icd = 0; icd < coords.lats.length; icd++) {
25
+ const lon = coords.lons[icd];
26
+ const lat = coords.lats[icd];
27
+ rot_vals[icd] = grid.getVectorRotationAtPoint(lon, lat);
28
+ }
29
+ }
30
+ const { format, type, row_alignment } = getGLFormatTypeAlignment(gl, 'float16');
31
+ const rot_img = {
32
+ format: format, type: type, row_alignment: row_alignment, image: new Uint16Array(rot_vals.buffer),
33
+ width: grid.ni, height: grid.nj, mag_filter: gl.LINEAR
34
+ };
35
+ const rot_tex = new WGLTexture(gl, rot_img);
36
+ return { 'rotation': rot_tex };
37
+ }
38
+ function autoZoomGridMixin(base) {
39
+ class AutoZoomGrid extends base {
40
+ constructor(...args) {
41
+ super(...args);
42
+ this.billboard_buffer_cache = new Cache((gl, thin_fac, max_zoom) => {
43
+ return makeWGLBillboardBuffers(gl, this, thin_fac, max_zoom);
44
+ });
45
+ this.vector_rotation_cache = new Cache((gl, data_are_earth_relative) => {
46
+ return makeVectorRotationTexture(gl, this, data_are_earth_relative);
47
+ });
48
+ }
49
+ async getWGLBillboardBuffers(gl, thin_fac, max_zoom) {
50
+ return await this.billboard_buffer_cache.getValue(gl, thin_fac, max_zoom);
51
+ }
52
+ getVectorRotationTexture(gl, data_are_earth_relative) {
53
+ return this.vector_rotation_cache.getValue(gl, data_are_earth_relative);
54
+ }
55
+ getVectorRotationAtPoint(lon, lat) {
56
+ const [x, y] = this.transform(lon, lat);
57
+ const [x_pertlon, y_pertlon] = this.transform(lon + 0.01, lat);
58
+ return Math.atan2(y_pertlon - y, x_pertlon - x);
59
+ }
60
+ }
61
+ return AutoZoomGrid;
62
+ }
63
+ export { autoZoomGridMixin };
@@ -0,0 +1,14 @@
1
+ import { WGLBuffer } from "autumn-wgl";
2
+ import { WebGLAnyRenderingContext } from "../AutumnTypes";
3
+ import { AbstractConstructor, Grid } from "./Grid";
4
+ type DomainBuffers = {
5
+ vertices: WGLBuffer;
6
+ texcoords: WGLBuffer;
7
+ };
8
+ interface DomainBufferIntf {
9
+ getDomainBuffers(gl: WebGLAnyRenderingContext): Promise<DomainBuffers>;
10
+ }
11
+ declare function domainBufferMixin<G extends AbstractConstructor<Grid>>(base: G): AbstractConstructor<DomainBufferIntf> & G;
12
+ type DomainBufferGrid<T extends Grid = Grid> = InstanceType<ReturnType<typeof domainBufferMixin<AbstractConstructor<T>>>>;
13
+ export { domainBufferMixin };
14
+ export type { DomainBuffers, DomainBufferGrid, DomainBufferIntf };
@@ -0,0 +1,16 @@
1
+ import { Cache } from "../utils";
2
+ function domainBufferMixin(base) {
3
+ class DomainBufferMixin extends base {
4
+ constructor(...args) {
5
+ super(...args);
6
+ this.buffer_cache = new Cache((gl) => {
7
+ return this.makeDomainBuffers(gl);
8
+ });
9
+ }
10
+ async getDomainBuffers(gl) {
11
+ return await this.buffer_cache.getValue(gl);
12
+ }
13
+ }
14
+ return DomainBufferMixin;
15
+ }
16
+ export { domainBufferMixin };
@@ -0,0 +1,35 @@
1
+ import { WebGLAnyRenderingContext } from "../AutumnTypes";
2
+ import { StructuredGrid } from "./StructuredGrid";
3
+ declare const GeostationaryImage_base: import("./Grid").AbstractConstructor<import("./GridCoordinates").GridCoordinateIntf> & typeof StructuredGrid;
4
+ /**
5
+ * Grid for geostationary satellite images
6
+ *
7
+ * ## Plot Component Compatibility
8
+ * - :white_check_mark: `Fill`
9
+ * - :white_check_mark: `Raster`
10
+ * - :white_check_mark: `Contour`
11
+ * - :white_check_mark: `Paintball`
12
+ * - :x: `Barbs`
13
+ * - :x: `Hodographs`
14
+ * - :x: `StationPlot`
15
+ */
16
+ declare class GeostationaryImage extends GeostationaryImage_base {
17
+ readonly satellite_lon: number;
18
+ readonly ll_x: number;
19
+ readonly ll_y: number;
20
+ readonly ur_x: number;
21
+ readonly ur_y: number;
22
+ private readonly vpp;
23
+ constructor(ni: number, nj: number, ll_x: number, ll_y: number, ur_x: number, ur_y: number, satellite_lon: number, thin_x?: number, thin_y?: number);
24
+ protected makeDomainBuffers(gl: WebGLAnyRenderingContext): Promise<{
25
+ vertices: import("autumn-wgl").WGLBuffer;
26
+ texcoords: import("autumn-wgl").WGLBuffer;
27
+ }>;
28
+ transform(x: number, y: number, opts?: {
29
+ inverse?: boolean;
30
+ }): [number, number];
31
+ copy(): GeostationaryImage;
32
+ /** @internal */
33
+ getThinnedGrid(thin_fac: number, map_max_zoom: number): this;
34
+ }
35
+ export { GeostationaryImage };
@@ -0,0 +1,47 @@
1
+ import { geostationaryProjection } from "../Map";
2
+ import { gridCoordinateMixin } from "./GridCoordinates";
3
+ import { StructuredGrid, makeCartesianDomainBuffers } from "./StructuredGrid";
4
+ /**
5
+ * Grid for geostationary satellite images
6
+ *
7
+ * ## Plot Component Compatibility
8
+ * - :white_check_mark: `Fill`
9
+ * - :white_check_mark: `Raster`
10
+ * - :white_check_mark: `Contour`
11
+ * - :white_check_mark: `Paintball`
12
+ * - :x: `Barbs`
13
+ * - :x: `Hodographs`
14
+ * - :x: `StationPlot`
15
+ */
16
+ class GeostationaryImage extends gridCoordinateMixin(StructuredGrid) {
17
+ constructor(ni, nj, ll_x, ll_y, ur_x, ur_y, satellite_lon, thin_x, thin_y) {
18
+ super('geostationary', false, ni, nj, thin_x, thin_y);
19
+ this.satellite_lon = satellite_lon;
20
+ this.ll_x = ll_x;
21
+ this.ll_y = ll_y;
22
+ this.ur_x = ur_x;
23
+ this.ur_y = ur_y;
24
+ //this.vpp = verticalPerspective({lon_0: satellite_lon, lat_0: 0, alt: 35786023.0, a: 6378137.0, b: 6356752.31414});
25
+ this.vpp = geostationaryProjection({ lon_0: satellite_lon, alt: 35786023.0 + 6378137.0, a: 6378137.0, b: 6356752.31414 });
26
+ this.setupCoordinateCaches(ll_x, ur_x, ll_y, ur_y);
27
+ }
28
+ async makeDomainBuffers(gl) {
29
+ const simplify_ni = Math.max(Math.floor(this.ni / 20), 20);
30
+ const simplify_nj = Math.max(Math.floor(this.nj / 20), 20);
31
+ return await makeCartesianDomainBuffers(gl, this, simplify_ni, simplify_nj, { margin_r: false, margin_s: false });
32
+ }
33
+ transform(x, y, opts) {
34
+ opts = opts === undefined ? {} : opts;
35
+ const inverse = opts.inverse === undefined ? false : opts.inverse;
36
+ return this.vpp(x, y, { inverse: inverse });
37
+ }
38
+ copy() {
39
+ return new GeostationaryImage(this.ni, this.nj, this.ll_x, this.ll_y, this.ur_x, this.ur_y, this.satellite_lon);
40
+ }
41
+ /** @internal */
42
+ getThinnedGrid(thin_fac, map_max_zoom) {
43
+ const { ni, nj, thin_x, thin_y, ll_x, ll_y, ur_x, ur_y } = this.thinnedGridParameters(thin_fac, map_max_zoom, this.ll_x, this.ll_y, this.ur_x, this.ur_y);
44
+ return new GeostationaryImage(ni, nj, ll_x, ll_y, ur_x, ur_y, this.satellite_lon, this.thin_x * thin_x, this.thin_y * thin_y);
45
+ }
46
+ }
47
+ export { GeostationaryImage };
@@ -0,0 +1,36 @@
1
+ import { TypedArray } from "../AutumnTypes";
2
+ interface EarthCoords {
3
+ lons: Float32Array;
4
+ lats: Float32Array;
5
+ }
6
+ interface GridCoords {
7
+ x: Float32Array;
8
+ y: Float32Array;
9
+ }
10
+ type GridType = 'latlon' | 'latlonrot' | 'lcc' | 'unstructured' | 'radar' | 'geostationary';
11
+ declare const WGS84_SEMIMAJOR = 6378137;
12
+ declare const WGS84_SEMIMINOR = 6356752.314245;
13
+ /** The base class for grid types */
14
+ declare abstract class Grid {
15
+ readonly type: GridType;
16
+ readonly ni: number;
17
+ readonly nj: number;
18
+ readonly is_conformal: boolean;
19
+ constructor(type: GridType, is_conformal: boolean, ni: number, nj: number);
20
+ abstract getEarthCoords(): EarthCoords;
21
+ abstract getGridCoords(): GridCoords;
22
+ abstract transform(x: number, y: number, opts?: {
23
+ inverse?: boolean;
24
+ }): [number, number];
25
+ abstract sampleNearestGridPoint(lon: number, lat: number, ary: TypedArray): {
26
+ sample: number;
27
+ sample_lon: number;
28
+ sample_lat: number;
29
+ };
30
+ abstract getThinnedGrid(thin_fac: number, map_max_zoom: number): this;
31
+ abstract thinDataArray<ArrayType extends TypedArray>(original_grid: Grid, ary: ArrayType): ArrayType;
32
+ abstract copy(): Grid;
33
+ }
34
+ type AbstractConstructor<T> = abstract new (...args: any[]) => T;
35
+ export { Grid, WGS84_SEMIMAJOR, WGS84_SEMIMINOR };
36
+ export type { AbstractConstructor, EarthCoords, GridCoords, GridType };
@@ -0,0 +1,12 @@
1
+ const WGS84_SEMIMAJOR = 6378137.0;
2
+ const WGS84_SEMIMINOR = 6356752.314245;
3
+ /** The base class for grid types */
4
+ class Grid {
5
+ constructor(type, is_conformal, ni, nj) {
6
+ this.type = type;
7
+ this.is_conformal = is_conformal;
8
+ this.ni = ni;
9
+ this.nj = nj;
10
+ }
11
+ }
12
+ export { Grid, WGS84_SEMIMAJOR, WGS84_SEMIMINOR };
@@ -0,0 +1,10 @@
1
+ import { AbstractConstructor, EarthCoords, Grid, GridCoords } from "./Grid";
2
+ type GridElement = 'center' | 'edge';
3
+ interface GridCoordinateIntf {
4
+ setupCoordinateCaches(start_i: number, end_i: number, start_j: number, end_j: number): void;
5
+ getEarthCoords(ni?: number, nj?: number, which_i?: GridElement, which_j?: GridElement): EarthCoords;
6
+ getGridCoords(): GridCoords;
7
+ }
8
+ declare function gridCoordinateMixin<G extends AbstractConstructor<Grid>>(base: G): AbstractConstructor<GridCoordinateIntf> & G;
9
+ export { gridCoordinateMixin };
10
+ export type { GridElement, GridCoordinateIntf };
@@ -0,0 +1,64 @@
1
+ import { Cache } from "../utils";
2
+ function gridCoordinateMixin(base) {
3
+ class GridCoordinates extends base {
4
+ constructor() {
5
+ super(...arguments);
6
+ this.ll_cache = null;
7
+ this.gc_cache = null;
8
+ }
9
+ setupCoordinateCaches(start_i, end_i, start_j, end_j) {
10
+ const di = (end_i - start_i) / (this.ni - 1);
11
+ const dj = (end_j - start_j) / (this.nj - 1);
12
+ this.ll_cache = new Cache((ni, nj, which_i, which_j) => {
13
+ const ni_grid = which_i == 'center' ? ni : ni + 1;
14
+ const nj_grid = which_j == 'center' ? nj : nj + 1;
15
+ const ni_grid_full = which_i == 'center' ? this.ni : this.ni + 1;
16
+ const nj_grid_full = which_j == 'center' ? this.nj : this.nj + 1;
17
+ const ni_offset = which_i == 'center' ? 0 : -di / 2;
18
+ const nj_offset = which_j == 'center' ? 0 : -dj / 2;
19
+ const lons = new Float32Array(ni_grid * nj_grid);
20
+ const lats = new Float32Array(ni_grid * nj_grid);
21
+ const di_req = (ni_grid_full - 1) / (ni_grid - 1) * di;
22
+ const dj_req = (nj_grid_full - 1) / (nj_grid - 1) * dj;
23
+ for (let i = 0; i < ni_grid; i++) {
24
+ const x = start_i + i * di_req + ni_offset;
25
+ for (let j = 0; j < nj_grid; j++) {
26
+ const y = start_j + j * dj_req + nj_offset;
27
+ const [lon, lat] = this.transform(x, y, { inverse: true });
28
+ const idx = i + j * ni_grid;
29
+ lons[idx] = lon;
30
+ lats[idx] = lat;
31
+ }
32
+ }
33
+ return { lons: lons, lats: lats };
34
+ });
35
+ this.gc_cache = new Cache(() => {
36
+ const x = new Float32Array(this.ni);
37
+ const y = new Float32Array(this.nj);
38
+ for (let i = 0; i < this.ni; i++) {
39
+ x[i] = start_i + i * di;
40
+ }
41
+ for (let j = 0; j < this.nj; j++) {
42
+ y[j] = start_j + j * dj;
43
+ }
44
+ return { x: x, y: y };
45
+ });
46
+ }
47
+ getEarthCoords(ni, nj, which_i, which_j) {
48
+ if (this.ll_cache === null)
49
+ throw "Need to set up coordinate caches first";
50
+ ni = ni === undefined ? this.ni : ni;
51
+ nj = nj === undefined ? this.nj : nj;
52
+ which_i = which_i === undefined ? 'center' : which_i;
53
+ which_j = which_j === undefined ? 'center' : which_j;
54
+ return this.ll_cache.getValue(ni, nj, which_i, which_j);
55
+ }
56
+ getGridCoords() {
57
+ if (this.gc_cache === null)
58
+ throw "Need to set up coordinate caches first";
59
+ return this.gc_cache.getValue();
60
+ }
61
+ }
62
+ return GridCoordinates;
63
+ }
64
+ export { gridCoordinateMixin };