autumnplot-gl 3.2.0 → 4.0.0-beta

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 (48) hide show
  1. package/lib/AutumnTypes.d.ts +53 -5
  2. package/lib/AutumnTypes.js +25 -1
  3. package/lib/Barbs.d.ts +6 -5
  4. package/lib/BillboardCollection.d.ts +8 -7
  5. package/lib/BillboardCollection.js +69 -58
  6. package/lib/Color.d.ts +1 -0
  7. package/lib/Color.js +3 -0
  8. package/lib/ColorBar.d.ts +10 -0
  9. package/lib/ColorBar.js +4 -2
  10. package/lib/Colormap.js +8 -8
  11. package/lib/Contour.d.ts +18 -8
  12. package/lib/Contour.js +17 -54
  13. package/lib/ContourCreator.d.ts +4 -0
  14. package/lib/ContourCreator.js +2 -1
  15. package/lib/Fill.d.ts +26 -14
  16. package/lib/Fill.js +97 -50
  17. package/lib/Grid.d.ts +124 -29
  18. package/lib/Grid.js +297 -94
  19. package/lib/Hodographs.d.ts +9 -8
  20. package/lib/Hodographs.js +14 -11
  21. package/lib/Map.js +1 -1
  22. package/lib/Paintball.d.ts +6 -5
  23. package/lib/Paintball.js +35 -30
  24. package/lib/ParticleTracer.d.ts +19 -0
  25. package/lib/ParticleTracer.js +37 -0
  26. package/lib/PlotComponent.d.ts +6 -7
  27. package/lib/PlotComponent.js +8 -3
  28. package/lib/PlotLayer.d.ts +3 -3
  29. package/lib/PlotLayer.worker.d.ts +1 -2
  30. package/lib/PlotLayer.worker.js +15 -50
  31. package/lib/PolylineCollection.d.ts +5 -3
  32. package/lib/PolylineCollection.js +60 -37
  33. package/lib/RawField.d.ts +76 -23
  34. package/lib/RawField.js +138 -29
  35. package/lib/ShaderManager.d.ts +12 -0
  36. package/lib/ShaderManager.js +58 -0
  37. package/lib/StationPlot.d.ts +136 -25
  38. package/lib/StationPlot.js +192 -60
  39. package/lib/TextCollection.d.ts +9 -6
  40. package/lib/TextCollection.js +94 -62
  41. package/lib/cpp/marchingsquares.js +483 -585
  42. package/lib/cpp/marchingsquares.wasm +0 -0
  43. package/lib/cpp/marchingsquares_embind.d.ts +23 -3
  44. package/lib/index.d.ts +4 -3
  45. package/lib/index.js +4 -3
  46. package/lib/utils.d.ts +4 -1
  47. package/lib/utils.js +12 -1
  48. package/package.json +2 -2
@@ -1,7 +1,5 @@
1
1
  import { Float16Array } from "@petamoriken/float16";
