@neaps/tide-predictor 0.0.4

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.
Files changed (46) hide show
  1. package/.eslintrc.js +22 -0
  2. package/.github/workflows/test.yml +15 -0
  3. package/.prettierrc +4 -0
  4. package/Gruntfile.js +87 -0
  5. package/LICENSE +21 -0
  6. package/README.md +199 -0
  7. package/babel.config.js +9 -0
  8. package/dist/tide-predictor.js +1013 -0
  9. package/examples/browser/index.html +51 -0
  10. package/jest.config.js +14 -0
  11. package/lib/astronomy/coefficients.js +31 -0
  12. package/lib/astronomy/constants.js +10 -0
  13. package/lib/astronomy/index.js +199 -0
  14. package/lib/constituents/compound-constituent.js +67 -0
  15. package/lib/constituents/constituent.js +74 -0
  16. package/lib/constituents/index.js +140 -0
  17. package/lib/harmonics/index.js +113 -0
  18. package/lib/harmonics/prediction.js +195 -0
  19. package/lib/index.es6.js +1005 -0
  20. package/lib/index.js +53 -0
  21. package/lib/node-corrections/index.js +147 -0
  22. package/package.json +45 -0
  23. package/rollup.config.js +21 -0
  24. package/src/__mocks__/constituents.js +335 -0
  25. package/src/__mocks__/secondary-station.js +11 -0
  26. package/src/__tests__/index.js +81 -0
  27. package/src/__tests__/noaa.js +92 -0
  28. package/src/astronomy/__tests__/coefficients.js +12 -0
  29. package/src/astronomy/__tests__/index.js +96 -0
  30. package/src/astronomy/coefficients.js +72 -0
  31. package/src/astronomy/constants.js +4 -0
  32. package/src/astronomy/index.js +201 -0
  33. package/src/constituents/__tests__/compound-constituent.js +44 -0
  34. package/src/constituents/__tests__/constituent.js +65 -0
  35. package/src/constituents/__tests__/index.js +34 -0
  36. package/src/constituents/compound-constituent.js +55 -0
  37. package/src/constituents/constituent.js +74 -0
  38. package/src/constituents/index.js +119 -0
  39. package/src/harmonics/__mocks__/water-levels.js +0 -0
  40. package/src/harmonics/__tests__/index.js +123 -0
  41. package/src/harmonics/__tests__/prediction.js +148 -0
  42. package/src/harmonics/index.js +87 -0
  43. package/src/harmonics/prediction.js +175 -0
  44. package/src/index.js +45 -0
  45. package/src/node-corrections/__tests__/index.js +114 -0
  46. package/src/node-corrections/index.js +208 -0
