Skip to content

Commit fb565a1

Browse files
authored
feat: better tests and type safety for projected grids (#68)
* fix partials for regular grid and better tests * cleanup internals of regular grid * wip: tests for projected * wip: improve projected grid internals * move getRotatedSWNE * fix: ukmo 2km grid * type safe projection grid definitions * some minor fixes * fix meteo schweiz domain definition * cleanup * remove unnecessary property for gaussian grid * fix gem regional domain grid definition and bounds calculation * add test for linear interpolation on partial grid * fix getValueFromLatLong for repeated worlds * support partials for gaussian grids * renaming * more renaming
1 parent 476e3b6 commit fb565a1

File tree

11 files changed

+605
-413
lines changed

11 files changed

+605
-413
lines changed

src/domains.ts

Lines changed: 49 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -41,11 +41,11 @@ export const domainOptions: Array<Domain> = [
4141
value: 'dmi_harmonie_arome_europe',
4242
label: 'DMI Harmonie Arome Europe',
4343
grid: {
44-
type: 'projected',
44+
type: 'projectedFromGeographicOrigin',
4545
nx: 1906,
4646
ny: 1606,
47-
latMin: 39.671,
48-
lonMin: -25.421997,
47+
latitude: 39.671,
48+
longitude: -25.421997,
4949
dx: 2000,
5050
dy: 2000,
5151
zoom: 4,
@@ -54,8 +54,6 @@ export const domainOptions: Array<Domain> = [
5454
ϕ0: 55.5,
5555
ϕ1: 55.5,
5656
ϕ2: 55.5,
57-
latitude: 39.671,
58-
longitude: -25.421997,
5957
radius: 6371229,
6058
name: 'LambertConformalConicProjection'
6159
}
@@ -191,21 +189,17 @@ export const domainOptions: Array<Domain> = [
191189
value: 'ncep_hrrr_conus',
192190
label: 'GFS HRRR Conus',
193191
grid: {
194-
type: 'projected',
192+
type: 'projectedFromBounds',
195193
nx: 1799,
196194
ny: 1059,
197-
latMin: 21.138,
198-
lonMin: -122.72,
199-
dx: 0,
200-
dy: 0,
195+
latitudeBounds: [21.138, 47.8424],
196+
longitudeBounds: [-122.72, -60.918],
201197
zoom: 3.5,
202198
projection: {
203199
λ0: -97.5,
204200
ϕ0: 0,
205201
ϕ1: 38.5,
206202
ϕ2: 38.5,
207-
latitude: [21.138, 47.8424],
208-
longitude: [-122.72, -60.918],
209203
name: 'LambertConformalConicProjection'
210204
}
211205
},
@@ -217,11 +211,11 @@ export const domainOptions: Array<Domain> = [
217211
value: 'ncep_nbm_conus',
218212
label: 'GFS NBM Conus',
219213
grid: {
220-
type: 'projected',
214+
type: 'projectedFromGeographicOrigin',
221215
nx: 2345,
222216
ny: 1597,
223-
latMin: 19.229,
224-
lonMin: 233.723 - 360,
217+
latitude: 19.229,
218+
longitude: 233.723 - 360,
225219
dx: 2539.7,
226220
dy: 2539.7,
227221
zoom: 3.5,
@@ -231,8 +225,6 @@ export const domainOptions: Array<Domain> = [
231225
ϕ1: 25,
232226
ϕ2: 25,
233227
radius: 6371200,
234-
latitude: 19.229,
235-
longitude: 233.723 - 360,
236228
name: 'LambertConformalConicProjection'
237229
}
238230
},
@@ -244,21 +236,17 @@ export const domainOptions: Array<Domain> = [
244236
value: 'ncep_nam_conus',
245237
label: 'GFS NAM Conus',
246238
grid: {
247-
type: 'projected',
239+
type: 'projectedFromBounds',
248240
nx: 1799,
249241
ny: 1059,
250-
latMin: 21.138,
251-
lonMin: -122.72,
252-
dx: 0,
253-
dy: 0,
242+
latitudeBounds: [21.138, 47.8424],
243+
longitudeBounds: [-122.72, -60.918],
254244
zoom: 3.5,
255245
projection: {
256246
λ0: -97.5,
257247
ϕ0: 0,
258248
ϕ1: 38.5,
259249
ϕ2: 38.5,
260-
latitude: [21.138, 47.8424],
261-
longitude: [-122.72, -60.918],
262250
name: 'LambertConformalConicProjection'
263251
}
264252
},
@@ -356,18 +344,15 @@ export const domainOptions: Array<Domain> = [
356344
value: 'cmc_gem_hrdps',
357345
label: 'GEM HRDPS Continental',
358346
grid: {
359-
type: 'projected',
347+
type: 'projectedFromBounds',
360348
nx: 2540,
361349
ny: 1290,
362-
latMin: 39.626034,
363-
lonMin: -133.62952,
364-
dx: 0.15,
365-
dy: 0.15,
350+
latitudeBounds: [39.626034, 47.876457],
351+
longitudeBounds: [-133.62952, -40.708557],
366352
zoom: 1,
367353
projection: {
368-
rotation: [-36.0885, 245.305],
369-
latitude: [39.626034, 47.876457],
370-
longitude: [-133.62952, -40.708557],
354+
rotatedLat: -36.0885,
355+
rotatedLon: 245.305,
371356
name: 'RotatedLatLonProjection'
372357
}
373358
},
@@ -379,18 +364,17 @@ export const domainOptions: Array<Domain> = [
379364
value: 'cmc_gem_rdps',
380365
label: 'GEM Regional',
381366
grid: {
382-
type: 'projected',
367+
type: 'projectedFromBounds',
383368
nx: 935,
384369
ny: 824,
385-
latMin: 18.14503,
386-
lonMin: 217.10745,
387-
dx: 0.15,
388-
dy: 0.15,
370+
latitudeBounds: [18.14503, 45.405453],
371+
longitudeBounds: [217.10745, 349.8256],
389372
zoom: 1,
390373
projection: {
391374
latitude: 90,
392375
longitude: 249,
393-
name: 'StereograpicProjection'
376+
radius: 6371229,
377+
name: 'StereographicProjection'
394378
}
395379
},
396380
time_interval: 1,
@@ -546,21 +530,17 @@ export const domainOptions: Array<Domain> = [
546530
value: 'metno_nordic_pp',
547531
label: 'MET Norway Nordic',
548532
grid: {
549-
type: 'projected',
533+
type: 'projectedFromBounds',
550534
nx: 1796,
551535
ny: 2321,
552-
latMin: 52.30272,
553-
lonMin: 1.9184653,
554-
dx: 0.25,
555-
dy: 0.25,
536+
latitudeBounds: [52.30272, 72.18527],
537+
longitudeBounds: [1.9184653, 41.764282],
556538
zoom: 4,
557539
projection: {
558540
λ0: 15,
559541
ϕ0: 63,
560542
ϕ1: 63,
561543
ϕ2: 63,
562-
latitude: [52.30272, 72.18527],
563-
longitude: [1.9184653, 41.764282],
564544
name: 'LambertConformalConicProjection'
565545
}
566546
},
@@ -591,11 +571,11 @@ export const domainOptions: Array<Domain> = [
591571
value: 'kma_ldps',
592572
label: 'KMA LDPS 1.5km',
593573
grid: {
594-
type: 'projected',
574+
type: 'projectedFromGeographicOrigin',
595575
nx: 602,
596576
ny: 781,
597-
latMin: 32.2569,
598-
lonMin: 121.834,
577+
latitude: 32.2569,
578+
longitude: 121.834,
599579
dx: 1500,
600580
dy: 1500,
601581
zoom: 5.5,
@@ -605,8 +585,6 @@ export const domainOptions: Array<Domain> = [
605585
ϕ1: 30,
606586
ϕ2: 60,
607587
radius: 6371229,
608-
latitude: 32.2569,
609-
longitude: 121.834,
610588
name: 'LambertConformalConicProjection'
611589
}
612590
},
@@ -620,18 +598,15 @@ export const domainOptions: Array<Domain> = [
620598
value: 'knmi_harmonie_arome_europe',
621599
label: 'KNMI Harmonie Arome Europe',
622600
grid: {
623-
type: 'projected',
601+
type: 'projectedFromBounds',
624602
nx: 676,
625603
ny: 564,
626-
latMin: 39.740627,
627-
lonMin: -25.162262,
628-
dx: 0,
629-
dy: 0,
604+
latitudeBounds: [39.740627, 62.619324],
605+
longitudeBounds: [-25.162262, 38.75702],
630606
zoom: 3.5,
631607
projection: {
632-
rotation: [-35, -8],
633-
latitude: [39.740627, 62.619324],
634-
longitude: [-25.162262, 38.75702],
608+
rotatedLat: -35,
609+
rotatedLon: -8,
635610
name: 'RotatedLatLonProjection'
636611
}
637612
},
@@ -662,20 +637,18 @@ export const domainOptions: Array<Domain> = [
662637
value: 'meteoswiss_icon_ch1',
663638
label: 'MeteoSwiss ICON CH1',
664639
grid: {
665-
type: 'projected',
640+
type: 'projectedFromProjectedOrigin',
666641
nx: 1089,
667642
ny: 705,
668-
latMin: 43.18,
669-
lonMin: -3.94,
643+
projectedLatitudeOrigin: -4.06,
644+
projectedLongitudeOrigin: -6.46,
670645
dx: 0.01,
671646
dy: 0.01,
672647
zoom: 5.2,
673648
projection: {
674-
rotation: [43.0, 190.0],
675-
latitude: -6.46,
676-
longitude: -4.06,
677-
name: 'RotatedLatLonProjection',
678-
projectOrigin: false
649+
rotatedLat: 43.0,
650+
rotatedLon: 190.0,
651+
name: 'RotatedLatLonProjection'
679652
}
680653
},
681654
time_interval: 1,
@@ -686,20 +659,18 @@ export const domainOptions: Array<Domain> = [
686659
value: 'meteoswiss_icon_ch2',
687660
label: 'MeteoSwiss ICON CH2',
688661
grid: {
689-
type: 'projected',
662+
type: 'projectedFromProjectedOrigin',
690663
nx: 545,
691664
ny: 353,
692-
latMin: 43.18,
693-
lonMin: -3.94,
665+
projectedLatitudeOrigin: -4.06,
666+
projectedLongitudeOrigin: -6.46,
694667
dx: 0.02,
695668
dy: 0.02,
696669
zoom: 5.2,
697670
projection: {
698-
rotation: [43.0, 190.0],
699-
latitude: -6.46,
700-
longitude: -4.06,
701-
name: 'RotatedLatLonProjection',
702-
projectOrigin: false
671+
rotatedLat: 43.0,
672+
rotatedLon: 190.0,
673+
name: 'RotatedLatLonProjection'
703674
}
704675
},
705676
time_interval: 1,
@@ -729,22 +700,19 @@ export const domainOptions: Array<Domain> = [
729700
value: 'ukmo_uk_deterministic_2km',
730701
label: 'UK Met Office 2km',
731702
grid: {
732-
type: 'projected',
703+
type: 'projectedFromProjectedOrigin',
733704
nx: 1042,
734705
ny: 970,
735-
latMin: 0, //-1036000
736-
lonMin: 0, //-1158000
706+
projectedLatitudeOrigin: -1036000,
707+
projectedLongitudeOrigin: -1158000,
737708
dx: 2000,
738709
dy: 2000,
739710
zoom: 4,
740711
projection: {
741712
λ0: -2.5,
742713
ϕ1: 54.9,
743-
latitude: -1036000,
744-
longitude: -1158000,
745714
radius: 6371229,
746-
name: 'LambertAzimuthalEqualAreaProjection',
747-
projectOrigin: false
715+
name: 'LambertAzimuthalEqualAreaProjection'
748716
}
749717
},
750718
time_interval: 1,

src/grids/factory.ts

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,23 @@ import { GridInterface } from './interface';
33
import { ProjectionGrid } from './projected';
44
import { RegularGrid } from './regular';
55

6-
import { DimensionRange, Domain } from '../types';
6+
import { DimensionRange, GridData } from '../types';
77

88
export class GridFactory {
9-
static create(data: Domain['grid'], ranges: DimensionRange[] | null = null): GridInterface {
10-
if (data.type === 'gaussian') {
11-
return new GaussianGrid(data, ranges);
12-
} else if (data.type === 'projected') {
13-
return new ProjectionGrid(data, ranges);
14-
} else if (data.type === 'regular') {
15-
return new RegularGrid(data, ranges);
16-
} else {
17-
throw new Error('Unsupported grid type');
9+
static create(data: GridData, ranges: DimensionRange[] | null = null): GridInterface {
10+
switch (data.type) {
11+
case 'gaussian':
12+
return new GaussianGrid(data, ranges);
13+
case 'projectedFromBounds':
14+
case 'projectedFromProjectedOrigin':
15+
case 'projectedFromGeographicOrigin':
16+
return new ProjectionGrid(data, ranges);
17+
case 'regular':
18+
return new RegularGrid(data, ranges);
19+
default:
20+
// This ensures exhaustiveness checking
21+
const _exhaustive: never = data;
22+
throw new Error(`Unknown grid type: ${_exhaustive}`);
1823
}
1924
}
2025
}

0 commit comments

Comments
 (0)