autumnplot-gl 4.0.0-beta → 4.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 +11 -207
- package/dist/983.autumnplot-gl.js +2 -0
- package/dist/983.autumnplot-gl.js.map +1 -0
- package/dist/autumnplot-gl.js +1 -1
- package/dist/autumnplot-gl.js.map +1 -1
- package/dist/marchingsquares.wasm +0 -0
- package/lib/AutumnTypes.d.ts +34 -3
- package/lib/AutumnTypes.js +4 -1
- package/lib/Barbs.d.ts +1 -0
- package/lib/Color.d.ts +1 -0
- package/lib/Color.js +1 -0
- package/lib/ColorBar.d.ts +9 -0
- package/lib/ColorBar.js +5 -4
- package/lib/Colormap.d.ts +1 -0
- package/lib/Contour.d.ts +10 -0
- package/lib/Contour.js +10 -0
- package/lib/ContourCreator.d.ts +5 -1
- package/lib/ContourCreator.js +3 -3
- package/lib/Fill.d.ts +2 -0
- package/lib/Grid.d.ts +10 -3
- package/lib/Grid.js +61 -8
- package/lib/Hodographs.d.ts +6 -0
- package/lib/Hodographs.js +34 -19
- package/lib/Map.d.ts +14 -1
- package/lib/Map.js +59 -3
- package/lib/Paintball.d.ts +1 -0
- package/lib/Paintball.js +1 -1
- package/lib/PlotComponent.d.ts +1 -0
- package/lib/PlotComponent.js +1 -0
- package/lib/PlotLayer.d.ts +2 -2
- package/lib/PlotLayer.js +2 -2
- package/lib/PlotLayer.worker.js +8 -2
- package/lib/RawField.d.ts +2 -0
- package/lib/RawField.js +9 -2
- package/lib/StationPlot.d.ts +59 -8
- package/lib/StationPlot.js +28 -11
- package/lib/TextCollection.js +3 -0
- package/lib/index.d.ts +9 -3
- package/lib/index.js +4 -2
- package/package.json +2 -2
- package/dist/110.autumnplot-gl.js +0 -2
- package/dist/110.autumnplot-gl.js.map +0 -1
package/lib/Map.js
CHANGED
|
@@ -9,8 +9,8 @@ function lambertConformalConic(params) {
|
|
|
9
9
|
return Math.cos(lat) / Math.sqrt(1 - eccen * eccen * sin_lat * sin_lat);
|
|
10
10
|
};
|
|
11
11
|
// WGS 84 spheroid
|
|
12
|
-
const semimajor =
|
|
13
|
-
const semiminor =
|
|
12
|
+
const semimajor = params.a;
|
|
13
|
+
const semiminor = params.b;
|
|
14
14
|
const eccen = Math.sqrt(1 - (semiminor * semiminor) / (semimajor * semimajor));
|
|
15
15
|
const radians = Math.PI / 180;
|
|
16
16
|
let { lon_0, lat_0, lat_std } = params;
|
|
@@ -121,6 +121,62 @@ function rotateSphere(params) {
|
|
|
121
121
|
return opts.inverse ? compute_rotation_inverse(a, b) : compute_rotation(a, b);
|
|
122
122
|
};
|
|
123
123
|
}
|
|
124
|
+
function verticalPerspective(params) {
|
|
125
|
+
// WGS 84 spheroid
|
|
126
|
+
const semimajor = params.a;
|
|
127
|
+
const semiminor = params.b;
|
|
128
|
+
const eccen = Math.sqrt(1 - (semiminor * semiminor) / (semimajor * semimajor));
|
|
129
|
+
const radians = Math.PI / 180;
|
|
130
|
+
let { lat_0, lon_0, alt } = params;
|
|
131
|
+
const alt_0 = 0;
|
|
132
|
+
const alt_00 = 0;
|
|
133
|
+
const eccen2 = eccen * eccen;
|
|
134
|
+
lat_0 *= radians;
|
|
135
|
+
lon_0 *= radians;
|
|
136
|
+
const sin_lat_0 = Math.sin(lat_0);
|
|
137
|
+
const cos_lat_0 = Math.cos(lat_0);
|
|
138
|
+
const N1 = semimajor / Math.sqrt(1 - (eccen * sin_lat_0) ** 2);
|
|
139
|
+
let lat_g = lat_0, P = 0;
|
|
140
|
+
for (let i = 0; i < 2; i++) {
|
|
141
|
+
P = Math.cos(lat_0) / Math.cos(lat_g) * (alt + N1 + alt_00) / semimajor;
|
|
142
|
+
lat_g = lat_0 - Math.asin(N1 * eccen * eccen * sin_lat_0 * cos_lat_0 / (P * semimajor));
|
|
143
|
+
}
|
|
144
|
+
const compute_perspective = (lon, lat) => {
|
|
145
|
+
lon *= radians;
|
|
146
|
+
lat *= radians;
|
|
147
|
+
const sin_lat = Math.sin(lat);
|
|
148
|
+
const cos_lat = Math.cos(lat);
|
|
149
|
+
const N = semimajor / Math.sqrt(1 - (eccen * sin_lat) ** 2);
|
|
150
|
+
const C = (N + alt_0) / semimajor * cos_lat;
|
|
151
|
+
const S = ((N * (1 - eccen * eccen) + alt_0) / semimajor) * sin_lat;
|
|
152
|
+
const K = alt / (P * Math.cos(lat_0 - lat_g) - S * sin_lat_0 - C * cos_lat_0 * Math.cos(lon - lon_0));
|
|
153
|
+
const x = K * C * Math.sin(lon - lon_0);
|
|
154
|
+
const y = K * (P * Math.sin(lat_0 - lat_g) + S * cos_lat_0 - C * sin_lat_0 * Math.cos(lon - lon_0));
|
|
155
|
+
return [x, y];
|
|
156
|
+
};
|
|
157
|
+
const B = P * Math.cos(lat_0 - lat_g);
|
|
158
|
+
const D = P * Math.sin(lat_0 - lat_g);
|
|
159
|
+
const L = 1 - eccen2 * cos_lat_0 * cos_lat_0;
|
|
160
|
+
const G = 1 - eccen2 * sin_lat_0 * sin_lat_0;
|
|
161
|
+
const J = 2 * eccen2 * sin_lat_0 * cos_lat_0;
|
|
162
|
+
const E = 1; // If alt_0 = 0, set E = 1
|
|
163
|
+
const t = P * P * (1 - (eccen * Math.cos(lat_g)) ** 2) - E * (1 - eccen2);
|
|
164
|
+
const compute_perspective_inverse = (x, y) => {
|
|
165
|
+
const u = -2 * B * L * alt - 2 * D * G * y + B * J * y + D * J * alt;
|
|
166
|
+
const v = L * alt * alt + G * y * y - alt * J * y + (1 - eccen2) * x * x;
|
|
167
|
+
const K_prime = (-u + Math.sqrt(u * u - 4 * t * v)) / (2 * t);
|
|
168
|
+
const X = semimajor * ((B - alt / K_prime) * cos_lat_0 - (y / K_prime - D) * sin_lat_0);
|
|
169
|
+
const Y = semimajor * x / K_prime;
|
|
170
|
+
const S = (y / K_prime - D) * cos_lat_0 + (B - alt / K_prime) * sin_lat_0;
|
|
171
|
+
const lon = lon_0 + Math.atan2(Y, X);
|
|
172
|
+
const lat = Math.atan2(S, Math.sqrt((1 - eccen2) * (1 - eccen2 - S * S)));
|
|
173
|
+
return [lon / radians, lat / radians];
|
|
174
|
+
};
|
|
175
|
+
return (a, b, opts) => {
|
|
176
|
+
opts = opts === undefined ? { inverse: false } : opts;
|
|
177
|
+
return opts.inverse ? compute_perspective_inverse(a, b) : compute_perspective(a, b);
|
|
178
|
+
};
|
|
179
|
+
}
|
|
124
180
|
function mercatorXfromLng(lng) {
|
|
125
181
|
return (180 + lng) / 360;
|
|
126
182
|
}
|
|
@@ -166,4 +222,4 @@ class LngLat {
|
|
|
166
222
|
return new LngLat(lngFromMercatorX(x), latFromMercatorY(y));
|
|
167
223
|
}
|
|
168
224
|
}
|
|
169
|
-
export { LngLat, lambertConformalConic, rotateSphere };
|
|
225
|
+
export { LngLat, lambertConformalConic, rotateSphere, verticalPerspective };
|
package/lib/Paintball.d.ts
CHANGED
|
@@ -3,6 +3,7 @@ import { StructuredGrid } from "./Grid";
|
|
|
3
3
|
import { MapLikeType } from "./Map";
|
|
4
4
|
import { PlotComponent } from "./PlotComponent";
|
|
5
5
|
import { RawScalarField } from "./RawField";
|
|
6
|
+
/** Options for {@link Paintball} components */
|
|
6
7
|
interface PaintballOptions {
|
|
7
8
|
/**
|
|
8
9
|
* The list of colors (as hex strings) to use for each member in the paintball plot. The first color corresponds to member 1, the second to member 2, etc.
|
package/lib/Paintball.js
CHANGED
|
@@ -76,7 +76,7 @@ class Paintball extends PlotComponent {
|
|
|
76
76
|
super();
|
|
77
77
|
this.field = field;
|
|
78
78
|
this.opts = normalizeOptions(opts, paintball_opt_defaults);
|
|
79
|
-
this.color_components =
|
|
79
|
+
this.color_components = this.opts.colors.map(color => Color.fromHex(color).toRGBATuple()).flat();
|
|
80
80
|
this.gl_elems = null;
|
|
81
81
|
this.fill_texture = null;
|
|
82
82
|
}
|
package/lib/PlotComponent.d.ts
CHANGED
|
@@ -12,6 +12,7 @@ declare const layer_worker: Comlink.Remote<{
|
|
|
12
12
|
};
|
|
13
13
|
makePolyLines: (lines: import("./AutumnTypes").LineData[]) => import("./AutumnTypes").Polyline;
|
|
14
14
|
}>;
|
|
15
|
+
/** Base class for all plot components */
|
|
15
16
|
declare abstract class PlotComponent<MapType extends MapLikeType> {
|
|
16
17
|
abstract onAdd(map: MapType, gl: WebGLAnyRenderingContext): Promise<void>;
|
|
17
18
|
abstract render(gl: WebGLAnyRenderingContext, arg: RenderMethodArg): void;
|
package/lib/PlotComponent.js
CHANGED
|
@@ -3,6 +3,7 @@ import { getOS } from "./utils";
|
|
|
3
3
|
import { isWebGL2Ctx } from './AutumnTypes';
|
|
4
4
|
const worker = new Worker(new URL('./PlotLayer.worker', import.meta.url));
|
|
5
5
|
const layer_worker = Comlink.wrap(worker);
|
|
6
|
+
/** Base class for all plot components */
|
|
6
7
|
class PlotComponent {
|
|
7
8
|
}
|
|
8
9
|
function getGLFormatTypeAlignment(gl, array_dtype) {
|
package/lib/PlotLayer.d.ts
CHANGED
|
@@ -11,7 +11,7 @@ declare abstract class PlotLayerBase<MapType extends MapLikeType> {
|
|
|
11
11
|
protected repaint(): void;
|
|
12
12
|
}
|
|
13
13
|
/**
|
|
14
|
-
* A static map layer. The data are assumed to be static in time. If the data have a time component (e.g., a model forecast),
|
|
14
|
+
* A static map layer. The data are assumed to be static in time. If the data have a time component (e.g., a model forecast), a {@link MultiPlotLayer}
|
|
15
15
|
* may be more appropriate.
|
|
16
16
|
* @example
|
|
17
17
|
* // Create map layers from provided fields
|
|
@@ -39,7 +39,7 @@ declare class PlotLayer<MapType extends MapLikeType> extends PlotLayerBase<MapTy
|
|
|
39
39
|
render(gl: WebGLAnyRenderingContext, matrix: RenderMethodArg): void;
|
|
40
40
|
}
|
|
41
41
|
/**
|
|
42
|
-
* A varying map layer. If the data don't have a varying component, such as over time, it might be easier to use
|
|
42
|
+
* A varying map layer. If the data don't have a varying component, such as over time, it might be easier to use a {@link PlotLayer} instead.
|
|
43
43
|
* @example
|
|
44
44
|
* // Create a varying map layer
|
|
45
45
|
* height_layer = new MultiPlotLayer('height-contours');
|
package/lib/PlotLayer.js
CHANGED
|
@@ -11,7 +11,7 @@ class PlotLayerBase {
|
|
|
11
11
|
}
|
|
12
12
|
}
|
|
13
13
|
/**
|
|
14
|
-
* A static map layer. The data are assumed to be static in time. If the data have a time component (e.g., a model forecast),
|
|
14
|
+
* A static map layer. The data are assumed to be static in time. If the data have a time component (e.g., a model forecast), a {@link MultiPlotLayer}
|
|
15
15
|
* may be more appropriate.
|
|
16
16
|
* @example
|
|
17
17
|
* // Create map layers from provided fields
|
|
@@ -46,7 +46,7 @@ class PlotLayer extends PlotLayerBase {
|
|
|
46
46
|
}
|
|
47
47
|
}
|
|
48
48
|
/**
|
|
49
|
-
* A varying map layer. If the data don't have a varying component, such as over time, it might be easier to use
|
|
49
|
+
* A varying map layer. If the data don't have a varying component, such as over time, it might be easier to use a {@link PlotLayer} instead.
|
|
50
50
|
* @example
|
|
51
51
|
* // Create a varying map layer
|
|
52
52
|
* height_layer = new MultiPlotLayer('height-contours');
|
package/lib/PlotLayer.worker.js
CHANGED
|
@@ -21,7 +21,10 @@ function makeBBElements(field_lats, field_lons, min_zoom, field_ni, field_nj, ma
|
|
|
21
21
|
const pt_ll = new LngLat(lon, lat).toMercatorCoord();
|
|
22
22
|
pts[istart_pts + 0] = pt_ll.x;
|
|
23
23
|
pts[istart_pts + 1] = pt_ll.y;
|
|
24
|
-
|
|
24
|
+
// Pack the min zoom in with the texture coordinates; only works because the min zoom is always an integer
|
|
25
|
+
// Another gotcha is that if the i texcoord is 1, then that bump up the zoom that gets unpacked on the GPU, which causes may cause the last column of billboards to
|
|
26
|
+
// disappear. To fix this, cap the texcoord at 0.99999, which should be good for textures up to 10^5 pixels in size.
|
|
27
|
+
tex_coords[istart_tc + 0] = Math.min(ilon / (field_ni - 1), 0.99999) + zoom;
|
|
25
28
|
tex_coords[istart_tc + 1] = ilat / (field_nj - 1);
|
|
26
29
|
istart_pts += n_coords_per_pt_pts;
|
|
27
30
|
istart_tc += n_coords_per_pt_tc;
|
|
@@ -204,7 +207,7 @@ function makePolylinesMiter(lines) {
|
|
|
204
207
|
}
|
|
205
208
|
*/
|
|
206
209
|
function makePolylines(lines) {
|
|
207
|
-
if (lines.length == 0) {
|
|
210
|
+
if (lines.length == 0 || lines[0].vertices.length == 0) {
|
|
208
211
|
return { vertices: new Float32Array([]), extrusion: new Float32Array([]) };
|
|
209
212
|
}
|
|
210
213
|
const n_points_per_vert = Object.fromEntries(Object.entries(lines[0]).map(([k, v]) => {
|
|
@@ -252,6 +255,9 @@ function makePolylines(lines) {
|
|
|
252
255
|
const v_ll = new LngLat(...v).toMercatorCoord();
|
|
253
256
|
return [v_ll.x, v_ll.y];
|
|
254
257
|
});
|
|
258
|
+
if (line.vertices.length == 0) {
|
|
259
|
+
return;
|
|
260
|
+
}
|
|
255
261
|
const has_offsets = line.offsets !== undefined;
|
|
256
262
|
const extrusion_verts = line.offsets !== undefined ? line.offsets : verts;
|
|
257
263
|
let pt_prev, pt_this = verts[0], pt_next = verts[1];
|
package/lib/RawField.d.ts
CHANGED
|
@@ -36,7 +36,9 @@ declare class RawScalarField<ArrayType extends TypedArray, GridType extends Grid
|
|
|
36
36
|
static aggregateFields<ArrayType extends TypedArray, GridType extends Grid>(func: (...args: number[]) => number, ...args: RawScalarField<ArrayType, GridType>[]): RawScalarField<ArrayType, GridType>;
|
|
37
37
|
sampleField(lon: number, lat: number): number;
|
|
38
38
|
}
|
|
39
|
+
/** The basis vectors for vector fields (i.e, whether vectors a relative to Earth or the grid) */
|
|
39
40
|
type VectorRelativeTo = 'earth' | 'grid';
|
|
41
|
+
/** Options for {@link RawVectorField}s */
|
|
40
42
|
interface RawVectorFieldOptions {
|
|
41
43
|
/**
|
|
42
44
|
* Whether the vectors are relative to the grid ('grid') or Earth ('earth')
|
package/lib/RawField.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { Float16Array } from "@petamoriken/float16";
|
|
2
|
+
import { isStormRelativeWindProfile } from "./AutumnTypes";
|
|
2
3
|
import { contourCreator } from "./ContourCreator";
|
|
3
4
|
import { Cache, getArrayConstructor, zip } from "./utils";
|
|
4
5
|
import { getGLFormatTypeAlignment } from "./PlotComponent";
|
|
@@ -160,8 +161,14 @@ class RawProfileField {
|
|
|
160
161
|
const v = new Float16Array(this.grid.ni * this.grid.nj).fill(parseFloat('nan'));
|
|
161
162
|
profiles.forEach(prof => {
|
|
162
163
|
const idx = prof.ilon + this.grid.ni * prof.jlat;
|
|
163
|
-
|
|
164
|
-
|
|
164
|
+
if (isStormRelativeWindProfile(prof)) {
|
|
165
|
+
u[idx] = prof.smu;
|
|
166
|
+
v[idx] = prof.smv;
|
|
167
|
+
}
|
|
168
|
+
else {
|
|
169
|
+
u[idx] = 0;
|
|
170
|
+
v[idx] = 0;
|
|
171
|
+
}
|
|
165
172
|
});
|
|
166
173
|
return new RawVectorField(this.grid, u, v, { relative_to: 'grid' });
|
|
167
174
|
}
|
package/lib/StationPlot.d.ts
CHANGED
|
@@ -19,6 +19,7 @@ import { RawObsField } from "./RawField";
|
|
|
19
19
|
* | `'c'` | center |
|
|
20
20
|
*/
|
|
21
21
|
type SPPosition = 'cl' | 'll' | 'lc' | 'lr' | 'cr' | 'ur' | 'uc' | 'ul' | 'c';
|
|
22
|
+
/** Configuration for numerical values on station plots */
|
|
22
23
|
interface SPNumberConfig {
|
|
23
24
|
type: 'number';
|
|
24
25
|
/**
|
|
@@ -30,6 +31,16 @@ interface SPNumberConfig {
|
|
|
30
31
|
* @default '#000000'
|
|
31
32
|
*/
|
|
32
33
|
color?: string;
|
|
34
|
+
/**
|
|
35
|
+
* Whether to draw a halo (outline) around the number
|
|
36
|
+
* @default true;
|
|
37
|
+
*/
|
|
38
|
+
halo?: boolean;
|
|
39
|
+
/**
|
|
40
|
+
* The color to use for the halo (outline)
|
|
41
|
+
* @default '#ffffff'
|
|
42
|
+
*/
|
|
43
|
+
halo_color?: string;
|
|
33
44
|
/**
|
|
34
45
|
* A function that properly formats the number for display
|
|
35
46
|
* @example (val) => val === null ? '' : val.toFixed(0)
|
|
@@ -38,22 +49,34 @@ interface SPNumberConfig {
|
|
|
38
49
|
*/
|
|
39
50
|
formatter?: (val: number | null) => string;
|
|
40
51
|
}
|
|
52
|
+
/** Configuration for strings on station plots */
|
|
41
53
|
interface SPStringConfig {
|
|
42
54
|
type: 'string';
|
|
43
55
|
/**
|
|
44
|
-
* The position on the station plot at which to place the
|
|
56
|
+
* The position on the station plot at which to place the string
|
|
45
57
|
*/
|
|
46
58
|
pos: SPPosition;
|
|
47
59
|
/**
|
|
48
|
-
* The color to use to draw the
|
|
60
|
+
* The color to use to draw the string
|
|
49
61
|
* @default '#000000'
|
|
50
62
|
*/
|
|
51
63
|
color?: string;
|
|
64
|
+
/**
|
|
65
|
+
* Whether to draw a halo (outline) around the string
|
|
66
|
+
* @default true;
|
|
67
|
+
*/
|
|
68
|
+
halo?: boolean;
|
|
69
|
+
/**
|
|
70
|
+
* The color to use for the halo (outline)
|
|
71
|
+
* @default '#ffffff'
|
|
72
|
+
*/
|
|
73
|
+
halo_color?: string;
|
|
52
74
|
}
|
|
75
|
+
/** Configuration for wind barbs on station plots */
|
|
53
76
|
interface SPBarbConfig {
|
|
54
77
|
type: 'barb';
|
|
55
78
|
/**
|
|
56
|
-
* The color to use to draw the
|
|
79
|
+
* The color to use to draw the barb
|
|
57
80
|
* @default '#000000'
|
|
58
81
|
*/
|
|
59
82
|
color?: string;
|
|
@@ -67,18 +90,30 @@ interface SPBarbConfig {
|
|
|
67
90
|
* Accepted symbol codes for sky cover and present weather symbols
|
|
68
91
|
*/
|
|
69
92
|
type SPSymbol = ('0/8' | '1/8' | '2/8' | '3/8' | '4/8' | '5/8' | '6/8' | '7/8' | '8/8' | 'clr' | 'few' | 'sct' | 'bkn' | 'ovc' | 'obsc' | 'va' | 'fu' | 'hz' | 'du' | 'bldu' | 'sa' | 'blsa' | 'vcblsa' | 'vcbldu' | 'blpy' | 'po' | 'vcpo' | 'vcds' | 'vcss' | 'br' | 'bcbr' | 'bc' | 'mifg' | 'vcts' | 'virga' | 'vcsh' | 'ts' | 'thdr' | 'vctshz' | 'tsfzfg' | 'tsbr' | 'tsdz' | 'vctsup' | '-tsup' | 'tsup' | '+tsup' | 'sq' | 'fc' | '+fc' | 'ds' | 'ss' | 'drsa' | 'drdu' | '+ds' | '+ss' | 'drsn' | '+drsn' | '-blsn' | 'blsn' | '+blsn' | 'vcblsn' | 'vcfg' | 'bcfg' | 'prfg' | 'fg' | 'fzfg' | '-vctsdz' | '-dz' | '-dzbr' | 'vctsdz' | 'dz' | '+vctsdz' | '+dz' | '-fzdz' | '-fzdzsn' | 'fzdz' | '+fzdz' | 'fzdzsn' | '-dzra' | 'dzra' | '+dzra' | '-ra' | '-rabr' | 'ra' | 'rabr' | 'rafg' | 'vcra' | '+ra' | '-fzra' | '-fzrasn' | '-fzrabr' | '-fzrapl' | '-fzrasnpl' | 'tsfzrapl' | '-tsfzra' | 'fzra' | '+fzra' | 'fzrasn' | 'tsfzra' | '-dzsn' | '-rasn' | '-snra' | '-sndz' | 'rasn' | '+rasn' | 'snra' | 'dzsn' | 'sndz' | '+dzsn' | '+sndz' | '-sn' | '-snbr' | 'sn' | '+sn' | '-snsg' | 'sg' | '-sg' | 'ic' | '-fzdzpl' | '-fzdzplsn' | 'fzdzpl' | '-fzraplsn' | 'fzrapl' | '+fzrapl' | '-rapl' | '-rasnpl' | '-raplsn' | '+rapl' | 'rapl' | '-snpl' | 'snpl' | '-pl' | 'pl' | '-plsn' | '-plra' | 'plra' | '-pldz' | '+pl' | 'plsn' | 'plup' | '+plsn' | '-sh' | '-shra' | 'sh' | 'shra' | '+sh' | '+shra' | '-shrasn' | '-shsnra' | '+shrabr' | 'shrasn' | '+shrasn' | 'shsnra' | '+shsnra' | '-shsn' | 'shsn' | '+shsn' | '-gs' | '-shgs' | 'fzraplgs' | '-sngs' | 'gsplsn' | 'gspl' | 'plgssn' | 'gs' | 'shgs' | '+gs' | '+shgs' | '-gr' | '-shgr' | '-sngr' | 'gr' | 'shgr' | '+gr' | '+shgr' | '-tsrasn' | 'tsrasn' | '-tssnra' | 'tssnra' | '-vctsra' | '-tsra' | 'tsra' | '-tsdz' | 'vctsra' | 'tspl' | '-tssn' | '-tspl' | 'tssn' | '-vctssn' | 'vctssn' | 'tsplsn' | 'tssnpl' | '-tssnpl' | '-tsragr' | 'tsrags' | 'tsragr' | 'tsgs' | 'tsgr' | '+tsfzrapl' | '+vctsra' | '+tsra' | '+tsfzra' | '+tssn' | '+tspl' | '+tsplsn' | '+vctssn' | 'tssa' | 'tsds' | 'tsdu' | '+tsgs' | '+tsgr' | '+tsrags' | '+tsragr' | 'in' | '-up' | 'up' | '+up' | '-fzup' | 'fzup' | '+fzup');
|
|
93
|
+
/** Configuration for symbols on station plots */
|
|
70
94
|
interface SPSymbolConfig {
|
|
71
95
|
type: 'symbol';
|
|
72
96
|
/**
|
|
73
|
-
* The position on the station plot at which to place the
|
|
97
|
+
* The position on the station plot at which to place the symbol
|
|
74
98
|
*/
|
|
75
99
|
pos: SPPosition;
|
|
76
100
|
/**
|
|
77
|
-
* The color to use to draw the
|
|
101
|
+
* The color to use to draw the symbol
|
|
78
102
|
* @default '#000000'
|
|
79
103
|
*/
|
|
80
104
|
color?: string;
|
|
105
|
+
/**
|
|
106
|
+
* Whether to draw a halo (outline) around the string
|
|
107
|
+
* @default true;
|
|
108
|
+
*/
|
|
109
|
+
halo?: boolean;
|
|
110
|
+
/**
|
|
111
|
+
* The color to use for the halo (outline)
|
|
112
|
+
* @default '#ffffff'
|
|
113
|
+
*/
|
|
114
|
+
halo_color?: string;
|
|
81
115
|
}
|
|
116
|
+
/** Configuration for station plot sub-elements */
|
|
82
117
|
type SPConfig = SPNumberConfig | SPStringConfig | SPBarbConfig | SPSymbolConfig;
|
|
83
118
|
/**
|
|
84
119
|
* Configuration for station data plots
|
|
@@ -98,6 +133,7 @@ type SPConfig = SPNumberConfig | SPStringConfig | SPBarbConfig | SPSymbolConfig;
|
|
|
98
133
|
* }
|
|
99
134
|
*/
|
|
100
135
|
type SPDataConfig<ObsFieldName extends string> = Record<ObsFieldName, SPConfig>;
|
|
136
|
+
/** Options for {@link StationPlot} components */
|
|
101
137
|
interface StationPlotOptions<ObsFieldName extends string> {
|
|
102
138
|
config: SPDataConfig<ObsFieldName>;
|
|
103
139
|
/**
|
|
@@ -120,15 +156,30 @@ interface StationPlotOptions<ObsFieldName extends string> {
|
|
|
120
156
|
*/
|
|
121
157
|
font_url_template?: string;
|
|
122
158
|
}
|
|
159
|
+
/**
|
|
160
|
+
* Station model plots for observed data
|
|
161
|
+
* @example
|
|
162
|
+
* // Specify how to set up the station plot
|
|
163
|
+
* const station_plot_locs = {
|
|
164
|
+
* tmpf: {type: 'number', pos: 'ul', color: '#cc0000', formatter: val => val === null ? '' : val.toFixed(0)},
|
|
165
|
+
* dwpf: {type: 'number', pos: 'll', color: '#00aa00', formatter: val => val === null ? '' : val.toFixed(0)},
|
|
166
|
+
* wind: {type: 'barb', pos: 'c'},
|
|
167
|
+
* preswx: {type: 'symbol', pos: 'cl', color: '#ff00ff'},
|
|
168
|
+
* skyc: {type: 'symbol', pos: 'c'},
|
|
169
|
+
* };
|
|
170
|
+
*
|
|
171
|
+
* // Create the station plot
|
|
172
|
+
* const station_plot = new StationPlot(obs_field, {config: station_plot_locs, thin_fac: 8, font_size: 14});
|
|
173
|
+
*/
|
|
123
174
|
declare class StationPlot<GridType extends Grid, MapType extends MapLikeType, ObsFieldName extends string> extends PlotComponent<MapType> {
|
|
124
175
|
private field;
|
|
125
176
|
readonly opts: Required<StationPlotOptions<ObsFieldName>>;
|
|
126
177
|
private gl_elems;
|
|
127
178
|
private text_components;
|
|
128
179
|
/**
|
|
129
|
-
*
|
|
130
|
-
* @param field
|
|
131
|
-
* @param opts
|
|
180
|
+
* Create station plots
|
|
181
|
+
* @param field - A field containing the observed data
|
|
182
|
+
* @param opts - Various options for the station plots
|
|
132
183
|
*/
|
|
133
184
|
constructor(field: RawObsField<GridType, ObsFieldName>, opts: StationPlotOptions<ObsFieldName>);
|
|
134
185
|
/**
|
package/lib/StationPlot.js
CHANGED
|
@@ -76,11 +76,26 @@ function positionToAlignmentAndOffset(pos, off_size) {
|
|
|
76
76
|
}
|
|
77
77
|
return { horizontal_align: ha, vertical_align: va, offset_x: xoff, offset_y: yoff };
|
|
78
78
|
}
|
|
79
|
+
/**
|
|
80
|
+
* Station model plots for observed data
|
|
81
|
+
* @example
|
|
82
|
+
* // Specify how to set up the station plot
|
|
83
|
+
* const station_plot_locs = {
|
|
84
|
+
* tmpf: {type: 'number', pos: 'ul', color: '#cc0000', formatter: val => val === null ? '' : val.toFixed(0)},
|
|
85
|
+
* dwpf: {type: 'number', pos: 'll', color: '#00aa00', formatter: val => val === null ? '' : val.toFixed(0)},
|
|
86
|
+
* wind: {type: 'barb', pos: 'c'},
|
|
87
|
+
* preswx: {type: 'symbol', pos: 'cl', color: '#ff00ff'},
|
|
88
|
+
* skyc: {type: 'symbol', pos: 'c'},
|
|
89
|
+
* };
|
|
90
|
+
*
|
|
91
|
+
* // Create the station plot
|
|
92
|
+
* const station_plot = new StationPlot(obs_field, {config: station_plot_locs, thin_fac: 8, font_size: 14});
|
|
93
|
+
*/
|
|
79
94
|
class StationPlot extends PlotComponent {
|
|
80
95
|
/**
|
|
81
|
-
*
|
|
82
|
-
* @param field
|
|
83
|
-
* @param opts
|
|
96
|
+
* Create station plots
|
|
97
|
+
* @param field - A field containing the observed data
|
|
98
|
+
* @param opts - Various options for the station plots
|
|
84
99
|
*/
|
|
85
100
|
constructor(field, opts) {
|
|
86
101
|
super();
|
|
@@ -110,8 +125,9 @@ class StationPlot extends PlotComponent {
|
|
|
110
125
|
const k = k_;
|
|
111
126
|
if (config.type == 'number' || config.type == 'string') {
|
|
112
127
|
const pos = config.pos;
|
|
113
|
-
const
|
|
114
|
-
const
|
|
128
|
+
const color = config.color === undefined ? Color.fromHex('#000000') : Color.normalizeColor(config.color);
|
|
129
|
+
const halo_color = config.halo_color === undefined ? Color.fromHex('#ffffff') : Color.normalizeColor(config.halo_color);
|
|
130
|
+
const halo = config.halo === undefined ? true : config.halo;
|
|
115
131
|
const coords = this.field.grid.getEarthCoords();
|
|
116
132
|
const zoom = this.field.grid.getMinVisibleZoom(this.opts.thin_fac);
|
|
117
133
|
let text_specs;
|
|
@@ -126,8 +142,8 @@ class StationPlot extends PlotComponent {
|
|
|
126
142
|
}
|
|
127
143
|
const tc_opts = {
|
|
128
144
|
...positionToAlignmentAndOffset(pos),
|
|
129
|
-
font_size: this.opts.font_size, halo:
|
|
130
|
-
text_color: color, halo_color:
|
|
145
|
+
font_size: this.opts.font_size, halo: halo,
|
|
146
|
+
text_color: color, halo_color: halo_color,
|
|
131
147
|
};
|
|
132
148
|
return await TextCollection.make(gl, text_specs, font_url, tc_opts);
|
|
133
149
|
}
|
|
@@ -138,8 +154,9 @@ class StationPlot extends PlotComponent {
|
|
|
138
154
|
}
|
|
139
155
|
else if (config.type == 'symbol') {
|
|
140
156
|
const pos = config.pos;
|
|
141
|
-
const
|
|
142
|
-
const
|
|
157
|
+
const color = config.color === undefined ? Color.fromHex('#000000') : Color.normalizeColor(config.color);
|
|
158
|
+
const halo_color = config.halo_color === undefined ? Color.fromHex('#ffffff') : Color.normalizeColor(config.halo_color);
|
|
159
|
+
const halo = config.halo === undefined ? true : config.halo;
|
|
143
160
|
const comp = this.field.getStrings(k);
|
|
144
161
|
const coords = this.field.grid.getEarthCoords();
|
|
145
162
|
const zoom = this.field.grid.getMinVisibleZoom(this.opts.thin_fac);
|
|
@@ -148,8 +165,8 @@ class StationPlot extends PlotComponent {
|
|
|
148
165
|
lat: coords.lats[i], lon: coords.lons[i], min_zoom: zoom[i] }));
|
|
149
166
|
const tc_opts = {
|
|
150
167
|
...positionToAlignmentAndOffset(pos),
|
|
151
|
-
font_size: this.opts.font_size, halo:
|
|
152
|
-
text_color: color, halo_color:
|
|
168
|
+
font_size: this.opts.font_size, halo: halo,
|
|
169
|
+
text_color: color, halo_color: halo_color,
|
|
153
170
|
};
|
|
154
171
|
if (tc_opts.offset_x !== undefined)
|
|
155
172
|
tc_opts.offset_x -= 3;
|
package/lib/TextCollection.js
CHANGED
|
@@ -154,6 +154,9 @@ function createAtlas(pbf_glyphs) {
|
|
|
154
154
|
const FONT_ATLAS_CACHE = new Cache(async (urls) => {
|
|
155
155
|
const promises = urls.map(async (url) => {
|
|
156
156
|
const resp = await fetch(url);
|
|
157
|
+
if (resp.status != 200) {
|
|
158
|
+
throw `Error ${resp.status} retrieving font pbf from '${url}'`;
|
|
159
|
+
}
|
|
157
160
|
const blob = await resp.blob();
|
|
158
161
|
const data_buffer = await blob.arrayBuffer();
|
|
159
162
|
// Parse the PBF and get the glyph data
|
package/lib/index.d.ts
CHANGED
|
@@ -6,7 +6,7 @@ import Paintball, { PaintballOptions } from "./Paintball";
|
|
|
6
6
|
import Hodographs, { HodographOptions } from './Hodographs';
|
|
7
7
|
import StationPlot, { StationPlotOptions, SPPosition, SPNumberConfig, SPStringConfig, SPBarbConfig, SPSymbolConfig, SPConfig, SPDataConfig, SPSymbol } from "./StationPlot";
|
|
8
8
|
import { PlotLayer, MultiPlotLayer } from './PlotLayer';
|
|
9
|
-
import { WindProfile, WebGLAnyRenderingContext, TypedArray, ContourData } from "./AutumnTypes";
|
|
9
|
+
import { WindProfile, StormRelativeWindProfile, GroundRelativeWindProfile, WebGLAnyRenderingContext, TypedArray, ContourData } from "./AutumnTypes";
|
|
10
10
|
import { MapLikeType } from "./Map";
|
|
11
11
|
import { ColorMap, ColorMapOptions } from './Colormap';
|
|
12
12
|
import { Color } from "./Color";
|
|
@@ -15,6 +15,7 @@ import { LineStyle } from "./PolylineCollection";
|
|
|
15
15
|
import { RawScalarField, RawVectorField, RawProfileField, VectorRelativeTo, RawVectorFieldOptions, RawObsField, ObsRawData } from "./RawField";
|
|
16
16
|
import { Grid, GridType, StructuredGrid, PlateCarreeGrid, PlateCarreeRotatedGrid, LambertGrid, UnstructuredGrid } from './Grid';
|
|
17
17
|
import { FieldContourOpts } from './ContourCreator';
|
|
18
|
+
/** All built-in colormaps */
|
|
18
19
|
declare const colormaps: {
|
|
19
20
|
bluered: (level_min: number, level_max: number, n_colors: number) => ColorMap;
|
|
20
21
|
redblue: (level_min: number, level_max: number, n_colors: number) => ColorMap;
|
|
@@ -25,9 +26,14 @@ declare const colormaps: {
|
|
|
25
26
|
pw_td2m: ColorMap;
|
|
26
27
|
nws_storm_clear_refl: ColorMap;
|
|
27
28
|
};
|
|
29
|
+
/** Options for initializing the autumnplot-gl library */
|
|
30
|
+
interface InitAutumnPlotOpts {
|
|
31
|
+
/** Base URL at which to find the WASM module (change with caution!) */
|
|
32
|
+
wasm_base_url?: string;
|
|
33
|
+
}
|
|
28
34
|
/**
|
|
29
35
|
* Initialize the WebAssembly module in autumnplot-gl. It's not strictly necessary to call it first, but if you call it
|
|
30
36
|
* first, you can prevent races when you contour a bunch of fields at once.
|
|
31
37
|
*/
|
|
32
|
-
declare function initAutumnPlot(): void;
|
|
33
|
-
export { PlotComponent, Barbs, BarbsOptions, Contour, ContourOptions, ContourLabels, ContourLabelOptions, ContourFill, Raster, ContourFillOptions, RasterOptions, Paintball, PaintballOptions, Hodographs, HodographOptions, WindProfile, StationPlot, StationPlotOptions, SPPosition, SPNumberConfig, SPStringConfig, SPBarbConfig, SPSymbolConfig, SPConfig, SPDataConfig, SPSymbol, PlotLayer, MultiPlotLayer, MapLikeType, LineStyle, ColorMap, ColorMapOptions, colormaps, makeColorBar, makePaintballKey, Color, ColorbarOrientation, ColorbarTickDirection, ColorBarOptions, PaintballKeyOptions, RawScalarField, RawVectorField, RawProfileField, RawObsField, ObsRawData, Grid, GridType, StructuredGrid, VectorRelativeTo, RawVectorFieldOptions, PlateCarreeGrid, PlateCarreeRotatedGrid, LambertGrid, UnstructuredGrid, WebGLAnyRenderingContext, TypedArray, ContourData, initAutumnPlot, FieldContourOpts };
|
|
38
|
+
declare function initAutumnPlot(opts?: InitAutumnPlotOpts): void;
|
|
39
|
+
export { PlotComponent, Barbs, BarbsOptions, Contour, ContourOptions, ContourLabels, ContourLabelOptions, ContourFill, Raster, ContourFillOptions, RasterOptions, Paintball, PaintballOptions, Hodographs, HodographOptions, WindProfile, StormRelativeWindProfile, GroundRelativeWindProfile, StationPlot, StationPlotOptions, SPPosition, SPNumberConfig, SPStringConfig, SPBarbConfig, SPSymbolConfig, SPConfig, SPDataConfig, SPSymbol, PlotLayer, MultiPlotLayer, MapLikeType, LineStyle, ColorMap, ColorMapOptions, colormaps, makeColorBar, makePaintballKey, Color, ColorbarOrientation, ColorbarTickDirection, ColorBarOptions, PaintballKeyOptions, RawScalarField, RawVectorField, RawProfileField, RawObsField, ObsRawData, Grid, GridType, StructuredGrid, VectorRelativeTo, RawVectorFieldOptions, PlateCarreeGrid, PlateCarreeRotatedGrid, LambertGrid, UnstructuredGrid, WebGLAnyRenderingContext, TypedArray, ContourData, initAutumnPlot, InitAutumnPlotOpts, FieldContourOpts };
|
package/lib/index.js
CHANGED
|
@@ -12,6 +12,7 @@ import { makeColorBar, makePaintballKey } from "./ColorBar";
|
|
|
12
12
|
import { RawScalarField, RawVectorField, RawProfileField, RawObsField } from "./RawField";
|
|
13
13
|
import { Grid, StructuredGrid, PlateCarreeGrid, PlateCarreeRotatedGrid, LambertGrid, UnstructuredGrid } from './Grid';
|
|
14
14
|
import { initMSModule } from './ContourCreator';
|
|
15
|
+
/** All built-in colormaps */
|
|
15
16
|
const colormaps = {
|
|
16
17
|
bluered: bluered,
|
|
17
18
|
redblue: redblue,
|
|
@@ -26,7 +27,8 @@ const colormaps = {
|
|
|
26
27
|
* Initialize the WebAssembly module in autumnplot-gl. It's not strictly necessary to call it first, but if you call it
|
|
27
28
|
* first, you can prevent races when you contour a bunch of fields at once.
|
|
28
29
|
*/
|
|
29
|
-
function initAutumnPlot() {
|
|
30
|
-
|
|
30
|
+
function initAutumnPlot(opts) {
|
|
31
|
+
opts = opts === undefined ? {} : opts;
|
|
32
|
+
initMSModule({ document_script: opts.wasm_base_url });
|
|
31
33
|
}
|
|
32
34
|
export { PlotComponent, Barbs, Contour, ContourLabels, ContourFill, Raster, Paintball, Hodographs, StationPlot, PlotLayer, MultiPlotLayer, ColorMap, colormaps, makeColorBar, makePaintballKey, Color, RawScalarField, RawVectorField, RawProfileField, RawObsField, Grid, StructuredGrid, PlateCarreeGrid, PlateCarreeRotatedGrid, LambertGrid, UnstructuredGrid, initAutumnPlot };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "autumnplot-gl",
|
|
3
|
-
"version": "4.0.0
|
|
3
|
+
"version": "4.0.0",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"types": "lib/index.d.ts",
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
"typedoc": "^0.25.13",
|
|
28
28
|
"typedoc-plugin-markdown": "^4.0.2",
|
|
29
29
|
"typescript": "^5.4.5",
|
|
30
|
-
"webpack": "
|
|
30
|
+
"webpack": "5.100",
|
|
31
31
|
"webpack-cli": "^5.0.1",
|
|
32
32
|
"webpack-dev-server": "^4.11.1",
|
|
33
33
|
"webpack-glsl-loader": "^1.0.1"
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.apgl=t():e.apgl=t()}(this,(()=>(()=>{"use strict";function e(e,t,r){for(var n=1,o=r;e%o!=0||t%o!=0;)n+=1,o/=2;return n}const t=Symbol("Comlink.proxy"),r=Symbol("Comlink.endpoint"),n=Symbol("Comlink.releaseProxy"),o=Symbol("Comlink.thrown"),a=e=>"object"==typeof e&&null!==e||"function"==typeof e,s=new Map([["proxy",{canHandle:e=>a(e)&&e[t],serialize(e){const{port1:t,port2:r}=new MessageChannel;return i(e,t),[r,[r]]},deserialize:e=>(e.start(),u(e,[],undefined))}],["throw",{canHandle:e=>a(e)&&o in e,serialize({value:e}){let t;return t=e instanceof Error?{isError:!0,value:{message:e.message,name:e.name,stack:e.stack}}:{isError:!1,value:e},[t,[]]},deserialize(e){if(e.isError)throw Object.assign(new Error(e.value.message),e.value);throw e.value}}]]);function i(e,r=self){r.addEventListener("message",(function n(a){if(!a||!a.data)return;const{id:s,type:f,path:u}=Object.assign({path:[]},a.data),l=(a.data.argumentList||[]).map(h);let p;try{const r=u.slice(0,-1).reduce(((e,t)=>e[t]),e),n=u.reduce(((e,t)=>e[t]),e);switch(f){case"GET":p=n;break;case"SET":r[u.slice(-1)[0]]=h(a.data.value),p=!0;break;case"APPLY":p=n.apply(r,l);break;case"CONSTRUCT":p=function(e){return Object.assign(e,{[t]:!0})}(new n(...l));break;case"ENDPOINT":{const{port1:t,port2:r}=new MessageChannel;i(e,r),p=function(e,t){return v.set(e,t),e}(t,[t])}break;case"RELEASE":p=void 0;break;default:return}}catch(e){p={value:e,[o]:0}}Promise.resolve(p).catch((e=>({value:e,[o]:0}))).then((e=>{const[t,o]=d(e);r.postMessage(Object.assign(Object.assign({},t),{id:s}),o),"RELEASE"===f&&(r.removeEventListener("message",n),c(r))}))})),r.start&&r.start()}function c(e){(function(e){return"MessagePort"===e.constructor.name})(e)&&e.close()}function f(e){if(e)throw new Error("Proxy has been released and is not useable")}function u(e,t=[],o=function(){}){let a=!1;const s=new Proxy(o,{get(r,o){if(f(a),o===n)return()=>p(e,{type:"RELEASE",path:t.map((e=>e.toString()))}).then((()=>{c(e),a=!0}));if("then"===o){if(0===t.length)return{then:()=>s};const r=p(e,{type:"GET",path:t.map((e=>e.toString()))}).then(h);return r.then.bind(r)}return u(e,[...t,o])},set(r,n,o){f(a);const[s,i]=d(o);return p(e,{type:"SET",path:[...t,n].map((e=>e.toString())),value:s},i).then(h)},apply(n,o,s){f(a);const i=t[t.length-1];if(i===r)return p(e,{type:"ENDPOINT"}).then(h);if("bind"===i)return u(e,t.slice(0,-1));const[c,v]=l(s);return p(e,{type:"APPLY",path:t.map((e=>e.toString())),argumentList:c},v).then(h)},construct(r,n){f(a);const[o,s]=l(n);return p(e,{type:"CONSTRUCT",path:t.map((e=>e.toString())),argumentList:o},s).then(h)}});return s}function l(e){const t=e.map(d);return[t.map((e=>e[0])),(r=t.map((e=>e[1])),Array.prototype.concat.apply([],r))];var r}const v=new WeakMap;function d(e){for(const[t,r]of s)if(r.canHandle(e)){const[n,o]=r.serialize(e);return[{type:"HANDLER",name:t,value:n},o]}return[{type:"RAW",value:e},v.get(e)||[]]}function h(e){switch(e.type){case"HANDLER":return s.get(e.name).deserialize(e.value);case"RAW":return e.value}}function p(e,t,r){return new Promise((n=>{const o=new Array(4).fill(0).map((()=>Math.floor(Math.random()*Number.MAX_SAFE_INTEGER).toString(16))).join("-");e.addEventListener("message",(function t(r){r.data&&r.data.id&&r.data.id===o&&(e.removeEventListener("message",t),n(r.data))})),e.start&&e.start(),e.postMessage(Object.assign({id:o},t),r)}))}var m=function(){function e(e,t){if(isNaN(e)||isNaN(t))throw new Error("Invalid LngLat object: (".concat(e,", ").concat(t,")"));if(this.lng=+e,this.lat=+t,this.lat>90||this.lat<-90)throw new Error("Invalid LngLat latitude value: must be between -90 and 90")}return e.prototype.toMercatorCoord=function(){return{x:(n=this.lng,(180+n)/360),y:(e=this.lat,t=Math.sin(e*Math.PI/180),r=(180-90/Math.PI*Math.log((1+t)/(1-t)))/360,Math.min(2,Math.max(-2,r)))};var e,t,r,n},e.fromMercatorCoord=function(t,r){return new e(function(e){return 360*e-180}(t),function(e){return 180*Math.atan(Math.sinh((180-360*e)*Math.PI/180))/Math.PI}(r))},e}(),y=function(e,t){var r="function"==typeof Symbol&&e[Symbol.iterator];if(!r)return e;var n,o,a=r.call(e),s=[];try{for(;(void 0===t||t-- >0)&&!(n=a.next()).done;)s.push(n.value)}catch(e){o={error:e}}finally{try{n&&!n.done&&(r=a.return)&&r.call(a)}finally{if(o)throw o.error}}return s};return i({makeBBElements:function(t,r,n,o,a,s){for(var i=Math.log2(a),c=Math.max(i+1-s,0),f=Math.pow(2,c),u=Math.floor((n-1)/f)+1,l=Math.floor((o-1)/f)+1,v=u*l*6*2,d=new Float32Array(u*l*6*3),h=new Float32Array(v),p=0,y=0,g=0;g<o;g++)for(var x=0;x<n;x++){var w=g*n+x,b=t[w],E=r[w],M=e(g,x,a);if(!(M>s)){for(var A=new m(E,b).toMercatorCoord(),S=0;S<6;S++){var L=Math.max(0,Math.min(S-1,3));d[p+3*S+0]=A.x,d[p+3*S+1]=A.y,d[p+3*S+2]=4*M+L,h[y+2*S+0]=x/(n-1),h[y+2*S+1]=g/(o-1)}p+=18,y+=12}}return{pts:d,tex_coords:h}},makeDomainVerticesAndTexCoords:function(e,t,r,n,o,a){for(var s=new Float32Array(4*(r-1)*(n+1)).fill(0),i=new Float32Array(4*(r-1)*(n+1)).fill(0),c=new Float32Array(2*(r-1)*(n+1)).fill(0),f=0,u=0,l=0;l<r-1;l++)for(var v=0;v<n;v++){var d=l+v*r,h=new m(t[d],e[d]).toMercatorCoord(),p=new m(t[d+1],e[d+1]).toMercatorCoord(),y=l/(r-1)*(1-2*o)+o,g=(l+1)/(r-1)*(1-2*o)+o,x=v/(n-1)*(1-2*a)+a;0==v&&(s[f]=h.x,s[f+1]=h.y,f+=2,i[u]=y,i[u+1]=x,u+=2),s[f]=h.x,s[f+1]=h.y,s[f+2]=p.x,s[f+3]=p.y,f+=4,i[u]=y,i[u+1]=x,i[u+2]=g,i[u+3]=x,u+=4,v==n-1&&(s[f]=p.x,s[f+1]=p.y,f+=2,i[u]=g,i[u+1]=x,u+=2)}var w=0;for(l=0;l<r-1;l++)for(v=0;v<n-1;v++){var b=0==v?2*(w+1):2*w,E=s[b],M=s[b+1],A=s[b+2],S=s[b+3],L=s[b+4],j=s[b+5],k=s[b+6],C=s[b+7],P=.5*Math.abs(E*(S-j)+A*(j-M)+L*(M-S)+k*(j-S)+L*(S-C)+A*(C-j));0==v&&(c[w]=P,w+=1),c[w]=P,c[w+1]=P,w+=2,v==n-2&&(c[w]=P,c[w+1]=P,c[w+2]=P,w+=3)}return{vertices:s,tex_coords:i,grid_cell_size:c}},makePolyLines:function(e){if(0==e.length)return{vertices:new Float32Array([]),extrusion:new Float32Array([])};var t=Object.fromEntries(Object.entries(e[0]).map((function(e){var t=y(e,2),r=t[0],n=t[1];return[r,"number"==typeof n||"number"==typeof n[0]?1:n[0].length]})));t.extrusion=2,t.vertices+=1;var r=4*e.map((function(e){return e.vertices.length})).reduce((function(e,t){return e+t}))-2*e.length,n=Object.fromEntries(Object.entries(t).map((function(e){var t=y(e,2),n=t[0],o=t[1];return[n,r*o]}))),o={vertices:new Float32Array(n.vertices),extrusion:new Float32Array(n.extrusion)};"offsets"in e[0]&&(o.offsets=new Float32Array(n.offsets)),"data"in e[0]&&(o.data=new Float32Array(n.data)),"zoom"in e[0]&&(o.zoom=new Float32Array(n.zoom));var a=Object.fromEntries(Object.keys(n).map((function(e){return[e,0]}))),s=function(e,t,r){var n=t[0]-e[0],o=t[1]-e[1],a=Math.hypot(n,o),s=-n/a;return[o/a,r?-s:s]};return e.forEach((function(e){var t,r,n,i,c=e.vertices.map((function(e){var t=(new(m.bind.apply(m,function(e,t,r){if(r||2===arguments.length)for(var n,o=0,a=t.length;o<a;o++)!n&&o in t||(n||(n=Array.prototype.slice.call(t,0,o)),n[o]=t[o]);return e.concat(n||Array.prototype.slice.call(t))}([void 0],y(e),!1)))).toMercatorCoord();return[t.x,t.y]})),f=void 0!==e.offsets,u=void 0!==e.offsets?e.offsets:c,l=c[0],v=(c[1],u[0]),d=u[1],h=1e-4,p=y(s(v,d,!f),2),g=p[0],x=p[1];o.vertices[a.vertices++]=l[0],o.vertices[a.vertices++]=l[1],o.vertices[a.vertices++]=h,o.extrusion[a.extrusion++]=g,o.extrusion[a.extrusion++]=x;for(var w=1;w<c.length;w++)l=c[w],r=c[w-1],v=u[w],n=u[w-1],g=(t=y(s(n,v,!f),2))[0],x=t[1],i=h,h+=Math.hypot(c[w-1][0]-c[w][0],c[w-1][1]-c[w][1]),o.vertices[a.vertices++]=r[0],o.vertices[a.vertices++]=r[1],o.vertices[a.vertices++]=-i,o.vertices[a.vertices++]=r[0],o.vertices[a.vertices++]=r[1],o.vertices[a.vertices++]=i,o.vertices[a.vertices++]=l[0],o.vertices[a.vertices++]=l[1],o.vertices[a.vertices++]=-h,o.vertices[a.vertices++]=l[0],o.vertices[a.vertices++]=l[1],o.vertices[a.vertices++]=h,o.extrusion[a.extrusion++]=g,o.extrusion[a.extrusion++]=x,o.extrusion[a.extrusion++]=-g,o.extrusion[a.extrusion++]=-x,o.extrusion[a.extrusion++]=g,o.extrusion[a.extrusion++]=x,o.extrusion[a.extrusion++]=-g,o.extrusion[a.extrusion++]=-x;if(o.vertices[a.vertices++]=l[0],o.vertices[a.vertices++]=l[1],o.vertices[a.vertices++]=h,o.extrusion[a.extrusion++]=-g,o.extrusion[a.extrusion++]=-x,void 0!==o.offsets&&void 0!==e.offsets){var b=e.offsets,E=void 0,M=b[0];for(o.offsets[a.offsets++]=M[0],o.offsets[a.offsets++]=M[1],w=1;w<b.length;w++)M=b[w],E=b[w-1],o.offsets[a.offsets++]=E[0],o.offsets[a.offsets++]=E[1],o.offsets[a.offsets++]=E[0],o.offsets[a.offsets++]=E[1],o.offsets[a.offsets++]=M[0],o.offsets[a.offsets++]=M[1],o.offsets[a.offsets++]=M[0],o.offsets[a.offsets++]=M[1];o.offsets[a.offsets++]=M[0],o.offsets[a.offsets++]=M[1]}if(void 0!==o.data&&void 0!==e.data){var A=e.data,S=void 0,L=A[0];for(o.data[a.data++]=L,w=1;w<A.length;w++)L=A[w],S=A[w-1],o.data[a.data++]=S,o.data[a.data++]=S,o.data[a.data++]=L,o.data[a.data++]=L;o.data[a.data++]=L}if(void 0!==o.zoom&&void 0!==e.zoom)for(w=0;w<4*c.length-2;w++)o.zoom[a.zoom++]=e.zoom})),o}}),{}})()));
|
|
2
|
-
//# sourceMappingURL=110.autumnplot-gl.js.map
|