autumnplot-gl 3.0.0 → 3.2.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 +6 -11
- package/dist/110.autumnplot-gl.js +1 -1
- package/dist/110.autumnplot-gl.js.map +1 -1
- package/dist/autumnplot-gl.js +1 -1
- package/dist/autumnplot-gl.js.map +1 -1
- package/dist/marchingsquares.wasm +0 -0
- package/lib/Barbs.d.ts +18 -2
- package/lib/Barbs.js +25 -19
- package/lib/BillboardCollection.d.ts +9 -2
- package/lib/BillboardCollection.js +46 -9
- package/lib/Color.d.ts +56 -0
- package/lib/Color.js +160 -0
- package/lib/ColorBar.d.ts +2 -1
- package/lib/ColorBar.js +5 -5
- package/lib/Colormap.d.ts +19 -18
- package/lib/Colormap.js +81 -20
- package/lib/Contour.d.ts +25 -6
- package/lib/Contour.js +61 -12
- package/lib/ContourCreator.js +4 -40
- package/lib/Fill.d.ts +2 -4
- package/lib/Fill.js +29 -45
- package/lib/Grid.d.ts +1 -0
- package/lib/Grid.js +6 -1
- package/lib/Hodographs.d.ts +19 -3
- package/lib/Hodographs.js +23 -20
- package/lib/Paintball.d.ts +2 -2
- package/lib/Paintball.js +9 -6
- package/lib/PlotComponent.js +9 -4
- package/lib/PlotLayer.d.ts +1 -1
- package/lib/PlotLayer.worker.js +10 -7
- package/lib/PolylineCollection.d.ts +13 -6
- package/lib/PolylineCollection.js +76 -64
- package/lib/StationPlot.d.ts +34 -0
- package/lib/StationPlot.js +73 -0
- package/lib/TextCollection.d.ts +3 -2
- package/lib/TextCollection.js +21 -11
- package/lib/cpp/marchingsquares.js +558 -1261
- package/lib/cpp/marchingsquares.wasm +0 -0
- package/lib/cpp/marchingsquares_embind.d.ts +4 -45
- package/lib/index.d.ts +4 -2
- package/lib/index.js +2 -1
- package/lib/utils.d.ts +2 -8
- package/lib/utils.js +1 -83
- package/package.json +2 -2
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { kdTree } from "kd-tree-javascript";
|
|
2
|
+
import { LngLat } from "./Map";
|
|
3
|
+
import { PlotComponent } from "./PlotComponent";
|
|
4
|
+
import { getMinZoom, normalizeOptions } from "./utils";
|
|
5
|
+
class UnstructuredGrid {
|
|
6
|
+
constructor(coords) {
|
|
7
|
+
this.coords = coords;
|
|
8
|
+
}
|
|
9
|
+
getZoomThinning(thin_fac, map_max_zoom) {
|
|
10
|
+
let min_label_lon = null, min_label_lat = null, max_label_lon = null, max_label_lat = null;
|
|
11
|
+
this.coords.forEach(coord => {
|
|
12
|
+
if (min_label_lon === null || coord.lon < min_label_lon)
|
|
13
|
+
min_label_lon = coord.lon;
|
|
14
|
+
if (max_label_lon === null || coord.lon > max_label_lon)
|
|
15
|
+
max_label_lon = coord.lon;
|
|
16
|
+
if (min_label_lat === null || coord.lat < min_label_lat)
|
|
17
|
+
min_label_lat = coord.lat;
|
|
18
|
+
if (max_label_lat === null || coord.lat > max_label_lat)
|
|
19
|
+
max_label_lat = coord.lat;
|
|
20
|
+
});
|
|
21
|
+
if (min_label_lon === null || min_label_lat === null || max_label_lon === null || max_label_lat === null)
|
|
22
|
+
return [];
|
|
23
|
+
const kd_nodes = this.coords.map(c => ({ lon: c.lon, lat: c.lat, min_zoom: map_max_zoom }));
|
|
24
|
+
const tree = new kdTree(kd_nodes, (a, b) => Math.hypot(a.lon - b.lon, a.lat - b.lat), ['lon', 'lat']);
|
|
25
|
+
const { x: min_label_x, y: max_label_y } = new LngLat(min_label_lon, min_label_lat).toMercatorCoord();
|
|
26
|
+
const { x: max_label_x, y: min_label_y } = new LngLat(max_label_lon, max_label_lat).toMercatorCoord();
|
|
27
|
+
const thin_grid_width = max_label_x - min_label_x;
|
|
28
|
+
const thin_grid_height = max_label_y - min_label_y;
|
|
29
|
+
const ni_thin_grid = Math.round(thin_grid_width * thin_fac); // thin_fac was 4 / contour_label_spacing for the contour labels
|
|
30
|
+
const nj_thin_grid = Math.round(thin_grid_height * thin_fac);
|
|
31
|
+
const thin_grid_xs = [];
|
|
32
|
+
const thin_grid_ys = [];
|
|
33
|
+
for (let idx = 0; idx < ni_thin_grid; idx++) {
|
|
34
|
+
thin_grid_xs.push(min_label_x + (idx / ni_thin_grid) * thin_grid_width);
|
|
35
|
+
}
|
|
36
|
+
for (let jdy = 0; jdy < nj_thin_grid; jdy++) {
|
|
37
|
+
thin_grid_ys.push(min_label_y + (jdy / nj_thin_grid) * thin_grid_height);
|
|
38
|
+
}
|
|
39
|
+
for (let idx = 0; idx < ni_thin_grid; idx++) {
|
|
40
|
+
for (let jdy = 0; jdy < nj_thin_grid; jdy++) {
|
|
41
|
+
const zoom = getMinZoom(jdy, idx, Math.pow(2, map_max_zoom));
|
|
42
|
+
const grid_x = thin_grid_xs[idx];
|
|
43
|
+
const grid_y = thin_grid_ys[jdy];
|
|
44
|
+
const ll = LngLat.fromMercatorCoord(grid_x, grid_y);
|
|
45
|
+
const [label, dist] = tree.nearest({ lon: ll.lng, lat: ll.lat, min_zoom: 0 }, 1)[0];
|
|
46
|
+
label.min_zoom = zoom;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
return kd_nodes.map(n => n.min_zoom);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
class ObsField {
|
|
53
|
+
constructor(data) {
|
|
54
|
+
this.grid = new UnstructuredGrid(data.map(d => d.coord));
|
|
55
|
+
this.data = data;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
const station_plot_opts_defaults = {};
|
|
59
|
+
class StationPlot extends PlotComponent {
|
|
60
|
+
constructor(field, data_positions, opts) {
|
|
61
|
+
super();
|
|
62
|
+
this.field = field;
|
|
63
|
+
this.data_positions = data_positions;
|
|
64
|
+
this.opts = normalizeOptions(opts, station_plot_opts_defaults);
|
|
65
|
+
}
|
|
66
|
+
async onAdd(map, gl) {
|
|
67
|
+
}
|
|
68
|
+
render(gl, matrix) {
|
|
69
|
+
if (matrix instanceof Float32Array)
|
|
70
|
+
matrix = [...matrix];
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
export { StationPlot };
|
package/lib/TextCollection.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { WebGLAnyRenderingContext } from "./AutumnTypes";
|
|
2
|
+
import { Color } from "./Color";
|
|
2
3
|
import { WGLBuffer, WGLProgram, WGLTexture } from "autumn-wgl";
|
|
3
4
|
interface TextSpec {
|
|
4
5
|
lat: number;
|
|
@@ -12,8 +13,8 @@ interface TextCollectionOptions {
|
|
|
12
13
|
horizontal_align?: HorizontalAlign;
|
|
13
14
|
vertical_align?: VerticalAlign;
|
|
14
15
|
font_size?: number;
|
|
15
|
-
text_color?:
|
|
16
|
-
halo_color?:
|
|
16
|
+
text_color?: Color;
|
|
17
|
+
halo_color?: Color;
|
|
17
18
|
halo?: boolean;
|
|
18
19
|
}
|
|
19
20
|
declare class TextCollection {
|
package/lib/TextCollection.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { isWebGL2Ctx } from "./AutumnTypes";
|
|
2
|
+
import { Color } from "./Color";
|
|
2
3
|
import { LngLat } from "./Map";
|
|
3
4
|
import { Cache, normalizeOptions } from "./utils";
|
|
4
5
|
import { WGLBuffer, WGLProgram, WGLTexture } from "autumn-wgl";
|
|
@@ -45,8 +46,8 @@ varying highp vec2 v_tex_coord;
|
|
|
45
46
|
uniform sampler2D u_sdf_sampler;
|
|
46
47
|
uniform int u_is_halo;
|
|
47
48
|
|
|
48
|
-
uniform lowp
|
|
49
|
-
uniform lowp
|
|
49
|
+
uniform lowp vec4 u_text_color;
|
|
50
|
+
uniform lowp vec4 u_halo_color;
|
|
50
51
|
|
|
51
52
|
#define SDF_FILL 0.75
|
|
52
53
|
#define SDF_HALO 0.45
|
|
@@ -57,18 +58,21 @@ void main() {
|
|
|
57
58
|
lowp float step_width = 0.08;
|
|
58
59
|
lowp float alpha = smoothstep(SDF_FILL - step_width, SDF_FILL + step_width, sdf_val);
|
|
59
60
|
|
|
60
|
-
lowp
|
|
61
|
+
lowp vec4 color = u_is_halo == 1 ? u_halo_color : u_text_color;
|
|
61
62
|
|
|
62
63
|
if (u_is_halo == 1) {
|
|
63
64
|
alpha = min(smoothstep(SDF_HALO - step_width, SDF_HALO + step_width, sdf_val), 1.0 - alpha);
|
|
64
65
|
}
|
|
65
66
|
|
|
66
|
-
|
|
67
|
+
color.a *= alpha;
|
|
68
|
+
gl_FragColor = color;
|
|
67
69
|
}`
|
|
68
70
|
const program_cache = new Cache((gl) => new WGLProgram(gl, text_vertex_shader_src, text_fragment_shader_src));
|
|
69
71
|
const PADDING = 3;
|
|
70
72
|
function parseFontPBF(data) {
|
|
71
73
|
const readGlyph = (tag, glyph, pbf) => {
|
|
74
|
+
if (pbf === undefined)
|
|
75
|
+
return;
|
|
72
76
|
switch (tag) {
|
|
73
77
|
case 1:
|
|
74
78
|
glyph.id = pbf.readVarint();
|
|
@@ -94,12 +98,16 @@ function parseFontPBF(data) {
|
|
|
94
98
|
}
|
|
95
99
|
};
|
|
96
100
|
const readFontStack = (tag, glyphs, pbf) => {
|
|
101
|
+
if (glyphs === undefined || pbf === undefined)
|
|
102
|
+
return;
|
|
97
103
|
if (tag == 3) {
|
|
98
104
|
const glyph = pbf.readMessage(readGlyph, {});
|
|
99
105
|
glyphs.push(glyph);
|
|
100
106
|
}
|
|
101
107
|
};
|
|
102
108
|
const readFontStacks = (tag, glyphs, pbf) => {
|
|
109
|
+
if (pbf === undefined)
|
|
110
|
+
return;
|
|
103
111
|
if (tag == 1) {
|
|
104
112
|
pbf.readMessage(readFontStack, glyphs);
|
|
105
113
|
}
|
|
@@ -119,6 +127,8 @@ function createAtlas(pbf_glyphs) {
|
|
|
119
127
|
const glyphs = {};
|
|
120
128
|
glyph_bins.forEach(glyph_bin => {
|
|
121
129
|
const { bin, glyph } = glyph_bin;
|
|
130
|
+
if (bin.x === undefined || bin.y === undefined)
|
|
131
|
+
throw `Potpack couldn't pack this pot, I guess?`;
|
|
122
132
|
glyphs[glyph.id] = {
|
|
123
133
|
id: glyph.id, width: glyph.width, height: glyph.height, left: glyph.left, top: glyph.top,
|
|
124
134
|
atlas_i: bin.x, atlas_j: bin.y, advance: glyph.advance
|
|
@@ -149,8 +159,8 @@ const text_collection_opt_defaults = {
|
|
|
149
159
|
horizontal_align: 'left',
|
|
150
160
|
vertical_align: 'baseline',
|
|
151
161
|
font_size: 12,
|
|
152
|
-
text_color: [0, 0, 0],
|
|
153
|
-
halo_color: [0, 0, 0],
|
|
162
|
+
text_color: new Color([0, 0, 0, 1]),
|
|
163
|
+
halo_color: new Color([0, 0, 0, 1]),
|
|
154
164
|
halo: false
|
|
155
165
|
};
|
|
156
166
|
class TextCollection {
|
|
@@ -229,22 +239,22 @@ class TextCollection {
|
|
|
229
239
|
tc_data[i_tc++] = glyph_info.atlas_j / font_atlas.atlas_height;
|
|
230
240
|
x_offset += glyph_info.advance - glyph_info.left;
|
|
231
241
|
}
|
|
232
|
-
if (opts.horizontal_align == 'center') {
|
|
242
|
+
if (this.opts.horizontal_align == 'center') {
|
|
233
243
|
for (let i = init_i_off; i < init_i_off + text.length * 12; i += 2) {
|
|
234
244
|
offset_data[i] -= x_offset / 2;
|
|
235
245
|
}
|
|
236
246
|
}
|
|
237
|
-
else if (opts.horizontal_align == 'right') {
|
|
247
|
+
else if (this.opts.horizontal_align == 'right') {
|
|
238
248
|
for (let i = init_i_off; i < init_i_off + text.length * 12; i += 2) {
|
|
239
249
|
offset_data[i] -= x_offset;
|
|
240
250
|
}
|
|
241
251
|
}
|
|
242
|
-
if (opts.vertical_align == 'top') {
|
|
252
|
+
if (this.opts.vertical_align == 'top') {
|
|
243
253
|
for (let i = init_i_off + 1; i < init_i_off + text.length * 12; i += 2) {
|
|
244
254
|
offset_data[i] -= (font_atlas.baseline - font_atlas.top);
|
|
245
255
|
}
|
|
246
256
|
}
|
|
247
|
-
else if (opts.vertical_align == 'middle') {
|
|
257
|
+
else if (this.opts.vertical_align == 'middle') {
|
|
248
258
|
for (let i = init_i_off + 1; i < init_i_off + text.length * 12; i += 2) {
|
|
249
259
|
offset_data[i] -= (font_atlas.baseline - font_atlas.top) / 2;
|
|
250
260
|
}
|
|
@@ -261,7 +271,7 @@ class TextCollection {
|
|
|
261
271
|
render(gl, matrix, [map_width, map_height], map_zoom) {
|
|
262
272
|
const uniforms = {
|
|
263
273
|
'u_matrix': matrix, 'u_map_width': map_width, 'u_map_height': map_height, 'u_map_zoom': map_zoom, 'u_font_size': this.opts.font_size,
|
|
264
|
-
'u_text_color': this.opts.text_color, 'u_halo_color': this.opts.halo_color, 'u_offset': 0
|
|
274
|
+
'u_text_color': this.opts.text_color.toRGBATuple(), 'u_halo_color': this.opts.halo_color.toRGBATuple(), 'u_offset': 0
|
|
265
275
|
};
|
|
266
276
|
uniforms['u_is_halo'] = this.opts.halo ? 1 : 0;
|
|
267
277
|
this.program.use({ 'a_pos': this.anchors, 'a_offset': this.offsets, 'a_tex_coord': this.texcoords }, uniforms, { 'u_sdf_sampler': this.texture });
|