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.
- package/lib/AutumnTypes.d.ts +53 -5
- package/lib/AutumnTypes.js +25 -1
- package/lib/Barbs.d.ts +6 -5
- package/lib/BillboardCollection.d.ts +8 -7
- package/lib/BillboardCollection.js +69 -58
- package/lib/Color.d.ts +1 -0
- package/lib/Color.js +3 -0
- package/lib/ColorBar.d.ts +10 -0
- package/lib/ColorBar.js +4 -2
- package/lib/Colormap.js +8 -8
- package/lib/Contour.d.ts +18 -8
- package/lib/Contour.js +17 -54
- package/lib/ContourCreator.d.ts +4 -0
- package/lib/ContourCreator.js +2 -1
- package/lib/Fill.d.ts +26 -14
- package/lib/Fill.js +97 -50
- package/lib/Grid.d.ts +124 -29
- package/lib/Grid.js +297 -94
- package/lib/Hodographs.d.ts +9 -8
- package/lib/Hodographs.js +14 -11
- package/lib/Map.js +1 -1
- package/lib/Paintball.d.ts +6 -5
- package/lib/Paintball.js +35 -30
- package/lib/ParticleTracer.d.ts +19 -0
- package/lib/ParticleTracer.js +37 -0
- package/lib/PlotComponent.d.ts +6 -7
- package/lib/PlotComponent.js +8 -3
- package/lib/PlotLayer.d.ts +3 -3
- package/lib/PlotLayer.worker.d.ts +1 -2
- package/lib/PlotLayer.worker.js +15 -50
- package/lib/PolylineCollection.d.ts +5 -3
- package/lib/PolylineCollection.js +60 -37
- package/lib/RawField.d.ts +76 -23
- package/lib/RawField.js +138 -29
- package/lib/ShaderManager.d.ts +12 -0
- package/lib/ShaderManager.js +58 -0
- package/lib/StationPlot.d.ts +136 -25
- package/lib/StationPlot.js +192 -60
- package/lib/TextCollection.d.ts +9 -6
- package/lib/TextCollection.js +94 -62
- package/lib/cpp/marchingsquares.js +483 -585
- package/lib/cpp/marchingsquares.wasm +0 -0
- package/lib/cpp/marchingsquares_embind.d.ts +23 -3
- package/lib/index.d.ts +4 -3
- package/lib/index.js +4 -3
- package/lib/utils.d.ts +4 -1
- package/lib/utils.js +12 -1
- package/package.json +2 -2
package/lib/Hodographs.js
CHANGED
|
@@ -77,17 +77,19 @@ class Hodographs extends PlotComponent {
|
|
|
77
77
|
const gl = this.gl_elems.gl;
|
|
78
78
|
this.gl_elems.bg_billboard.updateField(field.getStormMotionGrid());
|
|
79
79
|
const profiles = this.profile_field.profiles;
|
|
80
|
-
const
|
|
80
|
+
const { lats, lons } = this.profile_field.getProfileCoords();
|
|
81
|
+
const hodo_polyline = profiles.map((prof, iprof) => {
|
|
81
82
|
const zoom = getMinZoom(prof['jlat'], prof['ilon'], this.opts.thin_fac);
|
|
82
83
|
return {
|
|
83
84
|
'offsets': [...prof['u']].map((u, ipt) => [u - prof['smu'], prof['v'][ipt] - prof['smv']]),
|
|
84
|
-
'vertices': [...prof['u']].map(u => [
|
|
85
|
+
'vertices': [...prof['u']].map(u => [lons[iprof], lats[iprof]]),
|
|
85
86
|
'zoom': zoom,
|
|
86
87
|
'data': [...prof['z']],
|
|
87
88
|
};
|
|
88
89
|
});
|
|
89
|
-
const hodo_line = await PolylineCollection.make(gl, hodo_polyline, { line_width: this.opts.hodo_line_width, cmap: this.opts.height_cmap,
|
|
90
|
-
|
|
90
|
+
const hodo_line = await PolylineCollection.make(gl, hodo_polyline, { line_width: this.opts.hodo_line_width, cmap: this.opts.height_cmap,
|
|
91
|
+
offset_scale: this.hodo_scale * this.bg_size, offset_rotates_with_map: false });
|
|
92
|
+
const sm_polyline = profiles.map((prof, iprof) => {
|
|
91
93
|
const zoom = getMinZoom(prof['jlat'], prof['ilon'], this.opts.thin_fac);
|
|
92
94
|
const sm_mag = Math.hypot(prof['smu'], prof['smv']);
|
|
93
95
|
const sm_ang = Math.PI / 2 - Math.atan2(-prof['smv'], -prof['smu']);
|
|
@@ -95,11 +97,12 @@ class Hodographs extends PlotComponent {
|
|
|
95
97
|
return {
|
|
96
98
|
'offsets': [[buffer * Math.sin(sm_ang), buffer * Math.cos(sm_ang)],
|
|
97
99
|
[sm_mag * Math.sin(sm_ang), sm_mag * Math.cos(sm_ang)]],
|
|
98
|
-
'vertices': [[
|
|
100
|
+
'vertices': [[lons[iprof], lats[iprof]], [lons[iprof], lats[iprof]]],
|
|
99
101
|
'zoom': zoom
|
|
100
102
|
};
|
|
101
103
|
});
|
|
102
|
-
const sm_line = await PolylineCollection.make(gl, sm_polyline, { line_width: this.opts.background_line_width, color: this.opts.bgcolor,
|
|
104
|
+
const sm_line = await PolylineCollection.make(gl, sm_polyline, { line_width: this.opts.background_line_width, color: this.opts.bgcolor,
|
|
105
|
+
offset_scale: this.hodo_scale * this.bg_size, offset_rotates_with_map: false });
|
|
103
106
|
this.line_elems = {
|
|
104
107
|
hodo_line: hodo_line, sm_line: sm_line
|
|
105
108
|
};
|
|
@@ -111,7 +114,7 @@ class Hodographs extends PlotComponent {
|
|
|
111
114
|
async onAdd(map, gl) {
|
|
112
115
|
const bg_image = { 'format': gl.RGBA, 'type': gl.UNSIGNED_BYTE, 'image': this.hodo_bg_texture, 'mag_filter': gl.NEAREST };
|
|
113
116
|
const max_zoom = map.getMaxZoom();
|
|
114
|
-
const bg_billboard = new BillboardCollection(this.profile_field.getStormMotionGrid(), this.opts.thin_fac, max_zoom, bg_image, HODO_BG_DIMS, this.bg_size * 0.004, { color: Color.fromHex(this.opts.bgcolor) });
|
|
117
|
+
const bg_billboard = new BillboardCollection(this.profile_field.getStormMotionGrid(), this.opts.thin_fac, max_zoom, bg_image, HODO_BG_DIMS, this.bg_size * 0.004, { color: Color.fromHex(this.opts.bgcolor), rotate_with_map: false });
|
|
115
118
|
await bg_billboard.setup(gl);
|
|
116
119
|
this.gl_elems = {
|
|
117
120
|
gl: gl, map: map, bg_billboard: bg_billboard
|
|
@@ -122,7 +125,7 @@ class Hodographs extends PlotComponent {
|
|
|
122
125
|
* @internal
|
|
123
126
|
* Render the hodographs
|
|
124
127
|
*/
|
|
125
|
-
render(gl,
|
|
128
|
+
render(gl, arg) {
|
|
126
129
|
if (this.gl_elems === null || this.line_elems === null)
|
|
127
130
|
return;
|
|
128
131
|
const gl_elems = this.gl_elems;
|
|
@@ -132,9 +135,9 @@ class Hodographs extends PlotComponent {
|
|
|
132
135
|
const map_height = gl_elems.map.getCanvas().height;
|
|
133
136
|
const bearing = gl_elems.map.getBearing();
|
|
134
137
|
const pitch = gl_elems.map.getPitch();
|
|
135
|
-
line_elems.hodo_line.render(gl,
|
|
136
|
-
line_elems.sm_line.render(gl,
|
|
137
|
-
gl_elems.bg_billboard.render(gl,
|
|
138
|
+
line_elems.hodo_line.render(gl, arg, [map_width, map_height], zoom, bearing, pitch);
|
|
139
|
+
line_elems.sm_line.render(gl, arg, [map_width, map_height], zoom, bearing, bearing);
|
|
140
|
+
gl_elems.bg_billboard.render(gl, arg, [map_width, map_height], zoom, bearing, pitch);
|
|
138
141
|
}
|
|
139
142
|
}
|
|
140
143
|
export default Hodographs;
|
package/lib/Map.js
CHANGED
|
@@ -130,7 +130,7 @@ function lngFromMercatorX(x) {
|
|
|
130
130
|
function mercatorYfromLat(lat) {
|
|
131
131
|
const sin_lat = Math.sin(lat * Math.PI / 180);
|
|
132
132
|
const y = (180 - (90 / Math.PI * Math.log((1 + sin_lat) / (1 - sin_lat)))) / 360;
|
|
133
|
-
return Math.min(
|
|
133
|
+
return Math.min(1.5, Math.max(-0.5, y));
|
|
134
134
|
}
|
|
135
135
|
function latFromMercatorY(y) {
|
|
136
136
|
return Math.atan(Math.sinh((180 - y * 360) * Math.PI / 180)) * 180 / Math.PI;
|
package/lib/Paintball.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { TypedArray, WebGLAnyRenderingContext } from "./AutumnTypes";
|
|
1
|
+
import { RenderMethodArg, TypedArray, WebGLAnyRenderingContext } from "./AutumnTypes";
|
|
2
|
+
import { StructuredGrid } from "./Grid";
|
|
2
3
|
import { MapLikeType } from "./Map";
|
|
3
4
|
import { PlotComponent } from "./PlotComponent";
|
|
4
5
|
import { RawScalarField } from "./RawField";
|
|
@@ -20,7 +21,7 @@ interface PaintballOptions {
|
|
|
20
21
|
* of single-precision floats, this works for up to 24 members. (Technically speaking, I don't need the quotes around "bits", as they're bits of the
|
|
21
22
|
* significand of an IEEE 754 float.)
|
|
22
23
|
*/
|
|
23
|
-
declare class Paintball<ArrayType extends TypedArray, MapType extends MapLikeType> extends PlotComponent<MapType> {
|
|
24
|
+
declare class Paintball<ArrayType extends TypedArray, GridType extends StructuredGrid, MapType extends MapLikeType> extends PlotComponent<MapType> {
|
|
24
25
|
private field;
|
|
25
26
|
readonly opts: Required<PaintballOptions>;
|
|
26
27
|
private readonly color_components;
|
|
@@ -33,12 +34,12 @@ declare class Paintball<ArrayType extends TypedArray, MapType extends MapLikeTyp
|
|
|
33
34
|
* `M2` is the same thing for member 2, and `M3` and `M4` and up to `Mn` are the same thing for the rest of the members.
|
|
34
35
|
* @param opts - Options for creating the paintball plot
|
|
35
36
|
*/
|
|
36
|
-
constructor(field: RawScalarField<ArrayType>, opts?: PaintballOptions);
|
|
37
|
+
constructor(field: RawScalarField<ArrayType, GridType>, opts?: PaintballOptions);
|
|
37
38
|
/**
|
|
38
39
|
* Update the field displayed as a paintball plot
|
|
39
40
|
* @param field - The new field to display as a paintball plot
|
|
40
41
|
*/
|
|
41
|
-
updateField(field: RawScalarField<ArrayType>): Promise<void>;
|
|
42
|
+
updateField(field: RawScalarField<ArrayType, GridType>): Promise<void>;
|
|
42
43
|
/**
|
|
43
44
|
* @internal
|
|
44
45
|
* Add the paintball plot to a map.
|
|
@@ -48,7 +49,7 @@ declare class Paintball<ArrayType extends TypedArray, MapType extends MapLikeTyp
|
|
|
48
49
|
* @internal
|
|
49
50
|
* Render the paintball plot
|
|
50
51
|
*/
|
|
51
|
-
render(gl: WebGLAnyRenderingContext,
|
|
52
|
+
render(gl: WebGLAnyRenderingContext, arg: RenderMethodArg): void;
|
|
52
53
|
}
|
|
53
54
|
export default Paintball;
|
|
54
55
|
export type { PaintballOptions };
|
package/lib/Paintball.js
CHANGED
|
@@ -1,33 +1,40 @@
|
|
|
1
|
+
import { getRendererData } from "./AutumnTypes";
|
|
1
2
|
import { Color } from "./Color";
|
|
2
|
-
import { PlotComponent
|
|
3
|
+
import { PlotComponent } from "./PlotComponent";
|
|
4
|
+
import { ShaderProgramManager } from "./ShaderManager";
|
|
3
5
|
import { normalizeOptions } from "./utils";
|
|
4
|
-
import {
|
|
5
|
-
const paintball_vertex_shader_src =
|
|
6
|
+
import { WGLTexture } from "autumn-wgl";
|
|
7
|
+
const paintball_vertex_shader_src = `#version 300 es
|
|
8
|
+
|
|
6
9
|
uniform int u_offset;
|
|
7
10
|
|
|
8
|
-
|
|
9
|
-
|
|
11
|
+
in vec2 a_pos;
|
|
12
|
+
in vec2 a_tex_coord;
|
|
10
13
|
|
|
11
|
-
|
|
14
|
+
out highp vec2 v_tex_coord;
|
|
12
15
|
|
|
13
16
|
void main() {
|
|
14
17
|
float globe_width = 1.;
|
|
15
18
|
vec2 globe_offset = vec2(globe_width * float(u_offset), 0.);
|
|
16
19
|
|
|
17
|
-
gl_Position =
|
|
20
|
+
gl_Position = projectTile(a_pos.xy + globe_offset);
|
|
18
21
|
v_tex_coord = a_tex_coord;
|
|
19
22
|
}`
|
|
20
|
-
const paintball_fragment_shader_src = `#
|
|
23
|
+
const paintball_fragment_shader_src = `#version 300 es
|
|
24
|
+
|
|
25
|
+
#define MAX_N_COLORS 24
|
|
21
26
|
|
|
22
|
-
|
|
27
|
+
in highp vec2 v_tex_coord;
|
|
23
28
|
|
|
24
29
|
uniform sampler2D u_fill_sampler;
|
|
25
30
|
uniform lowp vec4 u_colors[MAX_N_COLORS];
|
|
26
31
|
uniform int u_num_colors;
|
|
27
32
|
uniform highp float u_opacity;
|
|
28
33
|
|
|
34
|
+
out highp vec4 fragColor;
|
|
35
|
+
|
|
29
36
|
void main() {
|
|
30
|
-
highp float fill_val =
|
|
37
|
+
highp float fill_val = texture(u_fill_sampler, v_tex_coord).r;
|
|
31
38
|
|
|
32
39
|
if (fill_val < 0.5) {
|
|
33
40
|
discard;
|
|
@@ -44,7 +51,7 @@ void main() {
|
|
|
44
51
|
}
|
|
45
52
|
|
|
46
53
|
color.a = color.a * u_opacity;
|
|
47
|
-
|
|
54
|
+
fragColor = color;
|
|
48
55
|
}`
|
|
49
56
|
const paintball_opt_defaults = {
|
|
50
57
|
colors: ['#000000'],
|
|
@@ -83,12 +90,7 @@ class Paintball extends PlotComponent {
|
|
|
83
90
|
return;
|
|
84
91
|
const gl = this.gl_elems.gl;
|
|
85
92
|
gl.pixelStorei(gl.UNPACK_ALIGNMENT, 2);
|
|
86
|
-
const
|
|
87
|
-
const { format, type, row_alignment } = getGLFormatTypeAlignment(gl, !(tex_data instanceof Float32Array));
|
|
88
|
-
const fill_image = { 'format': format, 'type': type,
|
|
89
|
-
'width': this.field.grid.ni, 'height': this.field.grid.nj, 'image': tex_data,
|
|
90
|
-
'mag_filter': gl.NEAREST, 'row_alignment': row_alignment,
|
|
91
|
-
};
|
|
93
|
+
const fill_image = this.field.getWGLTextureSpec(gl, gl.NEAREST);
|
|
92
94
|
if (this.fill_texture === null) {
|
|
93
95
|
this.fill_texture = new WGLTexture(gl, fill_image);
|
|
94
96
|
}
|
|
@@ -102,12 +104,12 @@ class Paintball extends PlotComponent {
|
|
|
102
104
|
*/
|
|
103
105
|
async onAdd(map, gl) {
|
|
104
106
|
gl.getExtension('OES_texture_float');
|
|
105
|
-
const program = new WGLProgram(gl, paintball_vertex_shader_src, paintball_fragment_shader_src);
|
|
106
107
|
const { vertices: verts_buf, texcoords: tex_coords_buf } = await this.field.grid.getWGLBuffers(gl);
|
|
107
108
|
const vertices = verts_buf;
|
|
108
109
|
const texcoords = tex_coords_buf;
|
|
110
|
+
const shader_manager = new ShaderProgramManager(paintball_vertex_shader_src, paintball_fragment_shader_src, []);
|
|
109
111
|
this.gl_elems = {
|
|
110
|
-
gl: gl,
|
|
112
|
+
gl: gl, shader_manager: shader_manager, vertices: vertices, texcoords: texcoords,
|
|
111
113
|
};
|
|
112
114
|
this.updateField(this.field);
|
|
113
115
|
}
|
|
@@ -115,23 +117,26 @@ class Paintball extends PlotComponent {
|
|
|
115
117
|
* @internal
|
|
116
118
|
* Render the paintball plot
|
|
117
119
|
*/
|
|
118
|
-
render(gl,
|
|
120
|
+
render(gl, arg) {
|
|
119
121
|
if (this.gl_elems === null || this.fill_texture === null)
|
|
120
122
|
return;
|
|
121
123
|
const gl_elems = this.gl_elems;
|
|
122
|
-
|
|
123
|
-
|
|
124
|
+
const render_data = getRendererData(arg);
|
|
125
|
+
const program = this.gl_elems.shader_manager.getShaderProgram(gl, render_data.shaderData);
|
|
124
126
|
// Render to framebuffer
|
|
125
|
-
|
|
127
|
+
program.use({ 'a_pos': gl_elems.vertices, 'a_tex_coord': gl_elems.texcoords }, { 'u_opacity': this.opts.opacity, 'u_colors': this.color_components, 'u_num_colors': this.opts.colors.length, 'u_offset': 0,
|
|
128
|
+
...this.gl_elems.shader_manager.getShaderUniforms(render_data) }, { 'u_fill_sampler': this.fill_texture });
|
|
126
129
|
gl.enable(gl.BLEND);
|
|
127
130
|
gl.blendFuncSeparate(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA, gl.ONE, gl.ONE_MINUS_SRC_ALPHA);
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
131
|
+
program.draw();
|
|
132
|
+
if (render_data.type != 'maplibre' || !render_data.shaderData.define.includes('GLOBE')) {
|
|
133
|
+
program.setUniforms({ 'u_offset': -2 });
|
|
134
|
+
program.draw();
|
|
135
|
+
program.setUniforms({ 'u_offset': -1 });
|
|
136
|
+
program.draw();
|
|
137
|
+
program.setUniforms({ 'u_offset': 1 });
|
|
138
|
+
program.draw();
|
|
139
|
+
}
|
|
135
140
|
}
|
|
136
141
|
}
|
|
137
142
|
export default Paintball;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { RenderMethodArg, TypedArray, WebGLAnyRenderingContext } from "./AutumnTypes";
|
|
2
|
+
import { Grid } from "./Grid";
|
|
3
|
+
import { MapLikeType } from "./Map";
|
|
4
|
+
import { PlotComponent } from "./PlotComponent";
|
|
5
|
+
import { RawVectorField } from "./RawField";
|
|
6
|
+
interface ParticleTracerOptions {
|
|
7
|
+
}
|
|
8
|
+
declare class ParticleTracer<ArrayType extends TypedArray, GridType extends Grid, MapType extends MapLikeType> extends PlotComponent<MapType> {
|
|
9
|
+
field: RawVectorField<ArrayType, GridType>;
|
|
10
|
+
readonly opts: Required<ParticleTracerOptions>;
|
|
11
|
+
private gl_elems;
|
|
12
|
+
private wind_textures;
|
|
13
|
+
constructor(fields: RawVectorField<ArrayType, GridType>, opts?: ParticleTracerOptions);
|
|
14
|
+
updateField(field: RawVectorField<ArrayType, GridType>): void;
|
|
15
|
+
onAdd(map: MapType, gl: WebGLAnyRenderingContext): Promise<void>;
|
|
16
|
+
onRemove(map: MapType, gl: WebGLAnyRenderingContext): void;
|
|
17
|
+
render(gl: WebGLAnyRenderingContext, args: RenderMethodArg): void;
|
|
18
|
+
}
|
|
19
|
+
export { ParticleTracer };
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { WGLTexture } from "autumn-wgl";
|
|
2
|
+
import { PlotComponent } from "./PlotComponent";
|
|
3
|
+
import { normalizeOptions } from "./utils";
|
|
4
|
+
const particle_tracer_opt_defaults = {};
|
|
5
|
+
class ParticleTracer extends PlotComponent {
|
|
6
|
+
constructor(fields, opts) {
|
|
7
|
+
super();
|
|
8
|
+
this.field = fields;
|
|
9
|
+
this.opts = normalizeOptions(opts, particle_tracer_opt_defaults);
|
|
10
|
+
this.gl_elems = null;
|
|
11
|
+
this.wind_textures = null;
|
|
12
|
+
}
|
|
13
|
+
updateField(field) {
|
|
14
|
+
this.field = field;
|
|
15
|
+
if (this.gl_elems === null)
|
|
16
|
+
return;
|
|
17
|
+
const gl = this.gl_elems.gl;
|
|
18
|
+
const { u: u_image, v: v_image } = this.field.getWGLTextureSpecs(gl, gl.NEAREST);
|
|
19
|
+
if (this.wind_textures === null) {
|
|
20
|
+
this.wind_textures = { u: new WGLTexture(gl, u_image), v: new WGLTexture(gl, v_image) };
|
|
21
|
+
}
|
|
22
|
+
else {
|
|
23
|
+
this.wind_textures.u.setImageData(u_image);
|
|
24
|
+
this.wind_textures.v.setImageData(v_image);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
async onAdd(map, gl) {
|
|
28
|
+
const { rotation: proj_rotation_tex } = this.field.grid.getVectorRotationTexture(gl, this.field.relative_to == 'earth');
|
|
29
|
+
this.gl_elems = { gl: gl, proj_rot_texture: proj_rotation_tex };
|
|
30
|
+
this.updateField(this.field);
|
|
31
|
+
}
|
|
32
|
+
onRemove(map, gl) {
|
|
33
|
+
}
|
|
34
|
+
render(gl, args) {
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
export { ParticleTracer };
|
package/lib/PlotComponent.d.ts
CHANGED
|
@@ -1,25 +1,24 @@
|
|
|
1
1
|
import * as Comlink from 'comlink';
|
|
2
2
|
import { MapLikeType } from './Map';
|
|
3
|
-
import { WebGLAnyRenderingContext } from './AutumnTypes';
|
|
3
|
+
import { RenderMethodArg, TypedArrayStr, WebGLAnyRenderingContext } from './AutumnTypes';
|
|
4
4
|
declare const layer_worker: Comlink.Remote<{
|
|
5
|
-
makeBBElements: (field_lats: Float32Array, field_lons: Float32Array,
|
|
5
|
+
makeBBElements: (field_lats: Float32Array, field_lons: Float32Array, min_zoom: Uint8Array, field_ni: number, field_nj: number, map_max_zoom: number) => {
|
|
6
6
|
pts: Float32Array;
|
|
7
7
|
tex_coords: Float32Array;
|
|
8
8
|
};
|
|
9
9
|
makeDomainVerticesAndTexCoords: (field_lats: Float32Array, field_lons: Float32Array, field_ni: number, field_nj: number, texcoord_margin_r: number, texcoord_margin_s: number) => {
|
|
10
10
|
vertices: Float32Array;
|
|
11
11
|
tex_coords: Float32Array;
|
|
12
|
-
grid_cell_size: Float32Array;
|
|
13
12
|
};
|
|
14
13
|
makePolyLines: (lines: import("./AutumnTypes").LineData[]) => import("./AutumnTypes").Polyline;
|
|
15
14
|
}>;
|
|
16
15
|
declare abstract class PlotComponent<MapType extends MapLikeType> {
|
|
17
16
|
abstract onAdd(map: MapType, gl: WebGLAnyRenderingContext): Promise<void>;
|
|
18
|
-
abstract render(gl: WebGLAnyRenderingContext,
|
|
17
|
+
abstract render(gl: WebGLAnyRenderingContext, arg: RenderMethodArg): void;
|
|
19
18
|
}
|
|
20
|
-
declare function getGLFormatTypeAlignment(gl: WebGLAnyRenderingContext,
|
|
21
|
-
format: 33325 | 33326 | 6409;
|
|
22
|
-
type: 36193 | 5131 | 5126;
|
|
19
|
+
declare function getGLFormatTypeAlignment(gl: WebGLAnyRenderingContext, array_dtype: TypedArrayStr): {
|
|
20
|
+
format: 33321 | 33325 | 33326 | 6409;
|
|
21
|
+
type: 36193 | 5131 | 5121 | 5126;
|
|
23
22
|
row_alignment: number;
|
|
24
23
|
};
|
|
25
24
|
export { PlotComponent, layer_worker, getGLFormatTypeAlignment };
|
package/lib/PlotComponent.js
CHANGED
|
@@ -5,10 +5,10 @@ const worker = new Worker(new URL('./PlotLayer.worker', import.meta.url));
|
|
|
5
5
|
const layer_worker = Comlink.wrap(worker);
|
|
6
6
|
class PlotComponent {
|
|
7
7
|
}
|
|
8
|
-
function getGLFormatTypeAlignment(gl,
|
|
8
|
+
function getGLFormatTypeAlignment(gl, array_dtype) {
|
|
9
9
|
let format, type, row_alignment;
|
|
10
10
|
const is_webgl2 = isWebGL2Ctx(gl);
|
|
11
|
-
if (
|
|
11
|
+
if (array_dtype == 'float16') {
|
|
12
12
|
const ext = gl.getExtension('OES_texture_half_float');
|
|
13
13
|
const ext_lin = gl.getExtension('OES_texture_half_float_linear');
|
|
14
14
|
if (is_webgl2) {
|
|
@@ -23,7 +23,7 @@ function getGLFormatTypeAlignment(gl, is_float16) {
|
|
|
23
23
|
}
|
|
24
24
|
row_alignment = 2;
|
|
25
25
|
}
|
|
26
|
-
else {
|
|
26
|
+
else if (array_dtype == 'float32') {
|
|
27
27
|
const ext = gl.getExtension('OES_texture_float');
|
|
28
28
|
const ext_lin = gl.getExtension('OES_texture_float_linear');
|
|
29
29
|
// As of 11/3/2023, Safari/WebKit on iOS reports as supporting float textures,
|
|
@@ -39,6 +39,11 @@ function getGLFormatTypeAlignment(gl, is_float16) {
|
|
|
39
39
|
type = gl.FLOAT;
|
|
40
40
|
row_alignment = 4;
|
|
41
41
|
}
|
|
42
|
+
else {
|
|
43
|
+
format = is_webgl2 ? gl.R8 : gl.LUMINANCE;
|
|
44
|
+
type = gl.UNSIGNED_BYTE;
|
|
45
|
+
row_alignment = 1;
|
|
46
|
+
}
|
|
42
47
|
return { format: format, type: type, row_alignment: row_alignment };
|
|
43
48
|
}
|
|
44
49
|
export { PlotComponent, layer_worker, getGLFormatTypeAlignment };
|
package/lib/PlotLayer.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { WebGLAnyRenderingContext } from './AutumnTypes';
|
|
1
|
+
import { RenderMethodArg, WebGLAnyRenderingContext } from './AutumnTypes';
|
|
2
2
|
import { MapLikeType } from './Map';
|
|
3
3
|
import { PlotComponent } from './PlotComponent';
|
|
4
4
|
declare abstract class PlotLayerBase<MapType extends MapLikeType> {
|
|
@@ -36,7 +36,7 @@ declare class PlotLayer<MapType extends MapLikeType> extends PlotLayerBase<MapTy
|
|
|
36
36
|
* @internal
|
|
37
37
|
* Render this layer
|
|
38
38
|
*/
|
|
39
|
-
render(gl: WebGLAnyRenderingContext, matrix:
|
|
39
|
+
render(gl: WebGLAnyRenderingContext, matrix: RenderMethodArg): void;
|
|
40
40
|
}
|
|
41
41
|
/**
|
|
42
42
|
* A varying map layer. If the data don't have a varying component, such as over time, it might be easier to use an {@link PlotLayer} instead.
|
|
@@ -70,7 +70,7 @@ declare class MultiPlotLayer<MapType extends MapLikeType> extends PlotLayerBase<
|
|
|
70
70
|
* @internal
|
|
71
71
|
* Render this layer
|
|
72
72
|
*/
|
|
73
|
-
render(gl: WebGLAnyRenderingContext, matrix:
|
|
73
|
+
render(gl: WebGLAnyRenderingContext, matrix: RenderMethodArg): void;
|
|
74
74
|
/**
|
|
75
75
|
* Set the active key
|
|
76
76
|
* @param key - The new key. The field with that key is plotted immediately.
|
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
import { LineData, Polyline } from "./AutumnTypes";
|
|
2
|
-
declare function makeBBElements(field_lats: Float32Array, field_lons: Float32Array,
|
|
2
|
+
declare function makeBBElements(field_lats: Float32Array, field_lons: Float32Array, min_zoom: Uint8Array, field_ni: number, field_nj: number, map_max_zoom: number): {
|
|
3
3
|
pts: Float32Array;
|
|
4
4
|
tex_coords: Float32Array;
|
|
5
5
|
};
|
|
6
6
|
declare function makeDomainVerticesAndTexCoords(field_lats: Float32Array, field_lons: Float32Array, field_ni: number, field_nj: number, texcoord_margin_r: number, texcoord_margin_s: number): {
|
|
7
7
|
vertices: Float32Array;
|
|
8
8
|
tex_coords: Float32Array;
|
|
9
|
-
grid_cell_size: Float32Array;
|
|
10
9
|
};
|
|
11
10
|
declare function makePolylines(lines: LineData[]): Polyline;
|
|
12
11
|
declare const ep_interface: {
|
package/lib/PlotLayer.worker.js
CHANGED
|
@@ -1,17 +1,11 @@
|
|
|
1
|
-
import { getMinZoom } from "./utils";
|
|
2
1
|
import * as Comlink from 'comlink';
|
|
3
2
|
import { LngLat } from "./Map";
|
|
4
|
-
function makeBBElements(field_lats, field_lons, field_ni, field_nj,
|
|
5
|
-
const
|
|
6
|
-
const n_coords_per_pt_pts = 3;
|
|
3
|
+
function makeBBElements(field_lats, field_lons, min_zoom, field_ni, field_nj, map_max_zoom) {
|
|
4
|
+
const n_coords_per_pt_pts = 2;
|
|
7
5
|
const n_coords_per_pt_tc = 2;
|
|
8
|
-
const
|
|
9
|
-
const
|
|
10
|
-
const
|
|
11
|
-
const field_ni_access = Math.floor((field_ni - 1) / trim_inaccessible) + 1;
|
|
12
|
-
const field_nj_access = Math.floor((field_nj - 1) / trim_inaccessible) + 1;
|
|
13
|
-
const n_elems_pts = field_ni_access * field_nj_access * n_pts_per_poly * n_coords_per_pt_pts;
|
|
14
|
-
const n_elems_tc = field_ni_access * field_nj_access * n_pts_per_poly * n_coords_per_pt_tc;
|
|
6
|
+
const field_n_access = min_zoom.filter(mz => mz <= map_max_zoom).length;
|
|
7
|
+
const n_elems_pts = field_n_access * n_coords_per_pt_pts;
|
|
8
|
+
const n_elems_tc = field_n_access * n_coords_per_pt_tc;
|
|
15
9
|
let pts = new Float32Array(n_elems_pts);
|
|
16
10
|
let tex_coords = new Float32Array(n_elems_tc);
|
|
17
11
|
let istart_pts = 0;
|
|
@@ -21,22 +15,16 @@ function makeBBElements(field_lats, field_lons, field_ni, field_nj, thin_fac_bas
|
|
|
21
15
|
const idx = ilat * field_ni + ilon;
|
|
22
16
|
const lat = field_lats[idx];
|
|
23
17
|
const lon = field_lons[idx];
|
|
24
|
-
const zoom =
|
|
25
|
-
if (zoom >
|
|
26
|
-
continue;
|
|
18
|
+
const zoom = min_zoom[idx];
|
|
19
|
+
if (zoom > map_max_zoom || lon === undefined || lat === undefined)
|
|
20
|
+
continue; // TAS: Adding the checks for lat/lon here may be a bug waiting to happen? Not sure.
|
|
27
21
|
const pt_ll = new LngLat(lon, lat).toMercatorCoord();
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
pts[istart_pts + icrnr * n_coords_per_pt_pts + 2] = zoom * 4 + actual_icrnr;
|
|
35
|
-
tex_coords[istart_tc + icrnr * n_coords_per_pt_tc + 0] = ilon / (field_ni - 1);
|
|
36
|
-
tex_coords[istart_tc + icrnr * n_coords_per_pt_tc + 1] = ilat / (field_nj - 1);
|
|
37
|
-
}
|
|
38
|
-
istart_pts += (n_pts_per_poly * n_coords_per_pt_pts);
|
|
39
|
-
istart_tc += (n_pts_per_poly * n_coords_per_pt_tc);
|
|
22
|
+
pts[istart_pts + 0] = pt_ll.x;
|
|
23
|
+
pts[istart_pts + 1] = pt_ll.y;
|
|
24
|
+
tex_coords[istart_tc + 0] = ilon / (field_ni - 1) + zoom; // Pack the min zoom in with the texture coordinates; only works because the min zoom is always an integer
|
|
25
|
+
tex_coords[istart_tc + 1] = ilat / (field_nj - 1);
|
|
26
|
+
istart_pts += n_coords_per_pt_pts;
|
|
27
|
+
istart_tc += n_coords_per_pt_tc;
|
|
40
28
|
}
|
|
41
29
|
}
|
|
42
30
|
return { 'pts': pts, 'tex_coords': tex_coords };
|
|
@@ -44,7 +32,6 @@ function makeBBElements(field_lats, field_lons, field_ni, field_nj, thin_fac_bas
|
|
|
44
32
|
function makeDomainVerticesAndTexCoords(field_lats, field_lons, field_ni, field_nj, texcoord_margin_r, texcoord_margin_s) {
|
|
45
33
|
const verts = new Float32Array(2 * 2 * (field_ni - 1) * (field_nj + 1)).fill(0);
|
|
46
34
|
const tex_coords = new Float32Array(2 * 2 * (field_ni - 1) * (field_nj + 1)).fill(0);
|
|
47
|
-
const grid_cell_size = new Float32Array(1 * 2 * (field_ni - 1) * (field_nj + 1)).fill(0);
|
|
48
35
|
let ivert = 0;
|
|
49
36
|
let itexcoord = 0;
|
|
50
37
|
for (let i = 0; i < field_ni - 1; i++) {
|
|
@@ -83,29 +70,7 @@ function makeDomainVerticesAndTexCoords(field_lats, field_lons, field_ni, field_
|
|
|
83
70
|
}
|
|
84
71
|
}
|
|
85
72
|
}
|
|
86
|
-
|
|
87
|
-
for (let i = 0; i < field_ni - 1; i++) {
|
|
88
|
-
for (let j = 0; j < field_nj - 1; j++) {
|
|
89
|
-
const ivert = j == 0 ? 2 * (igcs + 1) : 2 * igcs;
|
|
90
|
-
const x_ll = verts[ivert], y_ll = verts[ivert + 1], x_lr = verts[ivert + 2], y_lr = verts[ivert + 3], x_ul = verts[ivert + 4], y_ul = verts[ivert + 5], x_ur = verts[ivert + 6], y_ur = verts[ivert + 7];
|
|
91
|
-
const area = 0.5 * Math.abs(x_ll * (y_lr - y_ul) + x_lr * (y_ul - y_ll) + x_ul * (y_ll - y_lr) +
|
|
92
|
-
x_ur * (y_ul - y_lr) + x_ul * (y_lr - y_ur) + x_lr * (y_ur - y_ul));
|
|
93
|
-
if (j == 0) {
|
|
94
|
-
grid_cell_size[igcs] = area;
|
|
95
|
-
igcs += 1;
|
|
96
|
-
}
|
|
97
|
-
grid_cell_size[igcs] = area;
|
|
98
|
-
grid_cell_size[igcs + 1] = area;
|
|
99
|
-
igcs += 2;
|
|
100
|
-
if (j == field_nj - 2) {
|
|
101
|
-
grid_cell_size[igcs] = area;
|
|
102
|
-
grid_cell_size[igcs + 1] = area;
|
|
103
|
-
grid_cell_size[igcs + 2] = area;
|
|
104
|
-
igcs += 3;
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
return { 'vertices': verts, 'tex_coords': tex_coords, 'grid_cell_size': grid_cell_size };
|
|
73
|
+
return { 'vertices': verts, 'tex_coords': tex_coords };
|
|
109
74
|
}
|
|
110
75
|
/*
|
|
111
76
|
function makePolylinesMiter(lines) {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { LineData, WebGLAnyRenderingContext } from "./AutumnTypes";
|
|
1
|
+
import { LineData, WebGLAnyRenderingContext, RenderMethodArg } from "./AutumnTypes";
|
|
2
2
|
import { ColorMap } from "./Colormap";
|
|
3
3
|
/**
|
|
4
4
|
* A style to use to draw lines. The possible options are '-' for a solid line, '--' for a dashed line, ':' for a
|
|
@@ -9,6 +9,7 @@ type LineStyle = "-" | "--" | ":" | "-." | number[];
|
|
|
9
9
|
declare function isLineStyle(obj: any): obj is LineStyle;
|
|
10
10
|
interface PolylineCollectionOpts {
|
|
11
11
|
offset_scale?: number;
|
|
12
|
+
offset_rotates_with_map?: boolean;
|
|
12
13
|
color?: string;
|
|
13
14
|
cmap?: ColorMap;
|
|
14
15
|
line_width?: number;
|
|
@@ -17,7 +18,7 @@ interface PolylineCollectionOpts {
|
|
|
17
18
|
declare class PolylineCollection {
|
|
18
19
|
readonly width: number;
|
|
19
20
|
readonly scale: number | null;
|
|
20
|
-
private readonly
|
|
21
|
+
private readonly shader_manager;
|
|
21
22
|
private readonly vertices;
|
|
22
23
|
private readonly extrusion;
|
|
23
24
|
private readonly offset;
|
|
@@ -25,11 +26,12 @@ declare class PolylineCollection {
|
|
|
25
26
|
private readonly line_data;
|
|
26
27
|
private readonly color;
|
|
27
28
|
private readonly cmap_gpu;
|
|
29
|
+
private readonly offset_rotates_with_map;
|
|
28
30
|
private readonly dash_texture;
|
|
29
31
|
private readonly n_dash;
|
|
30
32
|
private constructor();
|
|
31
33
|
static make(gl: WebGLAnyRenderingContext, lines: LineData[], opts?: PolylineCollectionOpts): Promise<PolylineCollection>;
|
|
32
|
-
render(gl: WebGLAnyRenderingContext,
|
|
34
|
+
render(gl: WebGLAnyRenderingContext, arg: RenderMethodArg, [map_width, map_height]: [number, number], map_zoom: number, map_bearing: number, map_pitch: number): void;
|
|
33
35
|
}
|
|
34
36
|
export { PolylineCollection, isLineStyle };
|
|
35
37
|
export type { PolylineCollectionOpts, LineStyle };
|