autumnplot-gl 2.2.3 → 3.0.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 (49) hide show
  1. package/README.md +65 -8
  2. package/dist/110.autumnplot-gl.js +2 -0
  3. package/dist/110.autumnplot-gl.js.map +1 -0
  4. package/dist/autumnplot-gl.js +3 -0
  5. package/dist/autumnplot-gl.js.LICENSE.txt +12 -0
  6. package/dist/autumnplot-gl.js.map +1 -0
  7. package/dist/marchingsquares.wasm +0 -0
  8. package/lib/AutumnTypes.d.ts +14 -13
  9. package/lib/Barbs.d.ts +8 -3
  10. package/lib/Barbs.js +14 -1
  11. package/lib/BillboardCollection.d.ts +11 -7
  12. package/lib/BillboardCollection.js +52 -30
  13. package/lib/ColorBar.js +51 -7
  14. package/lib/Colormap.d.ts +14 -3
  15. package/lib/Colormap.js +63 -12
  16. package/lib/Contour.d.ts +73 -16
  17. package/lib/Contour.js +175 -146
  18. package/lib/ContourCreator.d.ts +18 -0
  19. package/lib/ContourCreator.js +59 -0
  20. package/lib/Fill.d.ts +17 -5
  21. package/lib/Fill.js +60 -37
  22. package/lib/Grid.d.ts +167 -0
  23. package/lib/Grid.js +339 -0
  24. package/lib/Hodographs.d.ts +13 -5
  25. package/lib/Hodographs.js +52 -67
  26. package/lib/Map.d.ts +14 -3
  27. package/lib/Map.js +9 -0
  28. package/lib/Paintball.d.ts +9 -3
  29. package/lib/Paintball.js +28 -10
  30. package/lib/PlotComponent.d.ts +5 -5
  31. package/lib/PlotLayer.d.ts +12 -12
  32. package/lib/PlotLayer.js +16 -14
  33. package/lib/PlotLayer.worker.d.ts +2 -2
  34. package/lib/PlotLayer.worker.js +102 -66
  35. package/lib/PolylineCollection.d.ts +20 -9
  36. package/lib/PolylineCollection.js +158 -32
  37. package/lib/RawField.d.ts +11 -167
  38. package/lib/RawField.js +37 -383
  39. package/lib/TextCollection.d.ts +31 -0
  40. package/lib/TextCollection.js +295 -0
  41. package/lib/cpp/marchingsquares.d.ts +6 -0
  42. package/lib/cpp/marchingsquares.js +4152 -0
  43. package/lib/cpp/marchingsquares.wasm +0 -0
  44. package/lib/cpp/marchingsquares_embind.d.ts +47 -0
  45. package/lib/index.d.ts +13 -6
  46. package/lib/index.js +12 -3
  47. package/lib/utils.d.ts +5 -3
  48. package/lib/utils.js +17 -6
  49. package/package.json +14 -9