2
2
  interface WindProfile {
3
- lat: number;
4
- lon: number;
5
3
  jlat: number;
6
4
  ilon: number;
7
5
  smu: number;
@@ -34,7 +32,57 @@ type Polyline = {
34
32
  };
35
33
  type WebGLAnyRenderingContext = WebGLRenderingContext | WebGL2RenderingContext;
36
34
  declare function isWebGL2Ctx(gl: WebGLAnyRenderingContext): gl is WebGL2RenderingContext;
37
- type TypedArray = Float16Array | Float32Array;
35
+ type TypedArray = Float16Array | Float32Array | Uint8Array;
36
+ type TypedArrayStr = 'float16' | 'float32' | 'uint8';
38
37
  type ContourData = Record<number, [number, number][][]>;
39
- export { isWebGL2Ctx };
40
- export type { WindProfile, BillboardSpec, Polyline, LineData, WebGLAnyRenderingContext, TypedArray, ContourData };
38
+ type mat4 = number[] | Float32Array | Float64Array;
39
+ type RenderShaderData = {
40
+ vertexShaderPrelude: string;
41
+ define: string;
42
+ variantName: string;
43
+ };
44
+ type MapLibreRendererDataProjection = {
45
+ clippingPlane: [number, number, number, number];
46
+ fallbackMatrix: mat4;
47
+ mainMatrix: mat4;
48
+ projectionTransition: number;
49
+ tileMercatorCoords: [number, number, number, number];
50
+ };
51
+ type MapLibreRendererDataShader = RenderShaderData;
52
+ type MapLibreRendererData = {
53
+ defaultProjectionData: MapLibreRendererDataProjection;
54
+ farZ: number;
55
+ fov: number;
56
+ modelViewProjectionMatrix: mat4;
57
+ nearZ: number;
58
+ projectionMatrix: mat4;
59
+ shaderData: MapLibreRendererDataShader;
60
+ };
61
+ type RenderMethodArg = mat4 | MapLibreRendererData;
62
+ type RendererDataProjection = {
63
+ clippingPlane: number[];
64
+ fallbackMatrix: number[];
65
+ mainMatrix: number[];
66
+ projectionTransition: number;
67
+ tileMercatorCoords: number[];
68
+ };
69
+ type RendererDataShader = RenderShaderData;
70
+ type RendererDataMapLibre = {
71
+ type: 'maplibre';
72
+ defaultProjectionData: RendererDataProjection;
73
+ farZ: number;
74
+ fov: number;
75
+ modelViewProjectionMatrix: number[];
76
+ nearZ: number;
77
+ projectionMatrix: number[];
78
+ shaderData: RendererDataShader;
79
+ };
80
+ type RendererDataAutumn = {
81
+ type: 'autumn';
82
+ mainMatrix: number[];
83
+ shaderData: null;
84
+ };
85
+ type RendererData = RendererDataMapLibre | RendererDataAutumn;
86
+ declare function getRendererData(arg: RenderMethodArg): RendererData;
87
+ export { isWebGL2Ctx, getRendererData };
88
+ export type { WindProfile, BillboardSpec, Polyline, LineData, WebGLAnyRenderingContext, TypedArray, TypedArrayStr, ContourData, RenderMethodArg, RendererData, RenderShaderData };
@@ -1,4 +1,28 @@
1
1
  function isWebGL2Ctx(gl) {
2
2
  return gl.getParameter(gl.VERSION).includes('WebGL 2.0');
3
3
  }
4
- export { isWebGL2Ctx };
4
+ function isMapLibreRenderArg(obj) {
5
+ return 'modelViewProjectionMatrix' in obj && 'defaultProjectionData' in obj && 'mainMatrix' in obj.defaultProjectionData;
6
+ }
7
+ function getRendererData(arg) {
8
+ if (isMapLibreRenderArg(arg)) {
9
+ return {
10
+ type: 'maplibre',
11
+ defaultProjectionData: {
12
+ clippingPlane: [...arg.defaultProjectionData.clippingPlane],
13
+ fallbackMatrix: [...arg.defaultProjectionData.fallbackMatrix],
14
+ mainMatrix: [...arg.defaultProjectionData.mainMatrix],
15
+ projectionTransition: arg.defaultProjectionData.projectionTransition,
16
+ tileMercatorCoords: [...arg.defaultProjectionData.tileMercatorCoords]
17
+ },
18
+ farZ: arg.farZ,
19
+ fov: arg.fov,
20
+ modelViewProjectionMatrix: [...arg.modelViewProjectionMatrix],
21
+ nearZ: arg.nearZ,
22
+ projectionMatrix: [...arg.projectionMatrix],
23
+ shaderData: arg.shaderData
24
+ };
25
+ }
26
+ return { type: 'autumn', mainMatrix: [...arg], shaderData: null };
27
+ }
28
+ export { isWebGL2Ctx, getRendererData };
package/lib/Barbs.d.ts CHANGED
@@ -1,8 +1,9 @@
1
1
  import { PlotComponent } from "./PlotComponent";
2
2
  import { RawVectorField } from "./RawField";
3
3
  import { MapLikeType } from "./Map";
4
- import { TypedArray, WebGLAnyRenderingContext } from "./AutumnTypes";
4
+ import { RenderMethodArg, TypedArray, WebGLAnyRenderingContext } from "./AutumnTypes";
5
5
  import { ColorMap } from "./Colormap";
6
+ import { Grid } from "./Grid";
6
7
  interface BarbsOptions {
7
8
  /**
8
9
  * The color to use for the barbs as a hex color string;.
@@ -38,7 +39,7 @@ interface BarbsOptions {
38
39
  * const vector_field = new RawVectorField(grid, u_data, v_data);
39
40
  * const barbs = new Barbs(vector_field, {color: '#000000', thin_fac: 16});
40
41
  */
41
- declare class Barbs<ArrayType extends TypedArray, MapType extends MapLikeType> extends PlotComponent<MapType> {
42
+ declare class Barbs<ArrayType extends TypedArray, GridType extends Grid, MapType extends MapLikeType> extends PlotComponent<MapType> {
42
43
  /** The vector field */
43
44
  private fields;
44
45
  readonly opts: Required<BarbsOptions>;
@@ -50,12 +51,12 @@ declare class Barbs<ArrayType extends TypedArray, MapType extends MapLikeType> e
50
51
  * @param fields - The vector field to plot as barbs
51
52
  * @param opts - Options for creating the wind barbs
52
53
  */
53
- constructor(fields: RawVectorField<ArrayType>, opts: BarbsOptions);
54
+ constructor(fields: RawVectorField<ArrayType, GridType>, opts: BarbsOptions);
54
55
  /**
55
56
  * Update the field displayed as barbs
56
57
  * @param fields - The new field to display as barbs
57
58
  */
58
- updateField(fields: RawVectorField<ArrayType>): Promise<void>;
59
+ updateField(fields: RawVectorField<ArrayType, GridType>): Promise<void>;
59
60
  /**
60
61
  * @internal
61
62
  * Add the barb field to a map
@@ -65,7 +66,7 @@ declare class Barbs<ArrayType extends TypedArray, MapType extends MapLikeType> e
65
66
  * @internal
66
67
  * Render the barb field
67
68
  */
68
- render(gl: WebGLAnyRenderingContext, matrix: number[] | Float32Array): void;
69
+ render(gl: WebGLAnyRenderingContext, matrix: RenderMethodArg): void;
69
70
  }
70
71
  export default Barbs;
71
72
  export type { BarbsOptions };
@@ -1,28 +1,29 @@
1
- import { BillboardSpec, TypedArray, WebGLAnyRenderingContext } from "./AutumnTypes";
1
+ import { BillboardSpec, RenderMethodArg, TypedArray, WebGLAnyRenderingContext } from "./AutumnTypes";
2
2
  import { Color } from "./Color";
3
3
  import { ColorMap } from "./Colormap";
4
+ import { Grid } from "./Grid";
4
5
  import { RawVectorField } from "./RawField";
5
6
  import { WGLTextureSpec } from "autumn-wgl";
6
7
  interface BillboardCollectionOpts {
7
8
  color?: Color;
8
9
  cmap?: ColorMap;
10
+ rotate_with_map?: boolean;
9
11
  }
10
- declare class BillboardCollection<ArrayType extends TypedArray> {
12
+ declare class BillboardCollection<ArrayType extends TypedArray, GridType extends Grid> {
11
13
  private field;
12
14
  readonly spec: BillboardSpec;
13
15
  readonly color: Color;
14
16
  readonly cmap: ColorMap | null;
17
+ readonly rotate_with_map: boolean;
15
18
  readonly size_multiplier: number;
16
19
  readonly thin_fac: number;
17
20
  readonly max_zoom: number;
18
21
  readonly billboard_image: WGLTextureSpec;
19
22
  private gl_elems;
20
23
  private wind_textures;
21
- private readonly trim_inaccessible;
22
- private show_field;
23
- constructor(field: RawVectorField<ArrayType>, thin_fac: number, max_zoom: number, billboard_image: WGLTextureSpec, billboard_spec: BillboardSpec, billboard_size_mult: number, opts?: BillboardCollectionOpts);
24
- updateField(field: RawVectorField<ArrayType>): void;
24
+ constructor(field: RawVectorField<ArrayType, GridType>, thin_fac: number, max_zoom: number, billboard_image: WGLTextureSpec, billboard_spec: BillboardSpec, billboard_size_mult: number, opts?: BillboardCollectionOpts);
25
+ updateField(field: RawVectorField<ArrayType, GridType>): void;
25
26
  setup(gl: WebGLAnyRenderingContext): Promise<void>;
26
- render(gl: WebGLAnyRenderingContext, matrix: number[] | Float32Array, [map_width, map_height]: [number, number], map_zoom: number, map_bearing: number, map_pitch: number): void;
27
+ render(gl: WebGLAnyRenderingContext, arg: RenderMethodArg, [map_width, map_height]: [number, number], map_zoom: number, map_bearing: number, map_pitch: number): void;
27
28
  }
28
29
  export { BillboardCollection };
@@ -1,29 +1,31 @@
1
+ import { getRendererData } from "./AutumnTypes";
1
2
  import { Color } from "./Color";
2
3
  import { ColorMapGPUInterface } from "./Colormap";
3
- import { getGLFormatTypeAlignment } from "./PlotComponent";
4
- import { WGLProgram, WGLTexture } from "autumn-wgl";
5
- const billboard_vertex_shader_src = `uniform mat4 u_matrix;
4
+ import { WGLBuffer, WGLTexture } from "autumn-wgl";
5
+ import { ShaderProgramManager } from "./ShaderManager";
6
+ const billboard_vertex_shader_src = `#version 300 es
7
+
6
8
  uniform int u_offset;
7
9
 
8
- attribute vec3 a_pos;
9
- attribute vec2 a_tex_coord;
10
+ in vec2 a_pos;
11
+ in vec2 a_tex_coord;
12
+ in lowp float a_geom;
10
13
  uniform lowp float u_bb_size;
11
14
  uniform lowp float u_map_aspect;
12
15
  uniform lowp float u_zoom;
13
- uniform highp float u_map_bearing;
14
16
  uniform lowp float u_bb_width;
15
17
  uniform lowp float u_bb_height;
16
18
  uniform highp float u_bb_mag_bin_size;
17
-
18
19
  uniform highp float u_bb_mag_wrap;
20
+ uniform int u_rotate_with_map;
19
21
 
20
22
  uniform sampler2D u_u_sampler;
21
23
  uniform sampler2D u_v_sampler;
22
24
  uniform sampler2D u_rot_sampler;
23
25
 
24
- varying highp vec2 v_tex_coord;
26
+ out highp vec2 v_tex_coord;
25
27
  #ifdef COLORMAP
26
- varying highp float v_mag;
28
+ out highp float v_mag;
27
29
  #endif
28
30
 
29
31
  mat4 scalingMatrix(float x_scale, float y_scale, float z_scale) {
@@ -57,14 +59,27 @@ void main() {
57
59
  float globe_width = 1.;
58
60
  vec2 globe_offset = vec2(globe_width * float(u_offset), 0.);
59
61
 
60
- vec4 pivot_pos = u_matrix * vec4(a_pos.xy + globe_offset, 0.0, 1.0);
61
- highp float zoom_corner = a_pos.z;
62
- lowp float min_zoom = floor(zoom_corner / 4.0);
63
- lowp float corner = mod(zoom_corner, 4.0);
62
+ mat4 map_stretch_matrix = scalingMatrix(1.0, 1. / u_map_aspect, 1.0);
63
+
64
+ vec4 pivot_pos = projectTile(a_pos.xy + globe_offset);
65
+ float globe_rotation = 0.0;
66
+
67
+ if (u_rotate_with_map == 1) {
68
+ vec4 pivot_pos_ihat = projectTile(a_pos.xy + globe_offset + vec2(1e-5, 0.));
69
+
70
+ vec2 pivot_east = normalize((inverse(map_stretch_matrix) * (pivot_pos_ihat - pivot_pos)).xy);
71
+ globe_rotation = atan(pivot_east.x, pivot_east.y) - 3.141592654 / 2.0;
72
+ }
64
73
 
65
- highp float u = texture2D(u_u_sampler, a_tex_coord).r;
66
- highp float v = texture2D(u_v_sampler, a_tex_coord).r;
67
- highp float rot = texture2D(u_rot_sampler, a_tex_coord).r;
74
+ highp float min_zoom = floor(a_tex_coord.x);
75
+ lowp float corner = a_geom;
76
+
77
+ vec2 data_texcoord = a_tex_coord;
78
+ data_texcoord.x = fract(data_texcoord.x);
79
+
80
+ highp float u = texture(u_u_sampler, data_texcoord).r;
81
+ highp float v = texture(u_v_sampler, data_texcoord).r;
82
+ highp float rot = texture(u_rot_sampler, data_texcoord).r;
68
83
 
69
84
  lowp float bb_aspect = u_bb_width / u_bb_height;
70
85
  lowp float ang = (abs(u) < 1e-6 && abs(v) < 1e-6) ? 0. : atan(v, u) - 3.141592654 / 2.0;
@@ -98,26 +113,29 @@ void main() {
98
113
  texcoord = tex_loc + vec2(u_bb_width, u_bb_height);
99
114
  }
100
115
 
101
- mat4 barb_rotation = rotationZMatrix(ang + radians(u_map_bearing) - rot);
102
- mat4 map_stretch_matrix = scalingMatrix(1.0, 1. / u_map_aspect, 1.0);
116
+ mat4 barb_rotation = rotationZMatrix(ang - globe_rotation - rot);
103
117
  offset = map_stretch_matrix * barb_rotation * offset;
104
118
  }
105
119
 
106
120
  gl_Position = pivot_pos + offset;
107
121
  v_tex_coord = texcoord;
108
122
  }`
109
- const billboard_fragment_shader_src = `varying highp vec2 v_tex_coord;
123
+ const billboard_fragment_shader_src = `#version 300 es
124
+
125
+ in highp vec2 v_tex_coord;
110
126
 
111
127
  #ifdef COLORMAP
112
- varying highp float v_mag;
128
+ in highp float v_mag;
113
129
  #else
114
130
  uniform lowp vec4 u_bb_color;
115
131
  #endif
116
132
 
117
133
  uniform sampler2D u_sampler;
118
134
 
135
+ out highp vec4 fragColor;
136
+
119
137
  void main() {
120
- lowp vec4 tex_color = texture2D(u_sampler, v_tex_coord);
138
+ lowp vec4 tex_color = texture(u_sampler, v_tex_coord);
121
139
 
122
140
  lowp vec4 color;
123
141
  #ifdef COLORMAP
@@ -127,13 +145,14 @@ void main() {
127
145
  #endif
128
146
 
129
147
  color.a *= tex_color.a;
130
- gl_FragColor = color;
148
+ fragColor = color;
131
149
  }`
132
150
  class BillboardCollection {
133
151
  constructor(field, thin_fac, max_zoom, billboard_image, billboard_spec, billboard_size_mult, opts) {
134
152
  opts = opts === undefined ? {} : opts;
135
153
  this.color = opts.color === undefined ? new Color([0, 0, 0, 1]) : opts.color;
136
154
  this.cmap = opts.cmap === undefined ? null : opts.cmap;
155
+ this.rotate_with_map = opts.rotate_with_map === undefined ? true : opts.rotate_with_map;
137
156
  this.field = field;
138
157
  this.spec = billboard_spec;
139
158
  this.size_multiplier = billboard_size_mult;
@@ -142,28 +161,14 @@ class BillboardCollection {
142
161
  this.billboard_image = billboard_image;
143
162
  this.gl_elems = null;
144
163
  this.wind_textures = null;
145
- const n_density_tiers = Math.log2(thin_fac);
146
- const n_inaccessible_tiers = Math.max(n_density_tiers + 1 - max_zoom, 0);
147
- this.trim_inaccessible = Math.pow(2, n_inaccessible_tiers);
148
- this.show_field = true;
149
164
  }
150
165
  updateField(field) {
151
166
  this.field = field;
152
167
  if (this.gl_elems === null)
153
168
  return;
154
169
  const gl = this.gl_elems.gl;
155
- const data = this.field.getThinnedField(this.trim_inaccessible, this.trim_inaccessible);
156
- const { u: u_thin, v: v_thin } = data.getTextureData();
157
- this.show_field = u_thin !== null;
158
- const { format, type, row_alignment } = getGLFormatTypeAlignment(gl, !(u_thin instanceof Float32Array));
159
- const u_image = { 'format': format, 'type': type,
160
- 'width': data.grid.ni, 'height': data.grid.nj, 'image': u_thin,
161
- 'mag_filter': gl.NEAREST, 'row_alignment': row_alignment,
162
- };
163
- const v_image = { 'format': format, 'type': type,
164
- 'width': data.grid.ni, 'height': data.grid.nj, 'image': v_thin,
165
- 'mag_filter': gl.NEAREST, 'row_alignment': row_alignment,
166
- };
170
+ const data = this.field.getThinnedField(this.thin_fac, this.max_zoom);
171
+ const { u: u_image, v: v_image } = data.getWGLTextureSpecs(gl, gl.NEAREST);
167
172
  if (this.wind_textures === null) {
168
173
  this.wind_textures = { u: new WGLTexture(gl, u_image), v: new WGLTexture(gl, v_image) };
169
174
  }
@@ -173,9 +178,11 @@ class BillboardCollection {
173
178
  }
174
179
  }
175
180
  async setup(gl) {
176
- const thinned_field = this.field.getThinnedField(this.trim_inaccessible, this.trim_inaccessible);
177
- const { vertices, texcoords } = await thinned_field.grid.getWGLBillboardBuffers(gl, this.thin_fac / this.trim_inaccessible, this.max_zoom);
178
- const { rotation: proj_rotation_tex } = thinned_field.grid.getVectorRotationTexture(gl);
181
+ const thinned_grid = this.field.grid.getThinnedGrid(this.thin_fac, this.max_zoom);
182
+ const geom_verts = new Float32Array([0., 1., 2., 3.]);
183
+ const geom_buffer = new WGLBuffer(gl, geom_verts, 1, gl.TRIANGLE_STRIP);
184
+ const { vertices, texcoords } = await thinned_grid.getWGLBillboardBuffers(gl, this.thin_fac, this.max_zoom);
185
+ const { rotation: proj_rotation_tex } = thinned_grid.getVectorRotationTexture(gl, this.field.relative_to == 'earth');
179
186
  const texture = new WGLTexture(gl, this.billboard_image);
180
187
  const shader_defines = [];
181
188
  let fragment_src = billboard_fragment_shader_src;
@@ -186,36 +193,40 @@ class BillboardCollection {
186
193
  cmap_gpu.setupShaderVariables(gl, gl.NEAREST);
187
194
  shader_defines.push('COLORMAP');
188
195
  }
189
- const program = new WGLProgram(gl, billboard_vertex_shader_src, fragment_src, { define: shader_defines });
190
- this.gl_elems = { gl: gl, program: program, vertices: vertices, texcoords: texcoords, texture: texture, proj_rot_texture: proj_rotation_tex, cmap_gpu: cmap_gpu };
196
+ const shader_manager = new ShaderProgramManager(billboard_vertex_shader_src, fragment_src, shader_defines);
197
+ this.gl_elems = { gl: gl, shader_manager: shader_manager, geom_vertices: geom_buffer, vertices: vertices, texcoords: texcoords, texture: texture,
198
+ proj_rot_texture: proj_rotation_tex, cmap_gpu: cmap_gpu };
191
199
  }
192
- render(gl, matrix, [map_width, map_height], map_zoom, map_bearing, map_pitch) {
193
- if (this.gl_elems === null || this.wind_textures === null || !this.show_field)
200
+ render(gl, arg, [map_width, map_height], map_zoom, map_bearing, map_pitch) {
201
+ if (this.gl_elems === null || this.wind_textures === null)
194
202
  return;
195
- if (matrix instanceof Float32Array)
196
- matrix = [...matrix];
203
+ const render_data = getRendererData(arg);
204
+ const program = this.gl_elems.shader_manager.getShaderProgram(gl, render_data.shaderData);
197
205
  const gl_elems = this.gl_elems;
198
206
  const bb_size = this.spec.BB_HEIGHT * (map_height / map_width) * this.size_multiplier;
199
207
  const bb_width = this.spec.BB_WIDTH / this.spec.BB_TEX_WIDTH;
200
208
  const bb_height = this.spec.BB_HEIGHT / this.spec.BB_TEX_HEIGHT;
201
- gl_elems.program.use({ 'a_pos': gl_elems.vertices, 'a_tex_coord': gl_elems.texcoords }, { 'u_bb_size': bb_size, 'u_bb_width': bb_width, 'u_bb_height': bb_height,
209
+ program.use({ 'a_geom': gl_elems.geom_vertices, 'a_pos': gl_elems.vertices, 'a_tex_coord': gl_elems.texcoords }, { 'u_bb_size': bb_size, 'u_bb_width': bb_width, 'u_bb_height': bb_height,
202
210
  'u_bb_mag_bin_size': this.spec.BB_MAG_BIN_SIZE, 'u_bb_mag_wrap': this.spec.BB_MAG_WRAP, 'u_offset': 0,
203
- 'u_matrix': matrix, 'u_map_aspect': map_height / map_width, 'u_zoom': map_zoom, 'u_map_bearing': map_bearing }, { 'u_sampler': gl_elems.texture, 'u_u_sampler': this.wind_textures.u, 'u_v_sampler': this.wind_textures.v, 'u_rot_sampler': gl_elems.proj_rot_texture });
211
+ 'u_map_aspect': map_height / map_width, 'u_zoom': map_zoom, 'u_rotate_with_map': this.rotate_with_map ? 1 : 0,
212
+ ...this.gl_elems.shader_manager.getShaderUniforms(render_data) }, { 'u_sampler': gl_elems.texture, 'u_u_sampler': this.wind_textures.u, 'u_v_sampler': this.wind_textures.v, 'u_rot_sampler': gl_elems.proj_rot_texture });
204
213
  if (gl_elems.cmap_gpu !== null) {
205
- gl_elems.cmap_gpu.bindShaderVariables(gl_elems.program);
214
+ gl_elems.cmap_gpu.bindShaderVariables(program);
206
215
  }
207
216
  else {
208
- gl_elems.program.setUniforms({ 'u_bb_color': this.color.toRGBATuple() });
217
+ program.setUniforms({ 'u_bb_color': this.color.toRGBATuple() });
209
218
  }
210
219
  gl.enable(gl.BLEND);
211
220
  gl.blendFuncSeparate(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA, gl.ONE, gl.ONE_MINUS_SRC_ALPHA);
212
- gl_elems.program.draw();
213
- gl_elems.program.setUniforms({ 'u_offset': -2 });
214
- gl_elems.program.draw();
215
- gl_elems.program.setUniforms({ 'u_offset': -1 });
216
- gl_elems.program.draw();
217
- gl_elems.program.setUniforms({ 'u_offset': 1 });
218
- gl_elems.program.draw();
221
+ program.draw();
222
+ if (render_data.type != 'maplibre' || !render_data.shaderData.define.includes('GLOBE')) {
223
+ program.setUniforms({ 'u_offset': -2 });
224
+ program.draw();
225
+ program.setUniforms({ 'u_offset': -1 });
226
+ program.draw();
227
+ program.setUniforms({ 'u_offset': 1 });
228
+ program.draw();
229
+ }
219
230
  }
220
231
  }
221
232
  export { BillboardCollection };
package/lib/Color.d.ts CHANGED
@@ -52,5 +52,6 @@ declare class Color {
52
52
  * @returns a new Color object
53
53
  */
54
54
  static fromHSVTuple(hsv: [number, number, number]): Color;
55
+ static normalizeColor(color: Color | string): Color;
55
56
  }
56
57
  export { Color };
package/lib/Color.js CHANGED
@@ -156,5 +156,8 @@ class Color {
156
156
  const rgb = hsv2rgb(hsv);
157
157
  return new Color([rgb[0], rgb[1], rgb[2], 1]);
158
158
  }
159
+ static normalizeColor(color) {
160
+ return color instanceof Color ? color : Color.fromHex(color);
161
+ }
159
162
  }
160
163
  export { Color };
package/lib/ColorBar.d.ts CHANGED
@@ -5,6 +5,16 @@ type ColorbarTickDirection = 'top' | 'bottom' | 'left' | 'right';
5
5
  interface ColorBarOptions {
6
6
  /** The label to place along the color bar */
7
7
  label?: string;
8
+ /**
9
+ * The size in pixels along the long axis of the colorbar
10
+ * @default 600
11
+ */
12
+ size_long?: number;
13
+ /**
14
+ * The size in pixels along the short axis of the colorbar
15
+ * @default size_long / 9
16
+ */
17
+ size_short?: number;
8
18
  /**
9
19
  * An array of numbers to use as the tick locations.
10
20
  * @default Use all the levels in the color map provided to {@link makeColorBar}.
package/lib/ColorBar.js CHANGED
@@ -30,6 +30,8 @@ function makeColorBar(colormap, opts) {
30
30
  const orientation = opts.orientation || 'vertical';
31
31
  const fontface = opts.fontface || 'sans-serif';
32
32
  const tickfontsize = opts.ticklabelsize || 12;
33
+ const size_long = opts.size_long || 600;
34
+ const size_short = opts.size_short || size_long / 9;
33
35
  const tick_dir = opts.tick_direction || (orientation == 'vertical' ? 'left' : 'bottom');
34
36
  if (orientation == 'vertical' && (tick_dir == 'top' || tick_dir == 'bottom') ||
35
37
  orientation == 'horizontal' && (tick_dir == 'left' || tick_dir == 'right')) {
@@ -41,8 +43,8 @@ function makeColorBar(colormap, opts) {
41
43
  const chars_left = getNChar(ticks[0]);
42
44
  const chars_right = getNChar(ticks[ticks.length - 1]);
43
45
  const need_overflow = colormap.underflow_color !== null || colormap.overflow_color !== null;
44
- const bar_long_size = 600;
45
- const bar_cross_size = bar_long_size / 9;
46
+ const bar_long_size = size_long;
47
+ const bar_cross_size = size_short;
46
48
  const bar_long_pad = Math.max(orientation == 'horizontal' ? Math.max(chars_left, chars_right) * 6 : 8, need_overflow ? bar_cross_size / (2 * Math.sqrt(3)) : 0);
47
49
  const bar_cross_pad = 3;
48
50
  const bar_thickness = 10;
package/lib/Colormap.js CHANGED
@@ -8,6 +8,7 @@ import { Float16Array } from "@petamoriken/float16";
8
8
  import { WGLTexture } from "autumn-wgl";
9
9
  import { getGLFormatTypeAlignment } from "./PlotComponent";
10
10
  import { Color } from "./Color";
11
+ import { mergeShaderCode } from "./utils";
11
12
  const colormap_shader_src = `
12
13
  uniform sampler2D u_cmap_sampler;
13
14
  uniform sampler2D u_cmap_nonlin_sampler;
@@ -30,8 +31,8 @@ lowp vec4 apply_colormap(highp float value) {
30
31
  else {
31
32
  lowp float index_buffer = 1. / (2. * float(u_n_index));
32
33
  normed_val = index_buffer + normed_val * (1. - 2. * index_buffer);
33
- highp float nonlin_val = texture2D(u_cmap_nonlin_sampler, vec2(normed_val, 0.5)).r;
34
- color = texture2D(u_cmap_sampler, vec2(nonlin_val, 0.5));
34
+ highp float nonlin_val = texture(u_cmap_nonlin_sampler, vec2(normed_val, 0.5)).r;
35
+ color = texture(u_cmap_sampler, vec2(nonlin_val, 0.5));
35
36
  }
36
37
 
37
38
  return color;
@@ -48,12 +49,11 @@ class ColorMap {
48
49
  if (levels.length != colors.length + 1) {
49
50
  throw `Mismatch between number of levels (${levels.length}) and number of colors (${colors.length}; expected ${levels.length - 1})`;
50
51
  }
51
- const normalizeColor = (c) => c instanceof Color ? c : Color.fromHex(c);
52
52
  this.levels = levels;
53
- this.colors = colors.map(c => normalizeColor(c));
53
+ this.colors = colors.map(c => Color.normalizeColor(c));
54
54
  opts = opts === undefined ? {} : opts;
55
- this.overflow_color = opts.overflow_color === undefined ? null : normalizeColor(opts.overflow_color);
56
- this.underflow_color = opts.underflow_color === undefined ? null : normalizeColor(opts.underflow_color);
55
+ this.overflow_color = opts.overflow_color === undefined ? null : Color.normalizeColor(opts.overflow_color);
56
+ this.underflow_color = opts.underflow_color === undefined ? null : Color.normalizeColor(opts.underflow_color);
57
57
  }
58
58
  /**
59
59
  * @returns an array of hex color strings
@@ -195,12 +195,12 @@ class ColorMapGPUInterface {
195
195
  this.gl_elems = null;
196
196
  }
197
197
  static applyShader(shader_src) {
198
- return colormap_shader_src + "\n" + shader_src;
198
+ return mergeShaderCode(colormap_shader_src, shader_src);
199
199
  }
200
200
  setupShaderVariables(gl, mag_filter) {
201
201
  const index_map = makeIndexMap(this.colormap);
202
202
  const cmap_image = makeTextureImage(this.colormap);
203
- const { format: format_nonlin, type: type_nonlin, row_alignment: row_alignment_nonlin } = getGLFormatTypeAlignment(gl, true);
203
+ const { format: format_nonlin, type: type_nonlin, row_alignment: row_alignment_nonlin } = getGLFormatTypeAlignment(gl, 'float16');
204
204
  const cmap_image_spec = { 'format': gl.RGBA, 'type': gl.UNSIGNED_BYTE, 'image': cmap_image, 'mag_filter': mag_filter };
205
205
  const cmap_texture = new WGLTexture(gl, cmap_image_spec);
206
206
  const cmap_nonlin_image = { 'format': format_nonlin, 'type': type_nonlin,
package/lib/Contour.d.ts CHANGED
@@ -1,9 +1,10 @@
1
- import { TypedArray, WebGLAnyRenderingContext } from './AutumnTypes';
1
+ import { RenderMethodArg, TypedArray, WebGLAnyRenderingContext } from './AutumnTypes';
2
2
  import { MapLikeType } from './Map';
3
3
  import { PlotComponent } from './PlotComponent';
4
4
  import { RawScalarField } from './RawField';
5
5
  import { LineStyle } from './PolylineCollection';
6
6
  import { ColorMap } from './Colormap';
7
+ import { StructuredGrid } from './Grid';
7
8
  interface ContourOptions {
8
9
  /**
9
10
  * The color of the contours as a hex color string
@@ -39,6 +40,10 @@ interface ContourOptions {
39
40
  * @default '-'
40
41
  */
41
42
  line_style?: LineStyle | ((level: number) => LineStyle);
43
+ /**
44
+ *
45
+ */
46
+ quad_as_tri?: boolean;
42
47
  }
43
48
  /**
44
49
  * A field of contoured data.
@@ -47,7 +52,7 @@ interface ContourOptions {
47
52
  * // meters).
48
53
  * const contours = new Contour(height_field, {color: '#000000', interval: 30});
49
54
  */
50
- declare class Contour<ArrayType extends TypedArray, MapType extends MapLikeType> extends PlotComponent<MapType> {
55
+ declare class Contour<ArrayType extends TypedArray, GridType extends StructuredGrid, MapType extends MapLikeType> extends PlotComponent<MapType> {
51
56
  private field;
52
57
  readonly opts: Required<ContourOptions>;
53
58
  private gl_elems;
@@ -57,12 +62,12 @@ declare class Contour<ArrayType extends TypedArray, MapType extends MapLikeType>
57
62
  * @param field - The field to contour
58
63
  * @param opts - Options for creating the contours
59
64
  */
60
- constructor(field: RawScalarField<ArrayType>, opts: ContourOptions);
65
+ constructor(field: RawScalarField<ArrayType, GridType>, opts: ContourOptions);
61
66
  /**
62
67
  * Update the data displayed as contours
63
68
  * @param field - The new field to contour
64
69
  */
65
- updateField(field: RawScalarField<ArrayType>): Promise<void>;
70
+ updateField(field: RawScalarField<ArrayType, GridType>): Promise<void>;
66
71
  getContours(): Promise<import("./AutumnTypes").ContourData>;
67
72
  /**
68
73
  * @internal
@@ -73,7 +78,7 @@ declare class Contour<ArrayType extends TypedArray, MapType extends MapLikeType>
73
78
  * @internal
74
79
  * Render the contours
75
80
  */
76
- render(gl: WebGLAnyRenderingContext, matrix: number[] | Float32Array): void;
81
+ render(gl: WebGLAnyRenderingContext, arg: RenderMethodArg): void;
77
82
  }
78
83
  interface ContourLabelOptions {
79
84
  /**
@@ -110,13 +115,18 @@ interface ContourLabelOptions {
110
115
  * @default false
111
116
  */
112
117
  halo?: boolean;
118
+ /**
119
+ * Label density. 2 makes the labels twice as dense, 0.5 makes them half as dense.
120
+ * @default 1
121
+ */
122
+ density?: number;
113
123
  }
114
- declare class ContourLabels<ArrayType extends TypedArray, MapType extends MapLikeType> extends PlotComponent<MapType> {
124
+ declare class ContourLabels<ArrayType extends TypedArray, GridType extends StructuredGrid, MapType extends MapLikeType> extends PlotComponent<MapType> {
115
125
  private readonly contours;
116
126
  private gl_elems;
117
127
  private text_collection;
118
128
  private readonly opts;
119
- constructor(contours: Contour<ArrayType, MapType>, opts?: ContourLabelOptions);
129
+ constructor(contours: Contour<ArrayType, GridType, MapType>, opts?: ContourLabelOptions);
120
130
  /**
121
131
  * Update contour labels when the field for the associated Contour object has been changed.
122
132
  */
@@ -130,7 +140,7 @@ declare class ContourLabels<ArrayType extends TypedArray, MapType extends MapLik
130
140
  * @internal
131
141
  * Render the contour labels
132
142
  */
133
- render(gl: WebGLAnyRenderingContext, matrix: number[]): void;
143
+ render(gl: WebGLAnyRenderingContext, arg: RenderMethodArg): void;
134
144
  }
135
145
  export default Contour;
136
146
  export { ContourLabels };