@@ -0,0 +1,51 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>Tide Predictor in the browser</title>
5
+ <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css"/>
6
+ </head>
7
+ <body>
8
+ <div class="container">
9
+ <h1>High/low tides for Monterey, CA</h1>
10
+ <table class="table">
11
+ <thead>
12
+ <tr>
13
+ <th>Time</th>
14
+ <th>High/Low</th>
15
+ <th>Level (meters)</th>
16
+ </tr>
17
+ <tbody id="tides">
18
+
19
+ </tbody>
20
+ </thead>
21
+ </table>
22
+ </div>
23
+
24
+ <script src="../../dist/tide-predictor.js"></script>
25
+ <script>
26
+ (()=> {
27
+ fetch(
28
+ 'https://tidesandcurrents.noaa.gov/mdapi/v1.0/webapi/stations/9413450/harcon.json?units=metric'
29
+ )
30
+ .then(response => {
31
+ return response.json()
32
+ }).then(harmonics => {
33
+ const start = new Date()
34
+ const end = new Date(start.getTime() + (10 * 24 * 60 * 60 * 1000))
35
+
36
+ const highLow = tidePredictor(harmonics.HarmonicConstituents).getExtremesPrediction(start, end)
37
+
38
+ highLow.forEach(level => {
39
+ const tableRow = document.createElement('tr')
40
+ tableRow.innerHTML = `
41
+ <td>${level.time}</td>
42
+ <td>${level.label}</td>
43
+ <td>${level.level}</td>
44
+ `
45
+ document.getElementById('tides').appendChild(tableRow)
46
+ })
47
+ })
48
+ })()
49
+ </script>
50
+ </body>
51
+ </html>
package/jest.config.js ADDED
@@ -0,0 +1,14 @@
1
+ module.exports = {
2
+ verbose: false,
3
+ reporters: ['default', 'jest-junit'],
4
+ testPathIgnorePatterns: [
5
+ `<rootDir>/examples/`,
6
+ `<rootDir>/lib/`,
7
+ `<rootDir>/www/`,
8
+ `<rootDir>/dist/`,
9
+ `<rootDir>/node_modules/`
10
+ ],
11
+ transform: {
12
+ '^.+\\.jsx?$': 'babel-jest'
13
+ }
14
+ }
@@ -0,0 +1,31 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.sexagesimalToDecimal = exports["default"] = void 0;
7
+
8
+ // Convert a sexagesimal angle into decimal degrees
9
+ var sexagesimalToDecimal = function sexagesimalToDecimal(degrees, arcmins, arcsecs, mas, muas) {
10
+ arcmins = typeof arcmins !== 'undefined' ? arcmins : 0;
11
+ arcsecs = typeof arcsecs !== 'undefined' ? arcsecs : 0;
12
+ mas = typeof mas !== 'undefined' ? mas : 0;
13
+ muas = typeof muas !== 'undefined' ? muas : 0;
14
+ return degrees + arcmins / 60.0 + arcsecs / (60.0 * 60.0) + mas / (60.0 * 60.0 * 1e3) + muas / (60.0 * 60.0 * 1e6);
15
+ };
16
+
17
+ exports.sexagesimalToDecimal = sexagesimalToDecimal;
18
+ var coefficients = {
19
+ // Meeus formula 21.3
20
+ terrestrialObliquity: [sexagesimalToDecimal(23, 26, 21.448), -sexagesimalToDecimal(0, 0, 4680.93), -sexagesimalToDecimal(0, 0, 1.55), sexagesimalToDecimal(0, 0, 1999.25), -sexagesimalToDecimal(0, 0, 51.38), -sexagesimalToDecimal(0, 0, 249.67), -sexagesimalToDecimal(0, 0, 39.05), sexagesimalToDecimal(0, 0, 7.12), sexagesimalToDecimal(0, 0, 27.87), sexagesimalToDecimal(0, 0, 5.79), sexagesimalToDecimal(0, 0, 2.45)].map(function (number, index) {
21
+ return number * Math.pow(1e-2, index);
22
+ }),
23
+ solarPerigee: [280.46645 - 357.5291, 36000.76932 - 35999.0503, 0.0003032 + 0.0001559, 0.00000048],
24
+ solarLongitude: [280.46645, 36000.76983, 0.0003032],
25
+ lunarInclination: [5.145],
26
+ lunarLongitude: [218.3164591, 481267.88134236, -0.0013268, 1 / 538841.0 - 1 / 65194000.0],
27
+ lunarNode: [125.044555, -1934.1361849, 0.0020762, 1 / 467410.0, -1 / 60616000.0],
28
+ lunarPerigee: [83.353243, 4069.0137111, -0.0103238, -1 / 80053.0, 1 / 18999000.0]
29
+ };
30
+ var _default = coefficients;
31
+ exports["default"] = _default;
@@ -0,0 +1,10 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.r2d = exports.d2r = void 0;
7
+ var d2r = Math.PI / 180.0;
8
+ exports.d2r = d2r;
9
+ var r2d = 180.0 / Math.PI;
10
+ exports.r2d = r2d;
@@ -0,0 +1,199 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports._nupp = exports._nup = exports._nu = exports._xi = exports._I = exports.JD = exports.T = exports.derivativePolynomial = exports.polynomial = exports["default"] = void 0;
7
+
8
+ var _constants = require("./constants");
9
+
10
+ var _coefficients = _interopRequireDefault(require("./coefficients"));
11
+
12
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
13
+
14
+ // Evaluates a polynomial at argument
15
+ var polynomial = function polynomial(coefficients, argument) {
16
+ var result = [];
17
+ coefficients.forEach(function (coefficient, index) {
18
+ result.push(coefficient * Math.pow(argument, index));
19
+ });
20
+ return result.reduce(function (a, b) {
21
+ return a + b;
22
+ });
23
+ }; // Evaluates a derivative polynomial at argument
24
+
25
+
26
+ exports.polynomial = polynomial;
27
+
28
+ var derivativePolynomial = function derivativePolynomial(coefficients, argument) {
29
+ var result = [];
30
+ coefficients.forEach(function (coefficient, index) {
31
+ result.push(coefficient * index * Math.pow(argument, index - 1));
32
+ });
33
+ return result.reduce(function (a, b) {
34
+ return a + b;
35
+ });
36
+ }; // Meeus formula 11.1
37
+
38
+
39
+ exports.derivativePolynomial = derivativePolynomial;
40
+
41
+ var T = function T(t) {
42
+ return (JD(t) - 2451545.0) / 36525;
43
+ }; // Meeus formula 7.1
44
+
45
+
46
+ exports.T = T;
47
+
48
+ var JD = function JD(t) {
49
+ var Y = t.getFullYear();
50
+ var M = t.getMonth() + 1;
51
+ var D = t.getDate() + t.getHours() / 24.0 + t.getMinutes() / (24.0 * 60.0) + t.getSeconds() / (24.0 * 60.0 * 60.0) + t.getMilliseconds() / (24.0 * 60.0 * 60.0 * 1e6);
52
+
53
+ if (M <= 2) {
54
+ Y = Y - 1;
55
+ M = M + 12;
56
+ }
57
+
58
+ var A = Math.floor(Y / 100.0);
59
+ var B = 2 - A + Math.floor(A / 4.0);
60
+ return Math.floor(365.25 * (Y + 4716)) + Math.floor(30.6001 * (M + 1)) + D + B - 1524.5;
61
+ };
62
+ /**
63
+ * @todo - What's with the array returned from the arccos?
64
+ * @param {*} N
65
+ * @param {*} i
66
+ * @param {*} omega
67
+ */
68
+
69
+
70
+ exports.JD = JD;
71
+
72
+ var _I = function _I(N, i, omega) {
73
+ N = _constants.d2r * N;
74
+ i = _constants.d2r * i;
75
+ omega = _constants.d2r * omega;
76
+ var cosI = Math.cos(i) * Math.cos(omega) - Math.sin(i) * Math.sin(omega) * Math.cos(N);
77
+ return _constants.r2d * Math.acos(cosI);
78
+ };
79
+
80
+ exports._I = _I;
81
+
82
+ var _xi = function _xi(N, i, omega) {
83
+ N = _constants.d2r * N;
84
+ i = _constants.d2r * i;
85
+ omega = _constants.d2r * omega;
86
+ var e1 = Math.cos(0.5 * (omega - i)) / Math.cos(0.5 * (omega + i)) * Math.tan(0.5 * N);
87
+ var e2 = Math.sin(0.5 * (omega - i)) / Math.sin(0.5 * (omega + i)) * Math.tan(0.5 * N);
88
+ e1 = Math.atan(e1);
89
+ e2 = Math.atan(e2);
90
+ e1 = e1 - 0.5 * N;
91
+ e2 = e2 - 0.5 * N;
92
+ return -(e1 + e2) * _constants.r2d;
93
+ };
94
+
95
+ exports._xi = _xi;
96
+
97
+ var _nu = function _nu(N, i, omega) {
98
+ N = _constants.d2r * N;
99
+ i = _constants.d2r * i;
100
+ omega = _constants.d2r * omega;
101
+ var e1 = Math.cos(0.5 * (omega - i)) / Math.cos(0.5 * (omega + i)) * Math.tan(0.5 * N);
102
+ var e2 = Math.sin(0.5 * (omega - i)) / Math.sin(0.5 * (omega + i)) * Math.tan(0.5 * N);
103
+ e1 = Math.atan(e1);
104
+ e2 = Math.atan(e2);
105
+ e1 = e1 - 0.5 * N;
106
+ e2 = e2 - 0.5 * N;
107
+ return (e1 - e2) * _constants.r2d;
108
+ }; // Schureman equation 224
109
+
110
+
111
+ exports._nu = _nu;
112
+
113
+ var _nup = function _nup(N, i, omega) {
114
+ var I = _constants.d2r * _I(N, i, omega);
115
+
116
+ var nu = _constants.d2r * _nu(N, i, omega);
117
+
118
+ return _constants.r2d * Math.atan(Math.sin(2 * I) * Math.sin(nu) / (Math.sin(2 * I) * Math.cos(nu) + 0.3347));
119
+ }; // Schureman equation 232
120
+
121
+
122
+ exports._nup = _nup;
123
+
124
+ var _nupp = function _nupp(N, i, omega) {
125
+ var I = _constants.d2r * _I(N, i, omega);
126
+
127
+ var nu = _constants.d2r * _nu(N, i, omega);
128
+
129
+ var tan2nupp = Math.pow(Math.sin(I), 2) * Math.sin(2 * nu) / (Math.pow(Math.sin(I), 2) * Math.cos(2 * nu) + 0.0727);
130
+ return _constants.r2d * 0.5 * Math.atan(tan2nupp);
131
+ };
132
+
133
+ exports._nupp = _nupp;
134
+
135
+ var modulus = function modulus(a, b) {
136
+ return (a % b + b) % b;
137
+ };
138
+
139
+ var astro = function astro(time) {
140
+ var result = {};
141
+ var polynomials = {
142
+ s: _coefficients["default"].lunarLongitude,
143
+ h: _coefficients["default"].solarLongitude,
144
+ p: _coefficients["default"].lunarPerigee,
145
+ N: _coefficients["default"].lunarNode,
146
+ pp: _coefficients["default"].solarPerigee,
147
+ 90: [90.0],
148
+ omega: _coefficients["default"].terrestrialObliquity,
149
+ i: _coefficients["default"].lunarInclination
150
+ }; // Polynomials are in T, that is Julian Centuries; we want our speeds to be
151
+ // in the more convenient unit of degrees per hour.
152
+
153
+ var dTdHour = 1 / (24 * 365.25 * 100);
154
+ Object.keys(polynomials).forEach(function (name) {
155
+ result[name] = {
156
+ value: modulus(polynomial(polynomials[name], T(time)), 360.0),
157
+ speed: derivativePolynomial(polynomials[name], T(time)) * dTdHour
158
+ };
159
+ }); // Some other parameters defined by Schureman which are dependent on the
160
+ // parameters N, i, omega for use in node factor calculations. We don't need
161
+ // their speeds.
162
+
163
+ var functions = {
164
+ I: _I,
165
+ xi: _xi,
166
+ nu: _nu,
167
+ nup: _nup,
168
+ nupp: _nupp
169
+ };
170
+ Object.keys(functions).forEach(function (name) {
171
+ var functionCall = functions[name];
172
+ result[name] = {
173
+ value: modulus(functionCall(result.N.value, result.i.value, result.omega.value), 360.0),
174
+ speed: null
175
+ };
176
+ }); // We don't work directly with the T (hours) parameter, instead our spanning
177
+ // set for equilibrium arguments #is given by T+h-s, s, h, p, N, pp, 90.
178
+ // This is in line with convention.
179
+
180
+ var hour = {
181
+ value: (JD(time) - Math.floor(JD(time))) * 360.0,
182
+ speed: 15.0
183
+ };
184
+ result['T+h-s'] = {
185
+ value: hour.value + result.h.value - result.s.value,
186
+ speed: hour.speed + result.h.speed - result.s.speed
187
+ }; // It is convenient to calculate Schureman's P here since several node
188
+ // factors need it, although it could be argued that these
189
+ // (along with I, xi, nu etc) belong somewhere else.
190
+
191
+ result.P = {
192
+ value: result.p.value - result.xi.value % 360.0,
193
+ speed: null
194
+ };
195
+ return result;
196
+ };
197
+
198
+ var _default = astro;
199
+ exports["default"] = _default;
@@ -0,0 +1,67 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports["default"] = void 0;
7
+
8
+ var compoundConstituentFactory = function compoundConstituentFactory(name, members) {
9
+ var coefficients = [];
10
+ members.forEach(function (_ref) {
11
+ var constituent = _ref.constituent,
12
+ factor = _ref.factor;
13
+ constituent.coefficients.forEach(function (coefficient, index) {
14
+ if (typeof coefficients[index] === 'undefined') {
15
+ coefficients[index] = 0;
16
+ }
17
+
18
+ coefficients[index] += coefficient * factor;
19
+ });
20
+ });
21
+ var compoundConstituent = {
22
+ name: name,
23
+ coefficients: coefficients,
24
+ speed: function speed(astro) {
25
+ var speed = 0;
26
+ members.forEach(function (_ref2) {
27
+ var constituent = _ref2.constituent,
28
+ factor = _ref2.factor;
29
+ speed += constituent.speed(astro) * factor;
30
+ });
31
+ return speed;
32
+ },
33
+ value: function value(astro) {
34
+ var value = 0;
35
+ members.forEach(function (_ref3) {
36
+ var constituent = _ref3.constituent,
37
+ factor = _ref3.factor;
38
+ value += constituent.value(astro) * factor;
39
+ });
40
+ return value;
41
+ },
42
+ u: function u(astro) {
43
+ var u = 0;
44
+ members.forEach(function (_ref4) {
45
+ var constituent = _ref4.constituent,
46
+ factor = _ref4.factor;
47
+ u += constituent.u(astro) * factor;
48
+ });
49
+ return u;
50
+ },
51
+ f: function f(astro) {
52
+ var f = [];
53
+ members.forEach(function (_ref5) {
54
+ var constituent = _ref5.constituent,
55
+ factor = _ref5.factor;
56
+ f.push(Math.pow(constituent.f(astro), Math.abs(factor)));
57
+ });
58
+ return f.reduce(function (previous, value) {
59
+ return previous * value;
60
+ });
61
+ }
62
+ };
63
+ return Object.freeze(compoundConstituent);
64
+ };
65
+
66
+ var _default = compoundConstituentFactory;
67
+ exports["default"] = _default;
@@ -0,0 +1,74 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.astronomicValues = exports.astronomicSpeed = exports.astronimicDoodsonNumber = exports["default"] = void 0;
7
+
8
+ var _index = _interopRequireDefault(require("../node-corrections/index"));
9
+
10
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
11
+
12
+ /**
13
+ * Computes the dot notation of two arrays
14
+ * @param {*} a
15
+ * @param {*} b
16
+ */
17
+ var dotArray = function dotArray(a, b) {
18
+ var results = [];
19
+ a.forEach(function (value, index) {
20
+ results.push(value * b[index]);
21
+ });
22
+ return results.reduce(function (total, value) {
23
+ return total + value;
24
+ });
25
+ };
26
+
27
+ var astronimicDoodsonNumber = function astronimicDoodsonNumber(astro) {
28
+ return [astro['T+h-s'], astro.s, astro.h, astro.p, astro.N, astro.pp, astro['90']];
29
+ };
30
+
31
+ exports.astronimicDoodsonNumber = astronimicDoodsonNumber;
32
+
33
+ var astronomicSpeed = function astronomicSpeed(astro) {
34
+ var results = [];
35
+ astronimicDoodsonNumber(astro).forEach(function (number) {
36
+ results.push(number.speed);
37
+ });
38
+ return results;
39
+ };
40
+
41
+ exports.astronomicSpeed = astronomicSpeed;
42
+
43
+ var astronomicValues = function astronomicValues(astro) {
44
+ var results = [];
45
+ astronimicDoodsonNumber(astro).forEach(function (number) {
46
+ results.push(number.value);
47
+ });
48
+ return results;
49
+ };
50
+
51
+ exports.astronomicValues = astronomicValues;
52
+
53
+ var constituentFactory = function constituentFactory(name, coefficients, u, f) {
54
+ if (!coefficients) {
55
+ throw new Error('Coefficient must be defined for a constituent');
56
+ }
57
+
58
+ var constituent = {
59
+ name: name,
60
+ coefficients: coefficients,
61
+ value: function value(astro) {
62
+ return dotArray(coefficients, astronomicValues(astro));
63
+ },
64
+ speed: function speed(astro) {
65
+ return dotArray(coefficients, astronomicSpeed(astro));
66
+ },
67
+ u: typeof u !== 'undefined' ? u : _index["default"].uZero,
68
+ f: typeof f !== 'undefined' ? f : _index["default"].fUnity
69
+ };
70
+ return Object.freeze(constituent);
71
+ };
72
+
73
+ var _default = constituentFactory;
74
+ exports["default"] = _default;