UNPKG

9.99 kBJavaScriptView Raw
1"use strict";
2
3Object.defineProperty(exports, "__esModule", {
4 value: true
5});
6
7var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }();
8
9var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
10
11exports.oneDegreeOfLongitude = oneDegreeOfLongitude;
12exports.oneDegreeOfLatitude = oneDegreeOfLatitude;
13exports.geocentricLatitudeDifference = geocentricLatitudeDifference;
14exports.approxAngularDistance = approxAngularDistance;
15exports.approxLinearDistance = approxLinearDistance;
16
17function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
18
19/**
20 * @copyright 2013 Sonia Keys
21 * @copyright 2016 commenthol
22 * @license MIT
23 * @module globe
24 */
25/**
26 * Globe: Chapter 11, The Earth's Globe.
27 *
28 * Globe contains functions concerning the surface of the Earth idealized as
29 * an ellipsoid of revolution.
30 */
31
32/**
33 * Ellipsoid represents an ellipsoid of revolution. */
34var Ellipsoid = exports.Ellipsoid = function () {
35 /**
36 * @param {number} radius - equatorial radius
37 * @param {number} flat - ellipsiod flattening
38 */
39 function Ellipsoid(radius, flat) {
40 _classCallCheck(this, Ellipsoid);
41
42 this.radius = radius;
43 this.flat = flat;
44 }
45
46 /** A is a common identifier for equatorial radius. */
47
48
49 _createClass(Ellipsoid, [{
50 key: "A",
51 value: function A() {
52 return this.radius;
53 }
54
55 /** B is a common identifier for polar radius. */
56
57 }, {
58 key: "B",
59 value: function B() {
60 return this.radius * (1 - this.flat);
61 }
62
63 /** eccentricity of a meridian. */
64
65 }, {
66 key: "eccentricity",
67 value: function eccentricity() {
68 return Math.sqrt((2 - this.flat) * this.flat);
69 }
70
71 /**
72 * parallaxConstants computes parallax constants ρ sin φ′ and ρ cos φ′.
73 *
74 * Arguments are geographic latitude φ in radians and height h
75 * in meters above the ellipsoid.
76 *
77 * @param {number} φ - geographic latitude in radians
78 * @param {number} h - height in meters above the ellipsoid
79 * @return {number[]} [ρ sin φ′, ρ cos φ] parallax constants
80 */
81
82 }, {
83 key: "parallaxConstants",
84 value: function parallaxConstants(φ, h) {
85 var boa = 1 - this.flat;
86 var su = Math.sin(Math.atan(boa * Math.tan(φ)));
87 var cu = Math.cos(Math.atan(boa * Math.tan(φ)));
88 var s = Math.sin(φ);
89 var c = Math.cos(φ);
90 var hoa = h * 1e-3 / this.radius;
91 // (s, c float)
92 return [su * boa + hoa * s, cu + hoa * c];
93 }
94
95 /**
96 * rho is distance from Earth center to a point on the ellipsoid.
97 *
98 * Result unit is fraction of the equatorial radius.
99 * @param {number} φ - geographic latitude in radians
100 * @returns {number} // TODO
101 */
102
103 }, {
104 key: "rho",
105 value: function rho(φ) {
106 // Magic numbers...
107 return 0.9983271 + 0.0016764 * Math.cos(2 * φ) - 0.0000035 * Math.cos(4 * φ);
108 }
109
110 /**
111 * radiusAtLatitude returns the radius of the circle that is the parallel of
112 * latitude at φ.
113 *
114 * Result unit is Km.
115 *
116 * @param {number} φ
117 * @return {number} radius in km
118 */
119
120 }, {
121 key: "radiusAtLatitude",
122 value: function radiusAtLatitude(φ) {
123 var s = Math.sin(φ);
124 var c = Math.cos(φ);
125 return this.A() * c / Math.sqrt(1 - (2 - this.flat) * this.flat * s * s);
126 }
127
128 /**
129 * radiusOfCurvature of meridian at latitude φ.
130 *
131 * Result unit is Km.
132 *
133 * @param {number} φ
134 * @return {number} radius in km
135 */
136
137 }, {
138 key: "radiusOfCurvature",
139 value: function radiusOfCurvature(φ) {
140 var s = Math.sin(φ);
141 var e2 = (2 - this.flat) * this.flat;
142 return this.A() * (1 - e2) / Math.pow(1 - e2 * s * s, 1.5);
143 }
144
145 /**
146 * distance is distance between two points measured along the surface
147 * of an ellipsoid.
148 *
149 * Accuracy is much better than that of approxAngularDistance or
150 * approxLinearDistance.
151 *
152 * Result unit is Km.
153 *
154 * @param {Coords} c1
155 * @param {Coords} c2
156 * @return {number} radius in km
157 */
158
159 }, {
160 key: "distance",
161 value: function distance(c1, c2) {
162 // From AA, ch 11, p 84.
163 var _sincos = sincos2((c1.lat + c2.lat) / 2),
164 _sincos2 = _slicedToArray(_sincos, 2),
165 s2f = _sincos2[0],
166 c2f = _sincos2[1];
167
168 var _sincos3 = sincos2((c1.lat - c2.lat) / 2),
169 _sincos4 = _slicedToArray(_sincos3, 2),
170 s2g = _sincos4[0],
171 c2g = _sincos4[1];
172
173 var _sincos5 = sincos2((c1.lon - c2.lon) / 2),
174 _sincos6 = _slicedToArray(_sincos5, 2),
175 s2λ = _sincos6[0],
176 c2λ = _sincos6[1];
177
178 var s = s2g * c2λ + c2f * s2λ;
179 var c = c2g * c2λ + s2f * s2λ;
180 var ω = Math.atan(Math.sqrt(s / c));
181 var r = Math.sqrt(s * c) / ω;
182 var d = 2 * ω * this.radius;
183 var h1 = (3 * r - 1) / (2 * c);
184 var h2 = (3 * r + 1) / (2 * s);
185 return d * (1 + this.flat * (h1 * s2f * c2g - h2 * c2f * s2g));
186 }
187 }]);
188
189 return Ellipsoid;
190}();
191
192/** IAU 1976 values. Radius in Km. */
193
194
195var Earth76 = exports.Earth76 = new Ellipsoid(6378.14, 1 / 298.257);
196
197/**
198 * RotationRate1996_5 is the rotational angular velocity of the Earth
199 * with respect to the stars at the epoch 1996.5.
200 *
201 * Unit is radian/second.
202 */
203var RotationRate1996_5 = exports.RotationRate1996_5 = 7.292114992e-5; // eslint-disable-line camelcase
204
205/**
206 * oneDegreeOfLongitude returns the length of one degree of longitude.
207 *
208 * Argument `rp` is the radius in Km of a circle that is a parallel of latitude
209 * (as returned by Ellipsoid.radiusAtLatitude.)
210 * Result is distance in Km along one degree of the circle.
211 *
212 * @param {number} rp
213 * @return {number} distance in Km
214 */
215function oneDegreeOfLongitude(rp) {
216 return rp * Math.PI / 180;
217}
218
219/**
220 * oneDegreeOfLatitude returns the length of one degree of latitude.
221 *
222 * Argument `rm` is the radius in Km of curvature along a meridian.
223 * (as returned by Ellipsoid.radiusOfCurvature.)
224 * Result is distance in Km along one degree of the meridian.
225 *
226 * @param {number} rm
227 * @return {number} distance in Km
228 */
229function oneDegreeOfLatitude(rm) {
230 return rm * Math.PI / 180;
231}
232
233/**
234 * geocentricLatitudeDifference returns geographic latitude - geocentric
235 * latitude (φ - φ′) with given geographic latitude (φ).
236 *
237 * Units are radians.
238 * @param {number} φ
239 * @returns {number} difference in Deg
240 */
241function geocentricLatitudeDifference(φ) {
242 // This appears to be an approximation with hard coded magic numbers.
243 // No explanation is given in the text. The ellipsoid is not specified.
244 // Perhaps the approximation works well enough for all ellipsoids?
245 return (692.73 * Math.sin(2 * φ) - 1.16 * Math.sin(4 * φ)) * Math.PI / (180 * 3600);
246}
247
248/**
249 * Coord represents geographic coordinates on the Earth.
250 *
251 * Longitude is measured positively westward from the Greenwich meridian.
252 */
253
254var Coord =
255/**
256 * @param {number} lat - latitude (φ) in radians
257 * @param {number} lon - longitude (ψ, or L) in radians (measured positively westward)
258 */
259exports.Coord = function Coord() {
260 var lat = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0;
261 var lon = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
262
263 _classCallCheck(this, Coord);
264
265 this.lat = lat;
266 this.lon = lon;
267};
268
269/**
270 * approxAngularDistance returns the cosine of the angle between two points.
271 *
272 * The accuracy deteriorates at small angles.
273 *
274 * @param {Coord} p1 - Point 1
275 * @param {Coord} p2 - Point 2
276 * @returns {number} cosine `cos` of the angle between two points.
277 * Use `d = Math.acos(cos)` to obtain geocentric angular distance in radians
278 */
279
280
281function approxAngularDistance(p1, p2) {
282 var s1 = Math.sin(p1.lat);
283 var c1 = Math.cos(p1.lat);
284 var s2 = Math.sin(p2.lat);
285 var c2 = Math.cos(p2.lat);
286 return s1 * s2 + c1 * c2 * Math.cos(p1.lon - p2.lon);
287}
288
289/**
290 * approxLinearDistance computes a distance across the surface of the Earth.
291 *
292 * Approximating the Earth as a sphere, the function takes a geocentric angular
293 * distance in radians and returns the corresponding linear distance in Km.
294 *
295 * @param {number} d - geocentric angular distance in radians
296 * @returns linear distance in Km
297 */
298function approxLinearDistance(d) {
299 return 6371 * d;
300}
301
302/**
303 * @private
304 */
305function sincos2(x) {
306 var s = Math.sin(x);
307 var c = Math.cos(x);
308 return [s * s, c * c];
309}
310
311exports.default = {
312 Ellipsoid: Ellipsoid,
313 Earth76: Earth76,
314 RotationRate1996_5: RotationRate1996_5,
315 oneDegreeOfLongitude: oneDegreeOfLongitude,
316 oneDegreeOfLatitude: oneDegreeOfLatitude,
317 geocentricLatitudeDifference: geocentricLatitudeDifference,
318 Coord: Coord,
319 approxAngularDistance: approxAngularDistance,
320 approxLinearDistance: approxLinearDistance
321};
\No newline at end of file