autumnplot-gl 2.2.2 → 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.
- package/README.md +65 -8
- package/dist/110.autumnplot-gl.js +2 -0
- package/dist/110.autumnplot-gl.js.map +1 -0
- package/dist/autumnplot-gl.js +3 -0
- package/dist/autumnplot-gl.js.LICENSE.txt +12 -0
- package/dist/autumnplot-gl.js.map +1 -0
- package/dist/marchingsquares.wasm +0 -0
- package/lib/AutumnTypes.d.ts +14 -13
- package/lib/Barbs.d.ts +8 -3
- package/lib/Barbs.js +14 -1
- package/lib/BillboardCollection.d.ts +11 -7
- package/lib/BillboardCollection.js +54 -31
- package/lib/ColorBar.js +51 -7
- package/lib/Colormap.d.ts +14 -3
- package/lib/Colormap.js +63 -12
- package/lib/Contour.d.ts +73 -16
- package/lib/Contour.js +175 -146
- package/lib/ContourCreator.d.ts +18 -0
- package/lib/ContourCreator.js +59 -0
- package/lib/Fill.d.ts +17 -5
- package/lib/Fill.js +60 -37
- package/lib/Grid.d.ts +167 -0
- package/lib/Grid.js +339 -0
- package/lib/Hodographs.d.ts +13 -5
- package/lib/Hodographs.js +52 -67
- package/lib/Map.d.ts +14 -3
- package/lib/Map.js +9 -0
- package/lib/Paintball.d.ts +9 -3
- package/lib/Paintball.js +28 -10
- package/lib/PlotComponent.d.ts +5 -5
- package/lib/PlotLayer.d.ts +12 -12
- package/lib/PlotLayer.js +16 -14
- package/lib/PlotLayer.worker.d.ts +2 -2
- package/lib/PlotLayer.worker.js +102 -66
- package/lib/PolylineCollection.d.ts +20 -9
- package/lib/PolylineCollection.js +158 -32
- package/lib/RawField.d.ts +11 -167
- package/lib/RawField.js +37 -383
- package/lib/TextCollection.d.ts +31 -0
- package/lib/TextCollection.js +295 -0
- package/lib/cpp/marchingsquares.d.ts +6 -0
- package/lib/cpp/marchingsquares.js +4152 -0
- package/lib/cpp/marchingsquares.wasm +0 -0
- package/lib/cpp/marchingsquares_embind.d.ts +47 -0
- package/lib/index.d.ts +13 -6
- package/lib/index.js +12 -3
- package/lib/utils.d.ts +5 -3
- package/lib/utils.js +17 -6
- package/package.json +14 -9
package/lib/PlotLayer.worker.js
CHANGED
|
@@ -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
|
|
244
|
+
if (typeof v === 'number') {
|
|
245
245
|
n_verts = 1;
|
|
246
246
|
}
|
|
247
|
-
else if (v[0]
|
|
248
|
-
n_verts =
|
|
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
|
-
|
|
257
|
-
const
|
|
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
|
-
|
|
261
|
-
|
|
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
|
-
|
|
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
|
|
275
|
-
|
|
276
|
-
|
|
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
|
|
279
|
-
let
|
|
280
|
-
|
|
281
|
-
ret[
|
|
282
|
-
ret[
|
|
283
|
-
ret[
|
|
284
|
-
ret[
|
|
285
|
-
ret[
|
|
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
|
-
|
|
290
|
-
|
|
291
|
-
[ext_x, ext_y] = compute_normal_vec(
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
ret[
|
|
295
|
-
ret[
|
|
296
|
-
ret[
|
|
297
|
-
ret[
|
|
298
|
-
ret[
|
|
299
|
-
ret[
|
|
300
|
-
ret[
|
|
301
|
-
ret[
|
|
302
|
-
ret[
|
|
303
|
-
ret[
|
|
304
|
-
ret[
|
|
305
|
-
ret[
|
|
306
|
-
ret[
|
|
307
|
-
ret[
|
|
308
|
-
ret[
|
|
309
|
-
ret[
|
|
310
|
-
ret[
|
|
311
|
-
ret[
|
|
312
|
-
ret[
|
|
313
|
-
ret[
|
|
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[
|
|
319
|
-
ret[
|
|
320
|
-
ret[
|
|
321
|
-
ret[
|
|
322
|
-
ret[
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
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
|
-
|
|
330
|
-
|
|
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 {
|
|
2
|
-
import {
|
|
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
|
|
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
|
|
12
|
-
private readonly
|
|
13
|
-
|
|
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
|
-
|
|
10
|
-
|
|
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
|
-
|
|
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
|
-
|
|
33
|
-
|
|
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
|
-
|
|
42
|
-
|
|
43
|
-
|
|
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
|
-
|
|
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
|
-
|
|
57
|
-
|
|
58
|
-
|
|
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
|
-
|
|
93
|
+
|
|
94
|
+
#ifdef DATA
|
|
95
|
+
v_data = a_data;
|
|
96
|
+
#endif
|
|
63
97
|
}`
|
|
64
|
-
const polyline_fragment_src =
|
|
98
|
+
const polyline_fragment_src = `#ifdef DATA
|
|
99
|
+
varying highp float v_data;
|
|
65
100
|
|
|
66
|
-
uniform sampler2D
|
|
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
|
-
|
|
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
|
-
|
|
74
|
-
|
|
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,
|
|
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
|
-
|
|
80
|
-
this.
|
|
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
|
-
|
|
85
|
-
|
|
86
|
-
|
|
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
|
-
|
|
92
|
-
|
|
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();
|