@@ -241,11 +241,11 @@ function makePolylinesMiter(lines) {
241
241
  function makePolylines(lines) {
242
242
  const n_points_per_vert = Object.fromEntries(Object.entries(lines[0]).map(([k, v]) => {
243
243
  let n_verts;
244
- if (v.length === undefined) {
244
+ if (typeof v === 'number') {
245
245
  n_verts = 1;
246
246
  }
247
- else if (v[0].length === undefined) {
248
- n_verts = v.length;
247
+ else if (typeof v[0] === 'number') {
248
+ n_verts = 1;
249
249
  }
250
250
  else {
251
251
  n_verts = v[0].length;
@@ -253,85 +253,121 @@ function makePolylines(lines) {
253
253
  return [k, n_verts];
254
254
  }));
255
255
  n_points_per_vert['extrusion'] = 2;
256
- const n_verts = lines.map(l => l['verts'].length).reduce((a, b) => a + b);
257
- const n_out_verts = (n_verts - lines.length) * 6;
256
+ n_points_per_vert['vertices'] += 1;
257
+ const n_verts = lines.map(l => l.vertices.length).reduce((a, b) => a + b);
258
+ const n_out_verts = n_verts * 4 - lines.length * 2;
258
259
  const ary_lens = Object.fromEntries(Object.entries(n_points_per_vert).map(([k, nppv]) => [k, n_out_verts * nppv]));
259
260
  let ret = {
260
- 'verts': new Float32Array(ary_lens['verts']),
261
- 'origin': new Float32Array(ary_lens['origin']),
262
- 'extrusion': new Float32Array(ary_lens['extrusion']),
263
- 'zoom': new Float32Array(ary_lens['zoom']),
264
- 'texcoords': new Float32Array(ary_lens['texcoords']),
261
+ vertices: new Float32Array(ary_lens['vertices']),
262
+ extrusion: new Float32Array(ary_lens['extrusion']),
265
263
  };
264
+ if ('offsets' in lines[0]) {
265
+ ret.offsets = new Float32Array(ary_lens['offsets']);
266
+ }
267
+ if ('data' in lines[0]) {
268
+ ret.data = new Float32Array(ary_lens['data']);
269
+ }
270
+ if ('zoom' in lines[0]) {
271
+ ret.zoom = new Float32Array(ary_lens['zoom']);
272
+ }
266
273
  let ilns = Object.fromEntries(Object.keys(ary_lens).map(k => [k, 0]));
267
- const compute_normal_vec = (pt1, pt2) => {
274
+ const compute_normal_vec = (pt1, pt2, flip_y_coord) => {
268
275
  const line_vec_x = pt2[0] - pt1[0];
269
276
  const line_vec_y = pt2[1] - pt1[1];
270
277
  const line_vec_mag = Math.hypot(line_vec_x, line_vec_y);
271
- return [line_vec_y / line_vec_mag, -line_vec_x / line_vec_mag];
278
+ const ext_x = line_vec_y / line_vec_mag;
279
+ const ext_y = -line_vec_x / line_vec_mag;
280
+ return [ext_x, flip_y_coord ? -ext_y : ext_y];
272
281
  };
273
282
  lines.forEach(line => {
274
- const verts = line['verts'];
275
- const texcoords = line['texcoords'];
276
- let ary_ivt = ilns['verts'];
283
+ const verts = line.vertices.map(v => {
284
+ const v_ll = new LngLat(...v).toMercatorCoord();
285
+ return [v_ll.x, v_ll.y];
286
+ });
287
+ const has_offsets = line.offsets !== undefined;
288
+ const extrusion_verts = has_offsets ? line.offsets : verts;
277
289
  let pt_prev, pt_this = verts[0], pt_next = verts[1];
278
- let tc_prev, tc_this = texcoords[0], tc_next = texcoords[1];
279
- let [ext_x, ext_y] = compute_normal_vec(pt_this, pt_next);
280
- ret['verts'][ary_ivt + 0] = pt_this[0];
281
- ret['verts'][ary_ivt + 1] = pt_this[1];
282
- ret['texcoords'][ary_ivt + 0] = tc_this[0];
283
- ret['texcoords'][ary_ivt + 1] = tc_this[1];
284
- ret['extrusion'][ary_ivt + 0] = ext_x;
285
- ret['extrusion'][ary_ivt + 1] = ext_y;
290
+ let ept_prev, ept_this = extrusion_verts[0], ept_next = extrusion_verts[1];
291
+ let len_prev, len_this = 0;
292
+ let [ext_x, ext_y] = compute_normal_vec(ept_this, ept_next, !has_offsets);
293
+ ret.vertices[ilns.vertices++] = pt_this[0];
294
+ ret.vertices[ilns.vertices++] = pt_this[1];
295
+ ret.vertices[ilns.vertices++] = len_this;
296
+ ret.extrusion[ilns.extrusion++] = ext_x;
297
+ ret.extrusion[ilns.extrusion++] = ext_y;
286
298
  for (let ivt = 1; ivt < verts.length; ivt++) {
287
299
  pt_this = verts[ivt];
288
300
  pt_prev = verts[ivt - 1];
289
- tc_this = texcoords[ivt];
290
- tc_prev = texcoords[ivt - 1];
291
- [ext_x, ext_y] = compute_normal_vec(pt_prev, pt_this);
292
- ary_ivt = ilns['verts'] + (1 + (ivt - 1) * 4) * n_points_per_vert['verts'];
293
- ret['verts'][ary_ivt + 0] = pt_prev[0];
294
- ret['verts'][ary_ivt + 1] = pt_prev[1];
295
- ret['verts'][ary_ivt + 2] = pt_prev[0];
296
- ret['verts'][ary_ivt + 3] = pt_prev[1];
297
- ret['verts'][ary_ivt + 4] = pt_this[0];
298
- ret['verts'][ary_ivt + 5] = pt_this[1];
299
- ret['verts'][ary_ivt + 6] = pt_this[0];
300
- ret['verts'][ary_ivt + 7] = pt_this[1];
301
- ret['texcoords'][ary_ivt + 0] = tc_prev[0];
302
- ret['texcoords'][ary_ivt + 1] = tc_prev[1];
303
- ret['texcoords'][ary_ivt + 2] = tc_prev[0];
304
- ret['texcoords'][ary_ivt + 3] = tc_prev[1];
305
- ret['texcoords'][ary_ivt + 4] = tc_this[0];
306
- ret['texcoords'][ary_ivt + 5] = tc_this[1];
307
- ret['texcoords'][ary_ivt + 6] = tc_this[0];
308
- ret['texcoords'][ary_ivt + 7] = tc_this[1];
309
- ret['extrusion'][ary_ivt + 0] = ext_x;
310
- ret['extrusion'][ary_ivt + 1] = ext_y;
311
- ret['extrusion'][ary_ivt + 2] = -ext_x;
312
- ret['extrusion'][ary_ivt + 3] = -ext_y;
313
- ret['extrusion'][ary_ivt + 4] = ext_x;
314
- ret['extrusion'][ary_ivt + 5] = ext_y;
315
- ret['extrusion'][ary_ivt + 6] = -ext_x;
316
- ret['extrusion'][ary_ivt + 7] = -ext_y;
301
+ ept_this = extrusion_verts[ivt];
302
+ ept_prev = extrusion_verts[ivt - 1];
303
+ [ext_x, ext_y] = compute_normal_vec(ept_prev, ept_this, !has_offsets);
304
+ len_prev = len_this;
305
+ len_this += Math.hypot(verts[ivt - 1][0] - verts[ivt][0], verts[ivt - 1][1] - verts[ivt][1]);
306
+ ret.vertices[ilns.vertices++] = pt_prev[0];
307
+ ret.vertices[ilns.vertices++] = pt_prev[1];
308
+ ret.vertices[ilns.vertices++] = len_prev;
309
+ ret.vertices[ilns.vertices++] = pt_prev[0];
310
+ ret.vertices[ilns.vertices++] = pt_prev[1];
311
+ ret.vertices[ilns.vertices++] = len_prev;
312
+ ret.vertices[ilns.vertices++] = pt_this[0];
313
+ ret.vertices[ilns.vertices++] = pt_this[1];
314
+ ret.vertices[ilns.vertices++] = len_this;
315
+ ret.vertices[ilns.vertices++] = pt_this[0];
316
+ ret.vertices[ilns.vertices++] = pt_this[1];
317
+ ret.vertices[ilns.vertices++] = len_this;
318
+ ret.extrusion[ilns.extrusion++] = ext_x;
319
+ ret.extrusion[ilns.extrusion++] = ext_y;
320
+ ret.extrusion[ilns.extrusion++] = -ext_x;
321
+ ret.extrusion[ilns.extrusion++] = -ext_y;
322
+ ret.extrusion[ilns.extrusion++] = ext_x;
323
+ ret.extrusion[ilns.extrusion++] = ext_y;
324
+ ret.extrusion[ilns.extrusion++] = -ext_x;
325
+ ret.extrusion[ilns.extrusion++] = -ext_y;
317
326
  }
318
- ret['verts'][ary_ivt + 8] = pt_this[0];
319
- ret['verts'][ary_ivt + 9] = pt_this[1];
320
- ret['texcoords'][ary_ivt + 8] = tc_this[0];
321
- ret['texcoords'][ary_ivt + 9] = tc_this[1];
322
- ret['extrusion'][ary_ivt + 8] = -ext_x;
323
- ret['extrusion'][ary_ivt + 9] = -ext_y;
324
- for (let ivt = 0; ivt < (verts.length - 1) * 6 * n_points_per_vert['origin']; ivt += n_points_per_vert['origin']) {
325
- line['origin'].forEach((cd, icd) => {
326
- ret['origin'][ilns['origin'] + ivt + icd] = cd;
327
- });
327
+ ret.vertices[ilns.vertices++] = pt_this[0];
328
+ ret.vertices[ilns.vertices++] = pt_this[1];
329
+ ret.vertices[ilns.vertices++] = len_this;
330
+ ret.extrusion[ilns.extrusion++] = -ext_x;
331
+ ret.extrusion[ilns.extrusion++] = -ext_y;
332
+ if ('offsets' in ret) {
333
+ const offsets = line.offsets;
334
+ let off_prev, off_this = offsets[0];
335
+ ret.offsets[ilns.offsets++] = off_this[0];
336
+ ret.offsets[ilns.offsets++] = off_this[1];
337
+ for (let ivt = 1; ivt < offsets.length; ivt++) {
338
+ off_this = offsets[ivt];
339
+ off_prev = offsets[ivt - 1];
340
+ ret.offsets[ilns.offsets++] = off_prev[0];
341
+ ret.offsets[ilns.offsets++] = off_prev[1];
342
+ ret.offsets[ilns.offsets++] = off_prev[0];
343
+ ret.offsets[ilns.offsets++] = off_prev[1];
344
+ ret.offsets[ilns.offsets++] = off_this[0];
345
+ ret.offsets[ilns.offsets++] = off_this[1];
346
+ ret.offsets[ilns.offsets++] = off_this[0];
347
+ ret.offsets[ilns.offsets++] = off_this[1];
348
+ }
349
+ ret.offsets[ilns.offsets++] = off_this[0];
350
+ ret.offsets[ilns.offsets++] = off_this[1];
328
351
  }
329
- for (let ivt = 0; ivt < (verts.length - 1) * 6 * n_points_per_vert['zoom']; ivt += n_points_per_vert['zoom']) {
330
- ret['zoom'][ilns['zoom'] + ivt] = line['zoom'];
352
+ if ('data' in ret) {
353
+ const data = line.data;
354
+ let data_prev, data_this = data[0];
355
+ ret.data[ilns.data++] = data_this;
356
+ for (let ivt = 1; ivt < data.length; ivt++) {
357
+ data_this = data[ivt];
358
+ data_prev = data[ivt - 1];
359
+ ret.data[ilns.data++] = data_prev;
360
+ ret.data[ilns.data++] = data_prev;
361
+ ret.data[ilns.data++] = data_this;
362
+ ret.data[ilns.data++] = data_this;
363
+ }
364
+ ret.data[ilns.data++] = data_this;
365
+ }
366
+ if ('zoom' in ret) {
367
+ for (let ivt = 0; ivt < verts.length * 4 - 2; ivt++) {
368
+ ret.zoom[ilns.zoom++] = line['zoom'];
369
+ }
331
370
  }
332
- Object.keys(ilns).forEach(k => {
333
- ilns[k] += (verts.length - 1) * 6 * n_points_per_vert[k];
334
- });
335
371
  });
336
372
  return ret;
337
373
  }
@@ -1,17 +1,28 @@
1
- import { WGLTextureSpec } from "autumn-wgl";
2
- import { PolylineSpec, LineSpec, WebGLAnyRenderingContext } from "./AutumnTypes";
1
+ import { LineData, WebGLAnyRenderingContext } from "./AutumnTypes";
2
+ import { ColorMap } from "./Colormap";
3
+ interface PolylineCollectionOpts {
4
+ offset_scale?: number;
5
+ color?: string;
6
+ cmap?: ColorMap;
7
+ line_width?: number;
8
+ }
3
9
  declare class PolylineCollection {
4
10
  readonly width: number;
5
- readonly scale: number;
11
+ readonly scale: number | null;
6
12
  private readonly program;
7
- private readonly origin;
8
- private readonly offset;
13
+ private readonly vertices;
9
14
  private readonly extrusion;
15
+ private readonly offset;
10
16
  private readonly min_zoom;
11
- private readonly texture;
12
- private readonly texcoords;
13
- constructor(gl: WebGLAnyRenderingContext, polyline: PolylineSpec, tex_image: WGLTextureSpec, line_width: number, offset_scale: number);
17
+ private readonly line_data;
18
+ private readonly line_texture;
19
+ private readonly color;
20
+ private readonly cmap_min;
21
+ private readonly cmap_max;
22
+ private readonly index_map;
23
+ private readonly cmap_nonlin_texture;
24
+ private constructor();
25
+ static make(gl: WebGLAnyRenderingContext, lines: LineData[], opts?: PolylineCollectionOpts): Promise<PolylineCollection>;
14
26
  render(gl: WebGLAnyRenderingContext, matrix: number[] | Float32Array, [map_width, map_height]: [number, number], map_zoom: number, map_bearing: number, map_pitch: number): void;
15
27
  }
16
28
  export { PolylineCollection };
17
- export type { PolylineSpec, LineSpec };
@@ -1,20 +1,39 @@
1
+ import { Float16Array } from "@petamoriken/float16";
1
2
  import { WGLBuffer, WGLProgram, WGLTexture } from "autumn-wgl";
3
+ import { makeIndexMap, makeTextureImage } from "./Colormap";
4
+ import { getGLFormatTypeAlignment, layer_worker } from "./PlotComponent";
5
+ import { hex2rgba } from "./utils";
2
6
  const polyline_vertex_src = `uniform mat4 u_matrix;
3
7
  uniform int u_offset;
4
8
 
5
9
  attribute vec2 a_pos;
6
- attribute float a_min_zoom;
7
10
  attribute vec2 a_extrusion;
11
+ attribute float a_data;
12
+
13
+ #ifdef ZOOM
14
+ attribute float a_min_zoom;
15
+ #endif
16
+
17
+ #ifdef OFFSET
8
18
  attribute vec2 a_offset;
9
- attribute vec2 a_tex_coord;
10
- uniform lowp float u_offset_scale;
11
- uniform lowp float u_map_aspect;
12
- uniform lowp float u_zoom;
19
+ #endif
20
+
13
21
  uniform lowp float u_line_width;
22
+ uniform lowp float u_map_width;
23
+ uniform lowp float u_map_height;
14
24
  uniform highp float u_map_bearing;
15
25
 
26
+ #ifdef ZOOM
27
+ uniform lowp float u_zoom;
28
+ #endif
16
29
 
17
- varying highp vec2 v_tex_coord;
30
+ #ifdef OFFSET
31
+ uniform lowp float u_offset_scale;
32
+ #endif
33
+
34
+ #ifdef DATA
35
+ varying highp float v_data;
36
+ #endif
18
37
 
19
38
  mat4 scalingMatrix(float x_scale, float y_scale, float z_scale) {
20
39
  return mat4(x_scale, 0.0, 0.0, 0.0,
@@ -29,8 +48,8 @@ mat4 rotationZMatrix(float angle) {
29
48
 
30
49
  return mat4( c, s, 0., 0.,
31
50
  -s, c, 0., 0.,
32
- 0., 0., 1., 0.,
33
- 0., 0., 0., 1.);
51
+ 0., 0., 1., 0.,
52
+ 0., 0., 0., 1.);
34
53
  }
35
54
 
36
55
  mat4 rotationXMatrix(float angle) {
@@ -38,9 +57,9 @@ mat4 rotationXMatrix(float angle) {
38
57
  float c = cos(angle);
39
58
 
40
59
  return mat4( 1., 0., 0., 0.,
41
- 0., c, s, 0.,
42
- 0., -s, c, 0.,
43
- 0., 0., 0., 1.);
60
+ 0., c, s, 0.,
61
+ 0., -s, c, 0.,
62
+ 0., 0., 0., 1.);
44
63
  }
45
64
 
46
65
  void main() {
@@ -49,47 +68,154 @@ void main() {
49
68
 
50
69
  vec4 center_pos = u_matrix * vec4(a_pos.xy + globe_offset, 0.0, 1.0);
51
70
  vec4 offset = vec4(0.0, 0.0, 0.0, 0.0);
52
-
71
+
72
+ #ifdef ZOOM
53
73
  if (u_zoom >= a_min_zoom) {
54
- vec2 offset_2d = a_offset + u_line_width * a_extrusion;
74
+ #endif
75
+
76
+ vec2 offset_ext = u_line_width * 1.5 * a_extrusion;
77
+
78
+ mat4 map_stretch_matrix = scalingMatrix(u_map_height / u_map_width, 1., 1.);
79
+ mat4 rotation_matrix = rotationZMatrix(radians(u_map_bearing));
80
+ offset = map_stretch_matrix * rotation_matrix * vec4(offset_ext, 0., 0.);
55
81
 
56
- mat4 rotation_matrix = rotationZMatrix(radians(u_map_bearing));
57
- mat4 map_stretch_matrix = scalingMatrix(u_offset_scale, u_offset_scale / u_map_aspect, 1.);
58
- offset = map_stretch_matrix * rotation_matrix * vec4(offset_2d, 0., 0.);
82
+ #ifdef OFFSET
83
+ map_stretch_matrix = scalingMatrix(1., u_map_width / u_map_height, 1.);
84
+ vec2 offset_offset = u_offset_scale * a_offset;
85
+ offset += map_stretch_matrix * rotation_matrix * vec4(offset_offset, 0., 0.);
86
+ #endif
87
+
88
+ #ifdef ZOOM
59
89
  }
90
+ #endif
60
91
 
61
92
  gl_Position = center_pos + offset;
62
- v_tex_coord = a_tex_coord;
93
+
94
+ #ifdef DATA
95
+ v_data = a_data;
96
+ #endif
63
97
  }`
64
- const polyline_fragment_src = `varying highp vec2 v_tex_coord;
98
+ const polyline_fragment_src = `#ifdef DATA
99
+ varying highp float v_data;
65
100
 
66
- uniform sampler2D u_sampler;
101
+ uniform sampler2D u_cmap_sampler;
102
+ uniform sampler2D u_cmap_nonlin_sampler;
103
+ uniform highp float u_cmap_min;
104
+ uniform highp float u_cmap_max;
105
+ uniform int u_n_index;
106
+ #else
107
+ uniform lowp vec4 u_color;
108
+ #endif
67
109
 
68
110
  void main() {
69
- if (v_tex_coord.x > 1.0) {
111
+ lowp vec4 color;
112
+ #ifdef DATA
113
+ lowp float index_buffer = 1. / (2. * float(u_n_index));
114
+ lowp float normed_val = (v_data - u_cmap_min) / (u_cmap_max - u_cmap_min);
115
+
116
+ if (normed_val < 0.0 || normed_val > 1.0) {
70
117
  discard;
71
118
  }
72
119
 
73
- lowp vec4 tex_color = texture2D(u_sampler, v_tex_coord);
74
- gl_FragColor = tex_color;
120
+ normed_val = index_buffer + normed_val * (1. - 2. * index_buffer);
121
+ highp float nonlin_val = texture2D(u_cmap_nonlin_sampler, vec2(normed_val, 0.5)).r;
122
+ color = texture2D(u_cmap_sampler, vec2(nonlin_val, 0.5));
123
+ #else
124
+ color = u_color;
125
+ #endif
126
+ gl_FragColor = color;
75
127
  }`
76
128
  class PolylineCollection {
77
- constructor(gl, polyline, tex_image, line_width, offset_scale) {
129
+ constructor(gl, polyline, opts) {
130
+ opts = opts === undefined ? {} : opts;
131
+ this.color = opts.color === undefined ? [0., 0., 0., 1.] : hex2rgba(opts.color);
132
+ const line_width = opts.line_width === undefined ? 1 : opts.line_width;
78
133
  this.width = line_width;
79
- this.scale = offset_scale;
80
- this.program = new WGLProgram(gl, polyline_vertex_src, polyline_fragment_src);
81
- this.origin = new WGLBuffer(gl, polyline['origin'], 2, gl.TRIANGLE_STRIP);
82
- this.offset = new WGLBuffer(gl, polyline['verts'], 2, gl.TRIANGLE_STRIP);
134
+ const shader_defines = [];
135
+ this.vertices = new WGLBuffer(gl, polyline['vertices'], 3, gl.TRIANGLE_STRIP);
83
136
  this.extrusion = new WGLBuffer(gl, polyline['extrusion'], 2, gl.TRIANGLE_STRIP);
84
- this.min_zoom = new WGLBuffer(gl, polyline['zoom'], 1, gl.TRIANGLE_STRIP);
85
- this.texture = new WGLTexture(gl, tex_image);
86
- this.texcoords = new WGLBuffer(gl, polyline['texcoords'], 2, gl.TRIANGLE_STRIP);
137
+ if (polyline.offsets !== undefined) {
138
+ this.offset = new WGLBuffer(gl, polyline.offsets, 2, gl.TRIANGLE_STRIP);
139
+ this.scale = opts.offset_scale === undefined ? 1 : opts.offset_scale;
140
+ shader_defines.push('OFFSET');
141
+ }
142
+ else {
143
+ this.offset = null;
144
+ this.scale = null;
145
+ }
146
+ if (polyline.zoom !== undefined) {
147
+ this.min_zoom = new WGLBuffer(gl, polyline.zoom, 1, gl.TRIANGLE_STRIP);
148
+ shader_defines.push('ZOOM');
149
+ }
150
+ else {
151
+ this.min_zoom = null;
152
+ }
153
+ this.cmap_min = -3.40282347e+38;
154
+ this.cmap_max = 3.40282347e+38;
155
+ if (polyline.data !== undefined) {
156
+ // TAS: this needs some cleanup (there's some repated code between here and the contour fills that should be combined?)
157
+ this.min_zoom = new WGLBuffer(gl, polyline.zoom, 1, gl.TRIANGLE_STRIP);
158
+ shader_defines.push('DATA');
159
+ const { format: format_nonlin, type: type_nonlin, row_alignment: row_alignment_nonlin } = getGLFormatTypeAlignment(gl, true);
160
+ let tex_image;
161
+ if (opts.cmap === undefined) {
162
+ tex_image = { 'format': gl.RGBA, 'type': gl.UNSIGNED_BYTE, 'width': 1, 'height': 1, 'image': new Uint8Array(this.color), 'mag_filter': gl.NEAREST };
163
+ this.index_map = new Float16Array([0., 1.]);
164
+ }
165
+ else {
166
+ tex_image = { 'format': gl.RGBA, 'type': gl.UNSIGNED_BYTE, 'image': makeTextureImage(opts.cmap), 'mag_filter': gl.NEAREST };
167
+ this.cmap_min = opts.cmap.levels[0];
168
+ this.cmap_max = opts.cmap.levels[opts.cmap.levels.length - 1];
169
+ this.index_map = makeIndexMap(opts.cmap);
170
+ }
171
+ const cmap_nonlin_image = { 'format': format_nonlin, 'type': type_nonlin,
172
+ 'width': this.index_map.length, 'height': 1,
173
+ 'image': new Uint16Array(this.index_map.buffer),
174
+ 'mag_filter': gl.LINEAR, 'row_alignment': row_alignment_nonlin,
175
+ };
176
+ this.cmap_nonlin_texture = new WGLTexture(gl, cmap_nonlin_image);
177
+ this.line_texture = new WGLTexture(gl, tex_image);
178
+ this.line_data = new WGLBuffer(gl, polyline['data'], 1, gl.TRIANGLE_STRIP);
179
+ }
180
+ else {
181
+ this.line_texture = null;
182
+ this.line_data = null;
183
+ this.index_map = null;
184
+ }
185
+ this.program = new WGLProgram(gl, polyline_vertex_src, polyline_fragment_src, { define: shader_defines });
186
+ }
187
+ static async make(gl, lines, opts) {
188
+ const polylines = await layer_worker.makePolyLines(lines);
189
+ return new PolylineCollection(gl, polylines, opts);
87
190
  }
88
191
  render(gl, matrix, [map_width, map_height], map_zoom, map_bearing, map_pitch) {
89
192
  if (matrix instanceof Float32Array)
90
193
  matrix = [...matrix];
91
- this.program.use({ 'a_pos': this.origin, 'a_offset': this.offset, 'a_extrusion': this.extrusion, 'a_min_zoom': this.min_zoom, 'a_tex_coord': this.texcoords }, { 'u_offset_scale': this.scale * (map_height / map_width), 'u_line_width': this.width, 'u_matrix': matrix,
92
- 'u_map_aspect': map_height / map_width, 'u_zoom': map_zoom, 'u_map_bearing': map_bearing, 'u_offset': 0 }, { 'u_sampler': this.texture });
194
+ const attributes = { 'a_pos': this.vertices, 'a_extrusion': this.extrusion };
195
+ const uniforms = {
196
+ 'u_matrix': matrix, 'u_line_width': this.width, 'u_map_width': map_width, 'u_map_height': map_height, 'u_map_bearing': map_bearing, 'u_offset': 0
197
+ };
198
+ const textures = {};
199
+ if (this.offset !== null) {
200
+ attributes['a_offset'] = this.offset;
201
+ uniforms['u_offset_scale'] = this.scale * (map_height / map_width);
202
+ }
203
+ if (this.min_zoom !== null) {
204
+ attributes['a_min_zoom'] = this.min_zoom;
205
+ uniforms['u_zoom'] = map_zoom;
206
+ }
207
+ if (this.line_data !== null && this.line_texture !== null) {
208
+ attributes['a_data'] = this.line_data;
209
+ textures['u_cmap_sampler'] = this.line_texture;
210
+ textures['u_cmap_nonlin_sampler'] = this.cmap_nonlin_texture;
211
+ uniforms['u_cmap_min'] = this.cmap_min;
212
+ uniforms['u_cmap_max'] = this.cmap_max;
213
+ uniforms['u_n_index'] = this.index_map.length;
214
+ }
215
+ else {
216
+ uniforms['u_color'] = this.color;
217
+ }
218
+ this.program.use(attributes, uniforms, textures);
93
219
  gl.enable(gl.BLEND);
94
220
  gl.blendFuncSeparate(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA, gl.ONE, gl.ONE_MINUS_SRC_ALPHA);
95
221
  this.program.draw();