UNPKG

270 kBJavaScriptView Raw
1(function (exports) {
2 'use strict';
3
4 function minMax(arr) {
5 var len = arr.length;
6 var min = Infinity;
7 var max = -Infinity;
8 while (len--) {
9 var el = arr[len];
10 if (el == null) {
11 // do nothing
12 } else if (el < min) {
13 min = el;
14 } else if (el > max) {
15 max = el;
16 }
17 }
18 if (min === Infinity) {
19 min = max;
20 } else if (max === -Infinity) {
21 max = min;
22 }
23 if (min === Infinity || min === -Infinity) {
24 // all values were null
25 min = null;
26 max = null;
27 }
28 return [min, max];
29 }
30
31 /**
32 * Return the indices of the two neighbors in the sorted array closest to the given number.
33 *
34 * @example
35 * var a = [2,5,8,12,13]
36 * var i = CovUtils.indicesOfNearest(a, 6)
37 * // i == [1,2]
38 * var j = CovUtils.indicesOfNearest(a, 5)
39 * // j == [1,1]
40 * var k = CovUtils.indicesOfNearest(a, 50)
41 * // k == [4,4]
42 *
43 * @param {Array<number>} a The array to search through. Must be sorted, ascending or descending.
44 * @param {number} x The target number.
45 * @return {[lo,hi]} The indices of the two closest values, may be equal.
46 * If `x` exists in the array, both neighbors point to `x`.
47 * If `x` is lower (greater if descending) than the first value, both neighbors point to 0.
48 * If `x` is greater (lower if descending) than the last value, both neighbors point to the last index.
49 */
50 function indicesOfNearest(a, x) {
51 if (a.length === 0) {
52 throw new Error('Array must have at least one element');
53 }
54 var lo = -1;
55 var hi = a.length;
56 var ascending = a.length === 1 || a[0] < a[1];
57 // we have two separate code paths to help the runtime optimize the loop
58 if (ascending) {
59 while (hi - lo > 1) {
60 var mid = Math.round((lo + hi) / 2);
61 if (a[mid] <= x) {
62 lo = mid;
63 } else {
64 hi = mid;
65 }
66 }
67 } else {
68 while (hi - lo > 1) {
69 var _mid = Math.round((lo + hi) / 2);
70 if (a[_mid] >= x) {
71 // here's the difference
72 lo = _mid;
73 } else {
74 hi = _mid;
75 }
76 }
77 }
78 if (a[lo] === x) hi = lo;
79 if (lo === -1) lo = hi;
80 if (hi === a.length) hi = lo;
81 return [lo, hi];
82 }
83
84 /**
85 * Return the index of the value closest to the given number in a sorted array.
86 *
87 * @example
88 * var a = [2,5,8,12,13]
89 * var i = CovUtils.indexOfNearest(a, 6)
90 * // i == 1
91 * var j = CovUtils.indexOfNearest(a, 7)
92 * // j == 2
93 * var k = CovUtils.indexOfNearest(a, 50)
94 * // k == 4
95 *
96 * @param {Array<number>} a The array to search through. Must be sorted, ascending or descending.
97 * @param {number} x The target number.
98 * @return {number} The array index whose value is closest to `x`.
99 * If `x` happens to be exactly between two values, then the lower index is returned.
100 */
101 function indexOfNearest(a, x) {
102 var i = indicesOfNearest(a, x);
103 var lo = i[0];
104 var hi = i[1];
105 if (Math.abs(x - a[lo]) <= Math.abs(x - a[hi])) {
106 return lo;
107 } else {
108 return hi;
109 }
110 }
111
112 var DOMAIN = 'Domain';
113 var COVERAGE = 'Coverage';
114 var COVERAGECOLLECTION = COVERAGE + 'Collection';
115
116 var COVJSON_NS = 'http://covjson.org/def/core#';
117
118 var COVJSON_DATATYPE_TUPLE = COVJSON_NS + 'tuple';
119 var COVJSON_DATATYPE_POLYGON = COVJSON_NS + 'polygon';
120
121 var DEFAULT_LANGUAGE = 'en';
122
123 /**
124 * @example
125 * var labels = {'en': 'Temperature', 'de': 'Temperatur'}
126 * var tag = CovUtils.getLanguageTag(labels, 'en-GB')
127 * // tag == 'en'
128 *
129 * @param {object} map An object that maps language tags to strings.
130 * @param {string} [preferredLanguage='en'] The preferred language as a language tag, e.g. 'de'.
131 * @return {string} The best matched language tag of the input map.
132 * If no match was found then this is an arbitrary tag of the map.
133 */
134 function getLanguageTag(map) {
135 var preferredLanguage = arguments.length <= 1 || arguments[1] === undefined ? DEFAULT_LANGUAGE : arguments[1];
136
137 if (preferredLanguage in map) {
138 return preferredLanguage;
139 }
140
141 // cut off any subtags following the language subtag and try to find a match
142 var prefTag = preferredLanguage.split('-')[0];
143 var matches = Object.keys(map).filter(function (tag) {
144 return prefTag === tag.split('-')[0];
145 });
146 if (matches.length) {
147 return matches[0];
148 }
149
150 // no luck, return a random tag
151 return Object.keys(map)[0];
152 }
153
154 /**
155 * @example
156 * var labels = {'en': 'Temperature', 'de': 'Temperatur'}
157 * var label = CovUtils.getLanguageString(labels, 'en-GB')
158 * // label == 'Temperature'
159 *
160 * @param {object} map An object that maps language tags to strings.
161 * @param {string} [preferredLanguage='en'] The preferred language as a language tag, e.g. 'de'.
162 * @return {string} The string within the input map whose language tag best matched.
163 * If no match was found then this is an arbitrary string of the map.
164 */
165 function getLanguageString(map) {
166 var preferredLanguage = arguments.length <= 1 || arguments[1] === undefined ? DEFAULT_LANGUAGE : arguments[1];
167
168 var tag = getLanguageTag(map, preferredLanguage);
169 return map[tag];
170 }
171
172 /**
173 * Converts a unit object to a human-readable symbol or label, where symbols are preferred.
174 *
175 * @example
176 * var unit = {
177 * symbol: '°C'
178 * }
179 * var str = CovUtils.stringifyUnit(unit) // str == '°C'
180 *
181 * @example
182 * var unit = {
183 * symbol: {
184 * value: 'Cel',
185 * type: 'http://www.opengis.net/def/uom/UCUM/'
186 * },
187 * label: {
188 * en: 'Degree Celsius'
189 * }
190 * }
191 * var str = CovUtils.stringifyUnit(unit) // str == '°C'
192 *
193 * @example
194 * var unit = {
195 * label: {
196 * en: 'Degree Celsius',
197 * de: 'Grad Celsius'
198 * }
199 * }
200 * var str = CovUtils.stringifyUnit(unit, 'en') // str == 'Degree Celsius'
201 */
202 function stringifyUnit(unit, language) {
203 if (!unit) {
204 return '';
205 }
206 if (unit.symbol) {
207 var symbol = unit.symbol.value || unit.symbol;
208 var scheme = unit.symbol.type;
209 if (scheme === 'http://www.opengis.net/def/uom/UCUM/') {
210 if (symbol === 'Cel') {
211 symbol = '°C';
212 } else if (symbol === '1') {
213 symbol = '';
214 }
215 }
216 return symbol;
217 } else {
218 return getLanguageString(unit.label, language);
219 }
220 }
221
222 var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) {
223 return typeof obj;
224 } : function (obj) {
225 return obj && typeof Symbol === "function" && obj.constructor === Symbol ? "symbol" : typeof obj;
226 };
227
228 var classCallCheck = function (instance, Constructor) {
229 if (!(instance instanceof Constructor)) {
230 throw new TypeError("Cannot call a class as a function");
231 }
232 };
233
234 var createClass = function () {
235 function defineProperties(target, props) {
236 for (var i = 0; i < props.length; i++) {
237 var descriptor = props[i];
238 descriptor.enumerable = descriptor.enumerable || false;
239 descriptor.configurable = true;
240 if ("value" in descriptor) descriptor.writable = true;
241 Object.defineProperty(target, descriptor.key, descriptor);
242 }
243 }
244
245 return function (Constructor, protoProps, staticProps) {
246 if (protoProps) defineProperties(Constructor.prototype, protoProps);
247 if (staticProps) defineProperties(Constructor, staticProps);
248 return Constructor;
249 };
250 }();
251
252 var defineProperty = function (obj, key, value) {
253 if (key in obj) {
254 Object.defineProperty(obj, key, {
255 value: value,
256 enumerable: true,
257 configurable: true,
258 writable: true
259 });
260 } else {
261 obj[key] = value;
262 }
263
264 return obj;
265 };
266
267 var slicedToArray = function () {
268 function sliceIterator(arr, i) {
269 var _arr = [];
270 var _n = true;
271 var _d = false;
272 var _e = undefined;
273
274 try {
275 for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) {
276 _arr.push(_s.value);
277
278 if (i && _arr.length === i) break;
279 }
280 } catch (err) {
281 _d = true;
282 _e = err;
283 } finally {
284 try {
285 if (!_n && _i["return"]) _i["return"]();
286 } finally {
287 if (_d) throw _e;
288 }
289 }
290
291 return _arr;
292 }
293
294 return function (arr, i) {
295 if (Array.isArray(arr)) {
296 return arr;
297 } else if (Symbol.iterator in Object(arr)) {
298 return sliceIterator(arr, i);
299 } else {
300 throw new TypeError("Invalid attempt to destructure non-iterable instance");
301 }
302 };
303 }();
304
305 var toConsumableArray = function (arr) {
306 if (Array.isArray(arr)) {
307 for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) arr2[i] = arr[i];
308
309 return arr2;
310 } else {
311 return Array.from(arr);
312 }
313 };
314
315 /**
316 * @external {Range} https://github.com/Reading-eScience-Centre/coverage-jsapi/blob/master/Range.md
317 */
318
319 /**
320 * Return the minimum/maximum across all range values, ignoring null's.
321 *
322 * @param {Range<number>} range The numeric coverage data range.
323 * @return {[min,max]} The minimum and maximum values of the range,
324 * or [undefined, undefined] if the range contains only `null` values.
325 */
326 function minMaxOfRange(range) {
327 var min = Infinity;
328 var max = -Infinity;
329 var fn = function fn(val) {
330 if (val === null) return;
331 if (val < min) min = val;
332 if (val > max) max = val;
333 };
334 iterateRange(range, fn);
335 return min === Infinity ? [undefined, undefined] : [min, max];
336 }
337
338 /**
339 * Apply a reduce function over the range values.
340 *
341 * @param {Range} range The coverage data range.
342 * @param {function} callback Function to execute on each value in the array with arguments `(previousValue, currentValue)`.
343 * @param start Value to use as the first argument to the first call of the `callback`.
344 * @return The reduced value.
345 */
346 function reduceRange(range, callback, start) {
347 var v1 = start;
348 var iterFn = function iterFn(v2) {
349 v1 = callback(v1, v2);
350 };
351 iterateRange(range, iterFn);
352 return v1;
353 }
354
355 /**
356 * Iterate over all range values and run a function for each value.
357 * No particular iteration order must be assumed.
358 */
359 function iterateRange(range, fn) {
360 // We use a precompiled function here for efficiency.
361 // See below for a slower recursive version.
362
363 // Benchmarks compared to recursive version:
364 // Chrome 46: around 1.03x faster
365 // Firefox 42: around 2x faster (and around 6x faster than Chrome 46!)
366
367 // nest loops from smallest to biggest
368 var shape = [].concat(toConsumableArray(range.shape));
369 shape.sort(function (_ref, _ref2) {
370 var _ref4 = slicedToArray(_ref, 2);
371
372 var size1 = _ref4[1];
373
374 var _ref3 = slicedToArray(_ref2, 2);
375
376 var size2 = _ref3[1];
377 return size1 - size2;
378 });
379
380 var begin = 'var obj = {}';
381 var end = '';
382 var _iteratorNormalCompletion = true;
383 var _didIteratorError = false;
384 var _iteratorError = undefined;
385
386 try {
387 for (var _iterator = shape[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
388 var _step$value = slicedToArray(_step.value, 2);
389
390 var axis = _step$value[0];
391 var size = _step$value[1];
392
393 begin += '\n for (var i' + axis + '=0; i' + axis + ' < ' + size + '; ++i' + axis + ') {\n obj[\'' + axis + '\'] = i' + axis + '\n ';
394 end += '}';
395 }
396 } catch (err) {
397 _didIteratorError = true;
398 _iteratorError = err;
399 } finally {
400 try {
401 if (!_iteratorNormalCompletion && _iterator.return) {
402 _iterator.return();
403 }
404 } finally {
405 if (_didIteratorError) {
406 throw _iteratorError;
407 }
408 }
409 }
410
411 begin += '\n fn(get(obj))\n ';
412
413 var iterateLoop = new Function('return function iterRange (get, fn) { ' + begin + ' ' + end + ' }')(); // eslint-disable-line
414 iterateLoop(range.get, fn);
415 }
416
417 /**
418 * Returns the category of the given parameter corresponding to the encoded integer value.
419 *
420 * @param {Parameter} parameter
421 * @param {number} val
422 * @return {Category}
423 */
424 function getCategory(parameter, val) {
425 var _iteratorNormalCompletion = true;
426 var _didIteratorError = false;
427 var _iteratorError = undefined;
428
429 try {
430 var _loop = function _loop() {
431 var _step$value = slicedToArray(_step.value, 2);
432
433 var catId = _step$value[0];
434 var vals = _step$value[1];
435
436 if (vals.indexOf(val) !== -1) {
437 var cat = parameter.observedProperty.categories.filter(function (c) {
438 return c.id === catId;
439 })[0];
440 return {
441 v: cat
442 };
443 }
444 };
445
446 for (var _iterator = parameter.categoryEncoding[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
447 var _ret = _loop();
448
449 if ((typeof _ret === "undefined" ? "undefined" : _typeof(_ret)) === "object") return _ret.v;
450 }
451 } catch (err) {
452 _didIteratorError = true;
453 _iteratorError = err;
454 } finally {
455 try {
456 if (!_iteratorNormalCompletion && _iterator.return) {
457 _iterator.return();
458 }
459 } finally {
460 if (_didIteratorError) {
461 throw _iteratorError;
462 }
463 }
464 }
465 }
466
467 function isCoverage(obj) {
468 return obj.type === COVERAGE;
469 }
470
471 function checkCoverage(obj) {
472 if (!isCoverage(obj)) {
473 throw new Error('must be a Coverage');
474 }
475 }
476
477 function isDomain(obj) {
478 return obj.type === DOMAIN;
479 }
480
481 function checkDomain(obj) {
482 if (!isDomain(obj)) {
483 throw new Error('must be a Domain');
484 }
485 }
486
487 function createCommonjsModule(fn, module) {
488 return module = { exports: {} }, fn(module, module.exports), module.exports;
489 }
490
491 var imlfn = createCommonjsModule(function (module) {
492 module.exports = function(ml, e0, e1, e2, e3) {
493 var phi;
494 var dphi;
495
496 phi = ml / e0;
497 for (var i = 0; i < 15; i++) {
498 dphi = (ml - (e0 * phi - e1 * Math.sin(2 * phi) + e2 * Math.sin(4 * phi) - e3 * Math.sin(6 * phi))) / (e0 - 2 * e1 * Math.cos(2 * phi) + 4 * e2 * Math.cos(4 * phi) - 6 * e3 * Math.cos(6 * phi));
499 phi += dphi;
500 if (Math.abs(dphi) <= 0.0000000001) {
501 return phi;
502 }
503 }
504
505 //..reportError("IMLFN-CONV:Latitude failed to converge after 15 iterations");
506 return NaN;
507 };
508 });
509
510 var require$$0$3 = (imlfn && typeof imlfn === 'object' && 'default' in imlfn ? imlfn['default'] : imlfn);
511
512 var asinz = createCommonjsModule(function (module) {
513 module.exports = function(x) {
514 if (Math.abs(x) > 1) {
515 x = (x > 1) ? 1 : -1;
516 }
517 return Math.asin(x);
518 };
519 });
520
521 var require$$0$4 = (asinz && typeof asinz === 'object' && 'default' in asinz ? asinz['default'] : asinz);
522
523 var gN = createCommonjsModule(function (module) {
524 module.exports = function(a, e, sinphi) {
525 var temp = e * sinphi;
526 return a / Math.sqrt(1 - temp * temp);
527 };
528 });
529
530 var require$$3 = (gN && typeof gN === 'object' && 'default' in gN ? gN['default'] : gN);
531
532 var e3fn = createCommonjsModule(function (module) {
533 module.exports = function(x) {
534 return (x * x * x * (35 / 3072));
535 };
536 });
537
538 var require$$4 = (e3fn && typeof e3fn === 'object' && 'default' in e3fn ? e3fn['default'] : e3fn);
539
540 var e2fn = createCommonjsModule(function (module) {
541 module.exports = function(x) {
542 return (0.05859375 * x * x * (1 + 0.75 * x));
543 };
544 });
545
546 var require$$5 = (e2fn && typeof e2fn === 'object' && 'default' in e2fn ? e2fn['default'] : e2fn);
547
548 var e1fn = createCommonjsModule(function (module) {
549 module.exports = function(x) {
550 return (0.375 * x * (1 + 0.25 * x * (1 + 0.46875 * x)));
551 };
552 });
553
554 var require$$6 = (e1fn && typeof e1fn === 'object' && 'default' in e1fn ? e1fn['default'] : e1fn);
555
556 var e0fn = createCommonjsModule(function (module) {
557 module.exports = function(x) {
558 return (1 - 0.25 * x * (1 + x / 16 * (3 + 1.25 * x)));
559 };
560 });
561
562 var require$$7 = (e0fn && typeof e0fn === 'object' && 'default' in e0fn ? e0fn['default'] : e0fn);
563
564 var mlfn = createCommonjsModule(function (module) {
565 module.exports = function(e0, e1, e2, e3, phi) {
566 return (e0 * phi - e1 * Math.sin(2 * phi) + e2 * Math.sin(4 * phi) - e3 * Math.sin(6 * phi));
567 };
568 });
569
570 var require$$3$1 = (mlfn && typeof mlfn === 'object' && 'default' in mlfn ? mlfn['default'] : mlfn);
571
572 var sign = createCommonjsModule(function (module) {
573 module.exports = function(x) {
574 return x<0 ? -1 : 1;
575 };
576 });
577
578 var require$$1 = (sign && typeof sign === 'object' && 'default' in sign ? sign['default'] : sign);
579
580 var adjust_lon = createCommonjsModule(function (module) {
581 var TWO_PI = Math.PI * 2;
582 // SPI is slightly greater than Math.PI, so values that exceed the -180..180
583 // degree range by a tiny amount don't get wrapped. This prevents points that
584 // have drifted from their original location along the 180th meridian (due to
585 // floating point error) from changing their sign.
586 var SPI = 3.14159265359;
587 var sign = require$$1;
588
589 module.exports = function(x) {
590 return (Math.abs(x) <= SPI) ? x : (x - (sign(x) * TWO_PI));
591 };
592 });
593
594 var require$$2 = (adjust_lon && typeof adjust_lon === 'object' && 'default' in adjust_lon ? adjust_lon['default'] : adjust_lon);
595
596 var aeqd = createCommonjsModule(function (module, exports) {
597 var adjust_lon = require$$2;
598 var HALF_PI = Math.PI/2;
599 var EPSLN = 1.0e-10;
600 var mlfn = require$$3$1;
601 var e0fn = require$$7;
602 var e1fn = require$$6;
603 var e2fn = require$$5;
604 var e3fn = require$$4;
605 var gN = require$$3;
606 var asinz = require$$0$4;
607 var imlfn = require$$0$3;
608 exports.init = function() {
609 this.sin_p12 = Math.sin(this.lat0);
610 this.cos_p12 = Math.cos(this.lat0);
611 };
612
613 exports.forward = function(p) {
614 var lon = p.x;
615 var lat = p.y;
616 var sinphi = Math.sin(p.y);
617 var cosphi = Math.cos(p.y);
618 var dlon = adjust_lon(lon - this.long0);
619 var e0, e1, e2, e3, Mlp, Ml, tanphi, Nl1, Nl, psi, Az, G, H, GH, Hs, c, kp, cos_c, s, s2, s3, s4, s5;
620 if (this.sphere) {
621 if (Math.abs(this.sin_p12 - 1) <= EPSLN) {
622 //North Pole case
623 p.x = this.x0 + this.a * (HALF_PI - lat) * Math.sin(dlon);
624 p.y = this.y0 - this.a * (HALF_PI - lat) * Math.cos(dlon);
625 return p;
626 }
627 else if (Math.abs(this.sin_p12 + 1) <= EPSLN) {
628 //South Pole case
629 p.x = this.x0 + this.a * (HALF_PI + lat) * Math.sin(dlon);
630 p.y = this.y0 + this.a * (HALF_PI + lat) * Math.cos(dlon);
631 return p;
632 }
633 else {
634 //default case
635 cos_c = this.sin_p12 * sinphi + this.cos_p12 * cosphi * Math.cos(dlon);
636 c = Math.acos(cos_c);
637 kp = c / Math.sin(c);
638 p.x = this.x0 + this.a * kp * cosphi * Math.sin(dlon);
639 p.y = this.y0 + this.a * kp * (this.cos_p12 * sinphi - this.sin_p12 * cosphi * Math.cos(dlon));
640 return p;
641 }
642 }
643 else {
644 e0 = e0fn(this.es);
645 e1 = e1fn(this.es);
646 e2 = e2fn(this.es);
647 e3 = e3fn(this.es);
648 if (Math.abs(this.sin_p12 - 1) <= EPSLN) {
649 //North Pole case
650 Mlp = this.a * mlfn(e0, e1, e2, e3, HALF_PI);
651 Ml = this.a * mlfn(e0, e1, e2, e3, lat);
652 p.x = this.x0 + (Mlp - Ml) * Math.sin(dlon);
653 p.y = this.y0 - (Mlp - Ml) * Math.cos(dlon);
654 return p;
655 }
656 else if (Math.abs(this.sin_p12 + 1) <= EPSLN) {
657 //South Pole case
658 Mlp = this.a * mlfn(e0, e1, e2, e3, HALF_PI);
659 Ml = this.a * mlfn(e0, e1, e2, e3, lat);
660 p.x = this.x0 + (Mlp + Ml) * Math.sin(dlon);
661 p.y = this.y0 + (Mlp + Ml) * Math.cos(dlon);
662 return p;
663 }
664 else {
665 //Default case
666 tanphi = sinphi / cosphi;
667 Nl1 = gN(this.a, this.e, this.sin_p12);
668 Nl = gN(this.a, this.e, sinphi);
669 psi = Math.atan((1 - this.es) * tanphi + this.es * Nl1 * this.sin_p12 / (Nl * cosphi));
670 Az = Math.atan2(Math.sin(dlon), this.cos_p12 * Math.tan(psi) - this.sin_p12 * Math.cos(dlon));
671 if (Az === 0) {
672 s = Math.asin(this.cos_p12 * Math.sin(psi) - this.sin_p12 * Math.cos(psi));
673 }
674 else if (Math.abs(Math.abs(Az) - Math.PI) <= EPSLN) {
675 s = -Math.asin(this.cos_p12 * Math.sin(psi) - this.sin_p12 * Math.cos(psi));
676 }
677 else {
678 s = Math.asin(Math.sin(dlon) * Math.cos(psi) / Math.sin(Az));
679 }
680 G = this.e * this.sin_p12 / Math.sqrt(1 - this.es);
681 H = this.e * this.cos_p12 * Math.cos(Az) / Math.sqrt(1 - this.es);
682 GH = G * H;
683 Hs = H * H;
684 s2 = s * s;
685 s3 = s2 * s;
686 s4 = s3 * s;
687 s5 = s4 * s;
688 c = Nl1 * s * (1 - s2 * Hs * (1 - Hs) / 6 + s3 / 8 * GH * (1 - 2 * Hs) + s4 / 120 * (Hs * (4 - 7 * Hs) - 3 * G * G * (1 - 7 * Hs)) - s5 / 48 * GH);
689 p.x = this.x0 + c * Math.sin(Az);
690 p.y = this.y0 + c * Math.cos(Az);
691 return p;
692 }
693 }
694
695
696 };
697
698 exports.inverse = function(p) {
699 p.x -= this.x0;
700 p.y -= this.y0;
701 var rh, z, sinz, cosz, lon, lat, con, e0, e1, e2, e3, Mlp, M, N1, psi, Az, cosAz, tmp, A, B, D, Ee, F;
702 if (this.sphere) {
703 rh = Math.sqrt(p.x * p.x + p.y * p.y);
704 if (rh > (2 * HALF_PI * this.a)) {
705 return;
706 }
707 z = rh / this.a;
708
709 sinz = Math.sin(z);
710 cosz = Math.cos(z);
711
712 lon = this.long0;
713 if (Math.abs(rh) <= EPSLN) {
714 lat = this.lat0;
715 }
716 else {
717 lat = asinz(cosz * this.sin_p12 + (p.y * sinz * this.cos_p12) / rh);
718 con = Math.abs(this.lat0) - HALF_PI;
719 if (Math.abs(con) <= EPSLN) {
720 if (this.lat0 >= 0) {
721 lon = adjust_lon(this.long0 + Math.atan2(p.x, - p.y));
722 }
723 else {
724 lon = adjust_lon(this.long0 - Math.atan2(-p.x, p.y));
725 }
726 }
727 else {
728 /*con = cosz - this.sin_p12 * Math.sin(lat);
729 if ((Math.abs(con) < EPSLN) && (Math.abs(p.x) < EPSLN)) {
730 //no-op, just keep the lon value as is
731 } else {
732 var temp = Math.atan2((p.x * sinz * this.cos_p12), (con * rh));
733 lon = adjust_lon(this.long0 + Math.atan2((p.x * sinz * this.cos_p12), (con * rh)));
734 }*/
735 lon = adjust_lon(this.long0 + Math.atan2(p.x * sinz, rh * this.cos_p12 * cosz - p.y * this.sin_p12 * sinz));
736 }
737 }
738
739 p.x = lon;
740 p.y = lat;
741 return p;
742 }
743 else {
744 e0 = e0fn(this.es);
745 e1 = e1fn(this.es);
746 e2 = e2fn(this.es);
747 e3 = e3fn(this.es);
748 if (Math.abs(this.sin_p12 - 1) <= EPSLN) {
749 //North pole case
750 Mlp = this.a * mlfn(e0, e1, e2, e3, HALF_PI);
751 rh = Math.sqrt(p.x * p.x + p.y * p.y);
752 M = Mlp - rh;
753 lat = imlfn(M / this.a, e0, e1, e2, e3);
754 lon = adjust_lon(this.long0 + Math.atan2(p.x, - 1 * p.y));
755 p.x = lon;
756 p.y = lat;
757 return p;
758 }
759 else if (Math.abs(this.sin_p12 + 1) <= EPSLN) {
760 //South pole case
761 Mlp = this.a * mlfn(e0, e1, e2, e3, HALF_PI);
762 rh = Math.sqrt(p.x * p.x + p.y * p.y);
763 M = rh - Mlp;
764
765 lat = imlfn(M / this.a, e0, e1, e2, e3);
766 lon = adjust_lon(this.long0 + Math.atan2(p.x, p.y));
767 p.x = lon;
768 p.y = lat;
769 return p;
770 }
771 else {
772 //default case
773 rh = Math.sqrt(p.x * p.x + p.y * p.y);
774 Az = Math.atan2(p.x, p.y);
775 N1 = gN(this.a, this.e, this.sin_p12);
776 cosAz = Math.cos(Az);
777 tmp = this.e * this.cos_p12 * cosAz;
778 A = -tmp * tmp / (1 - this.es);
779 B = 3 * this.es * (1 - A) * this.sin_p12 * this.cos_p12 * cosAz / (1 - this.es);
780 D = rh / N1;
781 Ee = D - A * (1 + A) * Math.pow(D, 3) / 6 - B * (1 + 3 * A) * Math.pow(D, 4) / 24;
782 F = 1 - A * Ee * Ee / 2 - D * Ee * Ee * Ee / 6;
783 psi = Math.asin(this.sin_p12 * Math.cos(Ee) + this.cos_p12 * Math.sin(Ee) * cosAz);
784 lon = adjust_lon(this.long0 + Math.asin(Math.sin(Az) * Math.sin(Ee) / Math.cos(psi)));
785 lat = Math.atan((1 - this.es * F * this.sin_p12 / Math.sin(psi)) * Math.tan(psi) / (1 - this.es));
786 p.x = lon;
787 p.y = lat;
788 return p;
789 }
790 }
791
792 };
793 exports.names = ["Azimuthal_Equidistant", "aeqd"];
794 });
795
796 var require$$0$2 = (aeqd && typeof aeqd === 'object' && 'default' in aeqd ? aeqd['default'] : aeqd);
797
798 var vandg = createCommonjsModule(function (module, exports) {
799 var adjust_lon = require$$2;
800 var HALF_PI = Math.PI/2;
801 var EPSLN = 1.0e-10;
802 var asinz = require$$0$4;
803 /* Initialize the Van Der Grinten projection
804 ----------------------------------------*/
805 exports.init = function() {
806 //this.R = 6370997; //Radius of earth
807 this.R = this.a;
808 };
809
810 exports.forward = function(p) {
811
812 var lon = p.x;
813 var lat = p.y;
814
815 /* Forward equations
816 -----------------*/
817 var dlon = adjust_lon(lon - this.long0);
818 var x, y;
819
820 if (Math.abs(lat) <= EPSLN) {
821 x = this.x0 + this.R * dlon;
822 y = this.y0;
823 }
824 var theta = asinz(2 * Math.abs(lat / Math.PI));
825 if ((Math.abs(dlon) <= EPSLN) || (Math.abs(Math.abs(lat) - HALF_PI) <= EPSLN)) {
826 x = this.x0;
827 if (lat >= 0) {
828 y = this.y0 + Math.PI * this.R * Math.tan(0.5 * theta);
829 }
830 else {
831 y = this.y0 + Math.PI * this.R * -Math.tan(0.5 * theta);
832 }
833 // return(OK);
834 }
835 var al = 0.5 * Math.abs((Math.PI / dlon) - (dlon / Math.PI));
836 var asq = al * al;
837 var sinth = Math.sin(theta);
838 var costh = Math.cos(theta);
839
840 var g = costh / (sinth + costh - 1);
841 var gsq = g * g;
842 var m = g * (2 / sinth - 1);
843 var msq = m * m;
844 var con = Math.PI * this.R * (al * (g - msq) + Math.sqrt(asq * (g - msq) * (g - msq) - (msq + asq) * (gsq - msq))) / (msq + asq);
845 if (dlon < 0) {
846 con = -con;
847 }
848 x = this.x0 + con;
849 //con = Math.abs(con / (Math.PI * this.R));
850 var q = asq + g;
851 con = Math.PI * this.R * (m * q - al * Math.sqrt((msq + asq) * (asq + 1) - q * q)) / (msq + asq);
852 if (lat >= 0) {
853 //y = this.y0 + Math.PI * this.R * Math.sqrt(1 - con * con - 2 * al * con);
854 y = this.y0 + con;
855 }
856 else {
857 //y = this.y0 - Math.PI * this.R * Math.sqrt(1 - con * con - 2 * al * con);
858 y = this.y0 - con;
859 }
860 p.x = x;
861 p.y = y;
862 return p;
863 };
864
865 /* Van Der Grinten inverse equations--mapping x,y to lat/long
866 ---------------------------------------------------------*/
867 exports.inverse = function(p) {
868 var lon, lat;
869 var xx, yy, xys, c1, c2, c3;
870 var a1;
871 var m1;
872 var con;
873 var th1;
874 var d;
875
876 /* inverse equations
877 -----------------*/
878 p.x -= this.x0;
879 p.y -= this.y0;
880 con = Math.PI * this.R;
881 xx = p.x / con;
882 yy = p.y / con;
883 xys = xx * xx + yy * yy;
884 c1 = -Math.abs(yy) * (1 + xys);
885 c2 = c1 - 2 * yy * yy + xx * xx;
886 c3 = -2 * c1 + 1 + 2 * yy * yy + xys * xys;
887 d = yy * yy / c3 + (2 * c2 * c2 * c2 / c3 / c3 / c3 - 9 * c1 * c2 / c3 / c3) / 27;
888 a1 = (c1 - c2 * c2 / 3 / c3) / c3;
889 m1 = 2 * Math.sqrt(-a1 / 3);
890 con = ((3 * d) / a1) / m1;
891 if (Math.abs(con) > 1) {
892 if (con >= 0) {
893 con = 1;
894 }
895 else {
896 con = -1;
897 }
898 }
899 th1 = Math.acos(con) / 3;
900 if (p.y >= 0) {
901 lat = (-m1 * Math.cos(th1 + Math.PI / 3) - c2 / 3 / c3) * Math.PI;
902 }
903 else {
904 lat = -(-m1 * Math.cos(th1 + Math.PI / 3) - c2 / 3 / c3) * Math.PI;
905 }
906
907 if (Math.abs(xx) < EPSLN) {
908 lon = this.long0;
909 }
910 else {
911 lon = adjust_lon(this.long0 + Math.PI * (xys - 1 + Math.sqrt(1 + 2 * (xx * xx - yy * yy) + xys * xys)) / 2 / xx);
912 }
913
914 p.x = lon;
915 p.y = lat;
916 return p;
917 };
918 exports.names = ["Van_der_Grinten_I", "VanDerGrinten", "vandg"];
919 });
920
921 var require$$1$1 = (vandg && typeof vandg === 'object' && 'default' in vandg ? vandg['default'] : vandg);
922
923 var adjust_lat = createCommonjsModule(function (module) {
924 var HALF_PI = Math.PI/2;
925 var sign = require$$1;
926
927 module.exports = function(x) {
928 return (Math.abs(x) < HALF_PI) ? x : (x - (sign(x) * Math.PI));
929 };
930 });
931
932 var require$$1$2 = (adjust_lat && typeof adjust_lat === 'object' && 'default' in adjust_lat ? adjust_lat['default'] : adjust_lat);
933
934 var msfnz = createCommonjsModule(function (module) {
935 module.exports = function(eccent, sinphi, cosphi) {
936 var con = eccent * sinphi;
937 return cosphi / (Math.sqrt(1 - con * con));
938 };
939 });
940
941 var require$$3$2 = (msfnz && typeof msfnz === 'object' && 'default' in msfnz ? msfnz['default'] : msfnz);
942
943 var eqdc = createCommonjsModule(function (module, exports) {
944 var e0fn = require$$7;
945 var e1fn = require$$6;
946 var e2fn = require$$5;
947 var e3fn = require$$4;
948 var msfnz = require$$3$2;
949 var mlfn = require$$3$1;
950 var adjust_lon = require$$2;
951 var adjust_lat = require$$1$2;
952 var imlfn = require$$0$3;
953 var EPSLN = 1.0e-10;
954 exports.init = function() {
955
956 /* Place parameters in static storage for common use
957 -------------------------------------------------*/
958 // Standard Parallels cannot be equal and on opposite sides of the equator
959 if (Math.abs(this.lat1 + this.lat2) < EPSLN) {
960 return;
961 }
962 this.lat2 = this.lat2 || this.lat1;
963 this.temp = this.b / this.a;
964 this.es = 1 - Math.pow(this.temp, 2);
965 this.e = Math.sqrt(this.es);
966 this.e0 = e0fn(this.es);
967 this.e1 = e1fn(this.es);
968 this.e2 = e2fn(this.es);
969 this.e3 = e3fn(this.es);
970
971 this.sinphi = Math.sin(this.lat1);
972 this.cosphi = Math.cos(this.lat1);
973
974 this.ms1 = msfnz(this.e, this.sinphi, this.cosphi);
975 this.ml1 = mlfn(this.e0, this.e1, this.e2, this.e3, this.lat1);
976
977 if (Math.abs(this.lat1 - this.lat2) < EPSLN) {
978 this.ns = this.sinphi;
979 }
980 else {
981 this.sinphi = Math.sin(this.lat2);
982 this.cosphi = Math.cos(this.lat2);
983 this.ms2 = msfnz(this.e, this.sinphi, this.cosphi);
984 this.ml2 = mlfn(this.e0, this.e1, this.e2, this.e3, this.lat2);
985 this.ns = (this.ms1 - this.ms2) / (this.ml2 - this.ml1);
986 }
987 this.g = this.ml1 + this.ms1 / this.ns;
988 this.ml0 = mlfn(this.e0, this.e1, this.e2, this.e3, this.lat0);
989 this.rh = this.a * (this.g - this.ml0);
990 };
991
992
993 /* Equidistant Conic forward equations--mapping lat,long to x,y
994 -----------------------------------------------------------*/
995 exports.forward = function(p) {
996 var lon = p.x;
997 var lat = p.y;
998 var rh1;
999
1000 /* Forward equations
1001 -----------------*/
1002 if (this.sphere) {
1003 rh1 = this.a * (this.g - lat);
1004 }
1005 else {
1006 var ml = mlfn(this.e0, this.e1, this.e2, this.e3, lat);
1007 rh1 = this.a * (this.g - ml);
1008 }
1009 var theta = this.ns * adjust_lon(lon - this.long0);
1010 var x = this.x0 + rh1 * Math.sin(theta);
1011 var y = this.y0 + this.rh - rh1 * Math.cos(theta);
1012 p.x = x;
1013 p.y = y;
1014 return p;
1015 };
1016
1017 /* Inverse equations
1018 -----------------*/
1019 exports.inverse = function(p) {
1020 p.x -= this.x0;
1021 p.y = this.rh - p.y + this.y0;
1022 var con, rh1, lat, lon;
1023 if (this.ns >= 0) {
1024 rh1 = Math.sqrt(p.x * p.x + p.y * p.y);
1025 con = 1;
1026 }
1027 else {
1028 rh1 = -Math.sqrt(p.x * p.x + p.y * p.y);
1029 con = -1;
1030 }
1031 var theta = 0;
1032 if (rh1 !== 0) {
1033 theta = Math.atan2(con * p.x, con * p.y);
1034 }
1035
1036 if (this.sphere) {
1037 lon = adjust_lon(this.long0 + theta / this.ns);
1038 lat = adjust_lat(this.g - rh1 / this.a);
1039 p.x = lon;
1040 p.y = lat;
1041 return p;
1042 }
1043 else {
1044 var ml = this.g - rh1 / this.a;
1045 lat = imlfn(ml, this.e0, this.e1, this.e2, this.e3);
1046 lon = adjust_lon(this.long0 + theta / this.ns);
1047 p.x = lon;
1048 p.y = lat;
1049 return p;
1050 }
1051
1052 };
1053 exports.names = ["Equidistant_Conic", "eqdc"];
1054 });
1055
1056 var require$$2$1 = (eqdc && typeof eqdc === 'object' && 'default' in eqdc ? eqdc['default'] : eqdc);
1057
1058 var moll = createCommonjsModule(function (module, exports) {
1059 var adjust_lon = require$$2;
1060 var EPSLN = 1.0e-10;
1061 exports.init = function() {};
1062
1063 /* Mollweide forward equations--mapping lat,long to x,y
1064 ----------------------------------------------------*/
1065 exports.forward = function(p) {
1066
1067 /* Forward equations
1068 -----------------*/
1069 var lon = p.x;
1070 var lat = p.y;
1071
1072 var delta_lon = adjust_lon(lon - this.long0);
1073 var theta = lat;
1074 var con = Math.PI * Math.sin(lat);
1075
1076 /* Iterate using the Newton-Raphson method to find theta
1077 -----------------------------------------------------*/
1078 for (var i = 0; true; i++) {
1079 var delta_theta = -(theta + Math.sin(theta) - con) / (1 + Math.cos(theta));
1080 theta += delta_theta;
1081 if (Math.abs(delta_theta) < EPSLN) {
1082 break;
1083 }
1084 }
1085 theta /= 2;
1086
1087 /* If the latitude is 90 deg, force the x coordinate to be "0 + false easting"
1088 this is done here because of precision problems with "cos(theta)"
1089 --------------------------------------------------------------------------*/
1090 if (Math.PI / 2 - Math.abs(lat) < EPSLN) {
1091 delta_lon = 0;
1092 }
1093 var x = 0.900316316158 * this.a * delta_lon * Math.cos(theta) + this.x0;
1094 var y = 1.4142135623731 * this.a * Math.sin(theta) + this.y0;
1095
1096 p.x = x;
1097 p.y = y;
1098 return p;
1099 };
1100
1101 exports.inverse = function(p) {
1102 var theta;
1103 var arg;
1104
1105 /* Inverse equations
1106 -----------------*/
1107 p.x -= this.x0;
1108 p.y -= this.y0;
1109 arg = p.y / (1.4142135623731 * this.a);
1110
1111 /* Because of division by zero problems, 'arg' can not be 1. Therefore
1112 a number very close to one is used instead.
1113 -------------------------------------------------------------------*/
1114 if (Math.abs(arg) > 0.999999999999) {
1115 arg = 0.999999999999;
1116 }
1117 theta = Math.asin(arg);
1118 var lon = adjust_lon(this.long0 + (p.x / (0.900316316158 * this.a * Math.cos(theta))));
1119 if (lon < (-Math.PI)) {
1120 lon = -Math.PI;
1121 }
1122 if (lon > Math.PI) {
1123 lon = Math.PI;
1124 }
1125 arg = (2 * theta + Math.sin(2 * theta)) / Math.PI;
1126 if (Math.abs(arg) > 1) {
1127 arg = 1;
1128 }
1129 var lat = Math.asin(arg);
1130
1131 p.x = lon;
1132 p.y = lat;
1133 return p;
1134 };
1135 exports.names = ["Mollweide", "moll"];
1136 });
1137
1138 var require$$3$3 = (moll && typeof moll === 'object' && 'default' in moll ? moll['default'] : moll);
1139
1140 var pj_mlfn = createCommonjsModule(function (module) {
1141 module.exports = function(phi, sphi, cphi, en) {
1142 cphi *= sphi;
1143 sphi *= sphi;
1144 return (en[0] * phi - cphi * (en[1] + sphi * (en[2] + sphi * (en[3] + sphi * en[4]))));
1145 };
1146 });
1147
1148 var require$$0$5 = (pj_mlfn && typeof pj_mlfn === 'object' && 'default' in pj_mlfn ? pj_mlfn['default'] : pj_mlfn);
1149
1150 var pj_inv_mlfn = createCommonjsModule(function (module) {
1151 var pj_mlfn = require$$0$5;
1152 var EPSLN = 1.0e-10;
1153 var MAX_ITER = 20;
1154 module.exports = function(arg, es, en) {
1155 var k = 1 / (1 - es);
1156 var phi = arg;
1157 for (var i = MAX_ITER; i; --i) { /* rarely goes over 2 iterations */
1158 var s = Math.sin(phi);
1159 var t = 1 - es * s * s;
1160 //t = this.pj_mlfn(phi, s, Math.cos(phi), en) - arg;
1161 //phi -= t * (t * Math.sqrt(t)) * k;
1162 t = (pj_mlfn(phi, s, Math.cos(phi), en) - arg) * (t * Math.sqrt(t)) * k;
1163 phi -= t;
1164 if (Math.abs(t) < EPSLN) {
1165 return phi;
1166 }
1167 }
1168 //..reportError("cass:pj_inv_mlfn: Convergence error");
1169 return phi;
1170 };
1171 });
1172
1173 var require$$1$3 = (pj_inv_mlfn && typeof pj_inv_mlfn === 'object' && 'default' in pj_inv_mlfn ? pj_inv_mlfn['default'] : pj_inv_mlfn);
1174
1175 var pj_enfn = createCommonjsModule(function (module) {
1176 var C00 = 1;
1177 var C02 = 0.25;
1178 var C04 = 0.046875;
1179 var C06 = 0.01953125;
1180 var C08 = 0.01068115234375;
1181 var C22 = 0.75;
1182 var C44 = 0.46875;
1183 var C46 = 0.01302083333333333333;
1184 var C48 = 0.00712076822916666666;
1185 var C66 = 0.36458333333333333333;
1186 var C68 = 0.00569661458333333333;
1187 var C88 = 0.3076171875;
1188
1189 module.exports = function(es) {
1190 var en = [];
1191 en[0] = C00 - es * (C02 + es * (C04 + es * (C06 + es * C08)));
1192 en[1] = es * (C22 - es * (C04 + es * (C06 + es * C08)));
1193 var t = es * es;
1194 en[2] = t * (C44 - es * (C46 + es * C48));
1195 t *= es;
1196 en[3] = t * (C66 - es * C68);
1197 en[4] = t * es * C88;
1198 return en;
1199 };
1200 });
1201
1202 var require$$3$4 = (pj_enfn && typeof pj_enfn === 'object' && 'default' in pj_enfn ? pj_enfn['default'] : pj_enfn);
1203
1204 var sinu = createCommonjsModule(function (module, exports) {
1205 var adjust_lon = require$$2;
1206 var adjust_lat = require$$1$2;
1207 var pj_enfn = require$$3$4;
1208 var MAX_ITER = 20;
1209 var pj_mlfn = require$$0$5;
1210 var pj_inv_mlfn = require$$1$3;
1211 var HALF_PI = Math.PI/2;
1212 var EPSLN = 1.0e-10;
1213 var asinz = require$$0$4;
1214 exports.init = function() {
1215 /* Place parameters in static storage for common use
1216 -------------------------------------------------*/
1217
1218
1219 if (!this.sphere) {
1220 this.en = pj_enfn(this.es);
1221 }
1222 else {
1223 this.n = 1;
1224 this.m = 0;
1225 this.es = 0;
1226 this.C_y = Math.sqrt((this.m + 1) / this.n);
1227 this.C_x = this.C_y / (this.m + 1);
1228 }
1229
1230 };
1231
1232 /* Sinusoidal forward equations--mapping lat,long to x,y
1233 -----------------------------------------------------*/
1234 exports.forward = function(p) {
1235 var x, y;
1236 var lon = p.x;
1237 var lat = p.y;
1238 /* Forward equations
1239 -----------------*/
1240 lon = adjust_lon(lon - this.long0);
1241
1242 if (this.sphere) {
1243 if (!this.m) {
1244 lat = this.n !== 1 ? Math.asin(this.n * Math.sin(lat)) : lat;
1245 }
1246 else {
1247 var k = this.n * Math.sin(lat);
1248 for (var i = MAX_ITER; i; --i) {
1249 var V = (this.m * lat + Math.sin(lat) - k) / (this.m + Math.cos(lat));
1250 lat -= V;
1251 if (Math.abs(V) < EPSLN) {
1252 break;
1253 }
1254 }
1255 }
1256 x = this.a * this.C_x * lon * (this.m + Math.cos(lat));
1257 y = this.a * this.C_y * lat;
1258
1259 }
1260 else {
1261
1262 var s = Math.sin(lat);
1263 var c = Math.cos(lat);
1264 y = this.a * pj_mlfn(lat, s, c, this.en);
1265 x = this.a * lon * c / Math.sqrt(1 - this.es * s * s);
1266 }
1267
1268 p.x = x;
1269 p.y = y;
1270 return p;
1271 };
1272
1273 exports.inverse = function(p) {
1274 var lat, temp, lon, s;
1275
1276 p.x -= this.x0;
1277 lon = p.x / this.a;
1278 p.y -= this.y0;
1279 lat = p.y / this.a;
1280
1281 if (this.sphere) {
1282 lat /= this.C_y;
1283 lon = lon / (this.C_x * (this.m + Math.cos(lat)));
1284 if (this.m) {
1285 lat = asinz((this.m * lat + Math.sin(lat)) / this.n);
1286 }
1287 else if (this.n !== 1) {
1288 lat = asinz(Math.sin(lat) / this.n);
1289 }
1290 lon = adjust_lon(lon + this.long0);
1291 lat = adjust_lat(lat);
1292 }
1293 else {
1294 lat = pj_inv_mlfn(p.y / this.a, this.es, this.en);
1295 s = Math.abs(lat);
1296 if (s < HALF_PI) {
1297 s = Math.sin(lat);
1298 temp = this.long0 + p.x * Math.sqrt(1 - this.es * s * s) / (this.a * Math.cos(lat));
1299 //temp = this.long0 + p.x / (this.a * Math.cos(lat));
1300 lon = adjust_lon(temp);
1301 }
1302 else if ((s - EPSLN) < HALF_PI) {
1303 lon = this.long0;
1304 }
1305 }
1306 p.x = lon;
1307 p.y = lat;
1308 return p;
1309 };
1310 exports.names = ["Sinusoidal", "sinu"];
1311 });
1312
1313 var require$$4$1 = (sinu && typeof sinu === 'object' && 'default' in sinu ? sinu['default'] : sinu);
1314
1315 var mill = createCommonjsModule(function (module, exports) {
1316 var adjust_lon = require$$2;
1317 /*
1318 reference
1319 "New Equal-Area Map Projections for Noncircular Regions", John P. Snyder,
1320 The American Cartographer, Vol 15, No. 4, October 1988, pp. 341-355.
1321 */
1322
1323
1324 /* Initialize the Miller Cylindrical projection
1325 -------------------------------------------*/
1326 exports.init = function() {
1327 //no-op
1328 };
1329
1330
1331 /* Miller Cylindrical forward equations--mapping lat,long to x,y
1332 ------------------------------------------------------------*/
1333 exports.forward = function(p) {
1334 var lon = p.x;
1335 var lat = p.y;
1336 /* Forward equations
1337 -----------------*/
1338 var dlon = adjust_lon(lon - this.long0);
1339 var x = this.x0 + this.a * dlon;
1340 var y = this.y0 + this.a * Math.log(Math.tan((Math.PI / 4) + (lat / 2.5))) * 1.25;
1341
1342 p.x = x;
1343 p.y = y;
1344 return p;
1345 };
1346
1347 /* Miller Cylindrical inverse equations--mapping x,y to lat/long
1348 ------------------------------------------------------------*/
1349 exports.inverse = function(p) {
1350 p.x -= this.x0;
1351 p.y -= this.y0;
1352
1353 var lon = adjust_lon(this.long0 + p.x / this.a);
1354 var lat = 2.5 * (Math.atan(Math.exp(0.8 * p.y / this.a)) - Math.PI / 4);
1355
1356 p.x = lon;
1357 p.y = lat;
1358 return p;
1359 };
1360 exports.names = ["Miller_Cylindrical", "mill"];
1361 });
1362
1363 var require$$5$1 = (mill && typeof mill === 'object' && 'default' in mill ? mill['default'] : mill);
1364
1365 var nzmg = createCommonjsModule(function (module, exports) {
1366 var SEC_TO_RAD = 4.84813681109535993589914102357e-6;
1367 /*
1368 reference
1369 Department of Land and Survey Technical Circular 1973/32
1370 http://www.linz.govt.nz/docs/miscellaneous/nz-map-definition.pdf
1371 OSG Technical Report 4.1
1372 http://www.linz.govt.nz/docs/miscellaneous/nzmg.pdf
1373 */
1374
1375 /**
1376 * iterations: Number of iterations to refine inverse transform.
1377 * 0 -> km accuracy
1378 * 1 -> m accuracy -- suitable for most mapping applications
1379 * 2 -> mm accuracy
1380 */
1381 exports.iterations = 1;
1382
1383 exports.init = function() {
1384 this.A = [];
1385 this.A[1] = 0.6399175073;
1386 this.A[2] = -0.1358797613;
1387 this.A[3] = 0.063294409;
1388 this.A[4] = -0.02526853;
1389 this.A[5] = 0.0117879;
1390 this.A[6] = -0.0055161;
1391 this.A[7] = 0.0026906;
1392 this.A[8] = -0.001333;
1393 this.A[9] = 0.00067;
1394 this.A[10] = -0.00034;
1395
1396 this.B_re = [];
1397 this.B_im = [];
1398 this.B_re[1] = 0.7557853228;
1399 this.B_im[1] = 0;
1400 this.B_re[2] = 0.249204646;
1401 this.B_im[2] = 0.003371507;
1402 this.B_re[3] = -0.001541739;
1403 this.B_im[3] = 0.041058560;
1404 this.B_re[4] = -0.10162907;
1405 this.B_im[4] = 0.01727609;
1406 this.B_re[5] = -0.26623489;
1407 this.B_im[5] = -0.36249218;
1408 this.B_re[6] = -0.6870983;
1409 this.B_im[6] = -1.1651967;
1410
1411 this.C_re = [];
1412 this.C_im = [];
1413 this.C_re[1] = 1.3231270439;
1414 this.C_im[1] = 0;
1415 this.C_re[2] = -0.577245789;
1416 this.C_im[2] = -0.007809598;
1417 this.C_re[3] = 0.508307513;
1418 this.C_im[3] = -0.112208952;
1419 this.C_re[4] = -0.15094762;
1420 this.C_im[4] = 0.18200602;
1421 this.C_re[5] = 1.01418179;
1422 this.C_im[5] = 1.64497696;
1423 this.C_re[6] = 1.9660549;
1424 this.C_im[6] = 2.5127645;
1425
1426 this.D = [];
1427 this.D[1] = 1.5627014243;
1428 this.D[2] = 0.5185406398;
1429 this.D[3] = -0.03333098;
1430 this.D[4] = -0.1052906;
1431 this.D[5] = -0.0368594;
1432 this.D[6] = 0.007317;
1433 this.D[7] = 0.01220;
1434 this.D[8] = 0.00394;
1435 this.D[9] = -0.0013;
1436 };
1437
1438 /**
1439 New Zealand Map Grid Forward - long/lat to x/y
1440 long/lat in radians
1441 */
1442 exports.forward = function(p) {
1443 var n;
1444 var lon = p.x;
1445 var lat = p.y;
1446
1447 var delta_lat = lat - this.lat0;
1448 var delta_lon = lon - this.long0;
1449
1450 // 1. Calculate d_phi and d_psi ... // and d_lambda
1451 // For this algorithm, delta_latitude is in seconds of arc x 10-5, so we need to scale to those units. Longitude is radians.
1452 var d_phi = delta_lat / SEC_TO_RAD * 1E-5;
1453 var d_lambda = delta_lon;
1454 var d_phi_n = 1; // d_phi^0
1455
1456 var d_psi = 0;
1457 for (n = 1; n <= 10; n++) {
1458 d_phi_n = d_phi_n * d_phi;
1459 d_psi = d_psi + this.A[n] * d_phi_n;
1460 }
1461
1462 // 2. Calculate theta
1463 var th_re = d_psi;
1464 var th_im = d_lambda;
1465
1466 // 3. Calculate z
1467 var th_n_re = 1;
1468 var th_n_im = 0; // theta^0
1469 var th_n_re1;
1470 var th_n_im1;
1471
1472 var z_re = 0;
1473 var z_im = 0;
1474 for (n = 1; n <= 6; n++) {
1475 th_n_re1 = th_n_re * th_re - th_n_im * th_im;
1476 th_n_im1 = th_n_im * th_re + th_n_re * th_im;
1477 th_n_re = th_n_re1;
1478 th_n_im = th_n_im1;
1479 z_re = z_re + this.B_re[n] * th_n_re - this.B_im[n] * th_n_im;
1480 z_im = z_im + this.B_im[n] * th_n_re + this.B_re[n] * th_n_im;
1481 }
1482
1483 // 4. Calculate easting and northing
1484 p.x = (z_im * this.a) + this.x0;
1485 p.y = (z_re * this.a) + this.y0;
1486
1487 return p;
1488 };
1489
1490
1491 /**
1492 New Zealand Map Grid Inverse - x/y to long/lat
1493 */
1494 exports.inverse = function(p) {
1495 var n;
1496 var x = p.x;
1497 var y = p.y;
1498
1499 var delta_x = x - this.x0;
1500 var delta_y = y - this.y0;
1501
1502 // 1. Calculate z
1503 var z_re = delta_y / this.a;
1504 var z_im = delta_x / this.a;
1505
1506 // 2a. Calculate theta - first approximation gives km accuracy
1507 var z_n_re = 1;
1508 var z_n_im = 0; // z^0
1509 var z_n_re1;
1510 var z_n_im1;
1511
1512 var th_re = 0;
1513 var th_im = 0;
1514 for (n = 1; n <= 6; n++) {
1515 z_n_re1 = z_n_re * z_re - z_n_im * z_im;
1516 z_n_im1 = z_n_im * z_re + z_n_re * z_im;
1517 z_n_re = z_n_re1;
1518 z_n_im = z_n_im1;
1519 th_re = th_re + this.C_re[n] * z_n_re - this.C_im[n] * z_n_im;
1520 th_im = th_im + this.C_im[n] * z_n_re + this.C_re[n] * z_n_im;
1521 }
1522
1523 // 2b. Iterate to refine the accuracy of the calculation
1524 // 0 iterations gives km accuracy
1525 // 1 iteration gives m accuracy -- good enough for most mapping applications
1526 // 2 iterations bives mm accuracy
1527 for (var i = 0; i < this.iterations; i++) {
1528 var th_n_re = th_re;
1529 var th_n_im = th_im;
1530 var th_n_re1;
1531 var th_n_im1;
1532
1533 var num_re = z_re;
1534 var num_im = z_im;
1535 for (n = 2; n <= 6; n++) {
1536 th_n_re1 = th_n_re * th_re - th_n_im * th_im;
1537 th_n_im1 = th_n_im * th_re + th_n_re * th_im;
1538 th_n_re = th_n_re1;
1539 th_n_im = th_n_im1;
1540 num_re = num_re + (n - 1) * (this.B_re[n] * th_n_re - this.B_im[n] * th_n_im);
1541 num_im = num_im + (n - 1) * (this.B_im[n] * th_n_re + this.B_re[n] * th_n_im);
1542 }
1543
1544 th_n_re = 1;
1545 th_n_im = 0;
1546 var den_re = this.B_re[1];
1547 var den_im = this.B_im[1];
1548 for (n = 2; n <= 6; n++) {
1549 th_n_re1 = th_n_re * th_re - th_n_im * th_im;
1550 th_n_im1 = th_n_im * th_re + th_n_re * th_im;
1551 th_n_re = th_n_re1;
1552 th_n_im = th_n_im1;
1553 den_re = den_re + n * (this.B_re[n] * th_n_re - this.B_im[n] * th_n_im);
1554 den_im = den_im + n * (this.B_im[n] * th_n_re + this.B_re[n] * th_n_im);
1555 }
1556
1557 // Complex division
1558 var den2 = den_re * den_re + den_im * den_im;
1559 th_re = (num_re * den_re + num_im * den_im) / den2;
1560 th_im = (num_im * den_re - num_re * den_im) / den2;
1561 }
1562
1563 // 3. Calculate d_phi ... // and d_lambda
1564 var d_psi = th_re;
1565 var d_lambda = th_im;
1566 var d_psi_n = 1; // d_psi^0
1567
1568 var d_phi = 0;
1569 for (n = 1; n <= 9; n++) {
1570 d_psi_n = d_psi_n * d_psi;
1571 d_phi = d_phi + this.D[n] * d_psi_n;
1572 }
1573
1574 // 4. Calculate latitude and longitude
1575 // d_phi is calcuated in second of arc * 10^-5, so we need to scale back to radians. d_lambda is in radians.
1576 var lat = this.lat0 + (d_phi * SEC_TO_RAD * 1E5);
1577 var lon = this.long0 + d_lambda;
1578
1579 p.x = lon;
1580 p.y = lat;
1581
1582 return p;
1583 };
1584 exports.names = ["New_Zealand_Map_Grid", "nzmg"];
1585 });
1586
1587 var require$$6$1 = (nzmg && typeof nzmg === 'object' && 'default' in nzmg ? nzmg['default'] : nzmg);
1588
1589 var poly = createCommonjsModule(function (module, exports) {
1590 var e0fn = require$$7;
1591 var e1fn = require$$6;
1592 var e2fn = require$$5;
1593 var e3fn = require$$4;
1594 var adjust_lon = require$$2;
1595 var adjust_lat = require$$1$2;
1596 var mlfn = require$$3$1;
1597 var EPSLN = 1.0e-10;
1598 var gN = require$$3;
1599 var MAX_ITER = 20;
1600 exports.init = function() {
1601 /* Place parameters in static storage for common use
1602 -------------------------------------------------*/
1603 this.temp = this.b / this.a;
1604 this.es = 1 - Math.pow(this.temp, 2); // devait etre dans tmerc.js mais n y est pas donc je commente sinon retour de valeurs nulles
1605 this.e = Math.sqrt(this.es);
1606 this.e0 = e0fn(this.es);
1607 this.e1 = e1fn(this.es);
1608 this.e2 = e2fn(this.es);
1609 this.e3 = e3fn(this.es);
1610 this.ml0 = this.a * mlfn(this.e0, this.e1, this.e2, this.e3, this.lat0); //si que des zeros le calcul ne se fait pas
1611 };
1612
1613
1614 /* Polyconic forward equations--mapping lat,long to x,y
1615 ---------------------------------------------------*/
1616 exports.forward = function(p) {
1617 var lon = p.x;
1618 var lat = p.y;
1619 var x, y, el;
1620 var dlon = adjust_lon(lon - this.long0);
1621 el = dlon * Math.sin(lat);
1622 if (this.sphere) {
1623 if (Math.abs(lat) <= EPSLN) {
1624 x = this.a * dlon;
1625 y = -1 * this.a * this.lat0;
1626 }
1627 else {
1628 x = this.a * Math.sin(el) / Math.tan(lat);
1629 y = this.a * (adjust_lat(lat - this.lat0) + (1 - Math.cos(el)) / Math.tan(lat));
1630 }
1631 }
1632 else {
1633 if (Math.abs(lat) <= EPSLN) {
1634 x = this.a * dlon;
1635 y = -1 * this.ml0;
1636 }
1637 else {
1638 var nl = gN(this.a, this.e, Math.sin(lat)) / Math.tan(lat);
1639 x = nl * Math.sin(el);
1640 y = this.a * mlfn(this.e0, this.e1, this.e2, this.e3, lat) - this.ml0 + nl * (1 - Math.cos(el));
1641 }
1642
1643 }
1644 p.x = x + this.x0;
1645 p.y = y + this.y0;
1646 return p;
1647 };
1648
1649
1650 /* Inverse equations
1651 -----------------*/
1652 exports.inverse = function(p) {
1653 var lon, lat, x, y, i;
1654 var al, bl;
1655 var phi, dphi;
1656 x = p.x - this.x0;
1657 y = p.y - this.y0;
1658
1659 if (this.sphere) {
1660 if (Math.abs(y + this.a * this.lat0) <= EPSLN) {
1661 lon = adjust_lon(x / this.a + this.long0);
1662 lat = 0;
1663 }
1664 else {
1665 al = this.lat0 + y / this.a;
1666 bl = x * x / this.a / this.a + al * al;
1667 phi = al;
1668 var tanphi;
1669 for (i = MAX_ITER; i; --i) {
1670 tanphi = Math.tan(phi);
1671 dphi = -1 * (al * (phi * tanphi + 1) - phi - 0.5 * (phi * phi + bl) * tanphi) / ((phi - al) / tanphi - 1);
1672 phi += dphi;
1673 if (Math.abs(dphi) <= EPSLN) {
1674 lat = phi;
1675 break;
1676 }
1677 }
1678 lon = adjust_lon(this.long0 + (Math.asin(x * Math.tan(phi) / this.a)) / Math.sin(lat));
1679 }
1680 }
1681 else {
1682 if (Math.abs(y + this.ml0) <= EPSLN) {
1683 lat = 0;
1684 lon = adjust_lon(this.long0 + x / this.a);
1685 }
1686 else {
1687
1688 al = (this.ml0 + y) / this.a;
1689 bl = x * x / this.a / this.a + al * al;
1690 phi = al;
1691 var cl, mln, mlnp, ma;
1692 var con;
1693 for (i = MAX_ITER; i; --i) {
1694 con = this.e * Math.sin(phi);
1695 cl = Math.sqrt(1 - con * con) * Math.tan(phi);
1696 mln = this.a * mlfn(this.e0, this.e1, this.e2, this.e3, phi);
1697 mlnp = this.e0 - 2 * this.e1 * Math.cos(2 * phi) + 4 * this.e2 * Math.cos(4 * phi) - 6 * this.e3 * Math.cos(6 * phi);
1698 ma = mln / this.a;
1699 dphi = (al * (cl * ma + 1) - ma - 0.5 * cl * (ma * ma + bl)) / (this.es * Math.sin(2 * phi) * (ma * ma + bl - 2 * al * ma) / (4 * cl) + (al - ma) * (cl * mlnp - 2 / Math.sin(2 * phi)) - mlnp);
1700 phi -= dphi;
1701 if (Math.abs(dphi) <= EPSLN) {
1702 lat = phi;
1703 break;
1704 }
1705 }
1706
1707 //lat=phi4z(this.e,this.e0,this.e1,this.e2,this.e3,al,bl,0,0);
1708 cl = Math.sqrt(1 - this.es * Math.pow(Math.sin(lat), 2)) * Math.tan(lat);
1709 lon = adjust_lon(this.long0 + Math.asin(x * cl / this.a) / Math.sin(lat));
1710 }
1711 }
1712
1713 p.x = lon;
1714 p.y = lat;
1715 return p;
1716 };
1717 exports.names = ["Polyconic", "poly"];
1718 });
1719
1720 var require$$7$1 = (poly && typeof poly === 'object' && 'default' in poly ? poly['default'] : poly);
1721
1722 var eqc = createCommonjsModule(function (module, exports) {
1723 var adjust_lon = require$$2;
1724 var adjust_lat = require$$1$2;
1725 exports.init = function() {
1726
1727 this.x0 = this.x0 || 0;
1728 this.y0 = this.y0 || 0;
1729 this.lat0 = this.lat0 || 0;
1730 this.long0 = this.long0 || 0;
1731 this.lat_ts = this.lat_ts || 0;
1732 this.title = this.title || "Equidistant Cylindrical (Plate Carre)";
1733
1734 this.rc = Math.cos(this.lat_ts);
1735 };
1736
1737
1738 // forward equations--mapping lat,long to x,y
1739 // -----------------------------------------------------------------
1740 exports.forward = function(p) {
1741
1742 var lon = p.x;
1743 var lat = p.y;
1744
1745 var dlon = adjust_lon(lon - this.long0);
1746 var dlat = adjust_lat(lat - this.lat0);
1747 p.x = this.x0 + (this.a * dlon * this.rc);
1748 p.y = this.y0 + (this.a * dlat);
1749 return p;
1750 };
1751
1752 // inverse equations--mapping x,y to lat/long
1753 // -----------------------------------------------------------------
1754 exports.inverse = function(p) {
1755
1756 var x = p.x;
1757 var y = p.y;
1758
1759 p.x = adjust_lon(this.long0 + ((x - this.x0) / (this.a * this.rc)));
1760 p.y = adjust_lat(this.lat0 + ((y - this.y0) / (this.a)));
1761 return p;
1762 };
1763 exports.names = ["Equirectangular", "Equidistant_Cylindrical", "eqc"];
1764 });
1765
1766 var require$$8 = (eqc && typeof eqc === 'object' && 'default' in eqc ? eqc['default'] : eqc);
1767
1768 var iqsfnz = createCommonjsModule(function (module) {
1769 var HALF_PI = Math.PI/2;
1770
1771 module.exports = function(eccent, q) {
1772 var temp = 1 - (1 - eccent * eccent) / (2 * eccent) * Math.log((1 - eccent) / (1 + eccent));
1773 if (Math.abs(Math.abs(q) - temp) < 1.0E-6) {
1774 if (q < 0) {
1775 return (-1 * HALF_PI);
1776 }
1777 else {
1778 return HALF_PI;
1779 }
1780 }
1781 //var phi = 0.5* q/(1-eccent*eccent);
1782 var phi = Math.asin(0.5 * q);
1783 var dphi;
1784 var sin_phi;
1785 var cos_phi;
1786 var con;
1787 for (var i = 0; i < 30; i++) {
1788 sin_phi = Math.sin(phi);
1789 cos_phi = Math.cos(phi);
1790 con = eccent * sin_phi;
1791 dphi = Math.pow(1 - con * con, 2) / (2 * cos_phi) * (q / (1 - eccent * eccent) - sin_phi / (1 - con * con) + 0.5 / eccent * Math.log((1 - con) / (1 + con)));
1792 phi += dphi;
1793 if (Math.abs(dphi) <= 0.0000000001) {
1794 return phi;
1795 }
1796 }
1797
1798 //console.log("IQSFN-CONV:Latitude failed to converge after 30 iterations");
1799 return NaN;
1800 };
1801 });
1802
1803 var require$$0$6 = (iqsfnz && typeof iqsfnz === 'object' && 'default' in iqsfnz ? iqsfnz['default'] : iqsfnz);
1804
1805 var qsfnz = createCommonjsModule(function (module) {
1806 module.exports = function(eccent, sinphi) {
1807 var con;
1808 if (eccent > 1.0e-7) {
1809 con = eccent * sinphi;
1810 return ((1 - eccent * eccent) * (sinphi / (1 - con * con) - (0.5 / eccent) * Math.log((1 - con) / (1 + con))));
1811 }
1812 else {
1813 return (2 * sinphi);
1814 }
1815 };
1816 });
1817
1818 var require$$1$4 = (qsfnz && typeof qsfnz === 'object' && 'default' in qsfnz ? qsfnz['default'] : qsfnz);
1819
1820 var cea = createCommonjsModule(function (module, exports) {
1821 var adjust_lon = require$$2;
1822 var qsfnz = require$$1$4;
1823 var msfnz = require$$3$2;
1824 var iqsfnz = require$$0$6;
1825 /*
1826 reference:
1827 "Cartographic Projection Procedures for the UNIX Environment-
1828 A User's Manual" by Gerald I. Evenden,
1829 USGS Open File Report 90-284and Release 4 Interim Reports (2003)
1830 */
1831 exports.init = function() {
1832 //no-op
1833 if (!this.sphere) {
1834 this.k0 = msfnz(this.e, Math.sin(this.lat_ts), Math.cos(this.lat_ts));
1835 }
1836 };
1837
1838
1839 /* Cylindrical Equal Area forward equations--mapping lat,long to x,y
1840 ------------------------------------------------------------*/
1841 exports.forward = function(p) {
1842 var lon = p.x;
1843 var lat = p.y;
1844 var x, y;
1845 /* Forward equations
1846 -----------------*/
1847 var dlon = adjust_lon(lon - this.long0);
1848 if (this.sphere) {
1849 x = this.x0 + this.a * dlon * Math.cos(this.lat_ts);
1850 y = this.y0 + this.a * Math.sin(lat) / Math.cos(this.lat_ts);
1851 }
1852 else {
1853 var qs = qsfnz(this.e, Math.sin(lat));
1854 x = this.x0 + this.a * this.k0 * dlon;
1855 y = this.y0 + this.a * qs * 0.5 / this.k0;
1856 }
1857
1858 p.x = x;
1859 p.y = y;
1860 return p;
1861 };
1862
1863 /* Cylindrical Equal Area inverse equations--mapping x,y to lat/long
1864 ------------------------------------------------------------*/
1865 exports.inverse = function(p) {
1866 p.x -= this.x0;
1867 p.y -= this.y0;
1868 var lon, lat;
1869
1870 if (this.sphere) {
1871 lon = adjust_lon(this.long0 + (p.x / this.a) / Math.cos(this.lat_ts));
1872 lat = Math.asin((p.y / this.a) * Math.cos(this.lat_ts));
1873 }
1874 else {
1875 lat = iqsfnz(this.e, 2 * p.y * this.k0 / this.a);
1876 lon = adjust_lon(this.long0 + p.x / (this.a * this.k0));
1877 }
1878
1879 p.x = lon;
1880 p.y = lat;
1881 return p;
1882 };
1883 exports.names = ["cea"];
1884 });
1885
1886 var require$$9 = (cea && typeof cea === 'object' && 'default' in cea ? cea['default'] : cea);
1887
1888 var gnom = createCommonjsModule(function (module, exports) {
1889 var adjust_lon = require$$2;
1890 var EPSLN = 1.0e-10;
1891 var asinz = require$$0$4;
1892
1893 /*
1894 reference:
1895 Wolfram Mathworld "Gnomonic Projection"
1896 http://mathworld.wolfram.com/GnomonicProjection.html
1897 Accessed: 12th November 2009
1898 */
1899 exports.init = function() {
1900
1901 /* Place parameters in static storage for common use
1902 -------------------------------------------------*/
1903 this.sin_p14 = Math.sin(this.lat0);
1904 this.cos_p14 = Math.cos(this.lat0);
1905 // Approximation for projecting points to the horizon (infinity)
1906 this.infinity_dist = 1000 * this.a;
1907 this.rc = 1;
1908 };
1909
1910
1911 /* Gnomonic forward equations--mapping lat,long to x,y
1912 ---------------------------------------------------*/
1913 exports.forward = function(p) {
1914 var sinphi, cosphi; /* sin and cos value */
1915 var dlon; /* delta longitude value */
1916 var coslon; /* cos of longitude */
1917 var ksp; /* scale factor */
1918 var g;
1919 var x, y;
1920 var lon = p.x;
1921 var lat = p.y;
1922 /* Forward equations
1923 -----------------*/
1924 dlon = adjust_lon(lon - this.long0);
1925
1926 sinphi = Math.sin(lat);
1927 cosphi = Math.cos(lat);
1928
1929 coslon = Math.cos(dlon);
1930 g = this.sin_p14 * sinphi + this.cos_p14 * cosphi * coslon;
1931 ksp = 1;
1932 if ((g > 0) || (Math.abs(g) <= EPSLN)) {
1933 x = this.x0 + this.a * ksp * cosphi * Math.sin(dlon) / g;
1934 y = this.y0 + this.a * ksp * (this.cos_p14 * sinphi - this.sin_p14 * cosphi * coslon) / g;
1935 }
1936 else {
1937
1938 // Point is in the opposing hemisphere and is unprojectable
1939 // We still need to return a reasonable point, so we project
1940 // to infinity, on a bearing
1941 // equivalent to the northern hemisphere equivalent
1942 // This is a reasonable approximation for short shapes and lines that
1943 // straddle the horizon.
1944
1945 x = this.x0 + this.infinity_dist * cosphi * Math.sin(dlon);
1946 y = this.y0 + this.infinity_dist * (this.cos_p14 * sinphi - this.sin_p14 * cosphi * coslon);
1947
1948 }
1949 p.x = x;
1950 p.y = y;
1951 return p;
1952 };
1953
1954
1955 exports.inverse = function(p) {
1956 var rh; /* Rho */
1957 var sinc, cosc;
1958 var c;
1959 var lon, lat;
1960
1961 /* Inverse equations
1962 -----------------*/
1963 p.x = (p.x - this.x0) / this.a;
1964 p.y = (p.y - this.y0) / this.a;
1965
1966 p.x /= this.k0;
1967 p.y /= this.k0;
1968
1969 if ((rh = Math.sqrt(p.x * p.x + p.y * p.y))) {
1970 c = Math.atan2(rh, this.rc);
1971 sinc = Math.sin(c);
1972 cosc = Math.cos(c);
1973
1974 lat = asinz(cosc * this.sin_p14 + (p.y * sinc * this.cos_p14) / rh);
1975 lon = Math.atan2(p.x * sinc, rh * this.cos_p14 * cosc - p.y * this.sin_p14 * sinc);
1976 lon = adjust_lon(this.long0 + lon);
1977 }
1978 else {
1979 lat = this.phic0;
1980 lon = 0;
1981 }
1982
1983 p.x = lon;
1984 p.y = lat;
1985 return p;
1986 };
1987 exports.names = ["gnom"];
1988 });
1989
1990 var require$$10 = (gnom && typeof gnom === 'object' && 'default' in gnom ? gnom['default'] : gnom);
1991
1992 var aea = createCommonjsModule(function (module, exports) {
1993 var EPSLN = 1.0e-10;
1994 var msfnz = require$$3$2;
1995 var qsfnz = require$$1$4;
1996 var adjust_lon = require$$2;
1997 var asinz = require$$0$4;
1998 exports.init = function() {
1999
2000 if (Math.abs(this.lat1 + this.lat2) < EPSLN) {
2001 return;
2002 }
2003 this.temp = this.b / this.a;
2004 this.es = 1 - Math.pow(this.temp, 2);
2005 this.e3 = Math.sqrt(this.es);
2006
2007 this.sin_po = Math.sin(this.lat1);
2008 this.cos_po = Math.cos(this.lat1);
2009 this.t1 = this.sin_po;
2010 this.con = this.sin_po;
2011 this.ms1 = msfnz(this.e3, this.sin_po, this.cos_po);
2012 this.qs1 = qsfnz(this.e3, this.sin_po, this.cos_po);
2013
2014 this.sin_po = Math.sin(this.lat2);
2015 this.cos_po = Math.cos(this.lat2);
2016 this.t2 = this.sin_po;
2017 this.ms2 = msfnz(this.e3, this.sin_po, this.cos_po);
2018 this.qs2 = qsfnz(this.e3, this.sin_po, this.cos_po);
2019
2020 this.sin_po = Math.sin(this.lat0);
2021 this.cos_po = Math.cos(this.lat0);
2022 this.t3 = this.sin_po;
2023 this.qs0 = qsfnz(this.e3, this.sin_po, this.cos_po);
2024
2025 if (Math.abs(this.lat1 - this.lat2) > EPSLN) {
2026 this.ns0 = (this.ms1 * this.ms1 - this.ms2 * this.ms2) / (this.qs2 - this.qs1);
2027 }
2028 else {
2029 this.ns0 = this.con;
2030 }
2031 this.c = this.ms1 * this.ms1 + this.ns0 * this.qs1;
2032 this.rh = this.a * Math.sqrt(this.c - this.ns0 * this.qs0) / this.ns0;
2033 };
2034
2035 /* Albers Conical Equal Area forward equations--mapping lat,long to x,y
2036 -------------------------------------------------------------------*/
2037 exports.forward = function(p) {
2038
2039 var lon = p.x;
2040 var lat = p.y;
2041
2042 this.sin_phi = Math.sin(lat);
2043 this.cos_phi = Math.cos(lat);
2044
2045 var qs = qsfnz(this.e3, this.sin_phi, this.cos_phi);
2046 var rh1 = this.a * Math.sqrt(this.c - this.ns0 * qs) / this.ns0;
2047 var theta = this.ns0 * adjust_lon(lon - this.long0);
2048 var x = rh1 * Math.sin(theta) + this.x0;
2049 var y = this.rh - rh1 * Math.cos(theta) + this.y0;
2050
2051 p.x = x;
2052 p.y = y;
2053 return p;
2054 };
2055
2056
2057 exports.inverse = function(p) {
2058 var rh1, qs, con, theta, lon, lat;
2059
2060 p.x -= this.x0;
2061 p.y = this.rh - p.y + this.y0;
2062 if (this.ns0 >= 0) {
2063 rh1 = Math.sqrt(p.x * p.x + p.y * p.y);
2064 con = 1;
2065 }
2066 else {
2067 rh1 = -Math.sqrt(p.x * p.x + p.y * p.y);
2068 con = -1;
2069 }
2070 theta = 0;
2071 if (rh1 !== 0) {
2072 theta = Math.atan2(con * p.x, con * p.y);
2073 }
2074 con = rh1 * this.ns0 / this.a;
2075 if (this.sphere) {
2076 lat = Math.asin((this.c - con * con) / (2 * this.ns0));
2077 }
2078 else {
2079 qs = (this.c - con * con) / this.ns0;
2080 lat = this.phi1z(this.e3, qs);
2081 }
2082
2083 lon = adjust_lon(theta / this.ns0 + this.long0);
2084 p.x = lon;
2085 p.y = lat;
2086 return p;
2087 };
2088
2089 /* Function to compute phi1, the latitude for the inverse of the
2090 Albers Conical Equal-Area projection.
2091 -------------------------------------------*/
2092 exports.phi1z = function(eccent, qs) {
2093 var sinphi, cosphi, con, com, dphi;
2094 var phi = asinz(0.5 * qs);
2095 if (eccent < EPSLN) {
2096 return phi;
2097 }
2098
2099 var eccnts = eccent * eccent;
2100 for (var i = 1; i <= 25; i++) {
2101 sinphi = Math.sin(phi);
2102 cosphi = Math.cos(phi);
2103 con = eccent * sinphi;
2104 com = 1 - con * con;
2105 dphi = 0.5 * com * com / cosphi * (qs / (1 - eccnts) - sinphi / com + 0.5 / eccent * Math.log((1 - con) / (1 + con)));
2106 phi = phi + dphi;
2107 if (Math.abs(dphi) <= 1e-7) {
2108 return phi;
2109 }
2110 }
2111 return null;
2112 };
2113 exports.names = ["Albers_Conic_Equal_Area", "Albers", "aea"];
2114 });
2115
2116 var require$$11 = (aea && typeof aea === 'object' && 'default' in aea ? aea['default'] : aea);
2117
2118 var laea = createCommonjsModule(function (module, exports) {
2119 var HALF_PI = Math.PI/2;
2120 var FORTPI = Math.PI/4;
2121 var EPSLN = 1.0e-10;
2122 var qsfnz = require$$1$4;
2123 var adjust_lon = require$$2;
2124 /*
2125 reference
2126 "New Equal-Area Map Projections for Noncircular Regions", John P. Snyder,
2127 The American Cartographer, Vol 15, No. 4, October 1988, pp. 341-355.
2128 */
2129
2130 exports.S_POLE = 1;
2131 exports.N_POLE = 2;
2132 exports.EQUIT = 3;
2133 exports.OBLIQ = 4;
2134
2135
2136 /* Initialize the Lambert Azimuthal Equal Area projection
2137 ------------------------------------------------------*/
2138 exports.init = function() {
2139 var t = Math.abs(this.lat0);
2140 if (Math.abs(t - HALF_PI) < EPSLN) {
2141 this.mode = this.lat0 < 0 ? this.S_POLE : this.N_POLE;
2142 }
2143 else if (Math.abs(t) < EPSLN) {
2144 this.mode = this.EQUIT;
2145 }
2146 else {
2147 this.mode = this.OBLIQ;
2148 }
2149 if (this.es > 0) {
2150 var sinphi;
2151
2152 this.qp = qsfnz(this.e, 1);
2153 this.mmf = 0.5 / (1 - this.es);
2154 this.apa = this.authset(this.es);
2155 switch (this.mode) {
2156 case this.N_POLE:
2157 this.dd = 1;
2158 break;
2159 case this.S_POLE:
2160 this.dd = 1;
2161 break;
2162 case this.EQUIT:
2163 this.rq = Math.sqrt(0.5 * this.qp);
2164 this.dd = 1 / this.rq;
2165 this.xmf = 1;
2166 this.ymf = 0.5 * this.qp;
2167 break;
2168 case this.OBLIQ:
2169 this.rq = Math.sqrt(0.5 * this.qp);
2170 sinphi = Math.sin(this.lat0);
2171 this.sinb1 = qsfnz(this.e, sinphi) / this.qp;
2172 this.cosb1 = Math.sqrt(1 - this.sinb1 * this.sinb1);
2173 this.dd = Math.cos(this.lat0) / (Math.sqrt(1 - this.es * sinphi * sinphi) * this.rq * this.cosb1);
2174 this.ymf = (this.xmf = this.rq) / this.dd;
2175 this.xmf *= this.dd;
2176 break;
2177 }
2178 }
2179 else {
2180 if (this.mode === this.OBLIQ) {
2181 this.sinph0 = Math.sin(this.lat0);
2182 this.cosph0 = Math.cos(this.lat0);
2183 }
2184 }
2185 };
2186
2187 /* Lambert Azimuthal Equal Area forward equations--mapping lat,long to x,y
2188 -----------------------------------------------------------------------*/
2189 exports.forward = function(p) {
2190
2191 /* Forward equations
2192 -----------------*/
2193 var x, y, coslam, sinlam, sinphi, q, sinb, cosb, b, cosphi;
2194 var lam = p.x;
2195 var phi = p.y;
2196
2197 lam = adjust_lon(lam - this.long0);
2198
2199 if (this.sphere) {
2200 sinphi = Math.sin(phi);
2201 cosphi = Math.cos(phi);
2202 coslam = Math.cos(lam);
2203 if (this.mode === this.OBLIQ || this.mode === this.EQUIT) {
2204 y = (this.mode === this.EQUIT) ? 1 + cosphi * coslam : 1 + this.sinph0 * sinphi + this.cosph0 * cosphi * coslam;
2205 if (y <= EPSLN) {
2206 return null;
2207 }
2208 y = Math.sqrt(2 / y);
2209 x = y * cosphi * Math.sin(lam);
2210 y *= (this.mode === this.EQUIT) ? sinphi : this.cosph0 * sinphi - this.sinph0 * cosphi * coslam;
2211 }
2212 else if (this.mode === this.N_POLE || this.mode === this.S_POLE) {
2213 if (this.mode === this.N_POLE) {
2214 coslam = -coslam;
2215 }
2216 if (Math.abs(phi + this.phi0) < EPSLN) {
2217 return null;
2218 }
2219 y = FORTPI - phi * 0.5;
2220 y = 2 * ((this.mode === this.S_POLE) ? Math.cos(y) : Math.sin(y));
2221 x = y * Math.sin(lam);
2222 y *= coslam;
2223 }
2224 }
2225 else {
2226 sinb = 0;
2227 cosb = 0;
2228 b = 0;
2229 coslam = Math.cos(lam);
2230 sinlam = Math.sin(lam);
2231 sinphi = Math.sin(phi);
2232 q = qsfnz(this.e, sinphi);
2233 if (this.mode === this.OBLIQ || this.mode === this.EQUIT) {
2234 sinb = q / this.qp;
2235 cosb = Math.sqrt(1 - sinb * sinb);
2236 }
2237 switch (this.mode) {
2238 case this.OBLIQ:
2239 b = 1 + this.sinb1 * sinb + this.cosb1 * cosb * coslam;
2240 break;
2241 case this.EQUIT:
2242 b = 1 + cosb * coslam;
2243 break;
2244 case this.N_POLE:
2245 b = HALF_PI + phi;
2246 q = this.qp - q;
2247 break;
2248 case this.S_POLE:
2249 b = phi - HALF_PI;
2250 q = this.qp + q;
2251 break;
2252 }
2253 if (Math.abs(b) < EPSLN) {
2254 return null;
2255 }
2256 switch (this.mode) {
2257 case this.OBLIQ:
2258 case this.EQUIT:
2259 b = Math.sqrt(2 / b);
2260 if (this.mode === this.OBLIQ) {
2261 y = this.ymf * b * (this.cosb1 * sinb - this.sinb1 * cosb * coslam);
2262 }
2263 else {
2264 y = (b = Math.sqrt(2 / (1 + cosb * coslam))) * sinb * this.ymf;
2265 }
2266 x = this.xmf * b * cosb * sinlam;
2267 break;
2268 case this.N_POLE:
2269 case this.S_POLE:
2270 if (q >= 0) {
2271 x = (b = Math.sqrt(q)) * sinlam;
2272 y = coslam * ((this.mode === this.S_POLE) ? b : -b);
2273 }
2274 else {
2275 x = y = 0;
2276 }
2277 break;
2278 }
2279 }
2280
2281 p.x = this.a * x + this.x0;
2282 p.y = this.a * y + this.y0;
2283 return p;
2284 };
2285
2286 /* Inverse equations
2287 -----------------*/
2288 exports.inverse = function(p) {
2289 p.x -= this.x0;
2290 p.y -= this.y0;
2291 var x = p.x / this.a;
2292 var y = p.y / this.a;
2293 var lam, phi, cCe, sCe, q, rho, ab;
2294
2295 if (this.sphere) {
2296 var cosz = 0,
2297 rh, sinz = 0;
2298
2299 rh = Math.sqrt(x * x + y * y);
2300 phi = rh * 0.5;
2301 if (phi > 1) {
2302 return null;
2303 }
2304 phi = 2 * Math.asin(phi);
2305 if (this.mode === this.OBLIQ || this.mode === this.EQUIT) {
2306 sinz = Math.sin(phi);
2307 cosz = Math.cos(phi);
2308 }
2309 switch (this.mode) {
2310 case this.EQUIT:
2311 phi = (Math.abs(rh) <= EPSLN) ? 0 : Math.asin(y * sinz / rh);
2312 x *= sinz;
2313 y = cosz * rh;
2314 break;
2315 case this.OBLIQ:
2316 phi = (Math.abs(rh) <= EPSLN) ? this.phi0 : Math.asin(cosz * this.sinph0 + y * sinz * this.cosph0 / rh);
2317 x *= sinz * this.cosph0;
2318 y = (cosz - Math.sin(phi) * this.sinph0) * rh;
2319 break;
2320 case this.N_POLE:
2321 y = -y;
2322 phi = HALF_PI - phi;
2323 break;
2324 case this.S_POLE:
2325 phi -= HALF_PI;
2326 break;
2327 }
2328 lam = (y === 0 && (this.mode === this.EQUIT || this.mode === this.OBLIQ)) ? 0 : Math.atan2(x, y);
2329 }
2330 else {
2331 ab = 0;
2332 if (this.mode === this.OBLIQ || this.mode === this.EQUIT) {
2333 x /= this.dd;
2334 y *= this.dd;
2335 rho = Math.sqrt(x * x + y * y);
2336 if (rho < EPSLN) {
2337 p.x = 0;
2338 p.y = this.phi0;
2339 return p;
2340 }
2341 sCe = 2 * Math.asin(0.5 * rho / this.rq);
2342 cCe = Math.cos(sCe);
2343 x *= (sCe = Math.sin(sCe));
2344 if (this.mode === this.OBLIQ) {
2345 ab = cCe * this.sinb1 + y * sCe * this.cosb1 / rho;
2346 q = this.qp * ab;
2347 y = rho * this.cosb1 * cCe - y * this.sinb1 * sCe;
2348 }
2349 else {
2350 ab = y * sCe / rho;
2351 q = this.qp * ab;
2352 y = rho * cCe;
2353 }
2354 }
2355 else if (this.mode === this.N_POLE || this.mode === this.S_POLE) {
2356 if (this.mode === this.N_POLE) {
2357 y = -y;
2358 }
2359 q = (x * x + y * y);
2360 if (!q) {
2361 p.x = 0;
2362 p.y = this.phi0;
2363 return p;
2364 }
2365 ab = 1 - q / this.qp;
2366 if (this.mode === this.S_POLE) {
2367 ab = -ab;
2368 }
2369 }
2370 lam = Math.atan2(x, y);
2371 phi = this.authlat(Math.asin(ab), this.apa);
2372 }
2373
2374
2375 p.x = adjust_lon(this.long0 + lam);
2376 p.y = phi;
2377 return p;
2378 };
2379
2380 /* determine latitude from authalic latitude */
2381 exports.P00 = 0.33333333333333333333;
2382 exports.P01 = 0.17222222222222222222;
2383 exports.P02 = 0.10257936507936507936;
2384 exports.P10 = 0.06388888888888888888;
2385 exports.P11 = 0.06640211640211640211;
2386 exports.P20 = 0.01641501294219154443;
2387
2388 exports.authset = function(es) {
2389 var t;
2390 var APA = [];
2391 APA[0] = es * this.P00;
2392 t = es * es;
2393 APA[0] += t * this.P01;
2394 APA[1] = t * this.P10;
2395 t *= es;
2396 APA[0] += t * this.P02;
2397 APA[1] += t * this.P11;
2398 APA[2] = t * this.P20;
2399 return APA;
2400 };
2401
2402 exports.authlat = function(beta, APA) {
2403 var t = beta + beta;
2404 return (beta + APA[0] * Math.sin(t) + APA[1] * Math.sin(t + t) + APA[2] * Math.sin(t + t + t));
2405 };
2406 exports.names = ["Lambert Azimuthal Equal Area", "Lambert_Azimuthal_Equal_Area", "laea"];
2407 });
2408
2409 var require$$12 = (laea && typeof laea === 'object' && 'default' in laea ? laea['default'] : laea);
2410
2411 var cass = createCommonjsModule(function (module, exports) {
2412 var mlfn = require$$3$1;
2413 var e0fn = require$$7;
2414 var e1fn = require$$6;
2415 var e2fn = require$$5;
2416 var e3fn = require$$4;
2417 var gN = require$$3;
2418 var adjust_lon = require$$2;
2419 var adjust_lat = require$$1$2;
2420 var imlfn = require$$0$3;
2421 var HALF_PI = Math.PI/2;
2422 var EPSLN = 1.0e-10;
2423 exports.init = function() {
2424 if (!this.sphere) {
2425 this.e0 = e0fn(this.es);
2426 this.e1 = e1fn(this.es);
2427 this.e2 = e2fn(this.es);
2428 this.e3 = e3fn(this.es);
2429 this.ml0 = this.a * mlfn(this.e0, this.e1, this.e2, this.e3, this.lat0);
2430 }
2431 };
2432
2433
2434
2435 /* Cassini forward equations--mapping lat,long to x,y
2436 -----------------------------------------------------------------------*/
2437 exports.forward = function(p) {
2438
2439 /* Forward equations
2440 -----------------*/
2441 var x, y;
2442 var lam = p.x;
2443 var phi = p.y;
2444 lam = adjust_lon(lam - this.long0);
2445
2446 if (this.sphere) {
2447 x = this.a * Math.asin(Math.cos(phi) * Math.sin(lam));
2448 y = this.a * (Math.atan2(Math.tan(phi), Math.cos(lam)) - this.lat0);
2449 }
2450 else {
2451 //ellipsoid
2452 var sinphi = Math.sin(phi);
2453 var cosphi = Math.cos(phi);
2454 var nl = gN(this.a, this.e, sinphi);
2455 var tl = Math.tan(phi) * Math.tan(phi);
2456 var al = lam * Math.cos(phi);
2457 var asq = al * al;
2458 var cl = this.es * cosphi * cosphi / (1 - this.es);
2459 var ml = this.a * mlfn(this.e0, this.e1, this.e2, this.e3, phi);
2460
2461 x = nl * al * (1 - asq * tl * (1 / 6 - (8 - tl + 8 * cl) * asq / 120));
2462 y = ml - this.ml0 + nl * sinphi / cosphi * asq * (0.5 + (5 - tl + 6 * cl) * asq / 24);
2463
2464
2465 }
2466
2467 p.x = x + this.x0;
2468 p.y = y + this.y0;
2469 return p;
2470 };
2471
2472 /* Inverse equations
2473 -----------------*/
2474 exports.inverse = function(p) {
2475 p.x -= this.x0;
2476 p.y -= this.y0;
2477 var x = p.x / this.a;
2478 var y = p.y / this.a;
2479 var phi, lam;
2480
2481 if (this.sphere) {
2482 var dd = y + this.lat0;
2483 phi = Math.asin(Math.sin(dd) * Math.cos(x));
2484 lam = Math.atan2(Math.tan(x), Math.cos(dd));
2485 }
2486 else {
2487 /* ellipsoid */
2488 var ml1 = this.ml0 / this.a + y;
2489 var phi1 = imlfn(ml1, this.e0, this.e1, this.e2, this.e3);
2490 if (Math.abs(Math.abs(phi1) - HALF_PI) <= EPSLN) {
2491 p.x = this.long0;
2492 p.y = HALF_PI;
2493 if (y < 0) {
2494 p.y *= -1;
2495 }
2496 return p;
2497 }
2498 var nl1 = gN(this.a, this.e, Math.sin(phi1));
2499
2500 var rl1 = nl1 * nl1 * nl1 / this.a / this.a * (1 - this.es);
2501 var tl1 = Math.pow(Math.tan(phi1), 2);
2502 var dl = x * this.a / nl1;
2503 var dsq = dl * dl;
2504 phi = phi1 - nl1 * Math.tan(phi1) / rl1 * dl * dl * (0.5 - (1 + 3 * tl1) * dl * dl / 24);
2505 lam = dl * (1 - dsq * (tl1 / 3 + (1 + 3 * tl1) * tl1 * dsq / 15)) / Math.cos(phi1);
2506
2507 }
2508
2509 p.x = adjust_lon(lam + this.long0);
2510 p.y = adjust_lat(phi);
2511 return p;
2512
2513 };
2514 exports.names = ["Cassini", "Cassini_Soldner", "cass"];
2515 });
2516
2517 var require$$13 = (cass && typeof cass === 'object' && 'default' in cass ? cass['default'] : cass);
2518
2519 var krovak = createCommonjsModule(function (module, exports) {
2520 var adjust_lon = require$$2;
2521 exports.init = function() {
2522 this.a = 6377397.155;
2523 this.es = 0.006674372230614;
2524 this.e = Math.sqrt(this.es);
2525 if (!this.lat0) {
2526 this.lat0 = 0.863937979737193;
2527 }
2528 if (!this.long0) {
2529 this.long0 = 0.7417649320975901 - 0.308341501185665;
2530 }
2531 /* if scale not set default to 0.9999 */
2532 if (!this.k0) {
2533 this.k0 = 0.9999;
2534 }
2535 this.s45 = 0.785398163397448; /* 45 */
2536 this.s90 = 2 * this.s45;
2537 this.fi0 = this.lat0;
2538 this.e2 = this.es;
2539 this.e = Math.sqrt(this.e2);
2540 this.alfa = Math.sqrt(1 + (this.e2 * Math.pow(Math.cos(this.fi0), 4)) / (1 - this.e2));
2541 this.uq = 1.04216856380474;
2542 this.u0 = Math.asin(Math.sin(this.fi0) / this.alfa);
2543 this.g = Math.pow((1 + this.e * Math.sin(this.fi0)) / (1 - this.e * Math.sin(this.fi0)), this.alfa * this.e / 2);
2544 this.k = Math.tan(this.u0 / 2 + this.s45) / Math.pow(Math.tan(this.fi0 / 2 + this.s45), this.alfa) * this.g;
2545 this.k1 = this.k0;
2546 this.n0 = this.a * Math.sqrt(1 - this.e2) / (1 - this.e2 * Math.pow(Math.sin(this.fi0), 2));
2547 this.s0 = 1.37008346281555;
2548 this.n = Math.sin(this.s0);
2549 this.ro0 = this.k1 * this.n0 / Math.tan(this.s0);
2550 this.ad = this.s90 - this.uq;
2551 };
2552
2553 /* ellipsoid */
2554 /* calculate xy from lat/lon */
2555 /* Constants, identical to inverse transform function */
2556 exports.forward = function(p) {
2557 var gfi, u, deltav, s, d, eps, ro;
2558 var lon = p.x;
2559 var lat = p.y;
2560 var delta_lon = adjust_lon(lon - this.long0);
2561 /* Transformation */
2562 gfi = Math.pow(((1 + this.e * Math.sin(lat)) / (1 - this.e * Math.sin(lat))), (this.alfa * this.e / 2));
2563 u = 2 * (Math.atan(this.k * Math.pow(Math.tan(lat / 2 + this.s45), this.alfa) / gfi) - this.s45);
2564 deltav = -delta_lon * this.alfa;
2565 s = Math.asin(Math.cos(this.ad) * Math.sin(u) + Math.sin(this.ad) * Math.cos(u) * Math.cos(deltav));
2566 d = Math.asin(Math.cos(u) * Math.sin(deltav) / Math.cos(s));
2567 eps = this.n * d;
2568 ro = this.ro0 * Math.pow(Math.tan(this.s0 / 2 + this.s45), this.n) / Math.pow(Math.tan(s / 2 + this.s45), this.n);
2569 p.y = ro * Math.cos(eps) / 1;
2570 p.x = ro * Math.sin(eps) / 1;
2571
2572 if (!this.czech) {
2573 p.y *= -1;
2574 p.x *= -1;
2575 }
2576 return (p);
2577 };
2578
2579 /* calculate lat/lon from xy */
2580 exports.inverse = function(p) {
2581 var u, deltav, s, d, eps, ro, fi1;
2582 var ok;
2583
2584 /* Transformation */
2585 /* revert y, x*/
2586 var tmp = p.x;
2587 p.x = p.y;
2588 p.y = tmp;
2589 if (!this.czech) {
2590 p.y *= -1;
2591 p.x *= -1;
2592 }
2593 ro = Math.sqrt(p.x * p.x + p.y * p.y);
2594 eps = Math.atan2(p.y, p.x);
2595 d = eps / Math.sin(this.s0);
2596 s = 2 * (Math.atan(Math.pow(this.ro0 / ro, 1 / this.n) * Math.tan(this.s0 / 2 + this.s45)) - this.s45);
2597 u = Math.asin(Math.cos(this.ad) * Math.sin(s) - Math.sin(this.ad) * Math.cos(s) * Math.cos(d));
2598 deltav = Math.asin(Math.cos(s) * Math.sin(d) / Math.cos(u));
2599 p.x = this.long0 - deltav / this.alfa;
2600 fi1 = u;
2601 ok = 0;
2602 var iter = 0;
2603 do {
2604 p.y = 2 * (Math.atan(Math.pow(this.k, - 1 / this.alfa) * Math.pow(Math.tan(u / 2 + this.s45), 1 / this.alfa) * Math.pow((1 + this.e * Math.sin(fi1)) / (1 - this.e * Math.sin(fi1)), this.e / 2)) - this.s45);
2605 if (Math.abs(fi1 - p.y) < 0.0000000001) {
2606 ok = 1;
2607 }
2608 fi1 = p.y;
2609 iter += 1;
2610 } while (ok === 0 && iter < 15);
2611 if (iter >= 15) {
2612 return null;
2613 }
2614
2615 return (p);
2616 };
2617 exports.names = ["Krovak", "krovak"];
2618 });
2619
2620 var require$$14 = (krovak && typeof krovak === 'object' && 'default' in krovak ? krovak['default'] : krovak);
2621
2622 var phi2z = createCommonjsModule(function (module) {
2623 var HALF_PI = Math.PI/2;
2624 module.exports = function(eccent, ts) {
2625 var eccnth = 0.5 * eccent;
2626 var con, dphi;
2627 var phi = HALF_PI - 2 * Math.atan(ts);
2628 for (var i = 0; i <= 15; i++) {
2629 con = eccent * Math.sin(phi);
2630 dphi = HALF_PI - 2 * Math.atan(ts * (Math.pow(((1 - con) / (1 + con)), eccnth))) - phi;
2631 phi += dphi;
2632 if (Math.abs(dphi) <= 0.0000000001) {
2633 return phi;
2634 }
2635 }
2636 //console.log("phi2z has NoConvergence");
2637 return -9999;
2638 };
2639 });
2640
2641 var require$$0$7 = (phi2z && typeof phi2z === 'object' && 'default' in phi2z ? phi2z['default'] : phi2z);
2642
2643 var tsfnz = createCommonjsModule(function (module) {
2644 var HALF_PI = Math.PI/2;
2645
2646 module.exports = function(eccent, phi, sinphi) {
2647 var con = eccent * sinphi;
2648 var com = 0.5 * eccent;
2649 con = Math.pow(((1 - con) / (1 + con)), com);
2650 return (Math.tan(0.5 * (HALF_PI - phi)) / con);
2651 };
2652 });
2653
2654 var require$$1$5 = (tsfnz && typeof tsfnz === 'object' && 'default' in tsfnz ? tsfnz['default'] : tsfnz);
2655
2656 var lcc = createCommonjsModule(function (module, exports) {
2657 var EPSLN = 1.0e-10;
2658 var msfnz = require$$3$2;
2659 var tsfnz = require$$1$5;
2660 var HALF_PI = Math.PI/2;
2661 var sign = require$$1;
2662 var adjust_lon = require$$2;
2663 var phi2z = require$$0$7;
2664 exports.init = function() {
2665
2666 // array of: r_maj,r_min,lat1,lat2,c_lon,c_lat,false_east,false_north
2667 //double c_lat; /* center latitude */
2668 //double c_lon; /* center longitude */
2669 //double lat1; /* first standard parallel */
2670 //double lat2; /* second standard parallel */
2671 //double r_maj; /* major axis */
2672 //double r_min; /* minor axis */
2673 //double false_east; /* x offset in meters */
2674 //double false_north; /* y offset in meters */
2675
2676 if (!this.lat2) {
2677 this.lat2 = this.lat1;
2678 } //if lat2 is not defined
2679 if (!this.k0) {
2680 this.k0 = 1;
2681 }
2682 this.x0 = this.x0 || 0;
2683 this.y0 = this.y0 || 0;
2684 // Standard Parallels cannot be equal and on opposite sides of the equator
2685 if (Math.abs(this.lat1 + this.lat2) < EPSLN) {
2686 return;
2687 }
2688
2689 var temp = this.b / this.a;
2690 this.e = Math.sqrt(1 - temp * temp);
2691
2692 var sin1 = Math.sin(this.lat1);
2693 var cos1 = Math.cos(this.lat1);
2694 var ms1 = msfnz(this.e, sin1, cos1);
2695 var ts1 = tsfnz(this.e, this.lat1, sin1);
2696
2697 var sin2 = Math.sin(this.lat2);
2698 var cos2 = Math.cos(this.lat2);
2699 var ms2 = msfnz(this.e, sin2, cos2);
2700 var ts2 = tsfnz(this.e, this.lat2, sin2);
2701
2702 var ts0 = tsfnz(this.e, this.lat0, Math.sin(this.lat0));
2703
2704 if (Math.abs(this.lat1 - this.lat2) > EPSLN) {
2705 this.ns = Math.log(ms1 / ms2) / Math.log(ts1 / ts2);
2706 }
2707 else {
2708 this.ns = sin1;
2709 }
2710 if (isNaN(this.ns)) {
2711 this.ns = sin1;
2712 }
2713 this.f0 = ms1 / (this.ns * Math.pow(ts1, this.ns));
2714 this.rh = this.a * this.f0 * Math.pow(ts0, this.ns);
2715 if (!this.title) {
2716 this.title = "Lambert Conformal Conic";
2717 }
2718 };
2719
2720
2721 // Lambert Conformal conic forward equations--mapping lat,long to x,y
2722 // -----------------------------------------------------------------
2723 exports.forward = function(p) {
2724
2725 var lon = p.x;
2726 var lat = p.y;
2727
2728 // singular cases :
2729 if (Math.abs(2 * Math.abs(lat) - Math.PI) <= EPSLN) {
2730 lat = sign(lat) * (HALF_PI - 2 * EPSLN);
2731 }
2732
2733 var con = Math.abs(Math.abs(lat) - HALF_PI);
2734 var ts, rh1;
2735 if (con > EPSLN) {
2736 ts = tsfnz(this.e, lat, Math.sin(lat));
2737 rh1 = this.a * this.f0 * Math.pow(ts, this.ns);
2738 }
2739 else {
2740 con = lat * this.ns;
2741 if (con <= 0) {
2742 return null;
2743 }
2744 rh1 = 0;
2745 }
2746 var theta = this.ns * adjust_lon(lon - this.long0);
2747 p.x = this.k0 * (rh1 * Math.sin(theta)) + this.x0;
2748 p.y = this.k0 * (this.rh - rh1 * Math.cos(theta)) + this.y0;
2749
2750 return p;
2751 };
2752
2753 // Lambert Conformal Conic inverse equations--mapping x,y to lat/long
2754 // -----------------------------------------------------------------
2755 exports.inverse = function(p) {
2756
2757 var rh1, con, ts;
2758 var lat, lon;
2759 var x = (p.x - this.x0) / this.k0;
2760 var y = (this.rh - (p.y - this.y0) / this.k0);
2761 if (this.ns > 0) {
2762 rh1 = Math.sqrt(x * x + y * y);
2763 con = 1;
2764 }
2765 else {
2766 rh1 = -Math.sqrt(x * x + y * y);
2767 con = -1;
2768 }
2769 var theta = 0;
2770 if (rh1 !== 0) {
2771 theta = Math.atan2((con * x), (con * y));
2772 }
2773 if ((rh1 !== 0) || (this.ns > 0)) {
2774 con = 1 / this.ns;
2775 ts = Math.pow((rh1 / (this.a * this.f0)), con);
2776 lat = phi2z(this.e, ts);
2777 if (lat === -9999) {
2778 return null;
2779 }
2780 }
2781 else {
2782 lat = -HALF_PI;
2783 }
2784 lon = adjust_lon(theta / this.ns + this.long0);
2785
2786 p.x = lon;
2787 p.y = lat;
2788 return p;
2789 };
2790
2791 exports.names = ["Lambert Tangential Conformal Conic Projection", "Lambert_Conformal_Conic", "Lambert_Conformal_Conic_2SP", "lcc"];
2792 });
2793
2794 var require$$15 = (lcc && typeof lcc === 'object' && 'default' in lcc ? lcc['default'] : lcc);
2795
2796 var omerc = createCommonjsModule(function (module, exports) {
2797 var tsfnz = require$$1$5;
2798 var adjust_lon = require$$2;
2799 var phi2z = require$$0$7;
2800 var HALF_PI = Math.PI/2;
2801 var FORTPI = Math.PI/4;
2802 var EPSLN = 1.0e-10;
2803
2804 /* Initialize the Oblique Mercator projection
2805 ------------------------------------------*/
2806 exports.init = function() {
2807 this.no_off = this.no_off || false;
2808 this.no_rot = this.no_rot || false;
2809
2810 if (isNaN(this.k0)) {
2811 this.k0 = 1;
2812 }
2813 var sinlat = Math.sin(this.lat0);
2814 var coslat = Math.cos(this.lat0);
2815 var con = this.e * sinlat;
2816
2817 this.bl = Math.sqrt(1 + this.es / (1 - this.es) * Math.pow(coslat, 4));
2818 this.al = this.a * this.bl * this.k0 * Math.sqrt(1 - this.es) / (1 - con * con);
2819 var t0 = tsfnz(this.e, this.lat0, sinlat);
2820 var dl = this.bl / coslat * Math.sqrt((1 - this.es) / (1 - con * con));
2821 if (dl * dl < 1) {
2822 dl = 1;
2823 }
2824 var fl;
2825 var gl;
2826 if (!isNaN(this.longc)) {
2827 //Central point and azimuth method
2828
2829 if (this.lat0 >= 0) {
2830 fl = dl + Math.sqrt(dl * dl - 1);
2831 }
2832 else {
2833 fl = dl - Math.sqrt(dl * dl - 1);
2834 }
2835 this.el = fl * Math.pow(t0, this.bl);
2836 gl = 0.5 * (fl - 1 / fl);
2837 this.gamma0 = Math.asin(Math.sin(this.alpha) / dl);
2838 this.long0 = this.longc - Math.asin(gl * Math.tan(this.gamma0)) / this.bl;
2839
2840 }
2841 else {
2842 //2 points method
2843 var t1 = tsfnz(this.e, this.lat1, Math.sin(this.lat1));
2844 var t2 = tsfnz(this.e, this.lat2, Math.sin(this.lat2));
2845 if (this.lat0 >= 0) {
2846 this.el = (dl + Math.sqrt(dl * dl - 1)) * Math.pow(t0, this.bl);
2847 }
2848 else {
2849 this.el = (dl - Math.sqrt(dl * dl - 1)) * Math.pow(t0, this.bl);
2850 }
2851 var hl = Math.pow(t1, this.bl);
2852 var ll = Math.pow(t2, this.bl);
2853 fl = this.el / hl;
2854 gl = 0.5 * (fl - 1 / fl);
2855 var jl = (this.el * this.el - ll * hl) / (this.el * this.el + ll * hl);
2856 var pl = (ll - hl) / (ll + hl);
2857 var dlon12 = adjust_lon(this.long1 - this.long2);
2858 this.long0 = 0.5 * (this.long1 + this.long2) - Math.atan(jl * Math.tan(0.5 * this.bl * (dlon12)) / pl) / this.bl;
2859 this.long0 = adjust_lon(this.long0);
2860 var dlon10 = adjust_lon(this.long1 - this.long0);
2861 this.gamma0 = Math.atan(Math.sin(this.bl * (dlon10)) / gl);
2862 this.alpha = Math.asin(dl * Math.sin(this.gamma0));
2863 }
2864
2865 if (this.no_off) {
2866 this.uc = 0;
2867 }
2868 else {
2869 if (this.lat0 >= 0) {
2870 this.uc = this.al / this.bl * Math.atan2(Math.sqrt(dl * dl - 1), Math.cos(this.alpha));
2871 }
2872 else {
2873 this.uc = -1 * this.al / this.bl * Math.atan2(Math.sqrt(dl * dl - 1), Math.cos(this.alpha));
2874 }
2875 }
2876
2877 };
2878
2879
2880 /* Oblique Mercator forward equations--mapping lat,long to x,y
2881 ----------------------------------------------------------*/
2882 exports.forward = function(p) {
2883 var lon = p.x;
2884 var lat = p.y;
2885 var dlon = adjust_lon(lon - this.long0);
2886 var us, vs;
2887 var con;
2888 if (Math.abs(Math.abs(lat) - HALF_PI) <= EPSLN) {
2889 if (lat > 0) {
2890 con = -1;
2891 }
2892 else {
2893 con = 1;
2894 }
2895 vs = this.al / this.bl * Math.log(Math.tan(FORTPI + con * this.gamma0 * 0.5));
2896 us = -1 * con * HALF_PI * this.al / this.bl;
2897 }
2898 else {
2899 var t = tsfnz(this.e, lat, Math.sin(lat));
2900 var ql = this.el / Math.pow(t, this.bl);
2901 var sl = 0.5 * (ql - 1 / ql);
2902 var tl = 0.5 * (ql + 1 / ql);
2903 var vl = Math.sin(this.bl * (dlon));
2904 var ul = (sl * Math.sin(this.gamma0) - vl * Math.cos(this.gamma0)) / tl;
2905 if (Math.abs(Math.abs(ul) - 1) <= EPSLN) {
2906 vs = Number.POSITIVE_INFINITY;
2907 }
2908 else {
2909 vs = 0.5 * this.al * Math.log((1 - ul) / (1 + ul)) / this.bl;
2910 }
2911 if (Math.abs(Math.cos(this.bl * (dlon))) <= EPSLN) {
2912 us = this.al * this.bl * (dlon);
2913 }
2914 else {
2915 us = this.al * Math.atan2(sl * Math.cos(this.gamma0) + vl * Math.sin(this.gamma0), Math.cos(this.bl * dlon)) / this.bl;
2916 }
2917 }
2918
2919 if (this.no_rot) {
2920 p.x = this.x0 + us;
2921 p.y = this.y0 + vs;
2922 }
2923 else {
2924
2925 us -= this.uc;
2926 p.x = this.x0 + vs * Math.cos(this.alpha) + us * Math.sin(this.alpha);
2927 p.y = this.y0 + us * Math.cos(this.alpha) - vs * Math.sin(this.alpha);
2928 }
2929 return p;
2930 };
2931
2932 exports.inverse = function(p) {
2933 var us, vs;
2934 if (this.no_rot) {
2935 vs = p.y - this.y0;
2936 us = p.x - this.x0;
2937 }
2938 else {
2939 vs = (p.x - this.x0) * Math.cos(this.alpha) - (p.y - this.y0) * Math.sin(this.alpha);
2940 us = (p.y - this.y0) * Math.cos(this.alpha) + (p.x - this.x0) * Math.sin(this.alpha);
2941 us += this.uc;
2942 }
2943 var qp = Math.exp(-1 * this.bl * vs / this.al);
2944 var sp = 0.5 * (qp - 1 / qp);
2945 var tp = 0.5 * (qp + 1 / qp);
2946 var vp = Math.sin(this.bl * us / this.al);
2947 var up = (vp * Math.cos(this.gamma0) + sp * Math.sin(this.gamma0)) / tp;
2948 var ts = Math.pow(this.el / Math.sqrt((1 + up) / (1 - up)), 1 / this.bl);
2949 if (Math.abs(up - 1) < EPSLN) {
2950 p.x = this.long0;
2951 p.y = HALF_PI;
2952 }
2953 else if (Math.abs(up + 1) < EPSLN) {
2954 p.x = this.long0;
2955 p.y = -1 * HALF_PI;
2956 }
2957 else {
2958 p.y = phi2z(this.e, ts);
2959 p.x = adjust_lon(this.long0 - Math.atan2(sp * Math.cos(this.gamma0) - vp * Math.sin(this.gamma0), Math.cos(this.bl * us / this.al)) / this.bl);
2960 }
2961 return p;
2962 };
2963
2964 exports.names = ["Hotine_Oblique_Mercator", "Hotine Oblique Mercator", "Hotine_Oblique_Mercator_Azimuth_Natural_Origin", "Hotine_Oblique_Mercator_Azimuth_Center", "omerc"];
2965 });
2966
2967 var require$$16 = (omerc && typeof omerc === 'object' && 'default' in omerc ? omerc['default'] : omerc);
2968
2969 var somerc = createCommonjsModule(function (module, exports) {
2970 /*
2971 references:
2972 Formules et constantes pour le Calcul pour la
2973 projection cylindrique conforme à axe oblique et pour la transformation entre
2974 des systèmes de référence.
2975 http://www.swisstopo.admin.ch/internet/swisstopo/fr/home/topics/survey/sys/refsys/switzerland.parsysrelated1.31216.downloadList.77004.DownloadFile.tmp/swissprojectionfr.pdf
2976 */
2977 exports.init = function() {
2978 var phy0 = this.lat0;
2979 this.lambda0 = this.long0;
2980 var sinPhy0 = Math.sin(phy0);
2981 var semiMajorAxis = this.a;
2982 var invF = this.rf;
2983 var flattening = 1 / invF;
2984 var e2 = 2 * flattening - Math.pow(flattening, 2);
2985 var e = this.e = Math.sqrt(e2);
2986 this.R = this.k0 * semiMajorAxis * Math.sqrt(1 - e2) / (1 - e2 * Math.pow(sinPhy0, 2));
2987 this.alpha = Math.sqrt(1 + e2 / (1 - e2) * Math.pow(Math.cos(phy0), 4));
2988 this.b0 = Math.asin(sinPhy0 / this.alpha);
2989 var k1 = Math.log(Math.tan(Math.PI / 4 + this.b0 / 2));
2990 var k2 = Math.log(Math.tan(Math.PI / 4 + phy0 / 2));
2991 var k3 = Math.log((1 + e * sinPhy0) / (1 - e * sinPhy0));
2992 this.K = k1 - this.alpha * k2 + this.alpha * e / 2 * k3;
2993 };
2994
2995
2996 exports.forward = function(p) {
2997 var Sa1 = Math.log(Math.tan(Math.PI / 4 - p.y / 2));
2998 var Sa2 = this.e / 2 * Math.log((1 + this.e * Math.sin(p.y)) / (1 - this.e * Math.sin(p.y)));
2999 var S = -this.alpha * (Sa1 + Sa2) + this.K;
3000
3001 // spheric latitude
3002 var b = 2 * (Math.atan(Math.exp(S)) - Math.PI / 4);
3003
3004 // spheric longitude
3005 var I = this.alpha * (p.x - this.lambda0);
3006
3007 // psoeudo equatorial rotation
3008 var rotI = Math.atan(Math.sin(I) / (Math.sin(this.b0) * Math.tan(b) + Math.cos(this.b0) * Math.cos(I)));
3009
3010 var rotB = Math.asin(Math.cos(this.b0) * Math.sin(b) - Math.sin(this.b0) * Math.cos(b) * Math.cos(I));
3011
3012 p.y = this.R / 2 * Math.log((1 + Math.sin(rotB)) / (1 - Math.sin(rotB))) + this.y0;
3013 p.x = this.R * rotI + this.x0;
3014 return p;
3015 };
3016
3017 exports.inverse = function(p) {
3018 var Y = p.x - this.x0;
3019 var X = p.y - this.y0;
3020
3021 var rotI = Y / this.R;
3022 var rotB = 2 * (Math.atan(Math.exp(X / this.R)) - Math.PI / 4);
3023
3024 var b = Math.asin(Math.cos(this.b0) * Math.sin(rotB) + Math.sin(this.b0) * Math.cos(rotB) * Math.cos(rotI));
3025 var I = Math.atan(Math.sin(rotI) / (Math.cos(this.b0) * Math.cos(rotI) - Math.sin(this.b0) * Math.tan(rotB)));
3026
3027 var lambda = this.lambda0 + I / this.alpha;
3028
3029 var S = 0;
3030 var phy = b;
3031 var prevPhy = -1000;
3032 var iteration = 0;
3033 while (Math.abs(phy - prevPhy) > 0.0000001) {
3034 if (++iteration > 20) {
3035 //...reportError("omercFwdInfinity");
3036 return;
3037 }
3038 //S = Math.log(Math.tan(Math.PI / 4 + phy / 2));
3039 S = 1 / this.alpha * (Math.log(Math.tan(Math.PI / 4 + b / 2)) - this.K) + this.e * Math.log(Math.tan(Math.PI / 4 + Math.asin(this.e * Math.sin(phy)) / 2));
3040 prevPhy = phy;
3041 phy = 2 * Math.atan(Math.exp(S)) - Math.PI / 2;
3042 }
3043
3044 p.x = lambda;
3045 p.y = phy;
3046 return p;
3047 };
3048
3049 exports.names = ["somerc"];
3050 });
3051
3052 var require$$17 = (somerc && typeof somerc === 'object' && 'default' in somerc ? somerc['default'] : somerc);
3053
3054 var stere = createCommonjsModule(function (module, exports) {
3055 var HALF_PI = Math.PI/2;
3056 var EPSLN = 1.0e-10;
3057 var sign = require$$1;
3058 var msfnz = require$$3$2;
3059 var tsfnz = require$$1$5;
3060 var phi2z = require$$0$7;
3061 var adjust_lon = require$$2;
3062 exports.ssfn_ = function(phit, sinphi, eccen) {
3063 sinphi *= eccen;
3064 return (Math.tan(0.5 * (HALF_PI + phit)) * Math.pow((1 - sinphi) / (1 + sinphi), 0.5 * eccen));
3065 };
3066
3067 exports.init = function() {
3068 this.coslat0 = Math.cos(this.lat0);
3069 this.sinlat0 = Math.sin(this.lat0);
3070 if (this.sphere) {
3071 if (this.k0 === 1 && !isNaN(this.lat_ts) && Math.abs(this.coslat0) <= EPSLN) {
3072 this.k0 = 0.5 * (1 + sign(this.lat0) * Math.sin(this.lat_ts));
3073 }
3074 }
3075 else {
3076 if (Math.abs(this.coslat0) <= EPSLN) {
3077 if (this.lat0 > 0) {
3078 //North pole
3079 //trace('stere:north pole');
3080 this.con = 1;
3081 }
3082 else {
3083 //South pole
3084 //trace('stere:south pole');
3085 this.con = -1;
3086 }
3087 }
3088 this.cons = Math.sqrt(Math.pow(1 + this.e, 1 + this.e) * Math.pow(1 - this.e, 1 - this.e));
3089 if (this.k0 === 1 && !isNaN(this.lat_ts) && Math.abs(this.coslat0) <= EPSLN) {
3090 this.k0 = 0.5 * this.cons * msfnz(this.e, Math.sin(this.lat_ts), Math.cos(this.lat_ts)) / tsfnz(this.e, this.con * this.lat_ts, this.con * Math.sin(this.lat_ts));
3091 }
3092 this.ms1 = msfnz(this.e, this.sinlat0, this.coslat0);
3093 this.X0 = 2 * Math.atan(this.ssfn_(this.lat0, this.sinlat0, this.e)) - HALF_PI;
3094 this.cosX0 = Math.cos(this.X0);
3095 this.sinX0 = Math.sin(this.X0);
3096 }
3097 };
3098
3099 // Stereographic forward equations--mapping lat,long to x,y
3100 exports.forward = function(p) {
3101 var lon = p.x;
3102 var lat = p.y;
3103 var sinlat = Math.sin(lat);
3104 var coslat = Math.cos(lat);
3105 var A, X, sinX, cosX, ts, rh;
3106 var dlon = adjust_lon(lon - this.long0);
3107
3108 if (Math.abs(Math.abs(lon - this.long0) - Math.PI) <= EPSLN && Math.abs(lat + this.lat0) <= EPSLN) {
3109 //case of the origine point
3110 //trace('stere:this is the origin point');
3111 p.x = NaN;
3112 p.y = NaN;
3113 return p;
3114 }
3115 if (this.sphere) {
3116 //trace('stere:sphere case');
3117 A = 2 * this.k0 / (1 + this.sinlat0 * sinlat + this.coslat0 * coslat * Math.cos(dlon));
3118 p.x = this.a * A * coslat * Math.sin(dlon) + this.x0;
3119 p.y = this.a * A * (this.coslat0 * sinlat - this.sinlat0 * coslat * Math.cos(dlon)) + this.y0;
3120 return p;
3121 }
3122 else {
3123 X = 2 * Math.atan(this.ssfn_(lat, sinlat, this.e)) - HALF_PI;
3124 cosX = Math.cos(X);
3125 sinX = Math.sin(X);
3126 if (Math.abs(this.coslat0) <= EPSLN) {
3127 ts = tsfnz(this.e, lat * this.con, this.con * sinlat);
3128 rh = 2 * this.a * this.k0 * ts / this.cons;
3129 p.x = this.x0 + rh * Math.sin(lon - this.long0);
3130 p.y = this.y0 - this.con * rh * Math.cos(lon - this.long0);
3131 //trace(p.toString());
3132 return p;
3133 }
3134 else if (Math.abs(this.sinlat0) < EPSLN) {
3135 //Eq
3136 //trace('stere:equateur');
3137 A = 2 * this.a * this.k0 / (1 + cosX * Math.cos(dlon));
3138 p.y = A * sinX;
3139 }
3140 else {
3141 //other case
3142 //trace('stere:normal case');
3143 A = 2 * this.a * this.k0 * this.ms1 / (this.cosX0 * (1 + this.sinX0 * sinX + this.cosX0 * cosX * Math.cos(dlon)));
3144 p.y = A * (this.cosX0 * sinX - this.sinX0 * cosX * Math.cos(dlon)) + this.y0;
3145 }
3146 p.x = A * cosX * Math.sin(dlon) + this.x0;
3147 }
3148 //trace(p.toString());
3149 return p;
3150 };
3151
3152
3153 //* Stereographic inverse equations--mapping x,y to lat/long
3154 exports.inverse = function(p) {
3155 p.x -= this.x0;
3156 p.y -= this.y0;
3157 var lon, lat, ts, ce, Chi;
3158 var rh = Math.sqrt(p.x * p.x + p.y * p.y);
3159 if (this.sphere) {
3160 var c = 2 * Math.atan(rh / (0.5 * this.a * this.k0));
3161 lon = this.long0;
3162 lat = this.lat0;
3163 if (rh <= EPSLN) {
3164 p.x = lon;
3165 p.y = lat;
3166 return p;
3167 }
3168 lat = Math.asin(Math.cos(c) * this.sinlat0 + p.y * Math.sin(c) * this.coslat0 / rh);
3169 if (Math.abs(this.coslat0) < EPSLN) {
3170 if (this.lat0 > 0) {
3171 lon = adjust_lon(this.long0 + Math.atan2(p.x, - 1 * p.y));
3172 }
3173 else {
3174 lon = adjust_lon(this.long0 + Math.atan2(p.x, p.y));
3175 }
3176 }
3177 else {
3178 lon = adjust_lon(this.long0 + Math.atan2(p.x * Math.sin(c), rh * this.coslat0 * Math.cos(c) - p.y * this.sinlat0 * Math.sin(c)));
3179 }
3180 p.x = lon;
3181 p.y = lat;
3182 return p;
3183 }
3184 else {
3185 if (Math.abs(this.coslat0) <= EPSLN) {
3186 if (rh <= EPSLN) {
3187 lat = this.lat0;
3188 lon = this.long0;
3189 p.x = lon;
3190 p.y = lat;
3191 //trace(p.toString());
3192 return p;
3193 }
3194 p.x *= this.con;
3195 p.y *= this.con;
3196 ts = rh * this.cons / (2 * this.a * this.k0);
3197 lat = this.con * phi2z(this.e, ts);
3198 lon = this.con * adjust_lon(this.con * this.long0 + Math.atan2(p.x, - 1 * p.y));
3199 }
3200 else {
3201 ce = 2 * Math.atan(rh * this.cosX0 / (2 * this.a * this.k0 * this.ms1));
3202 lon = this.long0;
3203 if (rh <= EPSLN) {
3204 Chi = this.X0;
3205 }
3206 else {
3207 Chi = Math.asin(Math.cos(ce) * this.sinX0 + p.y * Math.sin(ce) * this.cosX0 / rh);
3208 lon = adjust_lon(this.long0 + Math.atan2(p.x * Math.sin(ce), rh * this.cosX0 * Math.cos(ce) - p.y * this.sinX0 * Math.sin(ce)));
3209 }
3210 lat = -1 * phi2z(this.e, Math.tan(0.5 * (HALF_PI + Chi)));
3211 }
3212 }
3213 p.x = lon;
3214 p.y = lat;
3215
3216 //trace(p.toString());
3217 return p;
3218
3219 };
3220 exports.names = ["stere", "Stereographic_South_Pole", "Polar Stereographic (variant B)"];
3221 });
3222
3223 var require$$18 = (stere && typeof stere === 'object' && 'default' in stere ? stere['default'] : stere);
3224
3225 var srat = createCommonjsModule(function (module) {
3226 module.exports = function(esinp, exp) {
3227 return (Math.pow((1 - esinp) / (1 + esinp), exp));
3228 };
3229 });
3230
3231 var require$$0$8 = (srat && typeof srat === 'object' && 'default' in srat ? srat['default'] : srat);
3232
3233 var gauss = createCommonjsModule(function (module, exports) {
3234 var FORTPI = Math.PI/4;
3235 var srat = require$$0$8;
3236 var HALF_PI = Math.PI/2;
3237 var MAX_ITER = 20;
3238 exports.init = function() {
3239 var sphi = Math.sin(this.lat0);
3240 var cphi = Math.cos(this.lat0);
3241 cphi *= cphi;
3242 this.rc = Math.sqrt(1 - this.es) / (1 - this.es * sphi * sphi);
3243 this.C = Math.sqrt(1 + this.es * cphi * cphi / (1 - this.es));
3244 this.phic0 = Math.asin(sphi / this.C);
3245 this.ratexp = 0.5 * this.C * this.e;
3246 this.K = Math.tan(0.5 * this.phic0 + FORTPI) / (Math.pow(Math.tan(0.5 * this.lat0 + FORTPI), this.C) * srat(this.e * sphi, this.ratexp));
3247 };
3248
3249 exports.forward = function(p) {
3250 var lon = p.x;
3251 var lat = p.y;
3252
3253 p.y = 2 * Math.atan(this.K * Math.pow(Math.tan(0.5 * lat + FORTPI), this.C) * srat(this.e * Math.sin(lat), this.ratexp)) - HALF_PI;
3254 p.x = this.C * lon;
3255 return p;
3256 };
3257
3258 exports.inverse = function(p) {
3259 var DEL_TOL = 1e-14;
3260 var lon = p.x / this.C;
3261 var lat = p.y;
3262 var num = Math.pow(Math.tan(0.5 * lat + FORTPI) / this.K, 1 / this.C);
3263 for (var i = MAX_ITER; i > 0; --i) {
3264 lat = 2 * Math.atan(num * srat(this.e * Math.sin(p.y), - 0.5 * this.e)) - HALF_PI;
3265 if (Math.abs(lat - p.y) < DEL_TOL) {
3266 break;
3267 }
3268 p.y = lat;
3269 }
3270 /* convergence failed */
3271 if (!i) {
3272 return null;
3273 }
3274 p.x = lon;
3275 p.y = lat;
3276 return p;
3277 };
3278 exports.names = ["gauss"];
3279 });
3280
3281 var require$$1$6 = (gauss && typeof gauss === 'object' && 'default' in gauss ? gauss['default'] : gauss);
3282
3283 var sterea = createCommonjsModule(function (module, exports) {
3284 var gauss = require$$1$6;
3285 var adjust_lon = require$$2;
3286 exports.init = function() {
3287 gauss.init.apply(this);
3288 if (!this.rc) {
3289 return;
3290 }
3291 this.sinc0 = Math.sin(this.phic0);
3292 this.cosc0 = Math.cos(this.phic0);
3293 this.R2 = 2 * this.rc;
3294 if (!this.title) {
3295 this.title = "Oblique Stereographic Alternative";
3296 }
3297 };
3298
3299 exports.forward = function(p) {
3300 var sinc, cosc, cosl, k;
3301 p.x = adjust_lon(p.x - this.long0);
3302 gauss.forward.apply(this, [p]);
3303 sinc = Math.sin(p.y);
3304 cosc = Math.cos(p.y);
3305 cosl = Math.cos(p.x);
3306 k = this.k0 * this.R2 / (1 + this.sinc0 * sinc + this.cosc0 * cosc * cosl);
3307 p.x = k * cosc * Math.sin(p.x);
3308 p.y = k * (this.cosc0 * sinc - this.sinc0 * cosc * cosl);
3309 p.x = this.a * p.x + this.x0;
3310 p.y = this.a * p.y + this.y0;
3311 return p;
3312 };
3313
3314 exports.inverse = function(p) {
3315 var sinc, cosc, lon, lat, rho;
3316 p.x = (p.x - this.x0) / this.a;
3317 p.y = (p.y - this.y0) / this.a;
3318
3319 p.x /= this.k0;
3320 p.y /= this.k0;
3321 if ((rho = Math.sqrt(p.x * p.x + p.y * p.y))) {
3322 var c = 2 * Math.atan2(rho, this.R2);
3323 sinc = Math.sin(c);
3324 cosc = Math.cos(c);
3325 lat = Math.asin(cosc * this.sinc0 + p.y * sinc * this.cosc0 / rho);
3326 lon = Math.atan2(p.x * sinc, rho * this.cosc0 * cosc - p.y * this.sinc0 * sinc);
3327 }
3328 else {
3329 lat = this.phic0;
3330 lon = 0;
3331 }
3332
3333 p.x = lon;
3334 p.y = lat;
3335 gauss.inverse.apply(this, [p]);
3336 p.x = adjust_lon(p.x + this.long0);
3337 return p;
3338 };
3339
3340 exports.names = ["Stereographic_North_Pole", "Oblique_Stereographic", "Polar_Stereographic", "sterea","Oblique Stereographic Alternative"];
3341 });
3342
3343 var require$$19 = (sterea && typeof sterea === 'object' && 'default' in sterea ? sterea['default'] : sterea);
3344
3345 var tmerc = createCommonjsModule(function (module, exports) {
3346 var e0fn = require$$7;
3347 var e1fn = require$$6;
3348 var e2fn = require$$5;
3349 var e3fn = require$$4;
3350 var mlfn = require$$3$1;
3351 var adjust_lon = require$$2;
3352 var HALF_PI = Math.PI/2;
3353 var EPSLN = 1.0e-10;
3354 var sign = require$$1;
3355 var asinz = require$$0$4;
3356
3357 exports.init = function() {
3358 this.e0 = e0fn(this.es);
3359 this.e1 = e1fn(this.es);
3360 this.e2 = e2fn(this.es);
3361 this.e3 = e3fn(this.es);
3362 this.ml0 = this.a * mlfn(this.e0, this.e1, this.e2, this.e3, this.lat0);
3363 };
3364
3365 /**
3366 Transverse Mercator Forward - long/lat to x/y
3367 long/lat in radians
3368 */
3369 exports.forward = function(p) {
3370 var lon = p.x;
3371 var lat = p.y;
3372
3373 var delta_lon = adjust_lon(lon - this.long0);
3374 var con;
3375 var x, y;
3376 var sin_phi = Math.sin(lat);
3377 var cos_phi = Math.cos(lat);
3378
3379 if (this.sphere) {
3380 var b = cos_phi * Math.sin(delta_lon);
3381 if ((Math.abs(Math.abs(b) - 1)) < 0.0000000001) {
3382 return (93);
3383 }
3384 else {
3385 x = 0.5 * this.a * this.k0 * Math.log((1 + b) / (1 - b));
3386 con = Math.acos(cos_phi * Math.cos(delta_lon) / Math.sqrt(1 - b * b));
3387 if (lat < 0) {
3388 con = -con;
3389 }
3390 y = this.a * this.k0 * (con - this.lat0);
3391 }
3392 }
3393 else {
3394 var al = cos_phi * delta_lon;
3395 var als = Math.pow(al, 2);
3396 var c = this.ep2 * Math.pow(cos_phi, 2);
3397 var tq = Math.tan(lat);
3398 var t = Math.pow(tq, 2);
3399 con = 1 - this.es * Math.pow(sin_phi, 2);
3400 var n = this.a / Math.sqrt(con);
3401 var ml = this.a * mlfn(this.e0, this.e1, this.e2, this.e3, lat);
3402
3403 x = this.k0 * n * al * (1 + als / 6 * (1 - t + c + als / 20 * (5 - 18 * t + Math.pow(t, 2) + 72 * c - 58 * this.ep2))) + this.x0;
3404 y = this.k0 * (ml - this.ml0 + n * tq * (als * (0.5 + als / 24 * (5 - t + 9 * c + 4 * Math.pow(c, 2) + als / 30 * (61 - 58 * t + Math.pow(t, 2) + 600 * c - 330 * this.ep2))))) + this.y0;
3405
3406 }
3407 p.x = x;
3408 p.y = y;
3409 return p;
3410 };
3411
3412 /**
3413 Transverse Mercator Inverse - x/y to long/lat
3414 */
3415 exports.inverse = function(p) {
3416 var con, phi;
3417 var delta_phi;
3418 var i;
3419 var max_iter = 6;
3420 var lat, lon;
3421
3422 if (this.sphere) {
3423 var f = Math.exp(p.x / (this.a * this.k0));
3424 var g = 0.5 * (f - 1 / f);
3425 var temp = this.lat0 + p.y / (this.a * this.k0);
3426 var h = Math.cos(temp);
3427 con = Math.sqrt((1 - h * h) / (1 + g * g));
3428 lat = asinz(con);
3429 if (temp < 0) {
3430 lat = -lat;
3431 }
3432 if ((g === 0) && (h === 0)) {
3433 lon = this.long0;
3434 }
3435 else {
3436 lon = adjust_lon(Math.atan2(g, h) + this.long0);
3437 }
3438 }
3439 else { // ellipsoidal form
3440 var x = p.x - this.x0;
3441 var y = p.y - this.y0;
3442
3443 con = (this.ml0 + y / this.k0) / this.a;
3444 phi = con;
3445 for (i = 0; true; i++) {
3446 delta_phi = ((con + this.e1 * Math.sin(2 * phi) - this.e2 * Math.sin(4 * phi) + this.e3 * Math.sin(6 * phi)) / this.e0) - phi;
3447 phi += delta_phi;
3448 if (Math.abs(delta_phi) <= EPSLN) {
3449 break;
3450 }
3451 if (i >= max_iter) {
3452 return (95);
3453 }
3454 } // for()
3455 if (Math.abs(phi) < HALF_PI) {
3456 var sin_phi = Math.sin(phi);
3457 var cos_phi = Math.cos(phi);
3458 var tan_phi = Math.tan(phi);
3459 var c = this.ep2 * Math.pow(cos_phi, 2);
3460 var cs = Math.pow(c, 2);
3461 var t = Math.pow(tan_phi, 2);
3462 var ts = Math.pow(t, 2);
3463 con = 1 - this.es * Math.pow(sin_phi, 2);
3464 var n = this.a / Math.sqrt(con);
3465 var r = n * (1 - this.es) / con;
3466 var d = x / (n * this.k0);
3467 var ds = Math.pow(d, 2);
3468 lat = phi - (n * tan_phi * ds / r) * (0.5 - ds / 24 * (5 + 3 * t + 10 * c - 4 * cs - 9 * this.ep2 - ds / 30 * (61 + 90 * t + 298 * c + 45 * ts - 252 * this.ep2 - 3 * cs)));
3469 lon = adjust_lon(this.long0 + (d * (1 - ds / 6 * (1 + 2 * t + c - ds / 20 * (5 - 2 * c + 28 * t - 3 * cs + 8 * this.ep2 + 24 * ts))) / cos_phi));
3470 }
3471 else {
3472 lat = HALF_PI * sign(y);
3473 lon = this.long0;
3474 }
3475 }
3476 p.x = lon;
3477 p.y = lat;
3478 return p;
3479 };
3480 exports.names = ["Transverse_Mercator", "Transverse Mercator", "tmerc"];
3481 });
3482
3483 var require$$0$9 = (tmerc && typeof tmerc === 'object' && 'default' in tmerc ? tmerc['default'] : tmerc);
3484
3485 var utm = createCommonjsModule(function (module, exports) {
3486 var D2R = 0.01745329251994329577;
3487 var tmerc = require$$0$9;
3488 exports.dependsOn = 'tmerc';
3489 exports.init = function() {
3490 if (!this.zone) {
3491 return;
3492 }
3493 this.lat0 = 0;
3494 this.long0 = ((6 * Math.abs(this.zone)) - 183) * D2R;
3495 this.x0 = 500000;
3496 this.y0 = this.utmSouth ? 10000000 : 0;
3497 this.k0 = 0.9996;
3498
3499 tmerc.init.apply(this);
3500 this.forward = tmerc.forward;
3501 this.inverse = tmerc.inverse;
3502 };
3503 exports.names = ["Universal Transverse Mercator System", "utm"];
3504 });
3505
3506 var require$$20 = (utm && typeof utm === 'object' && 'default' in utm ? utm['default'] : utm);
3507
3508 var includedProjections = createCommonjsModule(function (module) {
3509 var projs = [
3510 require$$0$9,
3511 require$$20,
3512 require$$19,
3513 require$$18,
3514 require$$17,
3515 require$$16,
3516 require$$15,
3517 require$$14,
3518 require$$13,
3519 require$$12,
3520 require$$11,
3521 require$$10,
3522 require$$9,
3523 require$$8,
3524 require$$7$1,
3525 require$$6$1,
3526 require$$5$1,
3527 require$$4$1,
3528 require$$3$3,
3529 require$$2$1,
3530 require$$1$1,
3531 require$$0$2
3532 ];
3533 module.exports = function(proj4){
3534 projs.forEach(function(proj){
3535 proj4.Proj.projections.add(proj);
3536 });
3537 };
3538 });
3539
3540 var require$$0$1 = (includedProjections && typeof includedProjections === 'object' && 'default' in includedProjections ? includedProjections['default'] : includedProjections);
3541
3542 var name = "proj4";
3543 var version = "2.3.14";
3544 var description = "Proj4js is a JavaScript library to transform point coordinates from one coordinate system to another, including datum transformations.";
3545 var main = "lib/index.js";
3546 var directories = {"test":"test","doc":"docs"};
3547 var scripts = {"test":"./node_modules/istanbul/lib/cli.js test ./node_modules/mocha/bin/_mocha test/test.js"};
3548 var repository = {"type":"git","url":"git://github.com/proj4js/proj4js.git"};
3549 var author = "";
3550 var license = "MIT";
3551 var jam = {"main":"dist/proj4.js","include":["dist/proj4.js","README.md","AUTHORS","LICENSE.md"]};
3552 var devDependencies = {"grunt-cli":"~0.1.13","grunt":"~0.4.2","grunt-contrib-connect":"~0.6.0","grunt-contrib-jshint":"~0.8.0","chai":"~1.8.1","mocha":"~1.17.1","grunt-mocha-phantomjs":"~0.4.0","browserify":"~12.0.1","grunt-browserify":"~4.0.1","grunt-contrib-uglify":"~0.11.1","curl":"git://github.com/cujojs/curl.git","istanbul":"~0.2.4","tin":"~0.4.0"};
3553 var dependencies = {"mgrs":"~0.0.2"};
3554 var contributors = [{"name":"Mike Adair","email":"madair@dmsolutions.ca"},{"name":"Richard Greenwood","email":"rich@greenwoodmap.com"},{"name":"Calvin Metcalf","email":"calvin.metcalf@gmail.com"},{"name":"Richard Marsden","url":"http://www.winwaed.com"},{"name":"T. Mittan"},{"name":"D. Steinwand"},{"name":"S. Nelson"}];
3555 var gitHead = "7619c8a63df1eae5bad0b9ad31ca1d87b0549243";
3556 var bugs = {"url":"https://github.com/proj4js/proj4js/issues"};
3557 var homepage = "https://github.com/proj4js/proj4js#readme";
3558 var _id = "proj4@2.3.14";
3559 var _shasum = "928906144388980c914c5a357fc493aba59a747a";
3560 var _from = "proj4@>=2.3.14 <3.0.0";
3561 var _npmVersion = "2.14.12";
3562 var _nodeVersion = "4.2.6";
3563 var _npmUser = {"name":"ahocevar","email":"andreas.hocevar@gmail.com"};
3564 var dist = {"shasum":"928906144388980c914c5a357fc493aba59a747a","tarball":"https://registry.npmjs.org/proj4/-/proj4-2.3.14.tgz"};
3565 var maintainers = [{"name":"cwmma","email":"calvin.metcalf@gmail.com"},{"name":"ahocevar","email":"andreas.hocevar@gmail.com"}];
3566 var _npmOperationalInternal = {"host":"packages-13-west.internal.npmjs.com","tmp":"tmp/proj4-2.3.14.tgz_1457689264880_0.9409773757215589"};
3567 var _resolved = "https://registry.npmjs.org/proj4/-/proj4-2.3.14.tgz";
3568 var readme = "ERROR: No README data found!";
3569 var require$$1$7 = {
3570 name: name,
3571 version: version,
3572 description: description,
3573 main: main,
3574 directories: directories,
3575 scripts: scripts,
3576 repository: repository,
3577 author: author,
3578 license: license,
3579 jam: jam,
3580 devDependencies: devDependencies,
3581 dependencies: dependencies,
3582 contributors: contributors,
3583 gitHead: gitHead,
3584 bugs: bugs,
3585 homepage: homepage,
3586 _id: _id,
3587 _shasum: _shasum,
3588 _from: _from,
3589 _npmVersion: _npmVersion,
3590 _nodeVersion: _nodeVersion,
3591 _npmUser: _npmUser,
3592 dist: dist,
3593 maintainers: maintainers,
3594 _npmOperationalInternal: _npmOperationalInternal,
3595 _resolved: _resolved,
3596 readme: readme
3597 };
3598
3599 var mgrs = createCommonjsModule(function (module, exports) {
3600 /**
3601 * UTM zones are grouped, and assigned to one of a group of 6
3602 * sets.
3603 *
3604 * {int} @private
3605 */
3606 var NUM_100K_SETS = 6;
3607
3608 /**
3609 * The column letters (for easting) of the lower left value, per
3610 * set.
3611 *
3612 * {string} @private
3613 */
3614 var SET_ORIGIN_COLUMN_LETTERS = 'AJSAJS';
3615
3616 /**
3617 * The row letters (for northing) of the lower left value, per
3618 * set.
3619 *
3620 * {string} @private
3621 */
3622 var SET_ORIGIN_ROW_LETTERS = 'AFAFAF';
3623
3624 var A = 65; // A
3625 var I = 73; // I
3626 var O = 79; // O
3627 var V = 86; // V
3628 var Z = 90; // Z
3629
3630 /**
3631 * Conversion of lat/lon to MGRS.
3632 *
3633 * @param {object} ll Object literal with lat and lon properties on a
3634 * WGS84 ellipsoid.
3635 * @param {int} accuracy Accuracy in digits (5 for 1 m, 4 for 10 m, 3 for
3636 * 100 m, 2 for 1000 m or 1 for 10000 m). Optional, default is 5.
3637 * @return {string} the MGRS string for the given location and accuracy.
3638 */
3639 exports.forward = function(ll, accuracy) {
3640 accuracy = accuracy || 5; // default accuracy 1m
3641 return encode(LLtoUTM({
3642 lat: ll[1],
3643 lon: ll[0]
3644 }), accuracy);
3645 };
3646
3647 /**
3648 * Conversion of MGRS to lat/lon.
3649 *
3650 * @param {string} mgrs MGRS string.
3651 * @return {array} An array with left (longitude), bottom (latitude), right
3652 * (longitude) and top (latitude) values in WGS84, representing the
3653 * bounding box for the provided MGRS reference.
3654 */
3655 exports.inverse = function(mgrs) {
3656 var bbox = UTMtoLL(decode(mgrs.toUpperCase()));
3657 if (bbox.lat && bbox.lon) {
3658 return [bbox.lon, bbox.lat, bbox.lon, bbox.lat];
3659 }
3660 return [bbox.left, bbox.bottom, bbox.right, bbox.top];
3661 };
3662
3663 exports.toPoint = function(mgrs) {
3664 var bbox = UTMtoLL(decode(mgrs.toUpperCase()));
3665 if (bbox.lat && bbox.lon) {
3666 return [bbox.lon, bbox.lat];
3667 }
3668 return [(bbox.left + bbox.right) / 2, (bbox.top + bbox.bottom) / 2];
3669 };
3670 /**
3671 * Conversion from degrees to radians.
3672 *
3673 * @private
3674 * @param {number} deg the angle in degrees.
3675 * @return {number} the angle in radians.
3676 */
3677 function degToRad(deg) {
3678 return (deg * (Math.PI / 180.0));
3679 }
3680
3681 /**
3682 * Conversion from radians to degrees.
3683 *
3684 * @private
3685 * @param {number} rad the angle in radians.
3686 * @return {number} the angle in degrees.
3687 */
3688 function radToDeg(rad) {
3689 return (180.0 * (rad / Math.PI));
3690 }
3691
3692 /**
3693 * Converts a set of Longitude and Latitude co-ordinates to UTM
3694 * using the WGS84 ellipsoid.
3695 *
3696 * @private
3697 * @param {object} ll Object literal with lat and lon properties
3698 * representing the WGS84 coordinate to be converted.
3699 * @return {object} Object literal containing the UTM value with easting,
3700 * northing, zoneNumber and zoneLetter properties, and an optional
3701 * accuracy property in digits. Returns null if the conversion failed.
3702 */
3703 function LLtoUTM(ll) {
3704 var Lat = ll.lat;
3705 var Long = ll.lon;
3706 var a = 6378137.0; //ellip.radius;
3707 var eccSquared = 0.00669438; //ellip.eccsq;
3708 var k0 = 0.9996;
3709 var LongOrigin;
3710 var eccPrimeSquared;
3711 var N, T, C, A, M;
3712 var LatRad = degToRad(Lat);
3713 var LongRad = degToRad(Long);
3714 var LongOriginRad;
3715 var ZoneNumber;
3716 // (int)
3717 ZoneNumber = Math.floor((Long + 180) / 6) + 1;
3718
3719 //Make sure the longitude 180.00 is in Zone 60
3720 if (Long === 180) {
3721 ZoneNumber = 60;
3722 }
3723
3724 // Special zone for Norway
3725 if (Lat >= 56.0 && Lat < 64.0 && Long >= 3.0 && Long < 12.0) {
3726 ZoneNumber = 32;
3727 }
3728
3729 // Special zones for Svalbard
3730 if (Lat >= 72.0 && Lat < 84.0) {
3731 if (Long >= 0.0 && Long < 9.0) {
3732 ZoneNumber = 31;
3733 }
3734 else if (Long >= 9.0 && Long < 21.0) {
3735 ZoneNumber = 33;
3736 }
3737 else if (Long >= 21.0 && Long < 33.0) {
3738 ZoneNumber = 35;
3739 }
3740 else if (Long >= 33.0 && Long < 42.0) {
3741 ZoneNumber = 37;
3742 }
3743 }
3744
3745 LongOrigin = (ZoneNumber - 1) * 6 - 180 + 3; //+3 puts origin
3746 // in middle of
3747 // zone
3748 LongOriginRad = degToRad(LongOrigin);
3749
3750 eccPrimeSquared = (eccSquared) / (1 - eccSquared);
3751
3752 N = a / Math.sqrt(1 - eccSquared * Math.sin(LatRad) * Math.sin(LatRad));
3753 T = Math.tan(LatRad) * Math.tan(LatRad);
3754 C = eccPrimeSquared * Math.cos(LatRad) * Math.cos(LatRad);
3755 A = Math.cos(LatRad) * (LongRad - LongOriginRad);
3756
3757 M = a * ((1 - eccSquared / 4 - 3 * eccSquared * eccSquared / 64 - 5 * eccSquared * eccSquared * eccSquared / 256) * LatRad - (3 * eccSquared / 8 + 3 * eccSquared * eccSquared / 32 + 45 * eccSquared * eccSquared * eccSquared / 1024) * Math.sin(2 * LatRad) + (15 * eccSquared * eccSquared / 256 + 45 * eccSquared * eccSquared * eccSquared / 1024) * Math.sin(4 * LatRad) - (35 * eccSquared * eccSquared * eccSquared / 3072) * Math.sin(6 * LatRad));
3758
3759 var UTMEasting = (k0 * N * (A + (1 - T + C) * A * A * A / 6.0 + (5 - 18 * T + T * T + 72 * C - 58 * eccPrimeSquared) * A * A * A * A * A / 120.0) + 500000.0);
3760
3761 var UTMNorthing = (k0 * (M + N * Math.tan(LatRad) * (A * A / 2 + (5 - T + 9 * C + 4 * C * C) * A * A * A * A / 24.0 + (61 - 58 * T + T * T + 600 * C - 330 * eccPrimeSquared) * A * A * A * A * A * A / 720.0)));
3762 if (Lat < 0.0) {
3763 UTMNorthing += 10000000.0; //10000000 meter offset for
3764 // southern hemisphere
3765 }
3766
3767 return {
3768 northing: Math.round(UTMNorthing),
3769 easting: Math.round(UTMEasting),
3770 zoneNumber: ZoneNumber,
3771 zoneLetter: getLetterDesignator(Lat)
3772 };
3773 }
3774
3775 /**
3776 * Converts UTM coords to lat/long, using the WGS84 ellipsoid. This is a convenience
3777 * class where the Zone can be specified as a single string eg."60N" which
3778 * is then broken down into the ZoneNumber and ZoneLetter.
3779 *
3780 * @private
3781 * @param {object} utm An object literal with northing, easting, zoneNumber
3782 * and zoneLetter properties. If an optional accuracy property is
3783 * provided (in meters), a bounding box will be returned instead of
3784 * latitude and longitude.
3785 * @return {object} An object literal containing either lat and lon values
3786 * (if no accuracy was provided), or top, right, bottom and left values
3787 * for the bounding box calculated according to the provided accuracy.
3788 * Returns null if the conversion failed.
3789 */
3790 function UTMtoLL(utm) {
3791
3792 var UTMNorthing = utm.northing;
3793 var UTMEasting = utm.easting;
3794 var zoneLetter = utm.zoneLetter;
3795 var zoneNumber = utm.zoneNumber;
3796 // check the ZoneNummber is valid
3797 if (zoneNumber < 0 || zoneNumber > 60) {
3798 return null;
3799 }
3800
3801 var k0 = 0.9996;
3802 var a = 6378137.0; //ellip.radius;
3803 var eccSquared = 0.00669438; //ellip.eccsq;
3804 var eccPrimeSquared;
3805 var e1 = (1 - Math.sqrt(1 - eccSquared)) / (1 + Math.sqrt(1 - eccSquared));
3806 var N1, T1, C1, R1, D, M;
3807 var LongOrigin;
3808 var mu, phi1Rad;
3809
3810 // remove 500,000 meter offset for longitude
3811 var x = UTMEasting - 500000.0;
3812 var y = UTMNorthing;
3813
3814 // We must know somehow if we are in the Northern or Southern
3815 // hemisphere, this is the only time we use the letter So even
3816 // if the Zone letter isn't exactly correct it should indicate
3817 // the hemisphere correctly
3818 if (zoneLetter < 'N') {
3819 y -= 10000000.0; // remove 10,000,000 meter offset used
3820 // for southern hemisphere
3821 }
3822
3823 // There are 60 zones with zone 1 being at West -180 to -174
3824 LongOrigin = (zoneNumber - 1) * 6 - 180 + 3; // +3 puts origin
3825 // in middle of
3826 // zone
3827
3828 eccPrimeSquared = (eccSquared) / (1 - eccSquared);
3829
3830 M = y / k0;
3831 mu = M / (a * (1 - eccSquared / 4 - 3 * eccSquared * eccSquared / 64 - 5 * eccSquared * eccSquared * eccSquared / 256));
3832
3833 phi1Rad = mu + (3 * e1 / 2 - 27 * e1 * e1 * e1 / 32) * Math.sin(2 * mu) + (21 * e1 * e1 / 16 - 55 * e1 * e1 * e1 * e1 / 32) * Math.sin(4 * mu) + (151 * e1 * e1 * e1 / 96) * Math.sin(6 * mu);
3834 // double phi1 = ProjMath.radToDeg(phi1Rad);
3835
3836 N1 = a / Math.sqrt(1 - eccSquared * Math.sin(phi1Rad) * Math.sin(phi1Rad));
3837 T1 = Math.tan(phi1Rad) * Math.tan(phi1Rad);
3838 C1 = eccPrimeSquared * Math.cos(phi1Rad) * Math.cos(phi1Rad);
3839 R1 = a * (1 - eccSquared) / Math.pow(1 - eccSquared * Math.sin(phi1Rad) * Math.sin(phi1Rad), 1.5);
3840 D = x / (N1 * k0);
3841
3842 var lat = phi1Rad - (N1 * Math.tan(phi1Rad) / R1) * (D * D / 2 - (5 + 3 * T1 + 10 * C1 - 4 * C1 * C1 - 9 * eccPrimeSquared) * D * D * D * D / 24 + (61 + 90 * T1 + 298 * C1 + 45 * T1 * T1 - 252 * eccPrimeSquared - 3 * C1 * C1) * D * D * D * D * D * D / 720);
3843 lat = radToDeg(lat);
3844
3845 var lon = (D - (1 + 2 * T1 + C1) * D * D * D / 6 + (5 - 2 * C1 + 28 * T1 - 3 * C1 * C1 + 8 * eccPrimeSquared + 24 * T1 * T1) * D * D * D * D * D / 120) / Math.cos(phi1Rad);
3846 lon = LongOrigin + radToDeg(lon);
3847
3848 var result;
3849 if (utm.accuracy) {
3850 var topRight = UTMtoLL({
3851 northing: utm.northing + utm.accuracy,
3852 easting: utm.easting + utm.accuracy,
3853 zoneLetter: utm.zoneLetter,
3854 zoneNumber: utm.zoneNumber
3855 });
3856 result = {
3857 top: topRight.lat,
3858 right: topRight.lon,
3859 bottom: lat,
3860 left: lon
3861 };
3862 }
3863 else {
3864 result = {
3865 lat: lat,
3866 lon: lon
3867 };
3868 }
3869 return result;
3870 }
3871
3872 /**
3873 * Calculates the MGRS letter designator for the given latitude.
3874 *
3875 * @private
3876 * @param {number} lat The latitude in WGS84 to get the letter designator
3877 * for.
3878 * @return {char} The letter designator.
3879 */
3880 function getLetterDesignator(lat) {
3881 //This is here as an error flag to show that the Latitude is
3882 //outside MGRS limits
3883 var LetterDesignator = 'Z';
3884
3885 if ((84 >= lat) && (lat >= 72)) {
3886 LetterDesignator = 'X';
3887 }
3888 else if ((72 > lat) && (lat >= 64)) {
3889 LetterDesignator = 'W';
3890 }
3891 else if ((64 > lat) && (lat >= 56)) {
3892 LetterDesignator = 'V';
3893 }
3894 else if ((56 > lat) && (lat >= 48)) {
3895 LetterDesignator = 'U';
3896 }
3897 else if ((48 > lat) && (lat >= 40)) {
3898 LetterDesignator = 'T';
3899 }
3900 else if ((40 > lat) && (lat >= 32)) {
3901 LetterDesignator = 'S';
3902 }
3903 else if ((32 > lat) && (lat >= 24)) {
3904 LetterDesignator = 'R';
3905 }
3906 else if ((24 > lat) && (lat >= 16)) {
3907 LetterDesignator = 'Q';
3908 }
3909 else if ((16 > lat) && (lat >= 8)) {
3910 LetterDesignator = 'P';
3911 }
3912 else if ((8 > lat) && (lat >= 0)) {
3913 LetterDesignator = 'N';
3914 }
3915 else if ((0 > lat) && (lat >= -8)) {
3916 LetterDesignator = 'M';
3917 }
3918 else if ((-8 > lat) && (lat >= -16)) {
3919 LetterDesignator = 'L';
3920 }
3921 else if ((-16 > lat) && (lat >= -24)) {
3922 LetterDesignator = 'K';
3923 }
3924 else if ((-24 > lat) && (lat >= -32)) {
3925 LetterDesignator = 'J';
3926 }
3927 else if ((-32 > lat) && (lat >= -40)) {
3928 LetterDesignator = 'H';
3929 }
3930 else if ((-40 > lat) && (lat >= -48)) {
3931 LetterDesignator = 'G';
3932 }
3933 else if ((-48 > lat) && (lat >= -56)) {
3934 LetterDesignator = 'F';
3935 }
3936 else if ((-56 > lat) && (lat >= -64)) {
3937 LetterDesignator = 'E';
3938 }
3939 else if ((-64 > lat) && (lat >= -72)) {
3940 LetterDesignator = 'D';
3941 }
3942 else if ((-72 > lat) && (lat >= -80)) {
3943 LetterDesignator = 'C';
3944 }
3945 return LetterDesignator;
3946 }
3947
3948 /**
3949 * Encodes a UTM location as MGRS string.
3950 *
3951 * @private
3952 * @param {object} utm An object literal with easting, northing,
3953 * zoneLetter, zoneNumber
3954 * @param {number} accuracy Accuracy in digits (1-5).
3955 * @return {string} MGRS string for the given UTM location.
3956 */
3957 function encode(utm, accuracy) {
3958 // prepend with leading zeroes
3959 var seasting = "00000" + utm.easting,
3960 snorthing = "00000" + utm.northing;
3961
3962 return utm.zoneNumber + utm.zoneLetter + get100kID(utm.easting, utm.northing, utm.zoneNumber) + seasting.substr(seasting.length - 5, accuracy) + snorthing.substr(snorthing.length - 5, accuracy);
3963 }
3964
3965 /**
3966 * Get the two letter 100k designator for a given UTM easting,
3967 * northing and zone number value.
3968 *
3969 * @private
3970 * @param {number} easting
3971 * @param {number} northing
3972 * @param {number} zoneNumber
3973 * @return the two letter 100k designator for the given UTM location.
3974 */
3975 function get100kID(easting, northing, zoneNumber) {
3976 var setParm = get100kSetForZone(zoneNumber);
3977 var setColumn = Math.floor(easting / 100000);
3978 var setRow = Math.floor(northing / 100000) % 20;
3979 return getLetter100kID(setColumn, setRow, setParm);
3980 }
3981
3982 /**
3983 * Given a UTM zone number, figure out the MGRS 100K set it is in.
3984 *
3985 * @private
3986 * @param {number} i An UTM zone number.
3987 * @return {number} the 100k set the UTM zone is in.
3988 */
3989 function get100kSetForZone(i) {
3990 var setParm = i % NUM_100K_SETS;
3991 if (setParm === 0) {
3992 setParm = NUM_100K_SETS;
3993 }
3994
3995 return setParm;
3996 }
3997
3998 /**
3999 * Get the two-letter MGRS 100k designator given information
4000 * translated from the UTM northing, easting and zone number.
4001 *
4002 * @private
4003 * @param {number} column the column index as it relates to the MGRS
4004 * 100k set spreadsheet, created from the UTM easting.
4005 * Values are 1-8.
4006 * @param {number} row the row index as it relates to the MGRS 100k set
4007 * spreadsheet, created from the UTM northing value. Values
4008 * are from 0-19.
4009 * @param {number} parm the set block, as it relates to the MGRS 100k set
4010 * spreadsheet, created from the UTM zone. Values are from
4011 * 1-60.
4012 * @return two letter MGRS 100k code.
4013 */
4014 function getLetter100kID(column, row, parm) {
4015 // colOrigin and rowOrigin are the letters at the origin of the set
4016 var index = parm - 1;
4017 var colOrigin = SET_ORIGIN_COLUMN_LETTERS.charCodeAt(index);
4018 var rowOrigin = SET_ORIGIN_ROW_LETTERS.charCodeAt(index);
4019
4020 // colInt and rowInt are the letters to build to return
4021 var colInt = colOrigin + column - 1;
4022 var rowInt = rowOrigin + row;
4023 var rollover = false;
4024
4025 if (colInt > Z) {
4026 colInt = colInt - Z + A - 1;
4027 rollover = true;
4028 }
4029
4030 if (colInt === I || (colOrigin < I && colInt > I) || ((colInt > I || colOrigin < I) && rollover)) {
4031 colInt++;
4032 }
4033
4034 if (colInt === O || (colOrigin < O && colInt > O) || ((colInt > O || colOrigin < O) && rollover)) {
4035 colInt++;
4036
4037 if (colInt === I) {
4038 colInt++;
4039 }
4040 }
4041
4042 if (colInt > Z) {
4043 colInt = colInt - Z + A - 1;
4044 }
4045
4046 if (rowInt > V) {
4047 rowInt = rowInt - V + A - 1;
4048 rollover = true;
4049 }
4050 else {
4051 rollover = false;
4052 }
4053
4054 if (((rowInt === I) || ((rowOrigin < I) && (rowInt > I))) || (((rowInt > I) || (rowOrigin < I)) && rollover)) {
4055 rowInt++;
4056 }
4057
4058 if (((rowInt === O) || ((rowOrigin < O) && (rowInt > O))) || (((rowInt > O) || (rowOrigin < O)) && rollover)) {
4059 rowInt++;
4060
4061 if (rowInt === I) {
4062 rowInt++;
4063 }
4064 }
4065
4066 if (rowInt > V) {
4067 rowInt = rowInt - V + A - 1;
4068 }
4069
4070 var twoLetter = String.fromCharCode(colInt) + String.fromCharCode(rowInt);
4071 return twoLetter;
4072 }
4073
4074 /**
4075 * Decode the UTM parameters from a MGRS string.
4076 *
4077 * @private
4078 * @param {string} mgrsString an UPPERCASE coordinate string is expected.
4079 * @return {object} An object literal with easting, northing, zoneLetter,
4080 * zoneNumber and accuracy (in meters) properties.
4081 */
4082 function decode(mgrsString) {
4083
4084 if (mgrsString && mgrsString.length === 0) {
4085 throw ("MGRSPoint coverting from nothing");
4086 }
4087
4088 var length = mgrsString.length;
4089
4090 var hunK = null;
4091 var sb = "";
4092 var testChar;
4093 var i = 0;
4094
4095 // get Zone number
4096 while (!(/[A-Z]/).test(testChar = mgrsString.charAt(i))) {
4097 if (i >= 2) {
4098 throw ("MGRSPoint bad conversion from: " + mgrsString);
4099 }
4100 sb += testChar;
4101 i++;
4102 }
4103
4104 var zoneNumber = parseInt(sb, 10);
4105
4106 if (i === 0 || i + 3 > length) {
4107 // A good MGRS string has to be 4-5 digits long,
4108 // ##AAA/#AAA at least.
4109 throw ("MGRSPoint bad conversion from: " + mgrsString);
4110 }
4111
4112 var zoneLetter = mgrsString.charAt(i++);
4113
4114 // Should we check the zone letter here? Why not.
4115 if (zoneLetter <= 'A' || zoneLetter === 'B' || zoneLetter === 'Y' || zoneLetter >= 'Z' || zoneLetter === 'I' || zoneLetter === 'O') {
4116 throw ("MGRSPoint zone letter " + zoneLetter + " not handled: " + mgrsString);
4117 }
4118
4119 hunK = mgrsString.substring(i, i += 2);
4120
4121 var set = get100kSetForZone(zoneNumber);
4122
4123 var east100k = getEastingFromChar(hunK.charAt(0), set);
4124 var north100k = getNorthingFromChar(hunK.charAt(1), set);
4125
4126 // We have a bug where the northing may be 2000000 too low.
4127 // How
4128 // do we know when to roll over?
4129
4130 while (north100k < getMinNorthing(zoneLetter)) {
4131 north100k += 2000000;
4132 }
4133
4134 // calculate the char index for easting/northing separator
4135 var remainder = length - i;
4136
4137 if (remainder % 2 !== 0) {
4138 throw ("MGRSPoint has to have an even number \nof digits after the zone letter and two 100km letters - front \nhalf for easting meters, second half for \nnorthing meters" + mgrsString);
4139 }
4140
4141 var sep = remainder / 2;
4142
4143 var sepEasting = 0.0;
4144 var sepNorthing = 0.0;
4145 var accuracyBonus, sepEastingString, sepNorthingString, easting, northing;
4146 if (sep > 0) {
4147 accuracyBonus = 100000.0 / Math.pow(10, sep);
4148 sepEastingString = mgrsString.substring(i, i + sep);
4149 sepEasting = parseFloat(sepEastingString) * accuracyBonus;
4150 sepNorthingString = mgrsString.substring(i + sep);
4151 sepNorthing = parseFloat(sepNorthingString) * accuracyBonus;
4152 }
4153
4154 easting = sepEasting + east100k;
4155 northing = sepNorthing + north100k;
4156
4157 return {
4158 easting: easting,
4159 northing: northing,
4160 zoneLetter: zoneLetter,
4161 zoneNumber: zoneNumber,
4162 accuracy: accuracyBonus
4163 };
4164 }
4165
4166 /**
4167 * Given the first letter from a two-letter MGRS 100k zone, and given the
4168 * MGRS table set for the zone number, figure out the easting value that
4169 * should be added to the other, secondary easting value.
4170 *
4171 * @private
4172 * @param {char} e The first letter from a two-letter MGRS 100´k zone.
4173 * @param {number} set The MGRS table set for the zone number.
4174 * @return {number} The easting value for the given letter and set.
4175 */
4176 function getEastingFromChar(e, set) {
4177 // colOrigin is the letter at the origin of the set for the
4178 // column
4179 var curCol = SET_ORIGIN_COLUMN_LETTERS.charCodeAt(set - 1);
4180 var eastingValue = 100000.0;
4181 var rewindMarker = false;
4182
4183 while (curCol !== e.charCodeAt(0)) {
4184 curCol++;
4185 if (curCol === I) {
4186 curCol++;
4187 }
4188 if (curCol === O) {
4189 curCol++;
4190 }
4191 if (curCol > Z) {
4192 if (rewindMarker) {
4193 throw ("Bad character: " + e);
4194 }
4195 curCol = A;
4196 rewindMarker = true;
4197 }
4198 eastingValue += 100000.0;
4199 }
4200
4201 return eastingValue;
4202 }
4203
4204 /**
4205 * Given the second letter from a two-letter MGRS 100k zone, and given the
4206 * MGRS table set for the zone number, figure out the northing value that
4207 * should be added to the other, secondary northing value. You have to
4208 * remember that Northings are determined from the equator, and the vertical
4209 * cycle of letters mean a 2000000 additional northing meters. This happens
4210 * approx. every 18 degrees of latitude. This method does *NOT* count any
4211 * additional northings. You have to figure out how many 2000000 meters need
4212 * to be added for the zone letter of the MGRS coordinate.
4213 *
4214 * @private
4215 * @param {char} n Second letter of the MGRS 100k zone
4216 * @param {number} set The MGRS table set number, which is dependent on the
4217 * UTM zone number.
4218 * @return {number} The northing value for the given letter and set.
4219 */
4220 function getNorthingFromChar(n, set) {
4221
4222 if (n > 'V') {
4223 throw ("MGRSPoint given invalid Northing " + n);
4224 }
4225
4226 // rowOrigin is the letter at the origin of the set for the
4227 // column
4228 var curRow = SET_ORIGIN_ROW_LETTERS.charCodeAt(set - 1);
4229 var northingValue = 0.0;
4230 var rewindMarker = false;
4231
4232 while (curRow !== n.charCodeAt(0)) {
4233 curRow++;
4234 if (curRow === I) {
4235 curRow++;
4236 }
4237 if (curRow === O) {
4238 curRow++;
4239 }
4240 // fixing a bug making whole application hang in this loop
4241 // when 'n' is a wrong character
4242 if (curRow > V) {
4243 if (rewindMarker) { // making sure that this loop ends
4244 throw ("Bad character: " + n);
4245 }
4246 curRow = A;
4247 rewindMarker = true;
4248 }
4249 northingValue += 100000.0;
4250 }
4251
4252 return northingValue;
4253 }
4254
4255 /**
4256 * The function getMinNorthing returns the minimum northing value of a MGRS
4257 * zone.
4258 *
4259 * Ported from Geotrans' c Lattitude_Band_Value structure table.
4260 *
4261 * @private
4262 * @param {char} zoneLetter The MGRS zone to get the min northing for.
4263 * @return {number}
4264 */
4265 function getMinNorthing(zoneLetter) {
4266 var northing;
4267 switch (zoneLetter) {
4268 case 'C':
4269 northing = 1100000.0;
4270 break;
4271 case 'D':
4272 northing = 2000000.0;
4273 break;
4274 case 'E':
4275 northing = 2800000.0;
4276 break;
4277 case 'F':
4278 northing = 3700000.0;
4279 break;
4280 case 'G':
4281 northing = 4600000.0;
4282 break;
4283 case 'H':
4284 northing = 5500000.0;
4285 break;
4286 case 'J':
4287 northing = 6400000.0;
4288 break;
4289 case 'K':
4290 northing = 7300000.0;
4291 break;
4292 case 'L':
4293 northing = 8200000.0;
4294 break;
4295 case 'M':
4296 northing = 9100000.0;
4297 break;
4298 case 'N':
4299 northing = 0.0;
4300 break;
4301 case 'P':
4302 northing = 800000.0;
4303 break;
4304 case 'Q':
4305 northing = 1700000.0;
4306 break;
4307 case 'R':
4308 northing = 2600000.0;
4309 break;
4310 case 'S':
4311 northing = 3500000.0;
4312 break;
4313 case 'T':
4314 northing = 4400000.0;
4315 break;
4316 case 'U':
4317 northing = 5300000.0;
4318 break;
4319 case 'V':
4320 northing = 6200000.0;
4321 break;
4322 case 'W':
4323 northing = 7000000.0;
4324 break;
4325 case 'X':
4326 northing = 7900000.0;
4327 break;
4328 default:
4329 northing = -1.0;
4330 }
4331 if (northing >= 0.0) {
4332 return northing;
4333 }
4334 else {
4335 throw ("Invalid zone letter: " + zoneLetter);
4336 }
4337
4338 }
4339 });
4340
4341 var require$$0$10 = (mgrs && typeof mgrs === 'object' && 'default' in mgrs ? mgrs['default'] : mgrs);
4342
4343 var toPoint$1 = createCommonjsModule(function (module) {
4344 module.exports = function (array){
4345 var out = {
4346 x: array[0],
4347 y: array[1]
4348 };
4349 if (array.length>2) {
4350 out.z = array[2];
4351 }
4352 if (array.length>3) {
4353 out.m = array[3];
4354 }
4355 return out;
4356 };
4357 });
4358
4359 var require$$0$12 = (toPoint$1 && typeof toPoint$1 === 'object' && 'default' in toPoint$1 ? toPoint$1['default'] : toPoint$1);
4360
4361 var datum = createCommonjsModule(function (module) {
4362 var HALF_PI = Math.PI/2;
4363 var PJD_3PARAM = 1;
4364 var PJD_7PARAM = 2;
4365 var PJD_GRIDSHIFT = 3;
4366 var PJD_WGS84 = 4; // WGS84 or equivalent
4367 var PJD_NODATUM = 5; // WGS84 or equivalent
4368 var SEC_TO_RAD = 4.84813681109535993589914102357e-6;
4369 var AD_C = 1.0026000;
4370 var COS_67P5 = 0.38268343236508977;
4371 var datum = function(proj) {
4372 if (!(this instanceof datum)) {
4373 return new datum(proj);
4374 }
4375 this.datum_type = PJD_WGS84; //default setting
4376 if (!proj) {
4377 return;
4378 }
4379 if (proj.datumCode && proj.datumCode === 'none') {
4380 this.datum_type = PJD_NODATUM;
4381 }
4382
4383 if (proj.datum_params) {
4384 this.datum_params = proj.datum_params.map(parseFloat);
4385 if (this.datum_params[0] !== 0 || this.datum_params[1] !== 0 || this.datum_params[2] !== 0) {
4386 this.datum_type = PJD_3PARAM;
4387 }
4388 if (this.datum_params.length > 3) {
4389 if (this.datum_params[3] !== 0 || this.datum_params[4] !== 0 || this.datum_params[5] !== 0 || this.datum_params[6] !== 0) {
4390 this.datum_type = PJD_7PARAM;
4391 this.datum_params[3] *= SEC_TO_RAD;
4392 this.datum_params[4] *= SEC_TO_RAD;
4393 this.datum_params[5] *= SEC_TO_RAD;
4394 this.datum_params[6] = (this.datum_params[6] / 1000000.0) + 1.0;
4395 }
4396 }
4397 }
4398
4399 // DGR 2011-03-21 : nadgrids support
4400 this.datum_type = proj.grids ? PJD_GRIDSHIFT : this.datum_type;
4401
4402 this.a = proj.a; //datum object also uses these values
4403 this.b = proj.b;
4404 this.es = proj.es;
4405 this.ep2 = proj.ep2;
4406 if (this.datum_type === PJD_GRIDSHIFT) {
4407 this.grids = proj.grids;
4408 }
4409 };
4410 datum.prototype = {
4411
4412
4413 /****************************************************************/
4414 // cs_compare_datums()
4415 // Returns TRUE if the two datums match, otherwise FALSE.
4416 compare_datums: function(dest) {
4417 if (this.datum_type !== dest.datum_type) {
4418 return false; // false, datums are not equal
4419 }
4420 else if (this.a !== dest.a || Math.abs(this.es - dest.es) > 0.000000000050) {
4421 // the tolerence for es is to ensure that GRS80 and WGS84
4422 // are considered identical
4423 return false;
4424 }
4425 else if (this.datum_type === PJD_3PARAM) {
4426 return (this.datum_params[0] === dest.datum_params[0] && this.datum_params[1] === dest.datum_params[1] && this.datum_params[2] === dest.datum_params[2]);
4427 }
4428 else if (this.datum_type === PJD_7PARAM) {
4429 return (this.datum_params[0] === dest.datum_params[0] && this.datum_params[1] === dest.datum_params[1] && this.datum_params[2] === dest.datum_params[2] && this.datum_params[3] === dest.datum_params[3] && this.datum_params[4] === dest.datum_params[4] && this.datum_params[5] === dest.datum_params[5] && this.datum_params[6] === dest.datum_params[6]);
4430 }
4431 else if (this.datum_type === PJD_GRIDSHIFT || dest.datum_type === PJD_GRIDSHIFT) {
4432 //alert("ERROR: Grid shift transformations are not implemented.");
4433 //return false
4434 //DGR 2012-07-29 lazy ...
4435 return this.nadgrids === dest.nadgrids;
4436 }
4437 else {
4438 return true; // datums are equal
4439 }
4440 }, // cs_compare_datums()
4441
4442 /*
4443 * The function Convert_Geodetic_To_Geocentric converts geodetic coordinates
4444 * (latitude, longitude, and height) to geocentric coordinates (X, Y, Z),
4445 * according to the current ellipsoid parameters.
4446 *
4447 * Latitude : Geodetic latitude in radians (input)
4448 * Longitude : Geodetic longitude in radians (input)
4449 * Height : Geodetic height, in meters (input)
4450 * X : Calculated Geocentric X coordinate, in meters (output)
4451 * Y : Calculated Geocentric Y coordinate, in meters (output)
4452 * Z : Calculated Geocentric Z coordinate, in meters (output)
4453 *
4454 */
4455 geodetic_to_geocentric: function(p) {
4456 var Longitude = p.x;
4457 var Latitude = p.y;
4458 var Height = p.z ? p.z : 0; //Z value not always supplied
4459 var X; // output
4460 var Y;
4461 var Z;
4462
4463 var Error_Code = 0; // GEOCENT_NO_ERROR;
4464 var Rn; /* Earth radius at location */
4465 var Sin_Lat; /* Math.sin(Latitude) */
4466 var Sin2_Lat; /* Square of Math.sin(Latitude) */
4467 var Cos_Lat; /* Math.cos(Latitude) */
4468
4469 /*
4470 ** Don't blow up if Latitude is just a little out of the value
4471 ** range as it may just be a rounding issue. Also removed longitude
4472 ** test, it should be wrapped by Math.cos() and Math.sin(). NFW for PROJ.4, Sep/2001.
4473 */
4474 if (Latitude < -HALF_PI && Latitude > -1.001 * HALF_PI) {
4475 Latitude = -HALF_PI;
4476 }
4477 else if (Latitude > HALF_PI && Latitude < 1.001 * HALF_PI) {
4478 Latitude = HALF_PI;
4479 }
4480 else if ((Latitude < -HALF_PI) || (Latitude > HALF_PI)) {
4481 /* Latitude out of range */
4482 //..reportError('geocent:lat out of range:' + Latitude);
4483 return null;
4484 }
4485
4486 if (Longitude > Math.PI) {
4487 Longitude -= (2 * Math.PI);
4488 }
4489 Sin_Lat = Math.sin(Latitude);
4490 Cos_Lat = Math.cos(Latitude);
4491 Sin2_Lat = Sin_Lat * Sin_Lat;
4492 Rn = this.a / (Math.sqrt(1.0e0 - this.es * Sin2_Lat));
4493 X = (Rn + Height) * Cos_Lat * Math.cos(Longitude);
4494 Y = (Rn + Height) * Cos_Lat * Math.sin(Longitude);
4495 Z = ((Rn * (1 - this.es)) + Height) * Sin_Lat;
4496
4497 p.x = X;
4498 p.y = Y;
4499 p.z = Z;
4500 return Error_Code;
4501 }, // cs_geodetic_to_geocentric()
4502
4503
4504 geocentric_to_geodetic: function(p) {
4505 /* local defintions and variables */
4506 /* end-criterium of loop, accuracy of sin(Latitude) */
4507 var genau = 1e-12;
4508 var genau2 = (genau * genau);
4509 var maxiter = 30;
4510
4511 var P; /* distance between semi-minor axis and location */
4512 var RR; /* distance between center and location */
4513 var CT; /* sin of geocentric latitude */
4514 var ST; /* cos of geocentric latitude */
4515 var RX;
4516 var RK;
4517 var RN; /* Earth radius at location */
4518 var CPHI0; /* cos of start or old geodetic latitude in iterations */
4519 var SPHI0; /* sin of start or old geodetic latitude in iterations */
4520 var CPHI; /* cos of searched geodetic latitude */
4521 var SPHI; /* sin of searched geodetic latitude */
4522 var SDPHI; /* end-criterium: addition-theorem of sin(Latitude(iter)-Latitude(iter-1)) */
4523 var At_Pole; /* indicates location is in polar region */
4524 var iter; /* # of continous iteration, max. 30 is always enough (s.a.) */
4525
4526 var X = p.x;
4527 var Y = p.y;
4528 var Z = p.z ? p.z : 0.0; //Z value not always supplied
4529 var Longitude;
4530 var Latitude;
4531 var Height;
4532
4533 At_Pole = false;
4534 P = Math.sqrt(X * X + Y * Y);
4535 RR = Math.sqrt(X * X + Y * Y + Z * Z);
4536
4537 /* special cases for latitude and longitude */
4538 if (P / this.a < genau) {
4539
4540 /* special case, if P=0. (X=0., Y=0.) */
4541 At_Pole = true;
4542 Longitude = 0.0;
4543
4544 /* if (X,Y,Z)=(0.,0.,0.) then Height becomes semi-minor axis
4545 * of ellipsoid (=center of mass), Latitude becomes PI/2 */
4546 if (RR / this.a < genau) {
4547 Latitude = HALF_PI;
4548 Height = -this.b;
4549 return;
4550 }
4551 }
4552 else {
4553 /* ellipsoidal (geodetic) longitude
4554 * interval: -PI < Longitude <= +PI */
4555 Longitude = Math.atan2(Y, X);
4556 }
4557
4558 /* --------------------------------------------------------------
4559 * Following iterative algorithm was developped by
4560 * "Institut for Erdmessung", University of Hannover, July 1988.
4561 * Internet: www.ife.uni-hannover.de
4562 * Iterative computation of CPHI,SPHI and Height.
4563 * Iteration of CPHI and SPHI to 10**-12 radian resp.
4564 * 2*10**-7 arcsec.
4565 * --------------------------------------------------------------
4566 */
4567 CT = Z / RR;
4568 ST = P / RR;
4569 RX = 1.0 / Math.sqrt(1.0 - this.es * (2.0 - this.es) * ST * ST);
4570 CPHI0 = ST * (1.0 - this.es) * RX;
4571 SPHI0 = CT * RX;
4572 iter = 0;
4573
4574 /* loop to find sin(Latitude) resp. Latitude
4575 * until |sin(Latitude(iter)-Latitude(iter-1))| < genau */
4576 do {
4577 iter++;
4578 RN = this.a / Math.sqrt(1.0 - this.es * SPHI0 * SPHI0);
4579
4580 /* ellipsoidal (geodetic) height */
4581 Height = P * CPHI0 + Z * SPHI0 - RN * (1.0 - this.es * SPHI0 * SPHI0);
4582
4583 RK = this.es * RN / (RN + Height);
4584 RX = 1.0 / Math.sqrt(1.0 - RK * (2.0 - RK) * ST * ST);
4585 CPHI = ST * (1.0 - RK) * RX;
4586 SPHI = CT * RX;
4587 SDPHI = SPHI * CPHI0 - CPHI * SPHI0;
4588 CPHI0 = CPHI;
4589 SPHI0 = SPHI;
4590 }
4591 while (SDPHI * SDPHI > genau2 && iter < maxiter);
4592
4593 /* ellipsoidal (geodetic) latitude */
4594 Latitude = Math.atan(SPHI / Math.abs(CPHI));
4595
4596 p.x = Longitude;
4597 p.y = Latitude;
4598 p.z = Height;
4599 return p;
4600 }, // cs_geocentric_to_geodetic()
4601
4602 /** Convert_Geocentric_To_Geodetic
4603 * The method used here is derived from 'An Improved Algorithm for
4604 * Geocentric to Geodetic Coordinate Conversion', by Ralph Toms, Feb 1996
4605 */
4606 geocentric_to_geodetic_noniter: function(p) {
4607 var X = p.x;
4608 var Y = p.y;
4609 var Z = p.z ? p.z : 0; //Z value not always supplied
4610 var Longitude;
4611 var Latitude;
4612 var Height;
4613
4614 var W; /* distance from Z axis */
4615 var W2; /* square of distance from Z axis */
4616 var T0; /* initial estimate of vertical component */
4617 var T1; /* corrected estimate of vertical component */
4618 var S0; /* initial estimate of horizontal component */
4619 var S1; /* corrected estimate of horizontal component */
4620 var Sin_B0; /* Math.sin(B0), B0 is estimate of Bowring aux variable */
4621 var Sin3_B0; /* cube of Math.sin(B0) */
4622 var Cos_B0; /* Math.cos(B0) */
4623 var Sin_p1; /* Math.sin(phi1), phi1 is estimated latitude */
4624 var Cos_p1; /* Math.cos(phi1) */
4625 var Rn; /* Earth radius at location */
4626 var Sum; /* numerator of Math.cos(phi1) */
4627 var At_Pole; /* indicates location is in polar region */
4628
4629 X = parseFloat(X); // cast from string to float
4630 Y = parseFloat(Y);
4631 Z = parseFloat(Z);
4632
4633 At_Pole = false;
4634 if (X !== 0.0) {
4635 Longitude = Math.atan2(Y, X);
4636 }
4637 else {
4638 if (Y > 0) {
4639 Longitude = HALF_PI;
4640 }
4641 else if (Y < 0) {
4642 Longitude = -HALF_PI;
4643 }
4644 else {
4645 At_Pole = true;
4646 Longitude = 0.0;
4647 if (Z > 0.0) { /* north pole */
4648 Latitude = HALF_PI;
4649 }
4650 else if (Z < 0.0) { /* south pole */
4651 Latitude = -HALF_PI;
4652 }
4653 else { /* center of earth */
4654 Latitude = HALF_PI;
4655 Height = -this.b;
4656 return;
4657 }
4658 }
4659 }
4660 W2 = X * X + Y * Y;
4661 W = Math.sqrt(W2);
4662 T0 = Z * AD_C;
4663 S0 = Math.sqrt(T0 * T0 + W2);
4664 Sin_B0 = T0 / S0;
4665 Cos_B0 = W / S0;
4666 Sin3_B0 = Sin_B0 * Sin_B0 * Sin_B0;
4667 T1 = Z + this.b * this.ep2 * Sin3_B0;
4668 Sum = W - this.a * this.es * Cos_B0 * Cos_B0 * Cos_B0;
4669 S1 = Math.sqrt(T1 * T1 + Sum * Sum);
4670 Sin_p1 = T1 / S1;
4671 Cos_p1 = Sum / S1;
4672 Rn = this.a / Math.sqrt(1.0 - this.es * Sin_p1 * Sin_p1);
4673 if (Cos_p1 >= COS_67P5) {
4674 Height = W / Cos_p1 - Rn;
4675 }
4676 else if (Cos_p1 <= -COS_67P5) {
4677 Height = W / -Cos_p1 - Rn;
4678 }
4679 else {
4680 Height = Z / Sin_p1 + Rn * (this.es - 1.0);
4681 }
4682 if (At_Pole === false) {
4683 Latitude = Math.atan(Sin_p1 / Cos_p1);
4684 }
4685
4686 p.x = Longitude;
4687 p.y = Latitude;
4688 p.z = Height;
4689 return p;
4690 }, // geocentric_to_geodetic_noniter()
4691
4692 /****************************************************************/
4693 // pj_geocentic_to_wgs84( p )
4694 // p = point to transform in geocentric coordinates (x,y,z)
4695 geocentric_to_wgs84: function(p) {
4696
4697 if (this.datum_type === PJD_3PARAM) {
4698 // if( x[io] === HUGE_VAL )
4699 // continue;
4700 p.x += this.datum_params[0];
4701 p.y += this.datum_params[1];
4702 p.z += this.datum_params[2];
4703
4704 }
4705 else if (this.datum_type === PJD_7PARAM) {
4706 var Dx_BF = this.datum_params[0];
4707 var Dy_BF = this.datum_params[1];
4708 var Dz_BF = this.datum_params[2];
4709 var Rx_BF = this.datum_params[3];
4710 var Ry_BF = this.datum_params[4];
4711 var Rz_BF = this.datum_params[5];
4712 var M_BF = this.datum_params[6];
4713 // if( x[io] === HUGE_VAL )
4714 // continue;
4715 var x_out = M_BF * (p.x - Rz_BF * p.y + Ry_BF * p.z) + Dx_BF;
4716 var y_out = M_BF * (Rz_BF * p.x + p.y - Rx_BF * p.z) + Dy_BF;
4717 var z_out = M_BF * (-Ry_BF * p.x + Rx_BF * p.y + p.z) + Dz_BF;
4718 p.x = x_out;
4719 p.y = y_out;
4720 p.z = z_out;
4721 }
4722 }, // cs_geocentric_to_wgs84
4723
4724 /****************************************************************/
4725 // pj_geocentic_from_wgs84()
4726 // coordinate system definition,
4727 // point to transform in geocentric coordinates (x,y,z)
4728 geocentric_from_wgs84: function(p) {
4729
4730 if (this.datum_type === PJD_3PARAM) {
4731 //if( x[io] === HUGE_VAL )
4732 // continue;
4733 p.x -= this.datum_params[0];
4734 p.y -= this.datum_params[1];
4735 p.z -= this.datum_params[2];
4736
4737 }
4738 else if (this.datum_type === PJD_7PARAM) {
4739 var Dx_BF = this.datum_params[0];
4740 var Dy_BF = this.datum_params[1];
4741 var Dz_BF = this.datum_params[2];
4742 var Rx_BF = this.datum_params[3];
4743 var Ry_BF = this.datum_params[4];
4744 var Rz_BF = this.datum_params[5];
4745 var M_BF = this.datum_params[6];
4746 var x_tmp = (p.x - Dx_BF) / M_BF;
4747 var y_tmp = (p.y - Dy_BF) / M_BF;
4748 var z_tmp = (p.z - Dz_BF) / M_BF;
4749 //if( x[io] === HUGE_VAL )
4750 // continue;
4751
4752 p.x = x_tmp + Rz_BF * y_tmp - Ry_BF * z_tmp;
4753 p.y = -Rz_BF * x_tmp + y_tmp + Rx_BF * z_tmp;
4754 p.z = Ry_BF * x_tmp - Rx_BF * y_tmp + z_tmp;
4755 } //cs_geocentric_from_wgs84()
4756 }
4757 };
4758
4759 /** point object, nothing fancy, just allows values to be
4760 passed back and forth by reference rather than by value.
4761 Other point classes may be used as long as they have
4762 x and y properties, which will get modified in the transform method.
4763 */
4764 module.exports = datum;
4765 });
4766
4767 var require$$0$14 = (datum && typeof datum === 'object' && 'default' in datum ? datum['default'] : datum);
4768
4769 var extend = createCommonjsModule(function (module) {
4770 module.exports = function(destination, source) {
4771 destination = destination || {};
4772 var value, property;
4773 if (!source) {
4774 return destination;
4775 }
4776 for (property in source) {
4777 value = source[property];
4778 if (value !== undefined) {
4779 destination[property] = value;
4780 }
4781 }
4782 return destination;
4783 };
4784 });
4785
4786 var require$$0$15 = (extend && typeof extend === 'object' && 'default' in extend ? extend['default'] : extend);
4787
4788 var Ellipsoid = createCommonjsModule(function (module, exports) {
4789 exports.MERIT = {
4790 a: 6378137.0,
4791 rf: 298.257,
4792 ellipseName: "MERIT 1983"
4793 };
4794 exports.SGS85 = {
4795 a: 6378136.0,
4796 rf: 298.257,
4797 ellipseName: "Soviet Geodetic System 85"
4798 };
4799 exports.GRS80 = {
4800 a: 6378137.0,
4801 rf: 298.257222101,
4802 ellipseName: "GRS 1980(IUGG, 1980)"
4803 };
4804 exports.IAU76 = {
4805 a: 6378140.0,
4806 rf: 298.257,
4807 ellipseName: "IAU 1976"
4808 };
4809 exports.airy = {
4810 a: 6377563.396,
4811 b: 6356256.910,
4812 ellipseName: "Airy 1830"
4813 };
4814 exports.APL4 = {
4815 a: 6378137,
4816 rf: 298.25,
4817 ellipseName: "Appl. Physics. 1965"
4818 };
4819 exports.NWL9D = {
4820 a: 6378145.0,
4821 rf: 298.25,
4822 ellipseName: "Naval Weapons Lab., 1965"
4823 };
4824 exports.mod_airy = {
4825 a: 6377340.189,
4826 b: 6356034.446,
4827 ellipseName: "Modified Airy"
4828 };
4829 exports.andrae = {
4830 a: 6377104.43,
4831 rf: 300.0,
4832 ellipseName: "Andrae 1876 (Den., Iclnd.)"
4833 };
4834 exports.aust_SA = {
4835 a: 6378160.0,
4836 rf: 298.25,
4837 ellipseName: "Australian Natl & S. Amer. 1969"
4838 };
4839 exports.GRS67 = {
4840 a: 6378160.0,
4841 rf: 298.2471674270,
4842 ellipseName: "GRS 67(IUGG 1967)"
4843 };
4844 exports.bessel = {
4845 a: 6377397.155,
4846 rf: 299.1528128,
4847 ellipseName: "Bessel 1841"
4848 };
4849 exports.bess_nam = {
4850 a: 6377483.865,
4851 rf: 299.1528128,
4852 ellipseName: "Bessel 1841 (Namibia)"
4853 };
4854 exports.clrk66 = {
4855 a: 6378206.4,
4856 b: 6356583.8,
4857 ellipseName: "Clarke 1866"
4858 };
4859 exports.clrk80 = {
4860 a: 6378249.145,
4861 rf: 293.4663,
4862 ellipseName: "Clarke 1880 mod."
4863 };
4864 exports.clrk58 = {
4865 a: 6378293.645208759,
4866 rf: 294.2606763692654,
4867 ellipseName: "Clarke 1858"
4868 };
4869 exports.CPM = {
4870 a: 6375738.7,
4871 rf: 334.29,
4872 ellipseName: "Comm. des Poids et Mesures 1799"
4873 };
4874 exports.delmbr = {
4875 a: 6376428.0,
4876 rf: 311.5,
4877 ellipseName: "Delambre 1810 (Belgium)"
4878 };
4879 exports.engelis = {
4880 a: 6378136.05,
4881 rf: 298.2566,
4882 ellipseName: "Engelis 1985"
4883 };
4884 exports.evrst30 = {
4885 a: 6377276.345,
4886 rf: 300.8017,
4887 ellipseName: "Everest 1830"
4888 };
4889 exports.evrst48 = {
4890 a: 6377304.063,
4891 rf: 300.8017,
4892 ellipseName: "Everest 1948"
4893 };
4894 exports.evrst56 = {
4895 a: 6377301.243,
4896 rf: 300.8017,
4897 ellipseName: "Everest 1956"
4898 };
4899 exports.evrst69 = {
4900 a: 6377295.664,
4901 rf: 300.8017,
4902 ellipseName: "Everest 1969"
4903 };
4904 exports.evrstSS = {
4905 a: 6377298.556,
4906 rf: 300.8017,
4907 ellipseName: "Everest (Sabah & Sarawak)"
4908 };
4909 exports.fschr60 = {
4910 a: 6378166.0,
4911 rf: 298.3,
4912 ellipseName: "Fischer (Mercury Datum) 1960"
4913 };
4914 exports.fschr60m = {
4915 a: 6378155.0,
4916 rf: 298.3,
4917 ellipseName: "Fischer 1960"
4918 };
4919 exports.fschr68 = {
4920 a: 6378150.0,
4921 rf: 298.3,
4922 ellipseName: "Fischer 1968"
4923 };
4924 exports.helmert = {
4925 a: 6378200.0,
4926 rf: 298.3,
4927 ellipseName: "Helmert 1906"
4928 };
4929 exports.hough = {
4930 a: 6378270.0,
4931 rf: 297.0,
4932 ellipseName: "Hough"
4933 };
4934 exports.intl = {
4935 a: 6378388.0,
4936 rf: 297.0,
4937 ellipseName: "International 1909 (Hayford)"
4938 };
4939 exports.kaula = {
4940 a: 6378163.0,
4941 rf: 298.24,
4942 ellipseName: "Kaula 1961"
4943 };
4944 exports.lerch = {
4945 a: 6378139.0,
4946 rf: 298.257,
4947 ellipseName: "Lerch 1979"
4948 };
4949 exports.mprts = {
4950 a: 6397300.0,
4951 rf: 191.0,
4952 ellipseName: "Maupertius 1738"
4953 };
4954 exports.new_intl = {
4955 a: 6378157.5,
4956 b: 6356772.2,
4957 ellipseName: "New International 1967"
4958 };
4959 exports.plessis = {
4960 a: 6376523.0,
4961 rf: 6355863.0,
4962 ellipseName: "Plessis 1817 (France)"
4963 };
4964 exports.krass = {
4965 a: 6378245.0,
4966 rf: 298.3,
4967 ellipseName: "Krassovsky, 1942"
4968 };
4969 exports.SEasia = {
4970 a: 6378155.0,
4971 b: 6356773.3205,
4972 ellipseName: "Southeast Asia"
4973 };
4974 exports.walbeck = {
4975 a: 6376896.0,
4976 b: 6355834.8467,
4977 ellipseName: "Walbeck"
4978 };
4979 exports.WGS60 = {
4980 a: 6378165.0,
4981 rf: 298.3,
4982 ellipseName: "WGS 60"
4983 };
4984 exports.WGS66 = {
4985 a: 6378145.0,
4986 rf: 298.25,
4987 ellipseName: "WGS 66"
4988 };
4989 exports.WGS7 = {
4990 a: 6378135.0,
4991 rf: 298.26,
4992 ellipseName: "WGS 72"
4993 };
4994 exports.WGS84 = {
4995 a: 6378137.0,
4996 rf: 298.257223563,
4997 ellipseName: "WGS 84"
4998 };
4999 exports.sphere = {
5000 a: 6370997.0,
5001 b: 6370997.0,
5002 ellipseName: "Normal Sphere (r=6370997)"
5003 };
5004 });
5005
5006 var require$$2$2 = (Ellipsoid && typeof Ellipsoid === 'object' && 'default' in Ellipsoid ? Ellipsoid['default'] : Ellipsoid);
5007
5008 var Datum = createCommonjsModule(function (module, exports) {
5009 exports.wgs84 = {
5010 towgs84: "0,0,0",
5011 ellipse: "WGS84",
5012 datumName: "WGS84"
5013 };
5014 exports.ch1903 = {
5015 towgs84: "674.374,15.056,405.346",
5016 ellipse: "bessel",
5017 datumName: "swiss"
5018 };
5019 exports.ggrs87 = {
5020 towgs84: "-199.87,74.79,246.62",
5021 ellipse: "GRS80",
5022 datumName: "Greek_Geodetic_Reference_System_1987"
5023 };
5024 exports.nad83 = {
5025 towgs84: "0,0,0",
5026 ellipse: "GRS80",
5027 datumName: "North_American_Datum_1983"
5028 };
5029 exports.nad27 = {
5030 nadgrids: "@conus,@alaska,@ntv2_0.gsb,@ntv1_can.dat",
5031 ellipse: "clrk66",
5032 datumName: "North_American_Datum_1927"
5033 };
5034 exports.potsdam = {
5035 towgs84: "606.0,23.0,413.0",
5036 ellipse: "bessel",
5037 datumName: "Potsdam Rauenberg 1950 DHDN"
5038 };
5039 exports.carthage = {
5040 towgs84: "-263.0,6.0,431.0",
5041 ellipse: "clark80",
5042 datumName: "Carthage 1934 Tunisia"
5043 };
5044 exports.hermannskogel = {
5045 towgs84: "653.0,-212.0,449.0",
5046 ellipse: "bessel",
5047 datumName: "Hermannskogel"
5048 };
5049 exports.ire65 = {
5050 towgs84: "482.530,-130.596,564.557,-1.042,-0.214,-0.631,8.15",
5051 ellipse: "mod_airy",
5052 datumName: "Ireland 1965"
5053 };
5054 exports.rassadiran = {
5055 towgs84: "-133.63,-157.5,-158.62",
5056 ellipse: "intl",
5057 datumName: "Rassadiran"
5058 };
5059 exports.nzgd49 = {
5060 towgs84: "59.47,-5.04,187.44,0.47,-0.1,1.024,-4.5993",
5061 ellipse: "intl",
5062 datumName: "New Zealand Geodetic Datum 1949"
5063 };
5064 exports.osgb36 = {
5065 towgs84: "446.448,-125.157,542.060,0.1502,0.2470,0.8421,-20.4894",
5066 ellipse: "airy",
5067 datumName: "Airy 1830"
5068 };
5069 exports.s_jtsk = {
5070 towgs84: "589,76,480",
5071 ellipse: 'bessel',
5072 datumName: 'S-JTSK (Ferro)'
5073 };
5074 exports.beduaram = {
5075 towgs84: '-106,-87,188',
5076 ellipse: 'clrk80',
5077 datumName: 'Beduaram'
5078 };
5079 exports.gunung_segara = {
5080 towgs84: '-403,684,41',
5081 ellipse: 'bessel',
5082 datumName: 'Gunung Segara Jakarta'
5083 };
5084 exports.rnb72 = {
5085 towgs84: "106.869,-52.2978,103.724,-0.33657,0.456955,-1.84218,1",
5086 ellipse: "intl",
5087 datumName: "Reseau National Belge 1972"
5088 };
5089 });
5090
5091 var require$$3$5 = (Datum && typeof Datum === 'object' && 'default' in Datum ? Datum['default'] : Datum);
5092
5093 var deriveConstants = createCommonjsModule(function (module) {
5094 var Datum = require$$3$5;
5095 var Ellipsoid = require$$2$2;
5096 var extend = require$$0$15;
5097 var datum = require$$0$14;
5098 var EPSLN = 1.0e-10;
5099 // ellipoid pj_set_ell.c
5100 var SIXTH = 0.1666666666666666667;
5101 /* 1/6 */
5102 var RA4 = 0.04722222222222222222;
5103 /* 17/360 */
5104 var RA6 = 0.02215608465608465608;
5105 module.exports = function(json) {
5106 // DGR 2011-03-20 : nagrids -> nadgrids
5107 if (json.datumCode && json.datumCode !== 'none') {
5108 var datumDef = Datum[json.datumCode];
5109 if (datumDef) {
5110 json.datum_params = datumDef.towgs84 ? datumDef.towgs84.split(',') : null;
5111 json.ellps = datumDef.ellipse;
5112 json.datumName = datumDef.datumName ? datumDef.datumName : json.datumCode;
5113 }
5114 }
5115 if (!json.a) { // do we have an ellipsoid?
5116 var ellipse = Ellipsoid[json.ellps] ? Ellipsoid[json.ellps] : Ellipsoid.WGS84;
5117 extend(json, ellipse);
5118 }
5119 if (json.rf && !json.b) {
5120 json.b = (1.0 - 1.0 / json.rf) * json.a;
5121 }
5122 if (json.rf === 0 || Math.abs(json.a - json.b) < EPSLN) {
5123 json.sphere = true;
5124 json.b = json.a;
5125 }
5126 json.a2 = json.a * json.a; // used in geocentric
5127 json.b2 = json.b * json.b; // used in geocentric
5128 json.es = (json.a2 - json.b2) / json.a2; // e ^ 2
5129 json.e = Math.sqrt(json.es); // eccentricity
5130 if (json.R_A) {
5131 json.a *= 1 - json.es * (SIXTH + json.es * (RA4 + json.es * RA6));
5132 json.a2 = json.a * json.a;
5133 json.b2 = json.b * json.b;
5134 json.es = 0;
5135 }
5136 json.ep2 = (json.a2 - json.b2) / json.b2; // used in geocentric
5137 if (!json.k0) {
5138 json.k0 = 1.0; //default value
5139 }
5140 //DGR 2010-11-12: axis
5141 if (!json.axis) {
5142 json.axis = "enu";
5143 }
5144
5145 if (!json.datum) {
5146 json.datum = datum(json);
5147 }
5148 return json;
5149 };
5150 });
5151
5152 var require$$0$13 = (deriveConstants && typeof deriveConstants === 'object' && 'default' in deriveConstants ? deriveConstants['default'] : deriveConstants);
5153
5154 var longlat = createCommonjsModule(function (module, exports) {
5155 exports.init = function() {
5156 //no-op for longlat
5157 };
5158
5159 function identity(pt) {
5160 return pt;
5161 }
5162 exports.forward = identity;
5163 exports.inverse = identity;
5164 exports.names = ["longlat", "identity"];
5165 });
5166
5167 var require$$0$16 = (longlat && typeof longlat === 'object' && 'default' in longlat ? longlat['default'] : longlat);
5168
5169 var merc = createCommonjsModule(function (module, exports) {
5170 var msfnz = require$$3$2;
5171 var HALF_PI = Math.PI/2;
5172 var EPSLN = 1.0e-10;
5173 var R2D = 57.29577951308232088;
5174 var adjust_lon = require$$2;
5175 var FORTPI = Math.PI/4;
5176 var tsfnz = require$$1$5;
5177 var phi2z = require$$0$7;
5178 exports.init = function() {
5179 var con = this.b / this.a;
5180 this.es = 1 - con * con;
5181 if(!('x0' in this)){
5182 this.x0 = 0;
5183 }
5184 if(!('y0' in this)){
5185 this.y0 = 0;
5186 }
5187 this.e = Math.sqrt(this.es);
5188 if (this.lat_ts) {
5189 if (this.sphere) {
5190 this.k0 = Math.cos(this.lat_ts);
5191 }
5192 else {
5193 this.k0 = msfnz(this.e, Math.sin(this.lat_ts), Math.cos(this.lat_ts));
5194 }
5195 }
5196 else {
5197 if (!this.k0) {
5198 if (this.k) {
5199 this.k0 = this.k;
5200 }
5201 else {
5202 this.k0 = 1;
5203 }
5204 }
5205 }
5206 };
5207
5208 /* Mercator forward equations--mapping lat,long to x,y
5209 --------------------------------------------------*/
5210
5211 exports.forward = function(p) {
5212 var lon = p.x;
5213 var lat = p.y;
5214 // convert to radians
5215 if (lat * R2D > 90 && lat * R2D < -90 && lon * R2D > 180 && lon * R2D < -180) {
5216 return null;
5217 }
5218
5219 var x, y;
5220 if (Math.abs(Math.abs(lat) - HALF_PI) <= EPSLN) {
5221 return null;
5222 }
5223 else {
5224 if (this.sphere) {
5225 x = this.x0 + this.a * this.k0 * adjust_lon(lon - this.long0);
5226 y = this.y0 + this.a * this.k0 * Math.log(Math.tan(FORTPI + 0.5 * lat));
5227 }
5228 else {
5229 var sinphi = Math.sin(lat);
5230 var ts = tsfnz(this.e, lat, sinphi);
5231 x = this.x0 + this.a * this.k0 * adjust_lon(lon - this.long0);
5232 y = this.y0 - this.a * this.k0 * Math.log(ts);
5233 }
5234 p.x = x;
5235 p.y = y;
5236 return p;
5237 }
5238 };
5239
5240
5241 /* Mercator inverse equations--mapping x,y to lat/long
5242 --------------------------------------------------*/
5243 exports.inverse = function(p) {
5244
5245 var x = p.x - this.x0;
5246 var y = p.y - this.y0;
5247 var lon, lat;
5248
5249 if (this.sphere) {
5250 lat = HALF_PI - 2 * Math.atan(Math.exp(-y / (this.a * this.k0)));
5251 }
5252 else {
5253 var ts = Math.exp(-y / (this.a * this.k0));
5254 lat = phi2z(this.e, ts);
5255 if (lat === -9999) {
5256 return null;
5257 }
5258 }
5259 lon = adjust_lon(this.long0 + x / (this.a * this.k0));
5260
5261 p.x = lon;
5262 p.y = lat;
5263 return p;
5264 };
5265
5266 exports.names = ["Mercator", "Popular Visualisation Pseudo Mercator", "Mercator_1SP", "Mercator_Auxiliary_Sphere", "merc"];
5267 });
5268
5269 var require$$1$10 = (merc && typeof merc === 'object' && 'default' in merc ? merc['default'] : merc);
5270
5271 var projections = createCommonjsModule(function (module, exports) {
5272 var projs = [
5273 require$$1$10,
5274 require$$0$16
5275 ];
5276 var names = {};
5277 var projStore = [];
5278
5279 function add(proj, i) {
5280 var len = projStore.length;
5281 if (!proj.names) {
5282 console.log(i);
5283 return true;
5284 }
5285 projStore[len] = proj;
5286 proj.names.forEach(function(n) {
5287 names[n.toLowerCase()] = len;
5288 });
5289 return this;
5290 }
5291
5292 exports.add = add;
5293
5294 exports.get = function(name) {
5295 if (!name) {
5296 return false;
5297 }
5298 var n = name.toLowerCase();
5299 if (typeof names[n] !== 'undefined' && projStore[names[n]]) {
5300 return projStore[names[n]];
5301 }
5302 };
5303 exports.start = function() {
5304 projs.forEach(add);
5305 };
5306 });
5307
5308 var require$$1$9 = (projections && typeof projections === 'object' && 'default' in projections ? projections['default'] : projections);
5309
5310 var units = createCommonjsModule(function (module, exports) {
5311 exports.ft = {to_meter: 0.3048};
5312 exports['us-ft'] = {to_meter: 1200 / 3937};
5313 });
5314
5315 var require$$0$17 = (units && typeof units === 'object' && 'default' in units ? units['default'] : units);
5316
5317 var PrimeMeridian = createCommonjsModule(function (module, exports) {
5318 exports.greenwich = 0.0; //"0dE",
5319 exports.lisbon = -9.131906111111; //"9d07'54.862\"W",
5320 exports.paris = 2.337229166667; //"2d20'14.025\"E",
5321 exports.bogota = -74.080916666667; //"74d04'51.3\"W",
5322 exports.madrid = -3.687938888889; //"3d41'16.58\"W",
5323 exports.rome = 12.452333333333; //"12d27'8.4\"E",
5324 exports.bern = 7.439583333333; //"7d26'22.5\"E",
5325 exports.jakarta = 106.807719444444; //"106d48'27.79\"E",
5326 exports.ferro = -17.666666666667; //"17d40'W",
5327 exports.brussels = 4.367975; //"4d22'4.71\"E",
5328 exports.stockholm = 18.058277777778; //"18d3'29.8\"E",
5329 exports.athens = 23.7163375; //"23d42'58.815\"E",
5330 exports.oslo = 10.722916666667; //"10d43'22.5\"E"
5331 });
5332
5333 var require$$1$12 = (PrimeMeridian && typeof PrimeMeridian === 'object' && 'default' in PrimeMeridian ? PrimeMeridian['default'] : PrimeMeridian);
5334
5335 var projString = createCommonjsModule(function (module) {
5336 var D2R = 0.01745329251994329577;
5337 var PrimeMeridian = require$$1$12;
5338 var units = require$$0$17;
5339
5340 module.exports = function(defData) {
5341 var self = {};
5342 var paramObj = {};
5343 defData.split("+").map(function(v) {
5344 return v.trim();
5345 }).filter(function(a) {
5346 return a;
5347 }).forEach(function(a) {
5348 var split = a.split("=");
5349 split.push(true);
5350 paramObj[split[0].toLowerCase()] = split[1];
5351 });
5352 var paramName, paramVal, paramOutname;
5353 var params = {
5354 proj: 'projName',
5355 datum: 'datumCode',
5356 rf: function(v) {
5357 self.rf = parseFloat(v);
5358 },
5359 lat_0: function(v) {
5360 self.lat0 = v * D2R;
5361 },
5362 lat_1: function(v) {
5363 self.lat1 = v * D2R;
5364 },
5365 lat_2: function(v) {
5366 self.lat2 = v * D2R;
5367 },
5368 lat_ts: function(v) {
5369 self.lat_ts = v * D2R;
5370 },
5371 lon_0: function(v) {
5372 self.long0 = v * D2R;
5373 },
5374 lon_1: function(v) {
5375 self.long1 = v * D2R;
5376 },
5377 lon_2: function(v) {
5378 self.long2 = v * D2R;
5379 },
5380 alpha: function(v) {
5381 self.alpha = parseFloat(v) * D2R;
5382 },
5383 lonc: function(v) {
5384 self.longc = v * D2R;
5385 },
5386 x_0: function(v) {
5387 self.x0 = parseFloat(v);
5388 },
5389 y_0: function(v) {
5390 self.y0 = parseFloat(v);
5391 },
5392 k_0: function(v) {
5393 self.k0 = parseFloat(v);
5394 },
5395 k: function(v) {
5396 self.k0 = parseFloat(v);
5397 },
5398 a: function(v) {
5399 self.a = parseFloat(v);
5400 },
5401 b: function(v) {
5402 self.b = parseFloat(v);
5403 },
5404 r_a: function() {
5405 self.R_A = true;
5406 },
5407 zone: function(v) {
5408 self.zone = parseInt(v, 10);
5409 },
5410 south: function() {
5411 self.utmSouth = true;
5412 },
5413 towgs84: function(v) {
5414 self.datum_params = v.split(",").map(function(a) {
5415 return parseFloat(a);
5416 });
5417 },
5418 to_meter: function(v) {
5419 self.to_meter = parseFloat(v);
5420 },
5421 units: function(v) {
5422 self.units = v;
5423 if (units[v]) {
5424 self.to_meter = units[v].to_meter;
5425 }
5426 },
5427 from_greenwich: function(v) {
5428 self.from_greenwich = v * D2R;
5429 },
5430 pm: function(v) {
5431 self.from_greenwich = (PrimeMeridian[v] ? PrimeMeridian[v] : parseFloat(v)) * D2R;
5432 },
5433 nadgrids: function(v) {
5434 if (v === '@null') {
5435 self.datumCode = 'none';
5436 }
5437 else {
5438 self.nadgrids = v;
5439 }
5440 },
5441 axis: function(v) {
5442 var legalAxis = "ewnsud";
5443 if (v.length === 3 && legalAxis.indexOf(v.substr(0, 1)) !== -1 && legalAxis.indexOf(v.substr(1, 1)) !== -1 && legalAxis.indexOf(v.substr(2, 1)) !== -1) {
5444 self.axis = v;
5445 }
5446 }
5447 };
5448 for (paramName in paramObj) {
5449 paramVal = paramObj[paramName];
5450 if (paramName in params) {
5451 paramOutname = params[paramName];
5452 if (typeof paramOutname === 'function') {
5453 paramOutname(paramVal);
5454 }
5455 else {
5456 self[paramOutname] = paramVal;
5457 }
5458 }
5459 else {
5460 self[paramName] = paramVal;
5461 }
5462 }
5463 if(typeof self.datumCode === 'string' && self.datumCode !== "WGS84"){
5464 self.datumCode = self.datumCode.toLowerCase();
5465 }
5466 return self;
5467 };
5468 });
5469
5470 var require$$1$11 = (projString && typeof projString === 'object' && 'default' in projString ? projString['default'] : projString);
5471
5472 var wkt = createCommonjsModule(function (module) {
5473 var D2R = 0.01745329251994329577;
5474 var extend = require$$0$15;
5475
5476 function mapit(obj, key, v) {
5477 obj[key] = v.map(function(aa) {
5478 var o = {};
5479 sExpr(aa, o);
5480 return o;
5481 }).reduce(function(a, b) {
5482 return extend(a, b);
5483 }, {});
5484 }
5485
5486 function sExpr(v, obj) {
5487 var key;
5488 if (!Array.isArray(v)) {
5489 obj[v] = true;
5490 return;
5491 }
5492 else {
5493 key = v.shift();
5494 if (key === 'PARAMETER') {
5495 key = v.shift();
5496 }
5497 if (v.length === 1) {
5498 if (Array.isArray(v[0])) {
5499 obj[key] = {};
5500 sExpr(v[0], obj[key]);
5501 }
5502 else {
5503 obj[key] = v[0];
5504 }
5505 }
5506 else if (!v.length) {
5507 obj[key] = true;
5508 }
5509 else if (key === 'TOWGS84') {
5510 obj[key] = v;
5511 }
5512 else {
5513 obj[key] = {};
5514 if (['UNIT', 'PRIMEM', 'VERT_DATUM'].indexOf(key) > -1) {
5515 obj[key] = {
5516 name: v[0].toLowerCase(),
5517 convert: v[1]
5518 };
5519 if (v.length === 3) {
5520 obj[key].auth = v[2];
5521 }
5522 }
5523 else if (key === 'SPHEROID') {
5524 obj[key] = {
5525 name: v[0],
5526 a: v[1],
5527 rf: v[2]
5528 };
5529 if (v.length === 4) {
5530 obj[key].auth = v[3];
5531 }
5532 }
5533 else if (['GEOGCS', 'GEOCCS', 'DATUM', 'VERT_CS', 'COMPD_CS', 'LOCAL_CS', 'FITTED_CS', 'LOCAL_DATUM'].indexOf(key) > -1) {
5534 v[0] = ['name', v[0]];
5535 mapit(obj, key, v);
5536 }
5537 else if (v.every(function(aa) {
5538 return Array.isArray(aa);
5539 })) {
5540 mapit(obj, key, v);
5541 }
5542 else {
5543 sExpr(v, obj[key]);
5544 }
5545 }
5546 }
5547 }
5548
5549 function rename(obj, params) {
5550 var outName = params[0];
5551 var inName = params[1];
5552 if (!(outName in obj) && (inName in obj)) {
5553 obj[outName] = obj[inName];
5554 if (params.length === 3) {
5555 obj[outName] = params[2](obj[outName]);
5556 }
5557 }
5558 }
5559
5560 function d2r(input) {
5561 return input * D2R;
5562 }
5563
5564 function cleanWKT(wkt) {
5565 if (wkt.type === 'GEOGCS') {
5566 wkt.projName = 'longlat';
5567 }
5568 else if (wkt.type === 'LOCAL_CS') {
5569 wkt.projName = 'identity';
5570 wkt.local = true;
5571 }
5572 else {
5573 if (typeof wkt.PROJECTION === "object") {
5574 wkt.projName = Object.keys(wkt.PROJECTION)[0];
5575 }
5576 else {
5577 wkt.projName = wkt.PROJECTION;
5578 }
5579 }
5580 if (wkt.UNIT) {
5581 wkt.units = wkt.UNIT.name.toLowerCase();
5582 if (wkt.units === 'metre') {
5583 wkt.units = 'meter';
5584 }
5585 if (wkt.UNIT.convert) {
5586 if (wkt.type === 'GEOGCS') {
5587 if (wkt.DATUM && wkt.DATUM.SPHEROID) {
5588 wkt.to_meter = parseFloat(wkt.UNIT.convert, 10)*wkt.DATUM.SPHEROID.a;
5589 }
5590 } else {
5591 wkt.to_meter = parseFloat(wkt.UNIT.convert, 10);
5592 }
5593 }
5594 }
5595
5596 if (wkt.GEOGCS) {
5597 //if(wkt.GEOGCS.PRIMEM&&wkt.GEOGCS.PRIMEM.convert){
5598 // wkt.from_greenwich=wkt.GEOGCS.PRIMEM.convert*D2R;
5599 //}
5600 if (wkt.GEOGCS.DATUM) {
5601 wkt.datumCode = wkt.GEOGCS.DATUM.name.toLowerCase();
5602 }
5603 else {
5604 wkt.datumCode = wkt.GEOGCS.name.toLowerCase();
5605 }
5606 if (wkt.datumCode.slice(0, 2) === 'd_') {
5607 wkt.datumCode = wkt.datumCode.slice(2);
5608 }
5609 if (wkt.datumCode === 'new_zealand_geodetic_datum_1949' || wkt.datumCode === 'new_zealand_1949') {
5610 wkt.datumCode = 'nzgd49';
5611 }
5612 if (wkt.datumCode === "wgs_1984") {
5613 if (wkt.PROJECTION === 'Mercator_Auxiliary_Sphere') {
5614 wkt.sphere = true;
5615 }
5616 wkt.datumCode = 'wgs84';
5617 }
5618 if (wkt.datumCode.slice(-6) === '_ferro') {
5619 wkt.datumCode = wkt.datumCode.slice(0, - 6);
5620 }
5621 if (wkt.datumCode.slice(-8) === '_jakarta') {
5622 wkt.datumCode = wkt.datumCode.slice(0, - 8);
5623 }
5624 if (~wkt.datumCode.indexOf('belge')) {
5625 wkt.datumCode = "rnb72";
5626 }
5627 if (wkt.GEOGCS.DATUM && wkt.GEOGCS.DATUM.SPHEROID) {
5628 wkt.ellps = wkt.GEOGCS.DATUM.SPHEROID.name.replace('_19', '').replace(/[Cc]larke\_18/, 'clrk');
5629 if (wkt.ellps.toLowerCase().slice(0, 13) === "international") {
5630 wkt.ellps = 'intl';
5631 }
5632
5633 wkt.a = wkt.GEOGCS.DATUM.SPHEROID.a;
5634 wkt.rf = parseFloat(wkt.GEOGCS.DATUM.SPHEROID.rf, 10);
5635 }
5636 if (~wkt.datumCode.indexOf('osgb_1936')) {
5637 wkt.datumCode = "osgb36";
5638 }
5639 }
5640 if (wkt.b && !isFinite(wkt.b)) {
5641 wkt.b = wkt.a;
5642 }
5643
5644 function toMeter(input) {
5645 var ratio = wkt.to_meter || 1;
5646 return parseFloat(input, 10) * ratio;
5647 }
5648 var renamer = function(a) {
5649 return rename(wkt, a);
5650 };
5651 var list = [
5652 ['standard_parallel_1', 'Standard_Parallel_1'],
5653 ['standard_parallel_2', 'Standard_Parallel_2'],
5654 ['false_easting', 'False_Easting'],
5655 ['false_northing', 'False_Northing'],
5656 ['central_meridian', 'Central_Meridian'],
5657 ['latitude_of_origin', 'Latitude_Of_Origin'],
5658 ['latitude_of_origin', 'Central_Parallel'],
5659 ['scale_factor', 'Scale_Factor'],
5660 ['k0', 'scale_factor'],
5661 ['latitude_of_center', 'Latitude_of_center'],
5662 ['lat0', 'latitude_of_center', d2r],
5663 ['longitude_of_center', 'Longitude_Of_Center'],
5664 ['longc', 'longitude_of_center', d2r],
5665 ['x0', 'false_easting', toMeter],
5666 ['y0', 'false_northing', toMeter],
5667 ['long0', 'central_meridian', d2r],
5668 ['lat0', 'latitude_of_origin', d2r],
5669 ['lat0', 'standard_parallel_1', d2r],
5670 ['lat1', 'standard_parallel_1', d2r],
5671 ['lat2', 'standard_parallel_2', d2r],
5672 ['alpha', 'azimuth', d2r],
5673 ['srsCode', 'name']
5674 ];
5675 list.forEach(renamer);
5676 if (!wkt.long0 && wkt.longc && (wkt.projName === 'Albers_Conic_Equal_Area' || wkt.projName === "Lambert_Azimuthal_Equal_Area")) {
5677 wkt.long0 = wkt.longc;
5678 }
5679 if (!wkt.lat_ts && wkt.lat1 && (wkt.projName === 'Stereographic_South_Pole' || wkt.projName === 'Polar Stereographic (variant B)')) {
5680 wkt.lat0 = d2r(wkt.lat1 > 0 ? 90 : -90);
5681 wkt.lat_ts = wkt.lat1;
5682 }
5683 }
5684 module.exports = function(wkt, self) {
5685 var lisp = JSON.parse(("," + wkt).replace(/\s*\,\s*([A-Z_0-9]+?)(\[)/g, ',["$1",').slice(1).replace(/\s*\,\s*([A-Z_0-9]+?)\]/g, ',"$1"]').replace(/,\["VERTCS".+/,''));
5686 var type = lisp.shift();
5687 var name = lisp.shift();
5688 lisp.unshift(['name', name]);
5689 lisp.unshift(['type', type]);
5690 lisp.unshift('output');
5691 var obj = {};
5692 sExpr(lisp, obj);
5693 cleanWKT(obj.output);
5694 return extend(self, obj.output);
5695 };
5696 });
5697
5698 var require$$0$18 = (wkt && typeof wkt === 'object' && 'default' in wkt ? wkt['default'] : wkt);
5699
5700 var global$1 = createCommonjsModule(function (module) {
5701 module.exports = function(defs) {
5702 defs('EPSG:4326', "+title=WGS 84 (long/lat) +proj=longlat +ellps=WGS84 +datum=WGS84 +units=degrees");
5703 defs('EPSG:4269', "+title=NAD83 (long/lat) +proj=longlat +a=6378137.0 +b=6356752.31414036 +ellps=GRS80 +datum=NAD83 +units=degrees");
5704 defs('EPSG:3857', "+title=WGS 84 / Pseudo-Mercator +proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0 +k=1.0 +units=m +nadgrids=@null +no_defs");
5705
5706 defs.WGS84 = defs['EPSG:4326'];
5707 defs['EPSG:3785'] = defs['EPSG:3857']; // maintain backward compat, official code is 3857
5708 defs.GOOGLE = defs['EPSG:3857'];
5709 defs['EPSG:900913'] = defs['EPSG:3857'];
5710 defs['EPSG:102113'] = defs['EPSG:3857'];
5711 };
5712 });
5713
5714 var require$$2$4 = (global$1 && typeof global$1 === 'object' && 'default' in global$1 ? global$1['default'] : global$1);
5715
5716 var defs = createCommonjsModule(function (module) {
5717 var globals = require$$2$4;
5718 var parseProj = require$$1$11;
5719 var wkt = require$$0$18;
5720
5721 function defs(name) {
5722 /*global console*/
5723 var that = this;
5724 if (arguments.length === 2) {
5725 var def = arguments[1];
5726 if (typeof def === 'string') {
5727 if (def.charAt(0) === '+') {
5728 defs[name] = parseProj(arguments[1]);
5729 }
5730 else {
5731 defs[name] = wkt(arguments[1]);
5732 }
5733 } else {
5734 defs[name] = def;
5735 }
5736 }
5737 else if (arguments.length === 1) {
5738 if (Array.isArray(name)) {
5739 return name.map(function(v) {
5740 if (Array.isArray(v)) {
5741 defs.apply(that, v);
5742 }
5743 else {
5744 defs(v);
5745 }
5746 });
5747 }
5748 else if (typeof name === 'string') {
5749 if (name in defs) {
5750 return defs[name];
5751 }
5752 }
5753 else if ('EPSG' in name) {
5754 defs['EPSG:' + name.EPSG] = name;
5755 }
5756 else if ('ESRI' in name) {
5757 defs['ESRI:' + name.ESRI] = name;
5758 }
5759 else if ('IAU2000' in name) {
5760 defs['IAU2000:' + name.IAU2000] = name;
5761 }
5762 else {
5763 console.log(name);
5764 }
5765 return;
5766 }
5767
5768
5769 }
5770 globals(defs);
5771 module.exports = defs;
5772 });
5773
5774 var require$$2$3 = (defs && typeof defs === 'object' && 'default' in defs ? defs['default'] : defs);
5775
5776 var parseCode = createCommonjsModule(function (module) {
5777 var defs = require$$2$3;
5778 var wkt = require$$0$18;
5779 var projStr = require$$1$11;
5780 function testObj(code){
5781 return typeof code === 'string';
5782 }
5783 function testDef(code){
5784 return code in defs;
5785 }
5786 function testWKT(code){
5787 var codeWords = ['GEOGCS','GEOCCS','PROJCS','LOCAL_CS'];
5788 return codeWords.reduce(function(a,b){
5789 return a+1+code.indexOf(b);
5790 },0);
5791 }
5792 function testProj(code){
5793 return code[0] === '+';
5794 }
5795 function parse(code){
5796 if (testObj(code)) {
5797 //check to see if this is a WKT string
5798 if (testDef(code)) {
5799 return defs[code];
5800 }
5801 else if (testWKT(code)) {
5802 return wkt(code);
5803 }
5804 else if (testProj(code)) {
5805 return projStr(code);
5806 }
5807 }else{
5808 return code;
5809 }
5810 }
5811
5812 module.exports = parse;
5813 });
5814
5815 var require$$3$6 = (parseCode && typeof parseCode === 'object' && 'default' in parseCode ? parseCode['default'] : parseCode);
5816
5817 var Proj = createCommonjsModule(function (module) {
5818 var parseCode = require$$3$6;
5819 var extend = require$$0$15;
5820 var projections = require$$1$9;
5821 var deriveConstants = require$$0$13;
5822
5823 function Projection(srsCode,callback) {
5824 if (!(this instanceof Projection)) {
5825 return new Projection(srsCode);
5826 }
5827 callback = callback || function(error){
5828 if(error){
5829 throw error;
5830 }
5831 };
5832 var json = parseCode(srsCode);
5833 if(typeof json !== 'object'){
5834 callback(srsCode);
5835 return;
5836 }
5837 var modifiedJSON = deriveConstants(json);
5838 var ourProj = Projection.projections.get(modifiedJSON.projName);
5839 if(ourProj){
5840 extend(this, modifiedJSON);
5841 extend(this, ourProj);
5842 this.init();
5843 callback(null, this);
5844 }else{
5845 callback(srsCode);
5846 }
5847 }
5848 Projection.projections = projections;
5849 Projection.projections.start();
5850 module.exports = Projection;
5851 });
5852
5853 var require$$1$8 = (Proj && typeof Proj === 'object' && 'default' in Proj ? Proj['default'] : Proj);
5854
5855 var adjust_axis = createCommonjsModule(function (module) {
5856 module.exports = function(crs, denorm, point) {
5857 var xin = point.x,
5858 yin = point.y,
5859 zin = point.z || 0.0;
5860 var v, t, i;
5861 for (i = 0; i < 3; i++) {
5862 if (denorm && i === 2 && point.z === undefined) {
5863 continue;
5864 }
5865 if (i === 0) {
5866 v = xin;
5867 t = 'x';
5868 }
5869 else if (i === 1) {
5870 v = yin;
5871 t = 'y';
5872 }
5873 else {
5874 v = zin;
5875 t = 'z';
5876 }
5877 switch (crs.axis[i]) {
5878 case 'e':
5879 point[t] = v;
5880 break;
5881 case 'w':
5882 point[t] = -v;
5883 break;
5884 case 'n':
5885 point[t] = v;
5886 break;
5887 case 's':
5888 point[t] = -v;
5889 break;
5890 case 'u':
5891 if (point[t] !== undefined) {
5892 point.z = v;
5893 }
5894 break;
5895 case 'd':
5896 if (point[t] !== undefined) {
5897 point.z = -v;
5898 }
5899 break;
5900 default:
5901 //console.log("ERROR: unknow axis ("+crs.axis[i]+") - check definition of "+crs.projName);
5902 return null;
5903 }
5904 }
5905 return point;
5906 };
5907 });
5908
5909 var require$$2$5 = (adjust_axis && typeof adjust_axis === 'object' && 'default' in adjust_axis ? adjust_axis['default'] : adjust_axis);
5910
5911 var datum_transform = createCommonjsModule(function (module) {
5912 var PJD_3PARAM = 1;
5913 var PJD_7PARAM = 2;
5914 var PJD_GRIDSHIFT = 3;
5915 var PJD_NODATUM = 5; // WGS84 or equivalent
5916 var SRS_WGS84_SEMIMAJOR = 6378137; // only used in grid shift transforms
5917 var SRS_WGS84_ESQUARED = 0.006694379990141316; //DGR: 2012-07-29
5918 module.exports = function(source, dest, point) {
5919 var wp, i, l;
5920
5921 function checkParams(fallback) {
5922 return (fallback === PJD_3PARAM || fallback === PJD_7PARAM);
5923 }
5924 // Short cut if the datums are identical.
5925 if (source.compare_datums(dest)) {
5926 return point; // in this case, zero is sucess,
5927 // whereas cs_compare_datums returns 1 to indicate TRUE
5928 // confusing, should fix this
5929 }
5930
5931 // Explicitly skip datum transform by setting 'datum=none' as parameter for either source or dest
5932 if (source.datum_type === PJD_NODATUM || dest.datum_type === PJD_NODATUM) {
5933 return point;
5934 }
5935
5936 //DGR: 2012-07-29 : add nadgrids support (begin)
5937 var src_a = source.a;
5938 var src_es = source.es;
5939
5940 var dst_a = dest.a;
5941 var dst_es = dest.es;
5942
5943 var fallback = source.datum_type;
5944 // If this datum requires grid shifts, then apply it to geodetic coordinates.
5945 if (fallback === PJD_GRIDSHIFT) {
5946 if (this.apply_gridshift(source, 0, point) === 0) {
5947 source.a = SRS_WGS84_SEMIMAJOR;
5948 source.es = SRS_WGS84_ESQUARED;
5949 }
5950 else {
5951 // try 3 or 7 params transformation or nothing ?
5952 if (!source.datum_params) {
5953 source.a = src_a;
5954 source.es = source.es;
5955 return point;
5956 }
5957 wp = 1;
5958 for (i = 0, l = source.datum_params.length; i < l; i++) {
5959 wp *= source.datum_params[i];
5960 }
5961 if (wp === 0) {
5962 source.a = src_a;
5963 source.es = source.es;
5964 return point;
5965 }
5966 if (source.datum_params.length > 3) {
5967 fallback = PJD_7PARAM;
5968 }
5969 else {
5970 fallback = PJD_3PARAM;
5971 }
5972 }
5973 }
5974 if (dest.datum_type === PJD_GRIDSHIFT) {
5975 dest.a = SRS_WGS84_SEMIMAJOR;
5976 dest.es = SRS_WGS84_ESQUARED;
5977 }
5978 // Do we need to go through geocentric coordinates?
5979 if (source.es !== dest.es || source.a !== dest.a || checkParams(fallback) || checkParams(dest.datum_type)) {
5980 //DGR: 2012-07-29 : add nadgrids support (end)
5981 // Convert to geocentric coordinates.
5982 source.geodetic_to_geocentric(point);
5983 // CHECK_RETURN;
5984 // Convert between datums
5985 if (checkParams(source.datum_type)) {
5986 source.geocentric_to_wgs84(point);
5987 // CHECK_RETURN;
5988 }
5989 if (checkParams(dest.datum_type)) {
5990 dest.geocentric_from_wgs84(point);
5991 // CHECK_RETURN;
5992 }
5993 // Convert back to geodetic coordinates
5994 dest.geocentric_to_geodetic(point);
5995 // CHECK_RETURN;
5996 }
5997 // Apply grid shift to destination if required
5998 if (dest.datum_type === PJD_GRIDSHIFT) {
5999 this.apply_gridshift(dest, 1, point);
6000 // CHECK_RETURN;
6001 }
6002
6003 source.a = src_a;
6004 source.es = src_es;
6005 dest.a = dst_a;
6006 dest.es = dst_es;
6007
6008 return point;
6009 };
6010 });
6011
6012 var require$$3$7 = (datum_transform && typeof datum_transform === 'object' && 'default' in datum_transform ? datum_transform['default'] : datum_transform);
6013
6014 var transform = createCommonjsModule(function (module) {
6015 var D2R = 0.01745329251994329577;
6016 var R2D = 57.29577951308232088;
6017 var PJD_3PARAM = 1;
6018 var PJD_7PARAM = 2;
6019 var datum_transform = require$$3$7;
6020 var adjust_axis = require$$2$5;
6021 var proj = require$$1$8;
6022 var toPoint = require$$0$12;
6023 module.exports = function transform(source, dest, point) {
6024 var wgs84;
6025 if (Array.isArray(point)) {
6026 point = toPoint(point);
6027 }
6028 function checkNotWGS(source, dest) {
6029 return ((source.datum.datum_type === PJD_3PARAM || source.datum.datum_type === PJD_7PARAM) && dest.datumCode !== "WGS84");
6030 }
6031
6032 // Workaround for datum shifts towgs84, if either source or destination projection is not wgs84
6033 if (source.datum && dest.datum && (checkNotWGS(source, dest) || checkNotWGS(dest, source))) {
6034 wgs84 = new proj('WGS84');
6035 transform(source, wgs84, point);
6036 source = wgs84;
6037 }
6038 // DGR, 2010/11/12
6039 if (source.axis !== "enu") {
6040 adjust_axis(source, false, point);
6041 }
6042 // Transform source points to long/lat, if they aren't already.
6043 if (source.projName === "longlat") {
6044 point.x *= D2R; // convert degrees to radians
6045 point.y *= D2R;
6046 }
6047 else {
6048 if (source.to_meter) {
6049 point.x *= source.to_meter;
6050 point.y *= source.to_meter;
6051 }
6052 source.inverse(point); // Convert Cartesian to longlat
6053 }
6054 // Adjust for the prime meridian if necessary
6055 if (source.from_greenwich) {
6056 point.x += source.from_greenwich;
6057 }
6058
6059 // Convert datums if needed, and if possible.
6060 point = datum_transform(source.datum, dest.datum, point);
6061
6062 // Adjust for the prime meridian if necessary
6063 if (dest.from_greenwich) {
6064 point.x -= dest.from_greenwich;
6065 }
6066
6067 if (dest.projName === "longlat") {
6068 // convert radians to decimal degrees
6069 point.x *= R2D;
6070 point.y *= R2D;
6071 }
6072 else { // else project
6073 dest.forward(point);
6074 if (dest.to_meter) {
6075 point.x /= dest.to_meter;
6076 point.y /= dest.to_meter;
6077 }
6078 }
6079
6080 // DGR, 2010/11/12
6081 if (dest.axis !== "enu") {
6082 adjust_axis(dest, true, point);
6083 }
6084
6085 return point;
6086 };
6087 });
6088
6089 var require$$0$11 = (transform && typeof transform === 'object' && 'default' in transform ? transform['default'] : transform);
6090
6091 var Point = createCommonjsModule(function (module) {
6092 var mgrs = require$$0$10;
6093
6094 function Point(x, y, z) {
6095 if (!(this instanceof Point)) {
6096 return new Point(x, y, z);
6097 }
6098 if (Array.isArray(x)) {
6099 this.x = x[0];
6100 this.y = x[1];
6101 this.z = x[2] || 0.0;
6102 } else if(typeof x === 'object') {
6103 this.x = x.x;
6104 this.y = x.y;
6105 this.z = x.z || 0.0;
6106 } else if (typeof x === 'string' && typeof y === 'undefined') {
6107 var coords = x.split(',');
6108 this.x = parseFloat(coords[0], 10);
6109 this.y = parseFloat(coords[1], 10);
6110 this.z = parseFloat(coords[2], 10) || 0.0;
6111 } else {
6112 this.x = x;
6113 this.y = y;
6114 this.z = z || 0.0;
6115 }
6116 console.warn('proj4.Point will be removed in version 3, use proj4.toPoint');
6117 }
6118
6119 Point.fromMGRS = function(mgrsStr) {
6120 return new Point(mgrs.toPoint(mgrsStr));
6121 };
6122 Point.prototype.toMGRS = function(accuracy) {
6123 return mgrs.forward([this.x, this.y], accuracy);
6124 };
6125 module.exports = Point;
6126 });
6127
6128 var require$$6$2 = (Point && typeof Point === 'object' && 'default' in Point ? Point['default'] : Point);
6129
6130 var core = createCommonjsModule(function (module) {
6131 var proj = require$$1$8;
6132 var transform = require$$0$11;
6133 var wgs84 = proj('WGS84');
6134
6135 function transformer(from, to, coords) {
6136 var transformedArray;
6137 if (Array.isArray(coords)) {
6138 transformedArray = transform(from, to, coords);
6139 if (coords.length === 3) {
6140 return [transformedArray.x, transformedArray.y, transformedArray.z];
6141 }
6142 else {
6143 return [transformedArray.x, transformedArray.y];
6144 }
6145 }
6146 else {
6147 return transform(from, to, coords);
6148 }
6149 }
6150
6151 function checkProj(item) {
6152 if (item instanceof proj) {
6153 return item;
6154 }
6155 if (item.oProj) {
6156 return item.oProj;
6157 }
6158 return proj(item);
6159 }
6160 function proj4(fromProj, toProj, coord) {
6161 fromProj = checkProj(fromProj);
6162 var single = false;
6163 var obj;
6164 if (typeof toProj === 'undefined') {
6165 toProj = fromProj;
6166 fromProj = wgs84;
6167 single = true;
6168 }
6169 else if (typeof toProj.x !== 'undefined' || Array.isArray(toProj)) {
6170 coord = toProj;
6171 toProj = fromProj;
6172 fromProj = wgs84;
6173 single = true;
6174 }
6175 toProj = checkProj(toProj);
6176 if (coord) {
6177 return transformer(fromProj, toProj, coord);
6178 }
6179 else {
6180 obj = {
6181 forward: function(coords) {
6182 return transformer(fromProj, toProj, coords);
6183 },
6184 inverse: function(coords) {
6185 return transformer(toProj, fromProj, coords);
6186 }
6187 };
6188 if (single) {
6189 obj.oProj = toProj;
6190 }
6191 return obj;
6192 }
6193 }
6194 module.exports = proj4;
6195 });
6196
6197 var require$$8$1 = (core && typeof core === 'object' && 'default' in core ? core['default'] : core);
6198
6199 var index$2 = createCommonjsModule(function (module) {
6200 var proj4 = require$$8$1;
6201 proj4.defaultDatum = 'WGS84'; //default datum
6202 proj4.Proj = require$$1$8;
6203 proj4.WGS84 = new proj4.Proj('WGS84');
6204 proj4.Point = require$$6$2;
6205 proj4.toPoint = require$$0$12;
6206 proj4.defs = require$$2$3;
6207 proj4.transform = require$$0$11;
6208 proj4.mgrs = require$$0$10;
6209 proj4.version = require$$1$7.version;
6210 require$$0$1(proj4);
6211 module.exports = proj4;
6212 });
6213
6214 var require$$0 = (index$2 && typeof index$2 === 'object' && 'default' in index$2 ? index$2['default'] : index$2);
6215
6216 (function(self) {
6217 'use strict';
6218
6219 if (self.fetch) {
6220 return
6221 }
6222
6223 var support = {
6224 searchParams: 'URLSearchParams' in self,
6225 iterable: 'Symbol' in self && 'iterator' in Symbol,
6226 blob: 'FileReader' in self && 'Blob' in self && (function() {
6227 try {
6228 new Blob()
6229 return true
6230 } catch(e) {
6231 return false
6232 }
6233 })(),
6234 formData: 'FormData' in self,
6235 arrayBuffer: 'ArrayBuffer' in self
6236 }
6237
6238 function normalizeName(name) {
6239 if (typeof name !== 'string') {
6240 name = String(name)
6241 }
6242 if (/[^a-z0-9\-#$%&'*+.\^_`|~]/i.test(name)) {
6243 throw new TypeError('Invalid character in header field name')
6244 }
6245 return name.toLowerCase()
6246 }
6247
6248 function normalizeValue(value) {
6249 if (typeof value !== 'string') {
6250 value = String(value)
6251 }
6252 return value
6253 }
6254
6255 // Build a destructive iterator for the value list
6256 function iteratorFor(items) {
6257 var iterator = {
6258 next: function() {
6259 var value = items.shift()
6260 return {done: value === undefined, value: value}
6261 }
6262 }
6263
6264 if (support.iterable) {
6265 iterator[Symbol.iterator] = function() {
6266 return iterator
6267 }
6268 }
6269
6270 return iterator
6271 }
6272
6273 function Headers(headers) {
6274 this.map = {}
6275
6276 if (headers instanceof Headers) {
6277 headers.forEach(function(value, name) {
6278 this.append(name, value)
6279 }, this)
6280
6281 } else if (headers) {
6282 Object.getOwnPropertyNames(headers).forEach(function(name) {
6283 this.append(name, headers[name])
6284 }, this)
6285 }
6286 }
6287
6288 Headers.prototype.append = function(name, value) {
6289 name = normalizeName(name)
6290 value = normalizeValue(value)
6291 var list = this.map[name]
6292 if (!list) {
6293 list = []
6294 this.map[name] = list
6295 }
6296 list.push(value)
6297 }
6298
6299 Headers.prototype['delete'] = function(name) {
6300 delete this.map[normalizeName(name)]
6301 }
6302
6303 Headers.prototype.get = function(name) {
6304 var values = this.map[normalizeName(name)]
6305 return values ? values[0] : null
6306 }
6307
6308 Headers.prototype.getAll = function(name) {
6309 return this.map[normalizeName(name)] || []
6310 }
6311
6312 Headers.prototype.has = function(name) {
6313 return this.map.hasOwnProperty(normalizeName(name))
6314 }
6315
6316 Headers.prototype.set = function(name, value) {
6317 this.map[normalizeName(name)] = [normalizeValue(value)]
6318 }
6319
6320 Headers.prototype.forEach = function(callback, thisArg) {
6321 Object.getOwnPropertyNames(this.map).forEach(function(name) {
6322 this.map[name].forEach(function(value) {
6323 callback.call(thisArg, value, name, this)
6324 }, this)
6325 }, this)
6326 }
6327
6328 Headers.prototype.keys = function() {
6329 var items = []
6330 this.forEach(function(value, name) { items.push(name) })
6331 return iteratorFor(items)
6332 }
6333
6334 Headers.prototype.values = function() {
6335 var items = []
6336 this.forEach(function(value) { items.push(value) })
6337 return iteratorFor(items)
6338 }
6339
6340 Headers.prototype.entries = function() {
6341 var items = []
6342 this.forEach(function(value, name) { items.push([name, value]) })
6343 return iteratorFor(items)
6344 }
6345
6346 if (support.iterable) {
6347 Headers.prototype[Symbol.iterator] = Headers.prototype.entries
6348 }
6349
6350 function consumed(body) {
6351 if (body.bodyUsed) {
6352 return Promise.reject(new TypeError('Already read'))
6353 }
6354 body.bodyUsed = true
6355 }
6356
6357 function fileReaderReady(reader) {
6358 return new Promise(function(resolve, reject) {
6359 reader.onload = function() {
6360 resolve(reader.result)
6361 }
6362 reader.onerror = function() {
6363 reject(reader.error)
6364 }
6365 })
6366 }
6367
6368 function readBlobAsArrayBuffer(blob) {
6369 var reader = new FileReader()
6370 reader.readAsArrayBuffer(blob)
6371 return fileReaderReady(reader)
6372 }
6373
6374 function readBlobAsText(blob) {
6375 var reader = new FileReader()
6376 reader.readAsText(blob)
6377 return fileReaderReady(reader)
6378 }
6379
6380 function Body() {
6381 this.bodyUsed = false
6382
6383 this._initBody = function(body) {
6384 this._bodyInit = body
6385 if (typeof body === 'string') {
6386 this._bodyText = body
6387 } else if (support.blob && Blob.prototype.isPrototypeOf(body)) {
6388 this._bodyBlob = body
6389 } else if (support.formData && FormData.prototype.isPrototypeOf(body)) {
6390 this._bodyFormData = body
6391 } else if (support.searchParams && URLSearchParams.prototype.isPrototypeOf(body)) {
6392 this._bodyText = body.toString()
6393 } else if (!body) {
6394 this._bodyText = ''
6395 } else if (support.arrayBuffer && ArrayBuffer.prototype.isPrototypeOf(body)) {
6396 // Only support ArrayBuffers for POST method.
6397 // Receiving ArrayBuffers happens via Blobs, instead.
6398 } else {
6399 throw new Error('unsupported BodyInit type')
6400 }
6401
6402 if (!this.headers.get('content-type')) {
6403 if (typeof body === 'string') {
6404 this.headers.set('content-type', 'text/plain;charset=UTF-8')
6405 } else if (this._bodyBlob && this._bodyBlob.type) {
6406 this.headers.set('content-type', this._bodyBlob.type)
6407 } else if (support.searchParams && URLSearchParams.prototype.isPrototypeOf(body)) {
6408 this.headers.set('content-type', 'application/x-www-form-urlencoded;charset=UTF-8')
6409 }
6410 }
6411 }
6412
6413 if (support.blob) {
6414 this.blob = function() {
6415 var rejected = consumed(this)
6416 if (rejected) {
6417 return rejected
6418 }
6419
6420 if (this._bodyBlob) {
6421 return Promise.resolve(this._bodyBlob)
6422 } else if (this._bodyFormData) {
6423 throw new Error('could not read FormData body as blob')
6424 } else {
6425 return Promise.resolve(new Blob([this._bodyText]))
6426 }
6427 }
6428
6429 this.arrayBuffer = function() {
6430 return this.blob().then(readBlobAsArrayBuffer)
6431 }
6432
6433 this.text = function() {
6434 var rejected = consumed(this)
6435 if (rejected) {
6436 return rejected
6437 }
6438
6439 if (this._bodyBlob) {
6440 return readBlobAsText(this._bodyBlob)
6441 } else if (this._bodyFormData) {
6442 throw new Error('could not read FormData body as text')
6443 } else {
6444 return Promise.resolve(this._bodyText)
6445 }
6446 }
6447 } else {
6448 this.text = function() {
6449 var rejected = consumed(this)
6450 return rejected ? rejected : Promise.resolve(this._bodyText)
6451 }
6452 }
6453
6454 if (support.formData) {
6455 this.formData = function() {
6456 return this.text().then(decode)
6457 }
6458 }
6459
6460 this.json = function() {
6461 return this.text().then(JSON.parse)
6462 }
6463
6464 return this
6465 }
6466
6467 // HTTP methods whose capitalization should be normalized
6468 var methods = ['DELETE', 'GET', 'HEAD', 'OPTIONS', 'POST', 'PUT']
6469
6470 function normalizeMethod(method) {
6471 var upcased = method.toUpperCase()
6472 return (methods.indexOf(upcased) > -1) ? upcased : method
6473 }
6474
6475 function Request(input, options) {
6476 options = options || {}
6477 var body = options.body
6478 if (Request.prototype.isPrototypeOf(input)) {
6479 if (input.bodyUsed) {
6480 throw new TypeError('Already read')
6481 }
6482 this.url = input.url
6483 this.credentials = input.credentials
6484 if (!options.headers) {
6485 this.headers = new Headers(input.headers)
6486 }
6487 this.method = input.method
6488 this.mode = input.mode
6489 if (!body) {
6490 body = input._bodyInit
6491 input.bodyUsed = true
6492 }
6493 } else {
6494 this.url = input
6495 }
6496
6497 this.credentials = options.credentials || this.credentials || 'omit'
6498 if (options.headers || !this.headers) {
6499 this.headers = new Headers(options.headers)
6500 }
6501 this.method = normalizeMethod(options.method || this.method || 'GET')
6502 this.mode = options.mode || this.mode || null
6503 this.referrer = null
6504
6505 if ((this.method === 'GET' || this.method === 'HEAD') && body) {
6506 throw new TypeError('Body not allowed for GET or HEAD requests')
6507 }
6508 this._initBody(body)
6509 }
6510
6511 Request.prototype.clone = function() {
6512 return new Request(this)
6513 }
6514
6515 function decode(body) {
6516 var form = new FormData()
6517 body.trim().split('&').forEach(function(bytes) {
6518 if (bytes) {
6519 var split = bytes.split('=')
6520 var name = split.shift().replace(/\+/g, ' ')
6521 var value = split.join('=').replace(/\+/g, ' ')
6522 form.append(decodeURIComponent(name), decodeURIComponent(value))
6523 }
6524 })
6525 return form
6526 }
6527
6528 function headers(xhr) {
6529 var head = new Headers()
6530 var pairs = (xhr.getAllResponseHeaders() || '').trim().split('\n')
6531 pairs.forEach(function(header) {
6532 var split = header.trim().split(':')
6533 var key = split.shift().trim()
6534 var value = split.join(':').trim()
6535 head.append(key, value)
6536 })
6537 return head
6538 }
6539
6540 Body.call(Request.prototype)
6541
6542 function Response(bodyInit, options) {
6543 if (!options) {
6544 options = {}
6545 }
6546
6547 this.type = 'default'
6548 this.status = options.status
6549 this.ok = this.status >= 200 && this.status < 300
6550 this.statusText = options.statusText
6551 this.headers = options.headers instanceof Headers ? options.headers : new Headers(options.headers)
6552 this.url = options.url || ''
6553 this._initBody(bodyInit)
6554 }
6555
6556 Body.call(Response.prototype)
6557
6558 Response.prototype.clone = function() {
6559 return new Response(this._bodyInit, {
6560 status: this.status,
6561 statusText: this.statusText,
6562 headers: new Headers(this.headers),
6563 url: this.url
6564 })
6565 }
6566
6567 Response.error = function() {
6568 var response = new Response(null, {status: 0, statusText: ''})
6569 response.type = 'error'
6570 return response
6571 }
6572
6573 var redirectStatuses = [301, 302, 303, 307, 308]
6574
6575 Response.redirect = function(url, status) {
6576 if (redirectStatuses.indexOf(status) === -1) {
6577 throw new RangeError('Invalid status code')
6578 }
6579
6580 return new Response(null, {status: status, headers: {location: url}})
6581 }
6582
6583 self.Headers = Headers
6584 self.Request = Request
6585 self.Response = Response
6586
6587 self.fetch = function(input, init) {
6588 return new Promise(function(resolve, reject) {
6589 var request
6590 if (Request.prototype.isPrototypeOf(input) && !init) {
6591 request = input
6592 } else {
6593 request = new Request(input, init)
6594 }
6595
6596 var xhr = new XMLHttpRequest()
6597
6598 function responseURL() {
6599 if ('responseURL' in xhr) {
6600 return xhr.responseURL
6601 }
6602
6603 // Avoid security warnings on getResponseHeader when not allowed by CORS
6604 if (/^X-Request-URL:/m.test(xhr.getAllResponseHeaders())) {
6605 return xhr.getResponseHeader('X-Request-URL')
6606 }
6607
6608 return
6609 }
6610
6611 xhr.onload = function() {
6612 var options = {
6613 status: xhr.status,
6614 statusText: xhr.statusText,
6615 headers: headers(xhr),
6616 url: responseURL()
6617 }
6618 var body = 'response' in xhr ? xhr.response : xhr.responseText
6619 resolve(new Response(body, options))
6620 }
6621
6622 xhr.onerror = function() {
6623 reject(new TypeError('Network request failed'))
6624 }
6625
6626 xhr.ontimeout = function() {
6627 reject(new TypeError('Network request failed'))
6628 }
6629
6630 xhr.open(request.method, request.url, true)
6631
6632 if (request.credentials === 'include') {
6633 xhr.withCredentials = true
6634 }
6635
6636 if ('responseType' in xhr && support.blob) {
6637 xhr.responseType = 'blob'
6638 }
6639
6640 request.headers.forEach(function(value, name) {
6641 xhr.setRequestHeader(name, value)
6642 })
6643
6644 xhr.send(typeof request._bodyInit === 'undefined' ? null : request._bodyInit)
6645 })
6646 }
6647 self.fetch.polyfill = true
6648 })(typeof self !== 'undefined' ? self : this);
6649
6650 var index = createCommonjsModule(function (module, exports) {
6651 'use strict';
6652
6653 Object.defineProperty(exports, "__esModule", {
6654 value: true
6655 });
6656 exports.get = get;
6657 exports.load = load;
6658 exports.set = set;
6659
6660
6661
6662 var _proj = require$$0;
6663
6664 var _proj2 = _interopRequireDefault(_proj);
6665
6666 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
6667
6668 function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
6669
6670 var ROOT_PREFIX = 'http://www.opengis.net/def/crs/';
6671 var OGC_PREFIX = ROOT_PREFIX + 'OGC/';
6672 var EPSG_PREFIX = ROOT_PREFIX + 'EPSG/0/';
6673
6674 /**
6675 * @typedef {Object} Projection
6676 * @property {function(lonlat: Array<number>): Array<number>} forward
6677 * Transforms a geographic WGS84 [longitude, latitude] coordinate to an [x, y] projection coordinate.
6678 * @property {function(xy: Array<number>): Array<number>} inverse
6679 * Transforms an [x, y] projection coordinate to a geographic WGS84 [longitude, latitude] coordinate.
6680 */
6681
6682 // a cache of URI string -> Projection object mappings
6683 var projCache = {};
6684
6685 // work-arounds for incorrect epsg.io / proj4 behaviour
6686 var needsAxesReordering = _defineProperty({}, EPSG_PREFIX + 4326, true);
6687
6688 // store some built-in projections which are not available on epsg.io
6689 var LONLAT = (0, _proj2.default)('+proj=longlat +datum=WGS84 +no_defs');
6690 set(OGC_PREFIX + '1.3/CRS84', LONLAT);
6691 set(EPSG_PREFIX + 4979, reverseAxes(LONLAT));
6692
6693 /**
6694 * Returns a stored {@link Projection} for a given URI, or {@link undefined} if no {@link Projection} is stored for that URI.
6695 *
6696 * @param {string} crsUri The CRS URI for which to return a {@link Projection}.
6697 * @return {Projection|undefined} A {@link Projection} object, or {@link undefined} if not stored by {@link load} or {@link set}.
6698 *
6699 * @example
6700 * // has to be stored previously via load() or set()
6701 * var proj = uriproj.get('http://www.opengis.net/def/crs/EPSG/0/27700')
6702 * var [longitude, latitude] = [-1.54, 55.5]
6703 * var [easting,northing] = proj.forward([longitude, latitude])
6704 */
6705 function get(crsUri) {
6706 return projCache[crsUri];
6707 }
6708
6709 /**
6710 * Returns a {@link Promise} that succeeds with an already stored {@link Projection} or, if not stored,
6711 * that remotely loads the {@link Projection} (currently using https://epsg.io), stores it, and then succeeds with it.
6712 *
6713 * @param {string} crsUri The CRS URI for which to return a projection.
6714 * @return {Promise<Projection,Error>} A {@link Promise} object succeeding with a {@link Projection} object,
6715 * and failing with an {@link Error} object in case of network or PROJ.4 parsing problems.
6716 *
6717 * @example <caption>Loading a single projection</caption>
6718 * uriproj.load('http://www.opengis.net/def/crs/EPSG/0/27700').then(proj => {
6719 * var [longitude, latitude] = [-1.54, 55.5]
6720 * var [easting,northing] = proj.forward([longitude, latitude])
6721 * })
6722 *
6723 * @example <caption>Loading multiple projections</caption>
6724 * var uris = [
6725 * 'http://www.opengis.net/def/crs/EPSG/0/27700',
6726 * 'http://www.opengis.net/def/crs/EPSG/0/7376',
6727 * 'http://www.opengis.net/def/crs/EPSG/0/7375']
6728 * Promise.all(uris.map(uriproj.load)).then(projs => {
6729 * // all projections are loaded and stored now
6730 *
6731 * // get the first projection
6732 * var proj1 = projs[0]
6733 * // or:
6734 * var proj1 = uriproj.get(uris[0])
6735 * })
6736 *
6737 */
6738 function load(crsUri) {
6739 if (crsUri in projCache) {
6740 return Promise.resolve(projCache[crsUri]);
6741 }
6742
6743 var epsg = crsUriToEPSG(crsUri);
6744 var url = 'https://epsg.io/' + epsg + '.proj4';
6745
6746 return fetch(url).then(function (response) {
6747 if (!response.ok) {
6748 throw new Error('HTTP response code: ' + response.status);
6749 }
6750 return response.text();
6751 }).then(function (proj4string) {
6752 return set(crsUri, proj4string, { reverseAxes: crsUri in needsAxesReordering });
6753 });
6754 }
6755
6756 /**
6757 * Stores a given projection for a given URI that can then be accessed via {@link get} and {@link load}.
6758 *
6759 * @param {string} crsUri The CRS URI for which to store the projection.
6760 * @param {string|Projection} proj A proj4 string or a {@link Projection} object.
6761 * @param {Object} [options] Options object.
6762 * @param {boolean} [options.reverseAxes=false] If proj is a proj4 string, whether to reverse the projection axes.
6763 * @return {Projection} The newly stored projection.
6764 * @throws {Error} If crsUri or proj is missing, or if a PROJ.4 string cannot be parsed by proj4js.
6765 *
6766 * @example <caption>Storing a projection using a PROJ.4 string</caption>
6767 * var uri = 'http://www.opengis.net/def/crs/EPSG/0/27700'
6768 * var proj4 = '+proj=tmerc +lat_0=49 +lon_0=-2 +k=0.9996012717 +x_0=400000 +y_0=-100000 ' +
6769 * '+ellps=airy +towgs84=446.448,-125.157,542.06,0.15,0.247,0.842,-20.489 +units=m +no_defs'
6770 * uriproj.set(uri, proj4)
6771 *
6772 * @example <caption>Storing a projection using a Projection object</caption>
6773 * var uri = 'http://www.opengis.net/def/crs/EPSG/0/27700'
6774 * var proj = {
6775 * forward: ([lon,lat]) => [..., ...],
6776 * inverse: ([x,y]) => [..., ...]
6777 * }
6778 * uriproj.set(uri, proj)
6779 */
6780 function set(crsUri, proj) {
6781 var options = arguments.length <= 2 || arguments[2] === undefined ? {} : arguments[2];
6782
6783 if (!crsUri || !proj) {
6784 throw new Error('crsUri and proj cannot be empty');
6785 }
6786 var projobj = void 0;
6787 if (typeof proj === 'string') {
6788 projobj = (0, _proj2.default)(proj);
6789 if (!projobj) {
6790 throw new Error('Unsupported proj4 string: ' + proj);
6791 }
6792 if (options.reverseAxes) {
6793 projobj = reverseAxes(projobj);
6794 }
6795 } else {
6796 projobj = proj;
6797 }
6798 projCache[crsUri] = projobj;
6799 return projobj;
6800 }
6801
6802 /**
6803 * Return the EPSG code of an OGC CRS URI of the form
6804 * http://www.opengis.net/def/crs/EPSG/0/1234 (would return 1234).
6805 *
6806 * @param {string} crsUri The CRS URI for which to return the EPSG code.
6807 * @return {string} The EPSG code.
6808 */
6809 function crsUriToEPSG(uri) {
6810 var epsg = void 0;
6811 if (uri.indexOf(EPSG_PREFIX) === 0) {
6812 epsg = uri.substr(EPSG_PREFIX.length);
6813 } else {
6814 throw new Error('Unsupported CRS URI: ' + uri);
6815 }
6816
6817 return epsg;
6818 }
6819
6820 /**
6821 * Reverses projection axis order.
6822 *
6823 * For example, a projection with lon, lat axis order is turned into one with lat, lon order.
6824 * This is necessary since geographic projections in proj4 can only be defined with
6825 * lon,lat order, however some CRSs have lat,lon order (like EPSG4326).
6826 * Incorrectly, epsg.io returns a proj4 string (with lon,lat order) even if the CRS
6827 * has lat,lon order. This function manually flips the axis order of a given projection.
6828 * See also `needsAxesReordering` above.
6829 *
6830 * @param {Projection} proj The projection whose axis order to revert.
6831 * @return {Projection} The projection with reversed axis order.
6832 */
6833 function reverseAxes(proj) {
6834 return {
6835 forward: function forward(pos) {
6836 return proj.forward(pos).reverse();
6837 },
6838 inverse: function inverse(pos) {
6839 return proj.inverse([pos[1], pos[0]]);
6840 }
6841 };
6842 }
6843 });
6844
6845 var load = index.load;
6846 var get$1 = index.get;
6847
6848 var _LongitudeAxisIndex;
6849
6850 var OPENGIS_CRS_PREFIX = 'http://www.opengis.net/def/crs/';
6851
6852 /** 3D WGS84 in lat-lon-height order */
6853 var EPSG4979 = OPENGIS_CRS_PREFIX + 'EPSG/0/4979';
6854
6855 /** 2D WGS84 in lat-lon order */
6856 var EPSG4326 = OPENGIS_CRS_PREFIX + 'EPSG/0/4326';
6857
6858 /** 2D WGS84 in lon-lat order */
6859 var CRS84 = OPENGIS_CRS_PREFIX + 'OGC/1.3/CRS84';
6860
6861 /** CRSs in which position is specified by geodetic latitude and longitude */
6862 var GeographicCRSs = [EPSG4979, EPSG4326, CRS84];
6863
6864 /** Position of longitude axis */
6865 var LongitudeAxisIndex = (_LongitudeAxisIndex = {}, defineProperty(_LongitudeAxisIndex, EPSG4979, 1), defineProperty(_LongitudeAxisIndex, EPSG4326, 1), defineProperty(_LongitudeAxisIndex, CRS84, 0), _LongitudeAxisIndex);
6866
6867 /**
6868 * Return the reference system connection object for the given domain coordinate ID,
6869 * or undefined if none exists.
6870 */
6871 function getReferenceObject(domain, coordinateId) {
6872 var ref = domain.referencing.find(function (ref) {
6873 return ref.coordinates.indexOf(coordinateId) !== -1;
6874 });
6875 return ref;
6876 }
6877
6878 /**
6879 * Return the reference system connection object of the horizontal CRS of the domain,
6880 * or ``undefined`` if none found.
6881 * A horizontal CRS is either geodetic (typically ellipsoidal, meaning lat/lon)
6882 * or projected, and may be 2D or 3D (including height).
6883 */
6884 function getHorizontalCRSReferenceObject(domain) {
6885 var isHorizontal = function isHorizontal(ref) {
6886 return ['GeodeticCRS', 'GeographicCRS', 'GeocentricCRS', 'ProjectedCRS'].indexOf(ref.system.type) !== -1;
6887 };
6888 var ref = domain.referencing.find(isHorizontal);
6889 return ref;
6890 }
6891
6892 /**
6893 * Return whether the reference system is a CRS in which
6894 * horizontal position is specified by geodetic latitude and longitude.
6895 */
6896 function isEllipsoidalCRS(rs) {
6897 return rs.type === 'GeographicCRS' || GeographicCRSs.indexOf(rs.id) !== -1;
6898 }
6899
6900 /**
6901 * Return a projection object based on the CRS found in the coverage domain.
6902 * If no CRS is found or it is unsupported, then ``undefined`` is returned.
6903 * For non-built-in projections, this function returns already-cached projections
6904 * that were loaded via {@link loadProjection}.
6905 *
6906 * A projection converts between geodetic lat/lon and projected x/y values.
6907 *
6908 * For lat/lon CRSs the projection is defined such that an input lat/lon
6909 * position gets projected/wrapped to the longitude range used in the domain, for example
6910 * [0,360]. The purpose of this is to make intercomparison between different coverages easier.
6911 *
6912 * The following limitations currently apply:
6913 * - only primitive axes and Tuple/Polygon composite axes are supported for lat/lon CRSs
6914 *
6915 * @param {Domain} domain A coverage domain object.
6916 * @return {IProjection} A stripped-down Leaflet IProjection object.
6917 */
6918 function getProjection(domain) {
6919 var isEllipsoidal = domain.referencing.some(function (ref) {
6920 return isEllipsoidalCRS(ref.system);
6921 });
6922 if (isEllipsoidal) {
6923 return getLonLatProjection(domain);
6924 }
6925
6926 // try to get projection via uriproj library
6927 var ref = getHorizontalCRSReferenceObject(domain);
6928 if (!ref) {
6929 throw new Error('No horizontal CRS found in coverage domain');
6930 }
6931
6932 var uri = ref.system.id;
6933 var proj = get$1(uri);
6934 if (!proj) {
6935 throw new Error('Projection ' + uri + ' not cached in uriproj, use loadProjection() instead');
6936 }
6937 return wrapProj4(proj);
6938 }
6939
6940 /**
6941 * Like {@link getProjection} but will also try to remotely load a projection definition via the uriproj library.
6942 * On success, the loaded projection is automatically cached for later use and can be directly requested
6943 * with {@link getProjection}.
6944 *
6945 * @param {Domain} domain A coverage domain object.
6946 * @return {Promise<IProjection>} A Promise succeeding with a stripped-down Leaflet IProjection object.
6947 */
6948 function loadProjection(domain) {
6949 try {
6950 // we try the local one first so that we get our special lon/lat projection (which doesn't exist in uriproj)
6951 return getProjection(domain);
6952 } catch (e) {}
6953
6954 // try to load projection remotely via uriproj library
6955 var ref = getHorizontalCRSReferenceObject(domain);
6956 if (!ref) {
6957 throw new Error('No horizontal CRS found in coverage domain');
6958 }
6959
6960 var uri = ref.system.id;
6961 return load(uri).then(function (proj) {
6962 return wrapProj4(proj);
6963 });
6964 }
6965
6966 /**
6967 * Return the coordinate IDs of the horizontal CRS of the domain.
6968 *
6969 * @deprecated use getHorizontalCRSCoordinateIDs
6970 * @example
6971 * var [xComp,yComp] = getHorizontalCRSComponents(domain)
6972 */
6973 function getHorizontalCRSComponents(domain) {
6974 return getHorizontalCRSCoordinateIDs(domain);
6975 }
6976
6977 /**
6978 * Return the coordinate IDs of the horizontal CRS of the domain.
6979 *
6980 * @example
6981 * var [xComp,yComp] = getHorizontalCRSCoordinateIDs(domain)
6982 */
6983 function getHorizontalCRSCoordinateIDs(domain) {
6984 var ref = getHorizontalCRSReferenceObject(domain);
6985 return ref.coordinates;
6986 }
6987
6988 /**
6989 * Wraps a proj4 Projection object into an IProjection object.
6990 */
6991 function wrapProj4(proj) {
6992 return {
6993 project: function project(_ref) {
6994 var lon = _ref.lon;
6995 var lat = _ref.lat;
6996
6997 var _proj$forward = proj.forward([lon, lat]);
6998
6999 var _proj$forward2 = slicedToArray(_proj$forward, 2);
7000
7001 var x = _proj$forward2[0];
7002 var y = _proj$forward2[1];
7003
7004 return { x: x, y: y };
7005 },
7006 unproject: function unproject(_ref2) {
7007 var x = _ref2.x;
7008 var y = _ref2.y;
7009
7010 var _proj$inverse = proj.inverse([x, y]);
7011
7012 var _proj$inverse2 = slicedToArray(_proj$inverse, 2);
7013
7014 var lon = _proj$inverse2[0];
7015 var lat = _proj$inverse2[1];
7016
7017 return { lon: lon, lat: lat };
7018 }
7019 };
7020 }
7021
7022 function getLonLatProjection(domain) {
7023 var ref = domain.referencing.find(function (ref) {
7024 return isEllipsoidalCRS(ref.system);
7025 });
7026 var lonIdx = LongitudeAxisIndex[ref.system.id];
7027 if (lonIdx > 1) {
7028 // this should never happen as longitude is always the first or second axis
7029 throw new Error();
7030 }
7031
7032 var lonComponent = ref.coordinates[lonIdx];
7033
7034 // we find the min and max longitude occuring in the domain by inspecting the axis values
7035 // Note: this is inefficient for big composite axes.
7036 // In that case, something like a domain extent might help which has the min/max values for each component.
7037 // TODO handle bounds
7038 var lonMin = void 0,
7039 lonMax = void 0;
7040 if (domain.axes.has(lonComponent)) {
7041 // longitude is a grid axis
7042 var lonAxisName = lonComponent;
7043 var lonAxisVals = domain.axes.get(lonAxisName).values;
7044 lonMin = lonAxisVals[0];
7045 lonMax = lonAxisVals[lonAxisVals.length - 1];
7046 if (lonMin > lonMax) {
7047 var _ref3 = [lonMax, lonMin];
7048 lonMin = _ref3[0];
7049 lonMax = _ref3[1];
7050 }
7051 } else {
7052 // TODO there should be no dependency to CovJSON
7053
7054 // longitude is not a primitive grid axis but a component of a composite axis
7055
7056 // find the composite axis containing the longitude component
7057 var axes = [].concat(toConsumableArray(domain.axes.values()));
7058 var axis = axes.find(function (axis) {
7059 return axis.coordinates.indexOf(lonComponent) !== -1;
7060 });
7061 var lonCompIdx = axis.coordinates.indexOf(lonComponent);
7062
7063 // scan the composite axis for min/max longitude values
7064 lonMin = Infinity;
7065 lonMax = -Infinity;
7066 if (axis.dataType === COVJSON_DATATYPE_TUPLE) {
7067 var _iteratorNormalCompletion = true;
7068 var _didIteratorError = false;
7069 var _iteratorError = undefined;
7070
7071 try {
7072 for (var _iterator = axis.values[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
7073 var tuple = _step.value;
7074
7075 var lon = tuple[lonCompIdx];
7076 lonMin = Math.min(lon, lonMin);
7077 lonMax = Math.max(lon, lonMax);
7078 }
7079 } catch (err) {
7080 _didIteratorError = true;
7081 _iteratorError = err;
7082 } finally {
7083 try {
7084 if (!_iteratorNormalCompletion && _iterator.return) {
7085 _iterator.return();
7086 }
7087 } finally {
7088 if (_didIteratorError) {
7089 throw _iteratorError;
7090 }
7091 }
7092 }
7093 } else if (axis.dataType === COVJSON_DATATYPE_POLYGON) {
7094 var _iteratorNormalCompletion2 = true;
7095 var _didIteratorError2 = false;
7096 var _iteratorError2 = undefined;
7097
7098 try {
7099 for (var _iterator2 = axis.values[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) {
7100 var poly = _step2.value;
7101 var _iteratorNormalCompletion3 = true;
7102 var _didIteratorError3 = false;
7103 var _iteratorError3 = undefined;
7104
7105 try {
7106 for (var _iterator3 = poly[Symbol.iterator](), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) {
7107 var ring = _step3.value;
7108 var _iteratorNormalCompletion4 = true;
7109 var _didIteratorError4 = false;
7110 var _iteratorError4 = undefined;
7111
7112 try {
7113 for (var _iterator4 = ring[Symbol.iterator](), _step4; !(_iteratorNormalCompletion4 = (_step4 = _iterator4.next()).done); _iteratorNormalCompletion4 = true) {
7114 var point = _step4.value;
7115
7116 var _lon = point[lonCompIdx];
7117 lonMin = Math.min(_lon, lonMin);
7118 lonMax = Math.max(_lon, lonMax);
7119 }
7120 } catch (err) {
7121 _didIteratorError4 = true;
7122 _iteratorError4 = err;
7123 } finally {
7124 try {
7125 if (!_iteratorNormalCompletion4 && _iterator4.return) {
7126 _iterator4.return();
7127 }
7128 } finally {
7129 if (_didIteratorError4) {
7130 throw _iteratorError4;
7131 }
7132 }
7133 }
7134 }
7135 } catch (err) {
7136 _didIteratorError3 = true;
7137 _iteratorError3 = err;
7138 } finally {
7139 try {
7140 if (!_iteratorNormalCompletion3 && _iterator3.return) {
7141 _iterator3.return();
7142 }
7143 } finally {
7144 if (_didIteratorError3) {
7145 throw _iteratorError3;
7146 }
7147 }
7148 }
7149 }
7150 } catch (err) {
7151 _didIteratorError2 = true;
7152 _iteratorError2 = err;
7153 } finally {
7154 try {
7155 if (!_iteratorNormalCompletion2 && _iterator2.return) {
7156 _iterator2.return();
7157 }
7158 } finally {
7159 if (_didIteratorError2) {
7160 throw _iteratorError2;
7161 }
7162 }
7163 }
7164 } else {
7165 throw new Error('Unsupported data type: ' + axis.dataType);
7166 }
7167 }
7168
7169 var lonMid = (lonMax + lonMin) / 2;
7170 var lonMinExtended = lonMid - 180;
7171 var lonMaxExtended = lonMid + 180;
7172
7173 return {
7174 project: function project(_ref4) {
7175 var lon = _ref4.lon;
7176 var lat = _ref4.lat;
7177
7178 var lonProjected = void 0;
7179 if (lonMinExtended <= lon && lon <= lonMaxExtended) {
7180 // use unchanged to avoid introducing rounding errors
7181 lonProjected = lon;
7182 } else {
7183 lonProjected = ((lon - lonMinExtended) % 360 + 360) % 360 + lonMinExtended;
7184 }
7185
7186 var _ref5 = lonIdx === 0 ? [lonProjected, lat] : [lat, lonProjected];
7187
7188 var _ref6 = slicedToArray(_ref5, 2);
7189
7190 var x = _ref6[0];
7191 var y = _ref6[1];
7192
7193 return { x: x, y: y };
7194 },
7195 unproject: function unproject(_ref7) {
7196 var x = _ref7.x;
7197 var y = _ref7.y;
7198
7199 var _ref8 = lonIdx === 0 ? [x, y] : [y, x];
7200
7201 var _ref9 = slicedToArray(_ref8, 2);
7202
7203 var lon = _ref9[0];
7204 var lat = _ref9[1];
7205
7206 return { lon: lon, lat: lat };
7207 }
7208 };
7209 }
7210
7211 /**
7212 * Reprojects coordinates from one projection to another.
7213 */
7214 function reprojectCoords(pos, fromProjection, toProjection) {
7215 return toProjection.project(fromProjection.unproject(pos));
7216 }
7217
7218 /**
7219 * Returns a function which converts an arbitrary longitude to the
7220 * longitude extent used in the coverage domain.
7221 * This only supports primitive axes since this is what subsetByValue supports.
7222 * The longitude extent is extended to 360 degrees if the actual extent is smaller.
7223 * The extension is done equally on both sides of the extent.
7224 *
7225 * For example, the domain may have longitudes within [0,360].
7226 * An input longitude of -70 is converted to 290.
7227 * All longitudes within [0,360] are returned unchanged.
7228 *
7229 * If the domain has longitudes within [10,50] then the
7230 * extended longitude range is [-150,210] (-+180 from the middle point).
7231 * An input longitude of -170 is converted to 190.
7232 * All longitudes within [-150,210] are returned unchanged.
7233 *
7234 * @ignore
7235 */
7236 function getLongitudeWrapper(domain, axisName) {
7237 // TODO deprecate this in favour of getProjection, check leaflet-coverage
7238
7239 // for primitive axes, the axis identifier = component identifier
7240 if (!isLongitudeAxis(domain, axisName)) {
7241 throw new Error('\'' + axisName + '\' is not a longitude axis');
7242 }
7243
7244 var vals = domain.axes.get(axisName).values;
7245 var lon_min = vals[0];
7246 var lon_max = vals[vals.length - 1];
7247 if (lon_min > lon_max) {
7248 var _ref10 = [lon_max, lon_min];
7249 lon_min = _ref10[0];
7250 lon_max = _ref10[1];
7251 }
7252
7253 var x_mid = (lon_max + lon_min) / 2;
7254 var x_min = x_mid - 180;
7255 var x_max = x_mid + 180;
7256
7257 return function (lon) {
7258 if (x_min <= lon && lon <= x_max) {
7259 // directly return to avoid introducing rounding errors
7260 return lon;
7261 } else {
7262 return ((lon - x_min) % 360 + 360) % 360 + x_min;
7263 }
7264 };
7265 }
7266
7267 /**
7268 * Return whether the given domain axis represents longitudes.
7269 *
7270 * @ignore
7271 */
7272 function isLongitudeAxis(domain, axisName) {
7273 var ref = getReferenceObject(domain, axisName);
7274 if (!ref) {
7275 return false;
7276 }
7277
7278 var crsId = ref.system.id;
7279 // TODO should support unknown CRSs with embedded axis information
7280 if (GeographicCRSs.indexOf(crsId) === -1) {
7281 // this also covers the case when there is no ID property
7282 return false;
7283 }
7284
7285 var compIdx = ref.coordinates.indexOf(axisName);
7286 var isLongitude = LongitudeAxisIndex[crsId] === compIdx;
7287 return isLongitude;
7288 }
7289
7290 /**
7291 * Returns true if the given axis has ISO8601 date strings
7292 * as axis values.
7293 */
7294 function isISODateAxis(domain, axisName) {
7295 var val = domain.axes.get(axisName).values[0];
7296 if (typeof val !== 'string') {
7297 return false;
7298 }
7299 return !isNaN(new Date(val).getTime());
7300 }
7301
7302 function asTime(inp) {
7303 var res = void 0;
7304 var err = false;
7305 if (typeof inp === 'string') {
7306 res = new Date(inp).getTime();
7307 } else if (inp instanceof Date) {
7308 res = inp.getTime();
7309 } else {
7310 err = true;
7311 }
7312 if (isNaN(res)) {
7313 err = true;
7314 }
7315 if (err) {
7316 throw new Error('Invalid date: ' + inp);
7317 }
7318 return res;
7319 }
7320
7321 /**
7322 * After normalization, all constraints are start,stop,step objects.
7323 * It holds that stop > start, step > 0, start >= 0, stop >= 1.
7324 * For each axis, a constraint exists.
7325 */
7326 function normalizeIndexSubsetConstraints(domain, constraints) {
7327 // check and normalize constraints to simplify code
7328 var normalizedConstraints = {};
7329 for (var axisName in constraints) {
7330 if (!domain.axes.has(axisName)) {
7331 // TODO clarify cov behaviour in the JS API spec
7332 continue;
7333 }
7334 if (constraints[axisName] === undefined || constraints[axisName] === null) {
7335 continue;
7336 }
7337 if (typeof constraints[axisName] === 'number') {
7338 var constraint = constraints[axisName];
7339 normalizedConstraints[axisName] = { start: constraint, stop: constraint + 1 };
7340 } else {
7341 normalizedConstraints[axisName] = constraints[axisName];
7342 }
7343
7344 var _normalizedConstraint = normalizedConstraints[axisName];
7345 var _normalizedConstraint2 = _normalizedConstraint.start;
7346 var start = _normalizedConstraint2 === undefined ? 0 : _normalizedConstraint2;
7347 var _normalizedConstraint3 = _normalizedConstraint.stop;
7348 var stop = _normalizedConstraint3 === undefined ? domain.axes.get(axisName).values.length : _normalizedConstraint3;
7349 var _normalizedConstraint4 = _normalizedConstraint.step;
7350 var step = _normalizedConstraint4 === undefined ? 1 : _normalizedConstraint4;
7351
7352 if (step <= 0) {
7353 throw new Error('Invalid constraint for ' + axisName + ': step=' + step + ' must be > 0');
7354 }
7355 if (start >= stop || start < 0) {
7356 throw new Error('Invalid constraint for ' + axisName + ': stop=' + stop + ' must be > start=' + start + ' and both >= 0');
7357 }
7358 normalizedConstraints[axisName] = { start: start, stop: stop, step: step };
7359 }
7360 var _iteratorNormalCompletion = true;
7361 var _didIteratorError = false;
7362 var _iteratorError = undefined;
7363
7364 try {
7365 for (var _iterator = domain.axes.keys()[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
7366 var _axisName = _step.value;
7367
7368 if (!(_axisName in normalizedConstraints)) {
7369 var len = domain.axes.get(_axisName).values.length;
7370 normalizedConstraints[_axisName] = { start: 0, stop: len, step: 1 };
7371 }
7372 }
7373 } catch (err) {
7374 _didIteratorError = true;
7375 _iteratorError = err;
7376 } finally {
7377 try {
7378 if (!_iteratorNormalCompletion && _iterator.return) {
7379 _iterator.return();
7380 }
7381 } finally {
7382 if (_didIteratorError) {
7383 throw _iteratorError;
7384 }
7385 }
7386 }
7387
7388 return normalizedConstraints;
7389 }
7390
7391 function subsetDomainByIndex(domain, constraints) {
7392 constraints = normalizeIndexSubsetConstraints(domain, constraints);
7393
7394 // subset the axis arrays of the domain (immediately + cached)
7395 var newdomain = {
7396 type: DOMAIN,
7397 domainType: domain.domainType,
7398 axes: new Map(domain.axes),
7399 referencing: domain.referencing
7400 };
7401
7402 var _iteratorNormalCompletion2 = true;
7403 var _didIteratorError2 = false;
7404 var _iteratorError2 = undefined;
7405
7406 try {
7407 var _loop = function _loop() {
7408 var axisName = _step2.value;
7409
7410 var axis = domain.axes.get(axisName);
7411 var coords = axis.values;
7412 var bounds = axis.bounds;
7413 var constraint = constraints[axisName];
7414 var newcoords = void 0;
7415 var newbounds = void 0;
7416
7417 var start = constraint.start;
7418 var stop = constraint.stop;
7419 var step = constraint.step;
7420
7421 if (start === 0 && stop === coords.length && step === 1) {
7422 newcoords = coords;
7423 newbounds = bounds;
7424 } else if (step === 1) {
7425 // TypedArray has subarray which creates a view, while Array has slice which makes a copy
7426 if (coords.subarray) {
7427 newcoords = coords.subarray(start, stop);
7428 } else {
7429 newcoords = coords.slice(start, stop);
7430 }
7431 if (bounds) {
7432 newbounds = {
7433 get: function get(i) {
7434 return bounds.get(start + i);
7435 }
7436 };
7437 }
7438 } else {
7439 var q = Math.trunc((stop - start) / step);
7440 var r = (stop - start) % step;
7441 var len = q + r;
7442 newcoords = new coords.constructor(len); // array or typed array
7443 for (var i = start, j = 0; i < stop; i += step, j++) {
7444 newcoords[j] = coords[i];
7445 }
7446 if (bounds) {
7447 newbounds = {
7448 get: function get(i) {
7449 return bounds.get(start + i * step);
7450 }
7451 };
7452 }
7453 }
7454
7455 var newaxis = {
7456 dataType: axis.dataType,
7457 coordinates: axis.coordinates,
7458 values: newcoords,
7459 bounds: newbounds
7460 };
7461 newdomain.axes.set(axisName, newaxis);
7462 };
7463
7464 for (var _iterator2 = Object.keys(constraints)[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) {
7465 _loop();
7466 }
7467 } catch (err) {
7468 _didIteratorError2 = true;
7469 _iteratorError2 = err;
7470 } finally {
7471 try {
7472 if (!_iteratorNormalCompletion2 && _iterator2.return) {
7473 _iterator2.return();
7474 }
7475 } finally {
7476 if (_didIteratorError2) {
7477 throw _iteratorError2;
7478 }
7479 }
7480 }
7481
7482 return newdomain;
7483 }
7484
7485 /**
7486 * Returns a copy of the grid coverage subsetted to the given bounding box.
7487 *
7488 * Any grid cell is included which intersects with the bounding box.
7489 *
7490 * @param {Coverage} cov A Coverage object with domain Grid.
7491 * @param {array} bbox [xmin,ymin,xmax,ymax] in native CRS coordinates.
7492 * @param {array} [axes=['x','y']] Axis names [x,y].
7493 * @returns {Promise<Coverage>} A promise with a Coverage object as result.
7494 */
7495 function subsetByBbox(cov, bbox) {
7496 var _cov$subsetByValue;
7497
7498 var axes = arguments.length <= 2 || arguments[2] === undefined ? ['x', 'y'] : arguments[2];
7499
7500 var _bbox = slicedToArray(bbox, 4);
7501
7502 var xmin = _bbox[0];
7503 var ymin = _bbox[1];
7504 var xmax = _bbox[2];
7505 var ymax = _bbox[3];
7506
7507 return cov.subsetByValue((_cov$subsetByValue = {}, defineProperty(_cov$subsetByValue, axes[0], { start: xmin, stop: xmax }), defineProperty(_cov$subsetByValue, axes[1], { start: ymin, stop: ymax }), _cov$subsetByValue));
7508 }
7509
7510 /**
7511 * Generic subsetByIndex function that can be used when building new Coverage objects.
7512 *
7513 * @example
7514 * var cov = {
7515 * type: 'Coverage',
7516 * ...
7517 * subsetByIndex: constraints => CovUtils.subsetByIndex(cov, constraints)
7518 * }
7519 */
7520 function subsetByIndex(cov, constraints) {
7521 return cov.loadDomain().then(function (domain) {
7522 constraints = normalizeIndexSubsetConstraints(domain, constraints);
7523 var newdomain = subsetDomainByIndex(domain, constraints);
7524
7525 // subset ranges (on request)
7526 var rangeWrapper = function rangeWrapper(range) {
7527 var newrange = {
7528 dataType: range.dataType,
7529 get: function get(obj) {
7530 // translate subsetted to original indices
7531 var newobj = {};
7532 var _iteratorNormalCompletion = true;
7533 var _didIteratorError = false;
7534 var _iteratorError = undefined;
7535
7536 try {
7537 for (var _iterator = Object.keys(obj)[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
7538 var axisName = _step.value;
7539 var _constraints$axisName = constraints[axisName];
7540 var start = _constraints$axisName.start;
7541 var step = _constraints$axisName.step;
7542
7543 newobj[axisName] = start + obj[axisName] * step;
7544 }
7545 } catch (err) {
7546 _didIteratorError = true;
7547 _iteratorError = err;
7548 } finally {
7549 try {
7550 if (!_iteratorNormalCompletion && _iterator.return) {
7551 _iterator.return();
7552 }
7553 } finally {
7554 if (_didIteratorError) {
7555 throw _iteratorError;
7556 }
7557 }
7558 }
7559
7560 return range.get(newobj);
7561 }
7562 };
7563 newrange.shape = new Map();
7564 var _iteratorNormalCompletion2 = true;
7565 var _didIteratorError2 = false;
7566 var _iteratorError2 = undefined;
7567
7568 try {
7569 for (var _iterator2 = domain.axes.keys()[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) {
7570 var axisName = _step2.value;
7571
7572 var size = newdomain.axes.get(axisName).values.length;
7573 newrange.shape.set(axisName, size);
7574 }
7575 } catch (err) {
7576 _didIteratorError2 = true;
7577 _iteratorError2 = err;
7578 } finally {
7579 try {
7580 if (!_iteratorNormalCompletion2 && _iterator2.return) {
7581 _iterator2.return();
7582 }
7583 } finally {
7584 if (_didIteratorError2) {
7585 throw _iteratorError2;
7586 }
7587 }
7588 }
7589
7590 return newrange;
7591 };
7592
7593 var loadRange = function loadRange(key) {
7594 return cov.loadRange(key).then(rangeWrapper);
7595 };
7596
7597 var loadRanges = function loadRanges(keys) {
7598 return cov.loadRanges(keys).then(function (ranges) {
7599 return new Map([].concat(toConsumableArray(ranges)).map(function (_ref) {
7600 var _ref2 = slicedToArray(_ref, 2);
7601
7602 var key = _ref2[0];
7603 var range = _ref2[1];
7604 return [key, rangeWrapper(range)];
7605 }));
7606 });
7607 };
7608
7609 // assemble everything to a new coverage
7610 var newcov = {
7611 type: COVERAGE,
7612 domainType: cov.domainType,
7613 parameters: cov.parameters,
7614 loadDomain: function loadDomain() {
7615 return Promise.resolve(newdomain);
7616 },
7617 loadRange: loadRange,
7618 loadRanges: loadRanges
7619 };
7620 newcov.subsetByIndex = subsetByIndex.bind(null, newcov);
7621 newcov.subsetByValue = subsetByValue.bind(null, newcov);
7622 return newcov;
7623 });
7624 }
7625
7626 /**
7627 * Generic subsetByValue function that can be used when building new Coverage objects.
7628 * Requires cov.subsetByIndex function.
7629 *
7630 * @example
7631 * var cov = {
7632 * type: 'Coverage',
7633 * ...
7634 * subsetByValue: constraints => CovUtils.subsetByValue(cov, constraints)
7635 * }
7636 */
7637 function subsetByValue(cov, constraints) {
7638 return cov.loadDomain().then(function (domain) {
7639 // calculate indices and use subsetByIndex
7640 var indexConstraints = {};
7641
7642 var _iteratorNormalCompletion3 = true;
7643 var _didIteratorError3 = false;
7644 var _iteratorError3 = undefined;
7645
7646 try {
7647 for (var _iterator3 = Object.keys(constraints)[Symbol.iterator](), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) {
7648 var axisName = _step3.value;
7649
7650 var spec = constraints[axisName];
7651 if (spec === undefined || spec === null || !domain.axes.has(axisName)) {
7652 continue;
7653 }
7654 var axis = domain.axes.get(axisName);
7655 var vals = axis.values;
7656
7657 // special-case handling
7658 var isISODate = isISODateAxis(domain, axisName);
7659 var isLongitude = isLongitudeAxis(domain, axisName);
7660
7661 // wrap input longitudes into longitude range of domain axis
7662 var lonWrapper = isLongitude ? getLongitudeWrapper(domain, axisName) : undefined;
7663
7664 if (typeof spec === 'number' || typeof spec === 'string' || spec instanceof Date) {
7665 var match = spec;
7666 if (isISODate) {
7667 // convert times to numbers before searching
7668 match = asTime(match);
7669 vals = vals.map(function (v) {
7670 return new Date(v).getTime();
7671 });
7672 } else if (isLongitude) {
7673 match = lonWrapper(match);
7674 }
7675 var i = void 0;
7676 // older browsers don't have TypedArray.prototype.indexOf
7677 if (vals.indexOf) {
7678 i = vals.indexOf(match);
7679 } else {
7680 i = Array.prototype.indexOf.call(vals, match);
7681 }
7682 if (i === -1) {
7683 throw new Error('Domain value not found: ' + spec);
7684 }
7685 indexConstraints[axisName] = i;
7686 } else if ('target' in spec) {
7687 // find index of value closest to target
7688 var target = spec.target;
7689 if (isISODate) {
7690 // convert times to numbers before searching
7691 target = asTime(target);
7692 vals = vals.map(function (v) {
7693 return new Date(v).getTime();
7694 });
7695 } else if (isLongitude) {
7696 target = lonWrapper(target);
7697 } else if (typeof vals[0] !== 'number' || typeof target !== 'number') {
7698 throw new Error('Invalid axis or constraint value type');
7699 }
7700 var _i = indexOfNearest(vals, target);
7701 indexConstraints[axisName] = _i;
7702 } else if ('start' in spec && 'stop' in spec) {
7703 // TODO what about bounds?
7704
7705 var start = spec.start;
7706 var stop = spec.stop;
7707
7708 if (isISODate) {
7709 var _ref3 = [asTime(start), asTime(stop)];
7710 // convert times to numbers before searching
7711
7712 start = _ref3[0];
7713 stop = _ref3[1];
7714
7715 vals = vals.map(function (v) {
7716 return new Date(v).getTime();
7717 });
7718 } else if (isLongitude) {
7719 var _ref4 = [lonWrapper(start), lonWrapper(stop)];
7720 start = _ref4[0];
7721 stop = _ref4[1];
7722 } else if (typeof vals[0] !== 'number' || typeof start !== 'number') {
7723 throw new Error('Invalid axis or constraint value type');
7724 }
7725
7726 var _indicesOfNearest = indicesOfNearest(vals, start);
7727
7728 var _indicesOfNearest2 = slicedToArray(_indicesOfNearest, 2);
7729
7730 var lo1 = _indicesOfNearest2[0];
7731 var hi1 = _indicesOfNearest2[1];
7732
7733 var _indicesOfNearest3 = indicesOfNearest(vals, stop);
7734
7735 var _indicesOfNearest4 = slicedToArray(_indicesOfNearest3, 2);
7736
7737 var lo2 = _indicesOfNearest4[0];
7738 var hi2 = _indicesOfNearest4[1];
7739
7740 // cov is a bit arbitrary and may include one or two indices too much
7741 // (but since we don't handle bounds it doesn't matter that much)
7742
7743 var imin = Math.min(lo1, hi1, lo2, hi2);
7744 var imax = Math.max(lo1, hi1, lo2, hi2) + 1; // subsetByIndex is exclusive
7745
7746 indexConstraints[axisName] = { start: imin, stop: imax };
7747 } else {
7748 throw new Error('Invalid subset constraints');
7749 }
7750 }
7751 } catch (err) {
7752 _didIteratorError3 = true;
7753 _iteratorError3 = err;
7754 } finally {
7755 try {
7756 if (!_iteratorNormalCompletion3 && _iterator3.return) {
7757 _iterator3.return();
7758 }
7759 } finally {
7760 if (_didIteratorError3) {
7761 throw _iteratorError3;
7762 }
7763 }
7764 }
7765
7766 return cov.subsetByIndex(indexConstraints);
7767 });
7768 }
7769
7770 /**
7771 * Wraps a Domain into a Coverage object by adding dummy parameter and range data.
7772 *
7773 * @param {Domain} domain the Domain object
7774 * @param {array} [options.gridAxes] The horizontal grid axis names, used for checkerboard pattern.
7775 * @return {Coverage}
7776 */
7777 function fromDomain(domain) {
7778 var options = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];
7779
7780 checkDomain(domain);
7781
7782 var _options$gridAxes = options.gridAxes;
7783 _options$gridAxes = _options$gridAxes === undefined ? ['x', 'y'] : _options$gridAxes;
7784
7785 var _options$gridAxes2 = slicedToArray(_options$gridAxes, 2);
7786
7787 var x = _options$gridAxes2[0];
7788 var y = _options$gridAxes2[1];
7789
7790
7791 var dummyKey = 'domain';
7792 var dummyLabel = 'Domain';
7793
7794 var assumeGrid = domain.axes.has(x) && domain.axes.has(y) && (domain.axes.get(x).values.length > 1 || domain.axes.get(y).values.length > 1);
7795 var categories = void 0;
7796 var categoryEncoding = void 0;
7797 var a = 'a';
7798 var av = 0;
7799 var b = 'b';
7800 var bv = 1;
7801 if (assumeGrid) {
7802 categories = [{
7803 id: a,
7804 label: { en: 'A' }
7805 }, {
7806 id: b,
7807 label: { en: 'B' }
7808 }];
7809 categoryEncoding = new Map([[a, [av]], [b, [bv]]]);
7810 } else {
7811 categories = [{
7812 id: a,
7813 label: { en: 'X' }
7814 }];
7815 categoryEncoding = new Map([[a, [av]]]);
7816 }
7817
7818 var parameters = new Map();
7819 parameters.set(dummyKey, {
7820 key: dummyKey,
7821 observedProperty: {
7822 label: { en: dummyLabel },
7823 categories: categories
7824 },
7825 categoryEncoding: categoryEncoding
7826 });
7827
7828 var shape = new Map([].concat(toConsumableArray(domain.axes)).map(function (_ref) {
7829 var _ref2 = slicedToArray(_ref, 2);
7830
7831 var name = _ref2[0];
7832 var axis = _ref2[1];
7833 return [name, axis.values.length];
7834 }));
7835
7836 var get = void 0;
7837 if (assumeGrid) {
7838 (function () {
7839 // checkerboard pattern to see grid cells
7840 var isOdd = function isOdd(n) {
7841 return n % 2;
7842 };
7843 get = function get(_ref3) {
7844 var _ref3$x = _ref3.x;
7845 var x = _ref3$x === undefined ? 0 : _ref3$x;
7846 var _ref3$y = _ref3.y;
7847 var y = _ref3$y === undefined ? 0 : _ref3$y;
7848 return isOdd(x + y) ? av : bv;
7849 };
7850 })();
7851 } else {
7852 get = function get() {
7853 return av;
7854 };
7855 }
7856
7857 var loadRange = function loadRange() {
7858 return Promise.resolve({
7859 shape: shape,
7860 dataType: 'integer',
7861 get: get
7862 });
7863 };
7864
7865 var cov = {
7866 type: COVERAGE,
7867 domainType: domain.domainType,
7868 parameters: parameters,
7869 loadDomain: function loadDomain() {
7870 return Promise.resolve(domain);
7871 },
7872 loadRange: loadRange
7873 };
7874 addLoadRangesFunction(cov);
7875 addSubsetFunctions(cov);
7876 return cov;
7877 }
7878
7879 /**
7880 * Creates a Coverage with a single parameter from an xndarray object.
7881 *
7882 * @example
7883 * var arr = xndarray(new Float64Array(
7884 * [ 1,2,3,
7885 * 4,5,6 ]), {
7886 * shape: [2,3],
7887 * names: ['y','x'],
7888 * coords: {
7889 * y: [10,12,14],
7890 * x: [100,101,102],
7891 * t: [new Date('2001-01-01')]
7892 * }
7893 * })
7894 * var cov = CovUtils.fromXndarray(arr, {
7895 * parameter: {
7896 * key: 'temperature',
7897 * observedProperty: {
7898 * label: {en: 'Air temperature'}
7899 * },
7900 * unit: { symbol: '°C' }
7901 * }
7902 * })
7903 * let param = cov.parameters.get('temperature')
7904 * let unit = param.unit.symbol // °C
7905 * cov.loadRange('temperature').then(temps => {
7906 * let val = temps.get({x:0, y:1}) // val == 4
7907 * })
7908 *
7909 * @param {xndarray} xndarr - Coordinates must be primitive, not tuples etc.
7910 * @param {object} [options] Options object.
7911 * @param {Parameter} [options.parameter] Specifies the parameter, default parameter has a key of 'p1'.
7912 * @param {string} [options.domainType] A domain type URI.
7913 * @param {Array<object>} [options.referencing] Optional referencing system info,
7914 * defaults to longitude/latitude in WGS84 for x/y axes and ISO8601 time strings for t axis.
7915 * @return {Coverage}
7916 */
7917 function fromXndarray(xndarr) {
7918 var options = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];
7919 var _options$parameter = options.parameter;
7920 var parameter = _options$parameter === undefined ? {
7921 key: 'p1',
7922 observedProperty: {
7923 label: { en: 'Parameter 1' }
7924 }
7925 } : _options$parameter;
7926 var referencing = options.referencing;
7927 var domainType = options.domainType;
7928
7929
7930 var parameters = new Map();
7931 parameters.set(parameter.key, parameter);
7932
7933 // assume lon/lat/ISO time for x/y/t by default, for convenience
7934 if (!referencing) {
7935 referencing = [];
7936 if (xndarr.coords.has('x') && xndarr.coords.has('y')) {
7937 referencing.push({
7938 coordinates: ['x', 'y'],
7939 system: {
7940 type: 'GeographicCRS',
7941 id: 'http://www.opengis.net/def/crs/OGC/1.3/CRS84'
7942 }
7943 });
7944 }
7945 if (xndarr.coords.has('t')) {
7946 referencing.push({
7947 coordinates: ['t'],
7948 system: {
7949 type: 'TemporalRS',
7950 calendar: 'Gregorian'
7951 }
7952 });
7953 }
7954 }
7955
7956 var axes = new Map();
7957 var _iteratorNormalCompletion = true;
7958 var _didIteratorError = false;
7959 var _iteratorError = undefined;
7960
7961 try {
7962 for (var _iterator = xndarr.coords[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
7963 var _step$value = slicedToArray(_step.value, 2);
7964
7965 var axisName = _step$value[0];
7966 var vals1Dnd = _step$value[1];
7967
7968 var values = new Array(vals1Dnd.size);
7969 for (var i = 0; i < vals1Dnd.size; i++) {
7970 values[i] = vals1Dnd.get(i);
7971 }
7972 axes.set(axisName, {
7973 key: axisName,
7974 coordinates: [axisName],
7975 values: values
7976 });
7977 }
7978 } catch (err) {
7979 _didIteratorError = true;
7980 _iteratorError = err;
7981 } finally {
7982 try {
7983 if (!_iteratorNormalCompletion && _iterator.return) {
7984 _iterator.return();
7985 }
7986 } finally {
7987 if (_didIteratorError) {
7988 throw _iteratorError;
7989 }
7990 }
7991 }
7992
7993 var domain = {
7994 type: DOMAIN,
7995 domainType: domainType,
7996 referencing: referencing,
7997 axes: axes
7998 };
7999
8000 var shape = new Map([].concat(toConsumableArray(domain.axes)).map(function (_ref4) {
8001 var _ref5 = slicedToArray(_ref4, 2);
8002
8003 var name = _ref5[0];
8004 var axis = _ref5[1];
8005 return [name, axis.values.length];
8006 }));
8007 var dataType = xndarr.dtype.indexOf('int') !== -1 ? 'integer' : 'float';
8008
8009 var loadRange = function loadRange() {
8010 return Promise.resolve({
8011 shape: shape,
8012 dataType: dataType,
8013 get: xndarr.xget.bind(xndarr)
8014 });
8015 };
8016
8017 var cov = {
8018 type: COVERAGE,
8019 domainType: domainType,
8020 parameters: parameters,
8021 loadDomain: function loadDomain() {
8022 return Promise.resolve(domain);
8023 },
8024 loadRange: loadRange
8025 };
8026 addLoadRangesFunction(cov);
8027 addSubsetFunctions(cov);
8028 return cov;
8029 }
8030
8031 function addSubsetFunctions(cov) {
8032 checkCoverage(cov);
8033 cov.subsetByIndex = subsetByIndex.bind(null, cov);
8034 cov.subsetByValue = subsetByValue.bind(null, cov);
8035 }
8036
8037 function addLoadRangesFunction(cov) {
8038 checkCoverage(cov);
8039 function loadRanges(keys) {
8040 if (!keys) {
8041 keys = cov.parameters.keys();
8042 }
8043 return Promise.all([].concat(toConsumableArray(keys)).map(cov.loadRange)).then(function (ranges) {
8044 return new Map(keys.map(function (key, i) {
8045 return [key, ranges[i]];
8046 }));
8047 });
8048 }
8049 cov.loadRanges = loadRanges;
8050 }
8051
8052 /**
8053 * Shallow clone a given object.
8054 *
8055 * Note: This does *not* handle all kinds of objects!
8056 *
8057 * @ignore
8058 */
8059 function shallowcopy(obj) {
8060 var copy = void 0;
8061 if (obj instanceof Map) {
8062 copy = new Map(obj);
8063 } else {
8064 copy = Object.create(Object.getPrototypeOf(obj));
8065 for (var prop in obj) {
8066 copy[prop] = obj[prop];
8067 }
8068 }
8069 return copy;
8070 }
8071
8072 /**
8073 * Reproject a coverage.
8074 *
8075 * Reprojecting means returning a new coverage where the horizontal CRS is replaced
8076 * and the horizontal domain coordinates are reprojected.
8077 *
8078 * Current limitations:
8079 * - only point-type coverage domains are supported (Tuple only)
8080 * - only horizontal CRSs (2-dimensional) are supported
8081 * - non-lat/lon CRSs have to be pre-cached with loadProjection()
8082 *
8083 * @param {Coverage} cov The Coverage object to reproject.
8084 * @param {Domain} refDomain The reference domain from which the horizontal CRS is used.
8085 * @returns {Promise<Coverage>} A promise with the reprojected Coverage object as result.
8086 */
8087 function reproject(cov, refDomain) {
8088 return cov.loadDomain().then(function (sourceDomain) {
8089 var sourceRef = getHorizontalCRSReferenceObject(sourceDomain);
8090 if (sourceRef.coordinates.length > 2) {
8091 throw new Error('Reprojection not supported for >2D CRSs');
8092 }
8093 // check that the CRS coordinate IDs don't refer to grid axes
8094 if (sourceRef.coordinates.some(sourceDomain.axes.has)) {
8095 throw new Error('Grid reprojection not supported yet');
8096 }
8097
8098 var _sourceRef$coordinate = slicedToArray(sourceRef.coordinates, 2);
8099
8100 var xComp = _sourceRef$coordinate[0];
8101 var yComp = _sourceRef$coordinate[1];
8102
8103 // TODO reproject bounds
8104
8105 // find the composite axis that contains the horizontal coordinates
8106
8107 var axes = [].concat(toConsumableArray(sourceDomain.axes.values()));
8108 var axis = axes.find(function (axis) {
8109 return sourceRef.coordinates.every(function (comp) {
8110 return axis.coordinates.indexOf(comp) !== -1;
8111 });
8112 });
8113 var xCompIdx = axis.coordinates.indexOf(xComp);
8114 var yCompIdx = axis.coordinates.indexOf(yComp);
8115
8116 // find the target CRS and get the projection
8117
8118 var sourceProjection = getProjection(sourceDomain);
8119 var targetProjection = getProjection(refDomain);
8120
8121 // reproject the x/y part of every axis value
8122 // this is done by unprojecting to lon/lat, followed by projecting to the target x/y
8123 var values = void 0;
8124 if (axis.dataType === COVJSON_DATATYPE_TUPLE) {
8125 // make a deep copy of the axis values and replace x,y values by the reprojected ones
8126 values = axis.values.map(function (tuple) {
8127 return tuple.slice();
8128 });
8129 var _iteratorNormalCompletion = true;
8130 var _didIteratorError = false;
8131 var _iteratorError = undefined;
8132
8133 try {
8134 for (var _iterator = values[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
8135 var tuple = _step.value;
8136 var sourceX = tuple[xCompIdx];
8137 var sourceY = tuple[yCompIdx];
8138
8139 var latlon = sourceProjection.unproject({ x: sourceX, y: sourceY });
8140
8141 var _targetProjection$pro = targetProjection.project(latlon);
8142
8143 var x = _targetProjection$pro.x;
8144 var y = _targetProjection$pro.y;
8145
8146 tuple[xCompIdx] = x;
8147 tuple[yCompIdx] = y;
8148 }
8149 } catch (err) {
8150 _didIteratorError = true;
8151 _iteratorError = err;
8152 } finally {
8153 try {
8154 if (!_iteratorNormalCompletion && _iterator.return) {
8155 _iterator.return();
8156 }
8157 } finally {
8158 if (_didIteratorError) {
8159 throw _iteratorError;
8160 }
8161 }
8162 }
8163 } else {
8164 throw new Error('Unsupported data type: ' + axis.dataType);
8165 }
8166
8167 // assemble reprojected coverage
8168 var newAxes = new Map(sourceDomain.axes);
8169 var newAxis = shallowcopy(axis);
8170 delete newAxis.bounds;
8171 newAxis.values = values;
8172 newAxes.set(axis.key, newAxis);
8173
8174 var targetRef = getHorizontalCRSReferenceObject(refDomain);
8175 if (targetRef.coordinates.length > 2) {
8176 throw new Error('Reprojection not supported for >2D CRSs');
8177 }
8178 var newReferencing = sourceDomain.referencing.map(function (ref) {
8179 if (ref === sourceRef) {
8180 return {
8181 coordinates: sourceRef.coordinates,
8182 system: targetRef.system
8183 };
8184 } else {
8185 return ref;
8186 }
8187 });
8188
8189 var newDomain = {
8190 type: DOMAIN,
8191 domainType: sourceDomain.domainType,
8192 axes: newAxes,
8193 referencing: newReferencing
8194 };
8195
8196 var newCoverage = {
8197 type: COVERAGE,
8198 domainType: cov.domainType,
8199 parameters: cov.parameters,
8200 loadDomain: function loadDomain() {
8201 return Promise.resolve(newDomain);
8202 },
8203 loadRange: function loadRange(paramKey) {
8204 return cov.loadRange(paramKey);
8205 },
8206 loadRanges: function loadRanges(paramKeys) {
8207 return cov.loadRanges(paramKeys);
8208 },
8209 subsetByIndex: function subsetByIndex(constraints) {
8210 return cov.subsetByIndex(constraints).then(function (sub) {
8211 return reproject(sub, refDomain);
8212 });
8213 },
8214 subsetByValue: function subsetByValue(constraints) {
8215 return cov.subsetByValue(constraints).then(function (sub) {
8216 return reproject(sub, refDomain);
8217 });
8218 }
8219 };
8220 return newCoverage;
8221 });
8222 }
8223
8224 /**
8225 * Returns a copy of the given Coverage object with the parameters
8226 * replaced by the supplied ones.
8227 *
8228 * Note that this is a low-level function and no checks are done on the supplied parameters.
8229 */
8230 function withParameters(cov, params) {
8231 var newcov = {
8232 type: COVERAGE,
8233 domainType: cov.domainType,
8234 parameters: params,
8235 loadDomain: function loadDomain() {
8236 return cov.loadDomain();
8237 },
8238 loadRange: function loadRange(key) {
8239 return cov.loadRange(key);
8240 },
8241 loadRanges: function loadRanges(keys) {
8242 return cov.loadRanges(keys);
8243 },
8244 subsetByIndex: function subsetByIndex(constraints) {
8245 return cov.subsetByIndex(constraints).then(function (sub) {
8246 return withParameters(sub, params);
8247 });
8248 },
8249 subsetByValue: function subsetByValue(constraints) {
8250 return cov.subsetByValue(constraints).then(function (sub) {
8251 return withParameters(sub, params);
8252 });
8253 }
8254 };
8255 return newcov;
8256 }
8257
8258 /**
8259 * Returns a copy of the given Coverage object with the categories
8260 * of a given parameter replaced by the supplied ones and the encoding
8261 * adapted to the given mapping from old to new.
8262 *
8263 * @param {Coverage} cov The Coverage object.
8264 * @param {String} key The key of the parameter to work with.
8265 * @param {object} observedProperty The new observed property including the new array of category objects
8266 * that will be part of the returned coverage.
8267 * @param {Map<String,String>} mapping A mapping from source category id to destination category id.
8268 * @returns {Coverage}
8269 */
8270 function withCategories(cov, key, observedProperty, mapping) {
8271 /* check breaks with Babel, see https://github.com/jspm/jspm-cli/issues/1348
8272 if (!(mapping instanceof Map)) {
8273 throw new Error('mapping parameter must be a Map from/to category ID')
8274 }
8275 */
8276 checkCoverage(cov);
8277 if (observedProperty.categories.some(function (c) {
8278 return !c.id;
8279 })) {
8280 throw new Error('At least one category object is missing the "id" property');
8281 }
8282 var newparams = shallowcopy(cov.parameters);
8283 var newparam = shallowcopy(newparams.get(key));
8284 newparams.set(key, newparam);
8285 newparams.get(key).observedProperty = observedProperty;
8286
8287 var fromCatEnc = cov.parameters.get(key).categoryEncoding;
8288 var catEncoding = new Map();
8289 var categories = observedProperty.categories;
8290 var _iteratorNormalCompletion = true;
8291 var _didIteratorError = false;
8292 var _iteratorError = undefined;
8293
8294 try {
8295 for (var _iterator = categories[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
8296 var category = _step.value;
8297
8298 var vals = [];
8299 var _iteratorNormalCompletion2 = true;
8300 var _didIteratorError2 = false;
8301 var _iteratorError2 = undefined;
8302
8303 try {
8304 for (var _iterator2 = mapping[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) {
8305 var _step2$value = slicedToArray(_step2.value, 2);
8306
8307 var fromCatId = _step2$value[0];
8308 var toCatId = _step2$value[1];
8309
8310 if (toCatId === category.id && fromCatEnc.has(fromCatId)) {
8311 vals.push.apply(vals, toConsumableArray(fromCatEnc.get(fromCatId)));
8312 }
8313 }
8314 } catch (err) {
8315 _didIteratorError2 = true;
8316 _iteratorError2 = err;
8317 } finally {
8318 try {
8319 if (!_iteratorNormalCompletion2 && _iterator2.return) {
8320 _iterator2.return();
8321 }
8322 } finally {
8323 if (_didIteratorError2) {
8324 throw _iteratorError2;
8325 }
8326 }
8327 }
8328
8329 if (vals.length > 0) {
8330 catEncoding.set(category.id, vals);
8331 }
8332 }
8333 } catch (err) {
8334 _didIteratorError = true;
8335 _iteratorError = err;
8336 } finally {
8337 try {
8338 if (!_iteratorNormalCompletion && _iterator.return) {
8339 _iterator.return();
8340 }
8341 } finally {
8342 if (_didIteratorError) {
8343 throw _iteratorError;
8344 }
8345 }
8346 }
8347
8348 newparams.get(key).categoryEncoding = catEncoding;
8349
8350 var newcov = withParameters(cov, newparams);
8351 return newcov;
8352 }
8353
8354 /**
8355 * Returns a new coverage where the domainType field of the coverage and the domain
8356 * is set to the given one.
8357 *
8358 * @param {Coverage} cov The Coverage object.
8359 * @param {String} domainType The new domain type.
8360 * @returns {Coverage}
8361 */
8362 function withDomainType(cov, domainType) {
8363 checkCoverage(cov);
8364
8365 var domainWrapper = function domainWrapper(domain) {
8366 var newdomain = {
8367 type: DOMAIN,
8368 domainType: domainType,
8369 axes: domain.axes,
8370 referencing: domain.referencing
8371 };
8372 return newdomain;
8373 };
8374
8375 var newcov = {
8376 type: COVERAGE,
8377 domainType: domainType,
8378 parameters: cov.parameters,
8379 loadDomain: function loadDomain() {
8380 return cov.loadDomain().then(domainWrapper);
8381 },
8382 loadRange: function loadRange(key) {
8383 return cov.loadRange(key);
8384 },
8385 loadRanges: function loadRanges(keys) {
8386 return cov.loadRanges(keys);
8387 },
8388 subsetByIndex: function subsetByIndex(constraints) {
8389 return cov.subsetByIndex(constraints).then(function (sub) {
8390 return withDomainType(sub, domainType);
8391 });
8392 },
8393 subsetByValue: function subsetByValue(constraints) {
8394 return cov.subsetByValue(constraints).then(function (sub) {
8395 return withDomainType(sub, domainType);
8396 });
8397 }
8398 };
8399 return newcov;
8400 }
8401
8402 /**
8403 * Tries to transform the given Coverage object into a new one that
8404 * conforms to one of the CovJSON domain types.
8405 * If multiple domain types match, then the "smaller" one is preferred,
8406 * for example, Point instead of Grid.
8407 *
8408 * The transformation consists of:
8409 * - Setting domainType in coverage and domain object
8410 * - Renaming domain axes
8411 *
8412 * @see https://github.com/Reading-eScience-Centre/coveragejson/blob/master/domain-types.md
8413 *
8414 * @param {Coverage} cov The Coverage object.
8415 * @returns {Promise<Coverage>}
8416 * A Promise succeeding with the transformed coverage,
8417 * or failing if no CovJSON domain type matched the input coverage.
8418 */
8419 function asCovJSONDomainType(cov) {
8420 return cov.loadDomain().then(function (domain) {
8421
8422 // TODO implement me
8423
8424 });
8425 }
8426
8427 /**
8428 * @example
8429 * var cov = ...
8430 * var mapping = new Map()
8431 * mapping.set('lat', 'y').set('lon', 'x')
8432 * var newcov = CovUtils.renameAxes(cov, mapping)
8433 *
8434 * @param {Coverage} cov The coverage.
8435 * @param {Map<String,String>} mapping
8436 * @returns {Coverage}
8437 */
8438 function renameAxes(cov, mapping) {
8439 checkCoverage(cov);
8440 mapping = new Map(mapping);
8441 var _iteratorNormalCompletion3 = true;
8442 var _didIteratorError3 = false;
8443 var _iteratorError3 = undefined;
8444
8445 try {
8446 for (var _iterator3 = cov.axes.keys()[Symbol.iterator](), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) {
8447 var axisName = _step3.value;
8448
8449 if (!mapping.has(axisName)) {
8450 mapping.set(axisName, axisName);
8451 }
8452 }
8453 } catch (err) {
8454 _didIteratorError3 = true;
8455 _iteratorError3 = err;
8456 } finally {
8457 try {
8458 if (!_iteratorNormalCompletion3 && _iterator3.return) {
8459 _iterator3.return();
8460 }
8461 } finally {
8462 if (_didIteratorError3) {
8463 throw _iteratorError3;
8464 }
8465 }
8466 }
8467
8468 var domainWrapper = function domainWrapper(domain) {
8469 var newaxes = new Map();
8470 var _iteratorNormalCompletion4 = true;
8471 var _didIteratorError4 = false;
8472 var _iteratorError4 = undefined;
8473
8474 try {
8475 for (var _iterator4 = mapping[Symbol.iterator](), _step4; !(_iteratorNormalCompletion4 = (_step4 = _iterator4.next()).done); _iteratorNormalCompletion4 = true) {
8476 var _step4$value = slicedToArray(_step4.value, 2);
8477
8478 var from = _step4$value[0];
8479 var to = _step4$value[1];
8480
8481 var _domain$axes$get = domain.axes.get(from);
8482
8483 var dataType = _domain$axes$get.dataType;
8484 var coordinates = _domain$axes$get.coordinates;
8485 var values = _domain$axes$get.values;
8486 var bounds = _domain$axes$get.bounds;
8487
8488 var newaxis = {
8489 key: to,
8490 dataType: dataType,
8491 coordinates: coordinates.map(function (c) {
8492 return mapping.has(c) ? mapping.get(c) : c;
8493 }),
8494 values: values,
8495 bounds: bounds
8496 };
8497 newaxes.set(to, newaxis);
8498 }
8499 } catch (err) {
8500 _didIteratorError4 = true;
8501 _iteratorError4 = err;
8502 } finally {
8503 try {
8504 if (!_iteratorNormalCompletion4 && _iterator4.return) {
8505 _iterator4.return();
8506 }
8507 } finally {
8508 if (_didIteratorError4) {
8509 throw _iteratorError4;
8510 }
8511 }
8512 }
8513
8514 var newreferencing = domain.referencing.map(function (_ref) {
8515 var coordinates = _ref.coordinates;
8516 var system = _ref.system;
8517 return {
8518 coordinates: coordinates.map(function (c) {
8519 return mapping.has(c) ? mapping.get(c) : c;
8520 }),
8521 system: system
8522 };
8523 });
8524
8525 var newdomain = {
8526 type: DOMAIN,
8527 domainType: domain.domainType,
8528 axes: newaxes,
8529 referencing: newreferencing
8530 };
8531 return newdomain;
8532 };
8533
8534 // pre-compile for efficiency
8535 // get({['lat']: obj['y'], ['lon']: obj['x']})
8536 var getObjStr = [].concat(toConsumableArray(mapping)).map(function (_ref2) {
8537 var _ref3 = slicedToArray(_ref2, 2);
8538
8539 var from = _ref3[0];
8540 var to = _ref3[1];
8541 return '[\'' + from + '\']:obj[\'' + to + '\']';
8542 }).join(',');
8543
8544 var rangeWrapper = function rangeWrapper(range) {
8545 var get = new Function('range', 'return function get (obj){return range.get({' + getObjStr + '})}')(range); // eslint-disable-line
8546 var newrange = {
8547 shape: new Map([].concat(toConsumableArray(range.shape)).map(function (_ref4) {
8548 var _ref5 = slicedToArray(_ref4, 2);
8549
8550 var name = _ref5[0];
8551 var len = _ref5[1];
8552 return [mapping.get(name), len];
8553 })),
8554 dataType: range.dataType,
8555 get: get
8556 };
8557 return newrange;
8558 };
8559
8560 var loadRange = function loadRange(paramKey) {
8561 return cov.loadRange(paramKey).then(rangeWrapper);
8562 };
8563
8564 var loadRanges = function loadRanges(paramKeys) {
8565 return cov.loadRanges(paramKeys).then(function (ranges) {
8566 return new Map([].concat(toConsumableArray(ranges)).map(function (_ref6) {
8567 var _ref7 = slicedToArray(_ref6, 2);
8568
8569 var paramKey = _ref7[0];
8570 var range = _ref7[1];
8571 return [paramKey, rangeWrapper(range)];
8572 }));
8573 });
8574 };
8575
8576 var newcov = {
8577 type: COVERAGE,
8578 domainType: cov.domainType,
8579 parameters: cov.parameters,
8580 loadDomain: function loadDomain() {
8581 return cov.loadDomain().then(domainWrapper);
8582 },
8583 loadRange: loadRange,
8584 loadRanges: loadRanges,
8585 subsetByIndex: function subsetByIndex(constraints) {
8586 return cov.subsetByIndex(constraints).then(function (sub) {
8587 return renameAxes(sub, mapping);
8588 });
8589 },
8590 subsetByValue: function subsetByValue(constraints) {
8591 return cov.subsetByValue(constraints).then(function (sub) {
8592 return renameAxes(sub, mapping);
8593 });
8594 }
8595 };
8596
8597 return newcov;
8598 }
8599
8600 /**
8601 * @param {Coverage} cov The coverage.
8602 * @param {String} key The key of the parameter for which the mapping should be applied.
8603 * @param {Function} fn A function getting called as fn(obj, range) where obj is the axis indices object
8604 * and range is the original range object.
8605 * @param {String} [dataType] The new data type to use for the range. If omitted, the original type is used.
8606 * @returns {Coverage}
8607 */
8608 function mapRange(cov, key, fn, dataType) {
8609 checkCoverage(cov);
8610
8611 var rangeWrapper = function rangeWrapper(range) {
8612 var newrange = {
8613 shape: range.shape,
8614 dataType: dataType || range.dataType,
8615 get: function get(obj) {
8616 return fn(obj, range);
8617 }
8618 };
8619 return newrange;
8620 };
8621
8622 var loadRange = function loadRange(paramKey) {
8623 return key === paramKey ? cov.loadRange(paramKey).then(rangeWrapper) : cov.loadRange(paramKey);
8624 };
8625
8626 var loadRanges = function loadRanges(paramKeys) {
8627 return cov.loadRanges(paramKeys).then(function (ranges) {
8628 return new Map([].concat(toConsumableArray(ranges)).map(function (_ref8) {
8629 var _ref9 = slicedToArray(_ref8, 2);
8630
8631 var paramKey = _ref9[0];
8632 var range = _ref9[1];
8633 return [paramKey, key === paramKey ? rangeWrapper(range) : range];
8634 }));
8635 });
8636 };
8637
8638 var newcov = {
8639 type: COVERAGE,
8640 domainType: cov.domainType,
8641 parameters: cov.parameters,
8642 loadDomain: function loadDomain() {
8643 return cov.loadDomain();
8644 },
8645 loadRange: loadRange,
8646 loadRanges: loadRanges,
8647 subsetByIndex: function subsetByIndex(constraints) {
8648 return cov.subsetByIndex(constraints).then(function (sub) {
8649 return mapRange(sub, key, fn, dataType);
8650 });
8651 },
8652 subsetByValue: function subsetByValue(constraints) {
8653 return cov.subsetByValue(constraints).then(function (sub) {
8654 return mapRange(sub, key, fn, dataType);
8655 });
8656 }
8657 };
8658
8659 return newcov;
8660 }
8661
8662 /**
8663 *
8664 * @example
8665 * var cov = ... // has parameters 'NIR', 'red', 'green', 'blue'
8666 * var newcov = CovUtils.withDerivedParameter(cov, {
8667 * parameter: {
8668 * key: 'NDVI',
8669 * observedProperty: {
8670 * label: { en: 'Normalized Differenced Vegetation Index' }
8671 * }
8672 * },
8673 * inputParameters: ['NIR','red'],
8674 * dataType: 'float',
8675 * fn: function (obj, nirRange, redRange) {
8676 * var nir = nirRange.get(obj)
8677 * var red = redRange.get(obj)
8678 * if (nir === null || red === null) return null
8679 * return (nir - red) / (nir + red)
8680 * }
8681 * })
8682 */
8683 function withDerivedParameter(cov, options) {
8684 checkCoverage(cov);
8685 var parameter = options.parameter;
8686 var inputParameters = options.inputParameters;
8687 var _options$dataType = options.dataType;
8688 var dataType = _options$dataType === undefined ? 'float' : _options$dataType;
8689 var fn = options.fn;
8690
8691
8692 var parameters = new Map(cov.parameters);
8693 parameters.set(parameter.key, parameter);
8694
8695 var loadDerivedRange = function loadDerivedRange() {
8696 return cov.loadRanges(inputParameters).then(function (inputRanges) {
8697 var inputRangesArr = inputParameters.map(function (key) {
8698 return inputRanges.get(key);
8699 });
8700 var shape = inputRangesArr[0].shape;
8701 var range = {
8702 shape: shape,
8703 dataType: dataType,
8704 get: function get(obj) {
8705 return fn.apply(undefined, [obj].concat(toConsumableArray(inputRangesArr)));
8706 }
8707 };
8708 return range;
8709 });
8710 };
8711
8712 var loadRange = function loadRange(paramKey) {
8713 return parameter.key === paramKey ? loadDerivedRange() : cov.loadRange(paramKey);
8714 };
8715
8716 var newcov = {
8717 type: COVERAGE,
8718 domainType: cov.domainType,
8719 parameters: parameters,
8720 loadDomain: function loadDomain() {
8721 return cov.loadDomain();
8722 },
8723 loadRange: loadRange,
8724 subsetByIndex: function subsetByIndex(constraints) {
8725 return cov.subsetByIndex(constraints).then(function (sub) {
8726 return withDerivedParameter(sub, options);
8727 });
8728 },
8729 subsetByValue: function subsetByValue(constraints) {
8730 return cov.subsetByValue(constraints).then(function (sub) {
8731 return withDerivedParameter(sub, options);
8732 });
8733 }
8734 };
8735 addLoadRangesFunction(newcov);
8736
8737 return newcov;
8738 }
8739
8740 /**
8741 *
8742 * @example
8743 * var cov = ... // has parameters 'NIR', 'red', 'green', 'blue'
8744 * var newcov = CovUtils.withSimpleDerivedParameter(cov, {
8745 * parameter: {
8746 * key: 'NDVI',
8747 * observedProperty: {
8748 * label: { en: 'Normalized Differenced Vegetation Index' }
8749 * }
8750 * },
8751 * inputParameters: ['NIR','red'],
8752 * dataType: 'float',
8753 * fn: function (nir, red) {
8754 * return (nir - red) / (nir + red)
8755 * }
8756 * })
8757 */
8758 function withSimpleDerivedParameter(cov, options) {
8759 var parameter = options.parameter;
8760 var inputParameters = options.inputParameters;
8761 var dataType = options.dataType;
8762 var _fn = options.fn;
8763
8764 var options_ = {
8765 parameter: parameter,
8766 inputParameters: inputParameters,
8767 dataType: dataType,
8768 // TODO pre-compile if too slow
8769 fn: function fn(obj) {
8770 for (var _len = arguments.length, ranges = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
8771 ranges[_key - 1] = arguments[_key];
8772 }
8773
8774 var vals = inputParameters.map(function (_, i) {
8775 return ranges[i].get(obj);
8776 });
8777 if (vals.some(function (val) {
8778 return val === null;
8779 })) {
8780 return null;
8781 }
8782 return _fn.apply(undefined, toConsumableArray(vals));
8783 }
8784 };
8785 return withDerivedParameter(cov, options_);
8786 }
8787
8788 /**
8789 * Adds a basic query() function to the coverage collection object.
8790 * Note that this does not support paging.
8791 */
8792 function addCollectionQueryFunction(collection) {
8793 if (collection.paging) {
8794 throw new Error('Paged collections not supported');
8795 }
8796 collection.query = function () {
8797 return new CollectionQuery(collection);
8798 };
8799 }
8800
8801 var CollectionQuery = function () {
8802 /**
8803 * @param {CoverageCollection} collection
8804 */
8805
8806 function CollectionQuery(collection) {
8807 classCallCheck(this, CollectionQuery);
8808
8809 this._collection = collection;
8810 this._filter = {};
8811 this._subset = {};
8812 }
8813
8814 /**
8815 * Matching mode: intersect
8816 *
8817 * Supports ISO8601 date string axes.
8818 * All other string-type axes are compared alphabetically.
8819 *
8820 * @example
8821 * collection.query().filter({
8822 * 't': {start: '2015-01-01T01:00:00', stop: '2015-01-01T02:00:00'}
8823 * }).execute().then(filteredCollection => {
8824 * console.log(filteredCollection.coverages.length)
8825 * })
8826 * @param {Object} spec
8827 * @return {CollectionQuery}
8828 */
8829
8830
8831 createClass(CollectionQuery, [{
8832 key: 'filter',
8833 value: function filter(spec) {
8834 mergeInto(spec, this._filter);
8835 return this;
8836 }
8837
8838 /**
8839 * Subset coverages by domain values.
8840 *
8841 * Equivalent to calling {@link Coverage.subsetByValue}(spec) on each
8842 * coverage in the collection.
8843 *
8844 * @param {Object} spec
8845 * @return {CollectionQuery}
8846 */
8847
8848 }, {
8849 key: 'subset',
8850 value: function subset(spec) {
8851 mergeInto(spec, this._subset);
8852 return this;
8853 }
8854
8855 /**
8856 * Applies the query operators and returns
8857 * a Promise that succeeds with a new CoverageCollection.
8858 *
8859 * @return {Promise<CoverageCollection>}
8860 */
8861
8862 }, {
8863 key: 'execute',
8864 value: function execute() {
8865 var _this = this;
8866
8867 var coll = this._collection;
8868 var newcoll = {
8869 type: COVERAGECOLLECTION,
8870 coverages: [],
8871 parameters: coll.parameters,
8872 domainType: coll.domainType
8873 };
8874
8875 var promises = [];
8876 var _iteratorNormalCompletion = true;
8877 var _didIteratorError = false;
8878 var _iteratorError = undefined;
8879
8880 try {
8881 var _loop = function _loop() {
8882 var cov = _step.value;
8883
8884 promises.push(cov.loadDomain().then(function (domain) {
8885 if (!matchesFilter(domain, _this._filter)) {
8886 return;
8887 }
8888
8889 if (Object.keys(_this._subset).length === 0) {
8890 newcoll.coverages.push(cov);
8891 } else {
8892 return cov.subsetByValue(_this._subset).then(function (subsetted) {
8893 newcoll.coverages.push(subsetted);
8894 });
8895 }
8896 }));
8897 };
8898
8899 for (var _iterator = coll.coverages[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
8900 _loop();
8901 }
8902 } catch (err) {
8903 _didIteratorError = true;
8904 _iteratorError = err;
8905 } finally {
8906 try {
8907 if (!_iteratorNormalCompletion && _iterator.return) {
8908 _iterator.return();
8909 }
8910 } finally {
8911 if (_didIteratorError) {
8912 throw _iteratorError;
8913 }
8914 }
8915 }
8916
8917 return Promise.all(promises).then(function () {
8918 newcoll.query = function () {
8919 return new CollectionQuery(newcoll);
8920 };
8921 return newcoll;
8922 });
8923 }
8924 }]);
8925 return CollectionQuery;
8926 }();
8927
8928 function matchesFilter(domain, filter) {
8929 var _iteratorNormalCompletion2 = true;
8930 var _didIteratorError2 = false;
8931 var _iteratorError2 = undefined;
8932
8933 try {
8934 for (var _iterator2 = Object.keys(filter)[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) {
8935 var axisName = _step2.value;
8936
8937 var condition = filter[axisName];
8938 if (!domain.axes.has(axisName)) {
8939 throw new Error('Axis "' + axisName + '" does not exist');
8940 }
8941 var axis = domain.axes.get(axisName);
8942 var vals = axis.values;
8943
8944 var min = vals[0];
8945 var max = vals[vals.length - 1];
8946
8947 if (typeof min !== 'number' && typeof min !== 'string') {
8948 throw new Error('Can only filter primitive axis values');
8949 }
8950 var start = condition.start;
8951 var stop = condition.stop;
8952
8953 // special handling
8954
8955 if (isISODateAxis(domain, axisName)) {
8956 var _ref = [asTime(min), asTime(max)];
8957 min = _ref[0];
8958 max = _ref[1];
8959 var _ref2 = [asTime(start), asTime(stop)];
8960 start = _ref2[0];
8961 stop = _ref2[1];
8962 } else if (isLongitudeAxis(domain, axisName)) {
8963 var lonWrapper = getLongitudeWrapper(domain, axisName);var _ref3 = [lonWrapper(start), lonWrapper(stop)];
8964 start = _ref3[0];
8965 stop = _ref3[1];
8966 }
8967
8968 if (min > max) {
8969 var _ref4 = [max, min];
8970 min = _ref4[0];
8971 max = _ref4[1];
8972 }
8973 if (max < start || stop < min) {
8974 return false;
8975 }
8976 }
8977 } catch (err) {
8978 _didIteratorError2 = true;
8979 _iteratorError2 = err;
8980 } finally {
8981 try {
8982 if (!_iteratorNormalCompletion2 && _iterator2.return) {
8983 _iterator2.return();
8984 }
8985 } finally {
8986 if (_didIteratorError2) {
8987 throw _iteratorError2;
8988 }
8989 }
8990 }
8991
8992 return true;
8993 }
8994
8995 function mergeInto(inputObj, targetObj) {
8996 var _iteratorNormalCompletion3 = true;
8997 var _didIteratorError3 = false;
8998 var _iteratorError3 = undefined;
8999
9000 try {
9001 for (var _iterator3 = Object.keys(inputObj)[Symbol.iterator](), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) {
9002 var k = _step3.value;
9003
9004 targetObj[k] = inputObj[k];
9005 }
9006 } catch (err) {
9007 _didIteratorError3 = true;
9008 _iteratorError3 = err;
9009 } finally {
9010 try {
9011 if (!_iteratorNormalCompletion3 && _iterator3.return) {
9012 _iterator3.return();
9013 }
9014 } finally {
9015 if (_didIteratorError3) {
9016 throw _iteratorError3;
9017 }
9018 }
9019 }
9020 }
9021
9022 exports.minMax = minMax;
9023 exports.indicesOfNearest = indicesOfNearest;
9024 exports.indexOfNearest = indexOfNearest;
9025 exports.DOMAIN = DOMAIN;
9026 exports.COVERAGE = COVERAGE;
9027 exports.COVERAGECOLLECTION = COVERAGECOLLECTION;
9028 exports.COVJSON_DATATYPE_TUPLE = COVJSON_DATATYPE_TUPLE;
9029 exports.COVJSON_DATATYPE_POLYGON = COVJSON_DATATYPE_POLYGON;
9030 exports.getLanguageTag = getLanguageTag;
9031 exports.getLanguageString = getLanguageString;
9032 exports.stringifyUnit = stringifyUnit;
9033 exports.minMaxOfRange = minMaxOfRange;
9034 exports.reduceRange = reduceRange;
9035 exports.iterateRange = iterateRange;
9036 exports.getCategory = getCategory;
9037 exports.isCoverage = isCoverage;
9038 exports.checkCoverage = checkCoverage;
9039 exports.isDomain = isDomain;
9040 exports.checkDomain = checkDomain;
9041 exports.getReferenceObject = getReferenceObject;
9042 exports.getHorizontalCRSReferenceObject = getHorizontalCRSReferenceObject;
9043 exports.isEllipsoidalCRS = isEllipsoidalCRS;
9044 exports.getProjection = getProjection;
9045 exports.loadProjection = loadProjection;
9046 exports.getHorizontalCRSComponents = getHorizontalCRSComponents;
9047 exports.getHorizontalCRSCoordinateIDs = getHorizontalCRSCoordinateIDs;
9048 exports.reprojectCoords = reprojectCoords;
9049 exports.getLongitudeWrapper = getLongitudeWrapper;
9050 exports.isLongitudeAxis = isLongitudeAxis;
9051 exports.isISODateAxis = isISODateAxis;
9052 exports.asTime = asTime;
9053 exports.normalizeIndexSubsetConstraints = normalizeIndexSubsetConstraints;
9054 exports.subsetDomainByIndex = subsetDomainByIndex;
9055 exports.fromDomain = fromDomain;
9056 exports.fromXndarray = fromXndarray;
9057 exports.addSubsetFunctions = addSubsetFunctions;
9058 exports.addLoadRangesFunction = addLoadRangesFunction;
9059 exports.reproject = reproject;
9060 exports.subsetByBbox = subsetByBbox;
9061 exports.subsetByIndex = subsetByIndex;
9062 exports.subsetByValue = subsetByValue;
9063 exports.withSimpleDerivedParameter = withSimpleDerivedParameter;
9064 exports.withParameters = withParameters;
9065 exports.withCategories = withCategories;
9066 exports.withDomainType = withDomainType;
9067 exports.asCovJSONDomainType = asCovJSONDomainType;
9068 exports.renameAxes = renameAxes;
9069 exports.mapRange = mapRange;
9070 exports.withDerivedParameter = withDerivedParameter;
9071 exports.addCollectionQueryFunction = addCollectionQueryFunction;
9072 exports.CollectionQuery = CollectionQuery;
9073
9074}((this.CovUtils = this.CovUtils || {})));
9075//# sourceMappingURL=covutils-lite.src.js.map
\No newline at end of file