Skip to content

Commit c37686a

Browse files
author
Vincent van der Wal
committed
add wind var
1 parent 07a6cb7 commit c37686a

File tree

6 files changed

+228
-74
lines changed

6 files changed

+228
-74
lines changed

src/main.ts

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -162,14 +162,28 @@ if (mapContainer) {
162162
)
163163
.addTo(map);
164164
}
165-
const temp = getValueFromLatLong(
165+
let value = getValueFromLatLong(
166166
coordinates.lat,
167167
coordinates.lng,
168168
omUrl
169169
);
170-
if (temp) {
170+
if (value) {
171+
let string;
172+
if (Array === value.constructor) {
173+
string = '';
174+
for (let val of value) {
175+
string += val.toFixed(1) + ' ';
176+
}
177+
} else {
178+
string =
179+
value.toFixed(1) +
180+
(variable.value.startsWith('temperature')
181+
? 'C°'
182+
: '');
183+
}
184+
171185
popup.setLngLat(coordinates).setHTML(
172-
`<span style="color:black;">${temp.toFixed(1) + (variable.value.startsWith('temperature') ? 'C°' : '')}</span>`
186+
`<span style="color:black;">${string}</span>`
173187
);
174188
} else {
175189
popup.setLngLat(coordinates).setHTML(

src/om-protocol.ts

Lines changed: 185 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ const fileReader: FileReader = {
4545
backend: undefined
4646
};
4747

48-
const omFileDataCache = new QuickLRU<string, TypedArray>({
48+
const omFileDataCache = new QuickLRU<string, { values: TypedArray; direction?: TypedArray }>({
4949
maxSize: 1024,
5050
maxAge: ONE_HOUR_IN_MILLISECONDS
5151
});
@@ -54,26 +54,47 @@ const TILE_SIZE = Number(import.meta.env.VITE_TILE_SIZE);
5454

5555
export const getValueFromLatLong = (lat: number, lon: number, omUrl: string) => {
5656
const data = omFileDataCache.get(omUrl);
57+
if (data) {
58+
const values = data.values;
5759

58-
let indexObject;
59-
if (domain.grid.projection) {
60-
indexObject = projectionGrid.findPointInterpolated(lat, lon);
61-
} else {
62-
indexObject = getIndexFromLatLong(lat, lon, domain);
63-
}
60+
let indexObject;
61+
if (domain.grid.projection) {
62+
indexObject = projectionGrid.findPointInterpolated(lat, lon);
63+
} else {
64+
indexObject = getIndexFromLatLong(lat, lon, domain);
65+
}
6466

65-
const { index, xFraction, yFraction } = indexObject ?? {
66-
index: 0,
67-
xFraction: 0,
68-
yFraction: 0
69-
};
67+
const { index, xFraction, yFraction } = indexObject ?? {
68+
index: 0,
69+
xFraction: 0,
70+
yFraction: 0
71+
};
7072

71-
if (data && index) {
72-
//const px = interpolateLinear(data, index, xFraction, yFraction);
73-
const px = interpolate2DHermite(data, domain.grid.nx, index, xFraction, yFraction);
74-
return px;
75-
} else {
76-
return NaN;
73+
if (values && index) {
74+
//const px = interpolateLinear(data, index, xFraction, yFraction);
75+
const px = interpolate2DHermite(
76+
values,
77+
domain.grid.nx,
78+
index,
79+
xFraction,
80+
yFraction
81+
);
82+
if (variable.value === 'wind') {
83+
const direction = data.direction as TypedArray;
84+
const dir = interpolate2DHermite(
85+
direction,
86+
domain.grid.nx,
87+
index,
88+
xFraction,
89+
yFraction
90+
);
91+
return [px, dir];
92+
} else {
93+
return px;
94+
}
95+
} else {
96+
return NaN;
97+
}
7798
}
7899
};
79100

@@ -115,37 +136,80 @@ const renderTile = async (url: string) => {
115136
return tile;
116137
};
117138

139+
const getBorderPoints = () => {
140+
const points = [];
141+
console.log(nx, ny, dx, dy, projectionGrid);
142+
for (let i = 0; i < projectionGrid.ny; i++) {
143+
points.push([
144+
projectionGrid.origin[0],
145+
projectionGrid.origin[1] + i * projectionGrid.dy
146+
]);
147+
}
148+
for (let i = 0; i < projectionGrid.nx; i++) {
149+
points.push([
150+
projectionGrid.origin[0] + i * projectionGrid.dx,
151+
projectionGrid.origin[1] + projectionGrid.ny * projectionGrid.dy
152+
]);
153+
}
154+
for (let i = projectionGrid.ny; i >= 0; i--) {
155+
points.push([
156+
projectionGrid.origin[0] + projectionGrid.nx * projectionGrid.dx,
157+
projectionGrid.origin[1] + i * projectionGrid.dy
158+
]);
159+
}
160+
for (let i = projectionGrid.nx; i >= 0; i--) {
161+
points.push([
162+
projectionGrid.origin[0] + i * projectionGrid.dx,
163+
projectionGrid.origin[1]
164+
]);
165+
}
166+
167+
return points;
168+
};
169+
118170
const getTilejson = async (fullUrl: string): Promise<TileJSON> => {
119171
let minLon;
120172
let minLat;
121173
let maxLon;
122174
let maxLat;
123175

176+
let bounds;
124177
if (domain.grid.projection) {
125-
// loop over all border points to get max / min lat / lon
126-
127-
console.log(projection.reverse(0, dy * ny));
128-
console.log(projection.reverse(dx * nx, 0));
129-
console.log(projection.reverse(dx * nx, dy * ny));
130-
if (Array === lonMin.constructor) {
131-
minLon = lonMin[0];
132-
minLat = latMin[0];
133-
maxLon = lonMin[1];
134-
maxLat = latMin[1];
178+
if (domain.grid.projection.bounds) {
179+
bounds = domain.grid.projection.bounds;
135180
} else {
181+
// loop over all border points to get max / min lat / lon
182+
const borderPoints = getBorderPoints();
183+
const origin = projectionGrid.origin;
184+
const originLatLon = projection.reverse(origin);
136185
minLon = lonMin;
137186
minLat = latMin;
138-
maxLon = minLon + projection.reverse(dx * nx, dy * ny)[1];
139-
maxLat = minLat + projection.reverse(dx * nx, dy * ny)[0];
187+
maxLon = lonMin;
188+
maxLat = latMin;
189+
for (let borderPoint of borderPoints) {
190+
const borderPointLatLon = projection.reverse(borderPoint);
191+
if (borderPointLatLon[0] < minLat) {
192+
minLat = borderPointLatLon[0];
193+
}
194+
if (borderPointLatLon[0] > maxLat) {
195+
maxLat = borderPointLatLon[0];
196+
}
197+
if (borderPointLatLon[1] < minLon) {
198+
minLon = borderPointLatLon[1];
199+
}
200+
if (borderPointLatLon[1] > maxLon) {
201+
maxLon = borderPointLatLon[1];
202+
}
203+
}
204+
bounds = [minLon, minLat, maxLon, maxLat];
140205
}
141206
} else {
142207
minLon = lonMin;
143208
minLat = latMin;
144209
maxLon = minLon + dx * nx;
145210
maxLat = minLat + dy * ny;
211+
bounds = [minLon, minLat, maxLon, maxLat];
146212
}
147-
const bounds = [minLon, minLat, maxLon, maxLat];
148-
console.log(bounds);
149213

150214
return {
151215
tilejson: '2.2.0',
@@ -168,6 +232,12 @@ export const omProtocol = async (
168232
if (fileReader.reader) {
169233
fileReader.reader.dispose();
170234
}
235+
if (fileReader.readeru) {
236+
fileReader.readeru.dispose();
237+
}
238+
if (fileReader.readerv) {
239+
fileReader.readerv.dispose();
240+
}
171241
delete fileReader.reader;
172242
delete fileReader.backend;
173243

@@ -179,12 +249,15 @@ export const omProtocol = async (
179249

180250
nx = domain.grid.nx;
181251
ny = domain.grid.ny;
182-
lonMin = domain.grid.lonMin;
183252
latMin = domain.grid.latMin;
253+
lonMin = domain.grid.lonMin;
184254
dx = domain.grid.dx;
185255
dy = domain.grid.dy;
186256

187257
if (domain.grid.projection) {
258+
const latitude = domain.grid.projection.latitude ?? domain.grid.latMin;
259+
const longitude = domain.grid.projection.longitude ?? domain.grid.lonMin;
260+
188261
projectionName = domain.grid.projection.name;
189262
projection = new DynamicProjection(
190263
projectionName,
@@ -194,29 +267,91 @@ export const omProtocol = async (
194267
projection,
195268
nx,
196269
ny,
197-
latMin,
198-
lonMin,
270+
latitude,
271+
longitude,
199272
dx,
200273
dy
201274
);
202275
}
203276

204-
fileReader.backend = new MemoryHttpBackend({
205-
url: omUrl,
206-
maxFileSize: 500 * 1024 * 1024 // 500 MB
207-
});
208-
fileReader.reader = await OmFileReader.create(fileReader.backend).catch(() => {
209-
throw new Error(`OMFile error: 404 file not found`);
210-
});
211-
if (fileReader.reader) {
212-
const dimensions = fileReader.reader.getDimensions();
213-
214-
// Create ranges for each dimension
215-
const ranges = dimensions.map((dim, _) => {
216-
return { start: 0, end: dim };
277+
if (variable.value === 'wind') {
278+
fileReader.backendu = new MemoryHttpBackend({
279+
url: omUrl.replace('wind.om', 'wind_u_component_10m.om'),
280+
maxFileSize: 500 * 1024 * 1024 // 500 MB
281+
});
282+
fileReader.backendv = new MemoryHttpBackend({
283+
url: omUrl.replace('wind.om', 'wind_v_component_10m.om'),
284+
maxFileSize: 500 * 1024 * 1024 // 500 MB
217285
});
218-
const data = await fileReader.reader.read(OmDataType.FloatArray, ranges);
219-
omFileDataCache.set(omUrl, data);
286+
fileReader.readeru = await OmFileReader.create(fileReader.backendu).catch(
287+
() => {
288+
throw new Error(`OMFile error: 404 file not found`);
289+
}
290+
);
291+
fileReader.readerv = await OmFileReader.create(fileReader.backendv).catch(
292+
() => {
293+
throw new Error(`OMFile error: 404 file not found`);
294+
}
295+
);
296+
if (fileReader.readeru && fileReader.readerv) {
297+
const dimensions = fileReader.readeru.getDimensions();
298+
299+
// Create ranges for each dimension
300+
const ranges = dimensions.map((dim, _) => {
301+
return { start: 0, end: dim };
302+
});
303+
const datau = await fileReader.readeru.read(
304+
OmDataType.FloatArray,
305+
ranges
306+
);
307+
const datav = await fileReader.readerv.read(
308+
OmDataType.FloatArray,
309+
ranges
310+
);
311+
312+
const data: Float32Array<ArrayBuffer> = [];
313+
const dataDirection: Float32Array<ArrayBuffer> = [];
314+
315+
for (let [i, dp] of datau.entries()) {
316+
data.push(
317+
Math.sqrt(Math.pow(dp, 2) + Math.pow(datav[i], 2)) *
318+
1.94384
319+
);
320+
321+
dataDirection.push(
322+
(Math.atan2(dp, datav[i]) * (180 / Math.PI) + 360) %
323+
360
324+
);
325+
}
326+
327+
omFileDataCache.set(omUrl, {
328+
values: data,
329+
direction: dataDirection
330+
});
331+
}
332+
} else {
333+
fileReader.backend = new MemoryHttpBackend({
334+
url: omUrl,
335+
maxFileSize: 500 * 1024 * 1024 // 500 MB
336+
});
337+
fileReader.reader = await OmFileReader.create(fileReader.backend).catch(
338+
() => {
339+
throw new Error(`OMFile error: 404 file not found`);
340+
}
341+
);
342+
if (fileReader.reader) {
343+
const dimensions = fileReader.reader.getDimensions();
344+
345+
// Create ranges for each dimension
346+
const ranges = dimensions.map((dim, _) => {
347+
return { start: 0, end: dim };
348+
});
349+
const data = await fileReader.reader.read(
350+
OmDataType.FloatArray,
351+
ranges
352+
);
353+
omFileDataCache.set(omUrl, { values: data });
354+
}
220355
}
221356

222357
return {

src/types.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,8 +52,8 @@ export interface Domain {
5252
grid: {
5353
nx: number;
5454
ny: number;
55-
lonMin: number | number[];
56-
latMin: number | number[];
55+
lonMin: number;
56+
latMin: number;
5757
dx: number;
5858
dy: number;
5959
zoom?: number;
@@ -65,6 +65,9 @@ export interface Domain {
6565
ϕ2?: number;
6666
rotation?: number[];
6767
radius?: number;
68+
latitude?: number[];
69+
longitude?: number[];
70+
bounds?: number[];
6871
};
6972
center?:
7073
| {

0 commit comments

Comments
 (0)