UNPKG

688 kBSource Map (JSON)View Raw
1{"version":3,"file":"covutils.src.js","sources":["src/array.js","src/constants.js","src/i18n.js","src/unit.js","../../../../../\u0000babelHelpers","src/range.js","src/parameter.js","src/validate.js","../../../../../\u0000commonjsHelpers","node_modules/uriproj/node_modules/proj4/lib/common/imlfn.js","node_modules/uriproj/node_modules/proj4/lib/common/asinz.js","node_modules/uriproj/node_modules/proj4/lib/common/gN.js","node_modules/uriproj/node_modules/proj4/lib/common/e3fn.js","node_modules/uriproj/node_modules/proj4/lib/common/e2fn.js","node_modules/uriproj/node_modules/proj4/lib/common/e1fn.js","node_modules/uriproj/node_modules/proj4/lib/common/e0fn.js","node_modules/uriproj/node_modules/proj4/lib/common/mlfn.js","node_modules/uriproj/node_modules/proj4/lib/common/sign.js","node_modules/uriproj/node_modules/proj4/lib/common/adjust_lon.js","node_modules/uriproj/node_modules/proj4/lib/projections/aeqd.js","node_modules/uriproj/node_modules/proj4/lib/projections/vandg.js","node_modules/uriproj/node_modules/proj4/lib/common/adjust_lat.js","node_modules/uriproj/node_modules/proj4/lib/common/msfnz.js","node_modules/uriproj/node_modules/proj4/lib/projections/eqdc.js","node_modules/uriproj/node_modules/proj4/lib/projections/moll.js","node_modules/uriproj/node_modules/proj4/lib/common/pj_mlfn.js","node_modules/uriproj/node_modules/proj4/lib/common/pj_inv_mlfn.js","node_modules/uriproj/node_modules/proj4/lib/common/pj_enfn.js","node_modules/uriproj/node_modules/proj4/lib/projections/sinu.js","node_modules/uriproj/node_modules/proj4/lib/projections/mill.js","node_modules/uriproj/node_modules/proj4/lib/projections/nzmg.js","node_modules/uriproj/node_modules/proj4/lib/projections/poly.js","node_modules/uriproj/node_modules/proj4/lib/projections/eqc.js","node_modules/uriproj/node_modules/proj4/lib/common/iqsfnz.js","node_modules/uriproj/node_modules/proj4/lib/common/qsfnz.js","node_modules/uriproj/node_modules/proj4/lib/projections/cea.js","node_modules/uriproj/node_modules/proj4/lib/projections/gnom.js","node_modules/uriproj/node_modules/proj4/lib/projections/aea.js","node_modules/uriproj/node_modules/proj4/lib/projections/laea.js","node_modules/uriproj/node_modules/proj4/lib/projections/cass.js","node_modules/uriproj/node_modules/proj4/lib/projections/krovak.js","node_modules/uriproj/node_modules/proj4/lib/common/phi2z.js","node_modules/uriproj/node_modules/proj4/lib/common/tsfnz.js","node_modules/uriproj/node_modules/proj4/lib/projections/lcc.js","node_modules/uriproj/node_modules/proj4/lib/projections/omerc.js","node_modules/uriproj/node_modules/proj4/lib/projections/somerc.js","node_modules/uriproj/node_modules/proj4/lib/projections/stere.js","node_modules/uriproj/node_modules/proj4/lib/common/srat.js","node_modules/uriproj/node_modules/proj4/lib/projections/gauss.js","node_modules/uriproj/node_modules/proj4/lib/projections/sterea.js","node_modules/uriproj/node_modules/proj4/lib/projections/tmerc.js","node_modules/uriproj/node_modules/proj4/lib/projections/utm.js","node_modules/uriproj/node_modules/proj4/lib/includedProjections.js","node_modules/uriproj/node_modules/proj4/package.json","node_modules/uriproj/node_modules/proj4/node_modules/mgrs/mgrs.js","node_modules/uriproj/node_modules/proj4/lib/common/toPoint.js","node_modules/uriproj/node_modules/proj4/lib/datum.js","node_modules/uriproj/node_modules/proj4/lib/extend.js","node_modules/uriproj/node_modules/proj4/lib/constants/Ellipsoid.js","node_modules/uriproj/node_modules/proj4/lib/constants/Datum.js","node_modules/uriproj/node_modules/proj4/lib/deriveConstants.js","node_modules/uriproj/node_modules/proj4/lib/projections/longlat.js","node_modules/uriproj/node_modules/proj4/lib/projections/merc.js","node_modules/uriproj/node_modules/proj4/lib/projections.js","node_modules/uriproj/node_modules/proj4/lib/constants/units.js","node_modules/uriproj/node_modules/proj4/lib/constants/PrimeMeridian.js","node_modules/uriproj/node_modules/proj4/lib/projString.js","node_modules/uriproj/node_modules/proj4/lib/wkt.js","node_modules/uriproj/node_modules/proj4/lib/global.js","node_modules/uriproj/node_modules/proj4/lib/defs.js","node_modules/uriproj/node_modules/proj4/lib/parseCode.js","node_modules/uriproj/node_modules/proj4/lib/Proj.js","node_modules/uriproj/node_modules/proj4/lib/adjust_axis.js","node_modules/uriproj/node_modules/proj4/lib/datum_transform.js","node_modules/uriproj/node_modules/proj4/lib/transform.js","node_modules/uriproj/node_modules/proj4/lib/Point.js","node_modules/uriproj/node_modules/proj4/lib/core.js","node_modules/uriproj/node_modules/proj4/lib/index.js","node_modules/uriproj/node_modules/whatwg-fetch/fetch.js","node_modules/uriproj/lib/index.js","src/domain/referencing.js","src/domain/subset.js","src/coverage/subset.js","src/coverage/create.js","src/util.js","src/coverage/referencing.js","src/coverage/transform.js","src/collection/create.js","node_modules/point-in-big-polygon/node_modules/binary-search-bounds/search-bounds.js","node_modules/point-in-big-polygon/node_modules/interval-tree-1d/interval-tree.js","node_modules/point-in-big-polygon/node_modules/robust-orientation/node_modules/robust-subtract/robust-diff.js","node_modules/point-in-big-polygon/node_modules/robust-orientation/node_modules/robust-scale/node_modules/two-sum/two-sum.js","node_modules/point-in-big-polygon/node_modules/robust-orientation/node_modules/two-product/two-product.js","node_modules/point-in-big-polygon/node_modules/robust-orientation/node_modules/robust-scale/robust-scale.js","node_modules/point-in-big-polygon/node_modules/robust-orientation/node_modules/robust-sum/robust-sum.js","node_modules/point-in-big-polygon/node_modules/robust-orientation/orientation.js","node_modules/point-in-big-polygon/node_modules/slab-decomposition/lib/order-segments.js","node_modules/point-in-big-polygon/node_modules/slab-decomposition/node_modules/functional-red-black-tree/rbtree.js","node_modules/point-in-big-polygon/node_modules/slab-decomposition/slabs.js","node_modules/point-in-big-polygon/pnp-big.js","node_modules/topojson/lib/topojson/spherical.js","node_modules/topojson/lib/topojson/cartesian.js","src/domain/polygon.js","node_modules/ndarray/node_modules/is-buffer/index.js","node_modules/ndarray/node_modules/iota-array/iota.js","node_modules/ndarray/ndarray.js","src/coverage/transform-polygon.js"],"sourcesContent":["export function minMax (arr) {\r\n var len = arr.length\r\n var min = Infinity\r\n var max = -Infinity\r\n while (len--) {\r\n var el = arr[len]\r\n if (el == null) {\r\n // do nothing\r\n } else if (el < min) {\r\n min = el\r\n } else if (el > max) {\r\n max = el\r\n }\r\n }\r\n if (min === Infinity) {\r\n min = max\r\n } else if (max === -Infinity) {\r\n max = min\r\n }\r\n if (min === Infinity || min === -Infinity) {\r\n // all values were null\r\n min = null\r\n max = null\r\n }\r\n return [min, max]\r\n}\r\n\r\n/**\r\n * Return the indices of the two neighbors in the sorted array closest to the given number.\r\n *\r\n * @example\r\n * var a = [2,5,8,12,13]\r\n * var i = CovUtils.indicesOfNearest(a, 6)\r\n * // i == [1,2]\r\n * var j = CovUtils.indicesOfNearest(a, 5)\r\n * // j == [1,1]\r\n * var k = CovUtils.indicesOfNearest(a, 50)\r\n * // k == [4,4]\r\n *\r\n * @param {Array<number>} a The array to search through. Must be sorted, ascending or descending.\r\n * @param {number} x The target number.\r\n * @return {[lo,hi]} The indices of the two closest values, may be equal.\r\n * If `x` exists in the array, both neighbors point to `x`.\r\n * If `x` is lower (greater if descending) than the first value, both neighbors point to 0.\r\n * If `x` is greater (lower if descending) than the last value, both neighbors point to the last index.\r\n */\r\nexport function indicesOfNearest (a, x) {\r\n if (a.length === 0) {\r\n throw new Error('Array must have at least one element')\r\n }\r\n var lo = -1\r\n var hi = a.length\r\n const ascending = a.length === 1 || a[0] < a[1]\r\n // we have two separate code paths to help the runtime optimize the loop\r\n if (ascending) {\r\n while (hi - lo > 1) {\r\n let mid = Math.round((lo + hi) / 2)\r\n if (a[mid] <= x) {\r\n lo = mid\r\n } else {\r\n hi = mid\r\n }\r\n }\r\n } else {\r\n while (hi - lo > 1) {\r\n let mid = Math.round((lo + hi) / 2)\r\n if (a[mid] >= x) { // here's the difference\r\n lo = mid\r\n } else {\r\n hi = mid\r\n }\r\n }\r\n }\r\n if (a[lo] === x) hi = lo\r\n if (lo === -1) lo = hi\r\n if (hi === a.length) hi = lo\r\n return [lo, hi]\r\n}\r\n\r\n/**\r\n * Return the index of the value closest to the given number in a sorted array.\r\n *\r\n * @example\r\n * var a = [2,5,8,12,13]\r\n * var i = CovUtils.indexOfNearest(a, 6)\r\n * // i == 1\r\n * var j = CovUtils.indexOfNearest(a, 7)\r\n * // j == 2\r\n * var k = CovUtils.indexOfNearest(a, 50)\r\n * // k == 4\r\n *\r\n * @param {Array<number>} a The array to search through. Must be sorted, ascending or descending.\r\n * @param {number} x The target number.\r\n * @return {number} The array index whose value is closest to `x`.\r\n * If `x` happens to be exactly between two values, then the lower index is returned.\r\n */\r\nexport function indexOfNearest (a, x) {\r\n var i = indicesOfNearest(a, x)\r\n var lo = i[0]\r\n var hi = i[1]\r\n if (Math.abs(x - a[lo]) <= Math.abs(x - a[hi])) {\r\n return lo\r\n } else {\r\n return hi\r\n }\r\n}\r\n","export const DOMAIN = 'Domain'\r\nexport const COVERAGE = 'Coverage'\r\nexport const COVERAGECOLLECTION = COVERAGE + 'Collection'\r\n\r\nconst COVJSON_NS = 'http://covjson.org/def/core#'\r\n\r\nexport const COVJSON_DATATYPE_TUPLE = COVJSON_NS + 'tuple'\r\nexport const COVJSON_DATATYPE_POLYGON = COVJSON_NS + 'polygon'\r\n","const DEFAULT_LANGUAGE = 'en'\r\n\r\n/**\r\n * @example\r\n * var labels = {'en': 'Temperature', 'de': 'Temperatur'}\r\n * var tag = CovUtils.getLanguageTag(labels, 'en-GB')\r\n * // tag == 'en'\r\n *\r\n * @param {object} map An object that maps language tags to strings.\r\n * @param {string} [preferredLanguage='en'] The preferred language as a language tag, e.g. 'de'.\r\n * @return {string} The best matched language tag of the input map.\r\n * If no match was found then this is an arbitrary tag of the map.\r\n */\r\nexport function getLanguageTag (map, preferredLanguage = DEFAULT_LANGUAGE) {\r\n if (preferredLanguage in map) {\r\n return preferredLanguage\r\n }\r\n\r\n // cut off any subtags following the language subtag and try to find a match\r\n let prefTag = preferredLanguage.split('-')[0]\r\n let matches = Object.keys(map).filter(tag => prefTag === tag.split('-')[0])\r\n if (matches.length) {\r\n return matches[0]\r\n }\r\n\r\n // no luck, return a random tag\r\n return Object.keys(map)[0]\r\n}\r\n\r\n/**\r\n * @example\r\n * var labels = {'en': 'Temperature', 'de': 'Temperatur'}\r\n * var label = CovUtils.getLanguageString(labels, 'en-GB')\r\n * // label == 'Temperature'\r\n *\r\n * @param {object} map An object that maps language tags to strings.\r\n * @param {string} [preferredLanguage='en'] The preferred language as a language tag, e.g. 'de'.\r\n * @return {string} The string within the input map whose language tag best matched.\r\n * If no match was found then this is an arbitrary string of the map.\r\n */\r\nexport function getLanguageString (map, preferredLanguage = DEFAULT_LANGUAGE) {\r\n let tag = getLanguageTag(map, preferredLanguage)\r\n return map[tag]\r\n}\r\n","import { getLanguageString } from './i18n.js'\r\n\r\n/**\r\n * Converts a unit object to a human-readable symbol or label, where symbols are preferred.\r\n *\r\n * @example\r\n * var unit = {\r\n * symbol: '°C'\r\n * }\r\n * var str = CovUtils.stringifyUnit(unit) // str == '°C'\r\n *\r\n * @example\r\n * var unit = {\r\n * symbol: {\r\n * value: 'Cel',\r\n * type: 'http://www.opengis.net/def/uom/UCUM/'\r\n * },\r\n * label: {\r\n * en: 'Degree Celsius'\r\n * }\r\n * }\r\n * var str = CovUtils.stringifyUnit(unit) // str == '°C'\r\n *\r\n * @example\r\n * var unit = {\r\n * label: {\r\n * en: 'Degree Celsius',\r\n * de: 'Grad Celsius'\r\n * }\r\n * }\r\n * var str = CovUtils.stringifyUnit(unit, 'en') // str == 'Degree Celsius'\r\n */\r\nexport function stringifyUnit (unit, language) {\r\n if (!unit) {\r\n return ''\r\n }\r\n if (unit.symbol) {\r\n let symbol = unit.symbol.value || unit.symbol\r\n let scheme = unit.symbol.type\r\n if (scheme === 'http://www.opengis.net/def/uom/UCUM/') {\r\n if (symbol === 'Cel') {\r\n symbol = '°C'\r\n } else if (symbol === '1') {\r\n symbol = ''\r\n }\r\n }\r\n return symbol\r\n } else {\r\n return getLanguageString(unit.label, language)\r\n }\r\n}\r\n","var babelHelpers = {};\nvar _typeof = typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\" ? function (obj) {\n return typeof obj;\n} : function (obj) {\n return obj && typeof Symbol === \"function\" && obj.constructor === Symbol ? \"symbol\" : typeof obj;\n};\n\nexport var jsx = function () {\n var REACT_ELEMENT_TYPE = typeof Symbol === \"function\" && Symbol.for && Symbol.for(\"react.element\") || 0xeac7;\n return function createRawReactElement(type, props, key, children) {\n var defaultProps = type && type.defaultProps;\n var childrenLength = arguments.length - 3;\n\n if (!props && childrenLength !== 0) {\n props = {};\n }\n\n if (props && defaultProps) {\n for (var propName in defaultProps) {\n if (props[propName] === void 0) {\n props[propName] = defaultProps[propName];\n }\n }\n } else if (!props) {\n props = defaultProps || {};\n }\n\n if (childrenLength === 1) {\n props.children = children;\n } else if (childrenLength > 1) {\n var childArray = Array(childrenLength);\n\n for (var i = 0; i < childrenLength; i++) {\n childArray[i] = arguments[i + 3];\n }\n\n props.children = childArray;\n }\n\n return {\n $$typeof: REACT_ELEMENT_TYPE,\n type: type,\n key: key === undefined ? null : '' + key,\n ref: null,\n props: props,\n _owner: null\n };\n };\n}();\n\nexport var asyncToGenerator = function (fn) {\n return function () {\n var gen = fn.apply(this, arguments);\n return new Promise(function (resolve, reject) {\n function step(key, arg) {\n try {\n var info = gen[key](arg);\n var value = info.value;\n } catch (error) {\n reject(error);\n return;\n }\n\n if (info.done) {\n resolve(value);\n } else {\n return Promise.resolve(value).then(function (value) {\n return step(\"next\", value);\n }, function (err) {\n return step(\"throw\", err);\n });\n }\n }\n\n return step(\"next\");\n });\n };\n};\n\nexport var classCallCheck = function (instance, Constructor) {\n if (!(instance instanceof Constructor)) {\n throw new TypeError(\"Cannot call a class as a function\");\n }\n};\n\nexport var createClass = function () {\n function defineProperties(target, props) {\n for (var i = 0; i < props.length; i++) {\n var descriptor = props[i];\n descriptor.enumerable = descriptor.enumerable || false;\n descriptor.configurable = true;\n if (\"value\" in descriptor) descriptor.writable = true;\n Object.defineProperty(target, descriptor.key, descriptor);\n }\n }\n\n return function (Constructor, protoProps, staticProps) {\n if (protoProps) defineProperties(Constructor.prototype, protoProps);\n if (staticProps) defineProperties(Constructor, staticProps);\n return Constructor;\n };\n}();\n\nexport var defineEnumerableProperties = function (obj, descs) {\n for (var key in descs) {\n var desc = descs[key];\n desc.configurable = desc.enumerable = true;\n if (\"value\" in desc) desc.writable = true;\n Object.defineProperty(obj, key, desc);\n }\n\n return obj;\n};\n\nexport var defaults = function (obj, defaults) {\n var keys = Object.getOwnPropertyNames(defaults);\n\n for (var i = 0; i < keys.length; i++) {\n var key = keys[i];\n var value = Object.getOwnPropertyDescriptor(defaults, key);\n\n if (value && value.configurable && obj[key] === undefined) {\n Object.defineProperty(obj, key, value);\n }\n }\n\n return obj;\n};\n\nexport var defineProperty = function (obj, key, value) {\n if (key in obj) {\n Object.defineProperty(obj, key, {\n value: value,\n enumerable: true,\n configurable: true,\n writable: true\n });\n } else {\n obj[key] = value;\n }\n\n return obj;\n};\n\nvar _extends = Object.assign || function (target) {\n for (var i = 1; i < arguments.length; i++) {\n var source = arguments[i];\n\n for (var key in source) {\n if (Object.prototype.hasOwnProperty.call(source, key)) {\n target[key] = source[key];\n }\n }\n }\n\n return target;\n};\n\nexport var get = function get(object, property, receiver) {\n if (object === null) object = Function.prototype;\n var desc = Object.getOwnPropertyDescriptor(object, property);\n\n if (desc === undefined) {\n var parent = Object.getPrototypeOf(object);\n\n if (parent === null) {\n return undefined;\n } else {\n return get(parent, property, receiver);\n }\n } else if (\"value\" in desc) {\n return desc.value;\n } else {\n var getter = desc.get;\n\n if (getter === undefined) {\n return undefined;\n }\n\n return getter.call(receiver);\n }\n};\n\nexport var inherits = function (subClass, superClass) {\n if (typeof superClass !== \"function\" && superClass !== null) {\n throw new TypeError(\"Super expression must either be null or a function, not \" + typeof superClass);\n }\n\n subClass.prototype = Object.create(superClass && superClass.prototype, {\n constructor: {\n value: subClass,\n enumerable: false,\n writable: true,\n configurable: true\n }\n });\n if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass;\n};\n\nvar _instanceof = function (left, right) {\n if (right != null && typeof Symbol !== \"undefined\" && right[Symbol.hasInstance]) {\n return right[Symbol.hasInstance](left);\n } else {\n return left instanceof right;\n }\n};\n\nexport var interopRequireDefault = function (obj) {\n return obj && obj.__esModule ? obj : {\n default: obj\n };\n};\n\nexport var interopRequireWildcard = function (obj) {\n if (obj && obj.__esModule) {\n return obj;\n } else {\n var newObj = {};\n\n if (obj != null) {\n for (var key in obj) {\n if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key];\n }\n }\n\n newObj.default = obj;\n return newObj;\n }\n};\n\nexport var newArrowCheck = function (innerThis, boundThis) {\n if (innerThis !== boundThis) {\n throw new TypeError(\"Cannot instantiate an arrow function\");\n }\n};\n\nexport var objectDestructuringEmpty = function (obj) {\n if (obj == null) throw new TypeError(\"Cannot destructure undefined\");\n};\n\nexport var objectWithoutProperties = function (obj, keys) {\n var target = {};\n\n for (var i in obj) {\n if (keys.indexOf(i) >= 0) continue;\n if (!Object.prototype.hasOwnProperty.call(obj, i)) continue;\n target[i] = obj[i];\n }\n\n return target;\n};\n\nexport var possibleConstructorReturn = function (self, call) {\n if (!self) {\n throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\");\n }\n\n return call && (typeof call === \"object\" || typeof call === \"function\") ? call : self;\n};\n\nexport var selfGlobal = typeof global === \"undefined\" ? self : global;\n\nexport var set = function set(object, property, value, receiver) {\n var desc = Object.getOwnPropertyDescriptor(object, property);\n\n if (desc === undefined) {\n var parent = Object.getPrototypeOf(object);\n\n if (parent !== null) {\n set(parent, property, value, receiver);\n }\n } else if (\"value\" in desc && desc.writable) {\n desc.value = value;\n } else {\n var setter = desc.set;\n\n if (setter !== undefined) {\n setter.call(receiver, value);\n }\n }\n\n return value;\n};\n\nexport var slicedToArray = function () {\n function sliceIterator(arr, i) {\n var _arr = [];\n var _n = true;\n var _d = false;\n var _e = undefined;\n\n try {\n for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) {\n _arr.push(_s.value);\n\n if (i && _arr.length === i) break;\n }\n } catch (err) {\n _d = true;\n _e = err;\n } finally {\n try {\n if (!_n && _i[\"return\"]) _i[\"return\"]();\n } finally {\n if (_d) throw _e;\n }\n }\n\n return _arr;\n }\n\n return function (arr, i) {\n if (Array.isArray(arr)) {\n return arr;\n } else if (Symbol.iterator in Object(arr)) {\n return sliceIterator(arr, i);\n } else {\n throw new TypeError(\"Invalid attempt to destructure non-iterable instance\");\n }\n };\n}();\n\nexport var slicedToArrayLoose = function (arr, i) {\n if (Array.isArray(arr)) {\n return arr;\n } else if (Symbol.iterator in Object(arr)) {\n var _arr = [];\n\n for (var _iterator = arr[Symbol.iterator](), _step; !(_step = _iterator.next()).done;) {\n _arr.push(_step.value);\n\n if (i && _arr.length === i) break;\n }\n\n return _arr;\n } else {\n throw new TypeError(\"Invalid attempt to destructure non-iterable instance\");\n }\n};\n\nexport var taggedTemplateLiteral = function (strings, raw) {\n return Object.freeze(Object.defineProperties(strings, {\n raw: {\n value: Object.freeze(raw)\n }\n }));\n};\n\nexport var taggedTemplateLiteralLoose = function (strings, raw) {\n strings.raw = raw;\n return strings;\n};\n\nexport var temporalRef = function (val, name, undef) {\n if (val === undef) {\n throw new ReferenceError(name + \" is not defined - temporal dead zone\");\n } else {\n return val;\n }\n};\n\nexport var temporalUndefined = {};\n\nexport var toArray = function (arr) {\n return Array.isArray(arr) ? arr : Array.from(arr);\n};\n\nexport var toConsumableArray = function (arr) {\n if (Array.isArray(arr)) {\n for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) arr2[i] = arr[i];\n\n return arr2;\n } else {\n return Array.from(arr);\n }\n};\n\nbabelHelpers;\n\nexport { _typeof as typeof, _extends as extends, _instanceof as instanceof }","/**\r\n * @external {Range} https://github.com/Reading-eScience-Centre/coverage-jsapi/blob/master/Range.md\r\n */\r\n\r\n/**\r\n * Return the minimum/maximum across all range values, ignoring null's.\r\n *\r\n * @param {Range<number>} range The numeric coverage data range.\r\n * @return {[min,max]} The minimum and maximum values of the range,\r\n * or [undefined, undefined] if the range contains only `null` values.\r\n */\r\nexport function minMaxOfRange (range) {\r\n let min = Infinity\r\n let max = -Infinity\r\n let fn = val => {\r\n if (val === null) return\r\n if (val < min) min = val\r\n if (val > max) max = val\r\n }\r\n iterateRange(range, fn)\r\n return min === Infinity ? [undefined, undefined] : [min, max]\r\n}\r\n\r\n/**\r\n * Apply a reduce function over the range values.\r\n *\r\n * @param {Range} range The coverage data range.\r\n * @param {function} callback Function to execute on each value in the array with arguments `(previousValue, currentValue)`.\r\n * @param start Value to use as the first argument to the first call of the `callback`.\r\n * @return The reduced value.\r\n */\r\nexport function reduceRange (range, callback, start) {\r\n let v1 = start\r\n let iterFn = v2 => {\r\n v1 = callback(v1, v2)\r\n }\r\n iterateRange(range, iterFn)\r\n return v1\r\n}\r\n\r\n/**\r\n * Iterate over all range values and run a function for each value.\r\n * No particular iteration order must be assumed.\r\n */\r\nexport function iterateRange (range, fn) {\r\n // We use a precompiled function here for efficiency.\r\n // See below for a slower recursive version.\r\n\r\n // Benchmarks compared to recursive version:\r\n // Chrome 46: around 1.03x faster\r\n // Firefox 42: around 2x faster (and around 6x faster than Chrome 46!)\r\n\r\n // nest loops from smallest to biggest\r\n let shape = [...range.shape]\r\n shape.sort(([, size1], [, size2]) => size1 - size2)\r\n\r\n let begin = 'var obj = {}'\r\n let end = ''\r\n for (let [axis, size] of shape) {\r\n begin += `\r\n for (var i${axis}=0; i${axis} < ${size}; ++i${axis}) {\r\n obj['${axis}'] = i${axis}\r\n `\r\n end += `}`\r\n }\r\n begin += `\r\n fn(get(obj))\r\n `\r\n\r\n let iterateLoop = new Function(`return function iterRange (get, fn) { ${begin} ${end} }`)() // eslint-disable-line\r\n iterateLoop(range.get, fn)\r\n}\r\n\r\n/*\r\n * Recursive version of iterate(). For reference only.\r\n *\r\nexport function iterate (range, fn) {\r\n let get = range.get\r\n let shape = [...range.shape]\r\n // iterate from smallest to biggest dimension\r\n shape.sort(([,size1], [,size2]) => size1 - size2)\r\n let dims = shape.length\r\n\r\n function iterateRecurse (obj, axisIdx) {\r\n if (dims === axisIdx) {\r\n fn(get(obj))\r\n } else {\r\n let [axis,size] = shape[axisIdx]\r\n for (let i=0; i < size; i++) {\r\n obj[axis] = i\r\n iterateRecurse(obj, axisIdx+1)\r\n }\r\n }\r\n }\r\n iterateRecurse({}, 0)\r\n}\r\n*/\r\n","/**\r\n * Returns the category of the given parameter corresponding to the encoded integer value.\r\n *\r\n * @param {Parameter} parameter\r\n * @param {number} val\r\n * @return {Category}\r\n */\r\nexport function getCategory (parameter, val) {\r\n for (let [catId, vals] of parameter.categoryEncoding) {\r\n if (vals.indexOf(val) !== -1) {\r\n let cat = parameter.observedProperty.categories.filter(c => c.id === catId)[0]\r\n return cat\r\n }\r\n }\r\n}\r\n","import { COVERAGE, DOMAIN } from './constants.js'\r\n\r\nexport function isCoverage (obj) {\r\n return obj.type === COVERAGE\r\n}\r\n\r\nexport function checkCoverage (obj) {\r\n if (!isCoverage(obj)) {\r\n throw new Error('must be a Coverage')\r\n }\r\n}\r\n\r\nexport function isDomain (obj) {\r\n return obj.type === DOMAIN\r\n}\r\n\r\nexport function checkDomain (obj) {\r\n if (!isDomain(obj)) {\r\n throw new Error('must be a Domain')\r\n }\r\n}\r\n","\nexport var commonjsGlobal = typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {}\n\nexport function createCommonjsModule(fn, module) {\n\treturn module = { exports: {} }, fn(module, module.exports), module.exports;\n}","module.exports = function(ml, e0, e1, e2, e3) {\n var phi;\n var dphi;\n\n phi = ml / e0;\n for (var i = 0; i < 15; i++) {\n 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));\n phi += dphi;\n if (Math.abs(dphi) <= 0.0000000001) {\n return phi;\n }\n }\n\n //..reportError(\"IMLFN-CONV:Latitude failed to converge after 15 iterations\");\n return NaN;\n};","module.exports = function(x) {\n if (Math.abs(x) > 1) {\n x = (x > 1) ? 1 : -1;\n }\n return Math.asin(x);\n};","module.exports = function(a, e, sinphi) {\n var temp = e * sinphi;\n return a / Math.sqrt(1 - temp * temp);\n};","module.exports = function(x) {\n return (x * x * x * (35 / 3072));\n};","module.exports = function(x) {\n return (0.05859375 * x * x * (1 + 0.75 * x));\n};","module.exports = function(x) {\n return (0.375 * x * (1 + 0.25 * x * (1 + 0.46875 * x)));\n};","module.exports = function(x) {\n return (1 - 0.25 * x * (1 + x / 16 * (3 + 1.25 * x)));\n};","module.exports = function(e0, e1, e2, e3, phi) {\n return (e0 * phi - e1 * Math.sin(2 * phi) + e2 * Math.sin(4 * phi) - e3 * Math.sin(6 * phi));\n};","module.exports = function(x) {\n return x<0 ? -1 : 1;\n};","var TWO_PI = Math.PI * 2;\n// SPI is slightly greater than Math.PI, so values that exceed the -180..180\n// degree range by a tiny amount don't get wrapped. This prevents points that\n// have drifted from their original location along the 180th meridian (due to\n// floating point error) from changing their sign.\nvar SPI = 3.14159265359;\nvar sign = require('./sign');\n\nmodule.exports = function(x) {\n return (Math.abs(x) <= SPI) ? x : (x - (sign(x) * TWO_PI));\n};","var adjust_lon = require('../common/adjust_lon');\nvar HALF_PI = Math.PI/2;\nvar EPSLN = 1.0e-10;\nvar mlfn = require('../common/mlfn');\nvar e0fn = require('../common/e0fn');\nvar e1fn = require('../common/e1fn');\nvar e2fn = require('../common/e2fn');\nvar e3fn = require('../common/e3fn');\nvar gN = require('../common/gN');\nvar asinz = require('../common/asinz');\nvar imlfn = require('../common/imlfn');\nexports.init = function() {\n this.sin_p12 = Math.sin(this.lat0);\n this.cos_p12 = Math.cos(this.lat0);\n};\n\nexports.forward = function(p) {\n var lon = p.x;\n var lat = p.y;\n var sinphi = Math.sin(p.y);\n var cosphi = Math.cos(p.y);\n var dlon = adjust_lon(lon - this.long0);\n 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;\n if (this.sphere) {\n if (Math.abs(this.sin_p12 - 1) <= EPSLN) {\n //North Pole case\n p.x = this.x0 + this.a * (HALF_PI - lat) * Math.sin(dlon);\n p.y = this.y0 - this.a * (HALF_PI - lat) * Math.cos(dlon);\n return p;\n }\n else if (Math.abs(this.sin_p12 + 1) <= EPSLN) {\n //South Pole case\n p.x = this.x0 + this.a * (HALF_PI + lat) * Math.sin(dlon);\n p.y = this.y0 + this.a * (HALF_PI + lat) * Math.cos(dlon);\n return p;\n }\n else {\n //default case\n cos_c = this.sin_p12 * sinphi + this.cos_p12 * cosphi * Math.cos(dlon);\n c = Math.acos(cos_c);\n kp = c / Math.sin(c);\n p.x = this.x0 + this.a * kp * cosphi * Math.sin(dlon);\n p.y = this.y0 + this.a * kp * (this.cos_p12 * sinphi - this.sin_p12 * cosphi * Math.cos(dlon));\n return p;\n }\n }\n else {\n e0 = e0fn(this.es);\n e1 = e1fn(this.es);\n e2 = e2fn(this.es);\n e3 = e3fn(this.es);\n if (Math.abs(this.sin_p12 - 1) <= EPSLN) {\n //North Pole case\n Mlp = this.a * mlfn(e0, e1, e2, e3, HALF_PI);\n Ml = this.a * mlfn(e0, e1, e2, e3, lat);\n p.x = this.x0 + (Mlp - Ml) * Math.sin(dlon);\n p.y = this.y0 - (Mlp - Ml) * Math.cos(dlon);\n return p;\n }\n else if (Math.abs(this.sin_p12 + 1) <= EPSLN) {\n //South Pole case\n Mlp = this.a * mlfn(e0, e1, e2, e3, HALF_PI);\n Ml = this.a * mlfn(e0, e1, e2, e3, lat);\n p.x = this.x0 + (Mlp + Ml) * Math.sin(dlon);\n p.y = this.y0 + (Mlp + Ml) * Math.cos(dlon);\n return p;\n }\n else {\n //Default case\n tanphi = sinphi / cosphi;\n Nl1 = gN(this.a, this.e, this.sin_p12);\n Nl = gN(this.a, this.e, sinphi);\n psi = Math.atan((1 - this.es) * tanphi + this.es * Nl1 * this.sin_p12 / (Nl * cosphi));\n Az = Math.atan2(Math.sin(dlon), this.cos_p12 * Math.tan(psi) - this.sin_p12 * Math.cos(dlon));\n if (Az === 0) {\n s = Math.asin(this.cos_p12 * Math.sin(psi) - this.sin_p12 * Math.cos(psi));\n }\n else if (Math.abs(Math.abs(Az) - Math.PI) <= EPSLN) {\n s = -Math.asin(this.cos_p12 * Math.sin(psi) - this.sin_p12 * Math.cos(psi));\n }\n else {\n s = Math.asin(Math.sin(dlon) * Math.cos(psi) / Math.sin(Az));\n }\n G = this.e * this.sin_p12 / Math.sqrt(1 - this.es);\n H = this.e * this.cos_p12 * Math.cos(Az) / Math.sqrt(1 - this.es);\n GH = G * H;\n Hs = H * H;\n s2 = s * s;\n s3 = s2 * s;\n s4 = s3 * s;\n s5 = s4 * s;\n 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);\n p.x = this.x0 + c * Math.sin(Az);\n p.y = this.y0 + c * Math.cos(Az);\n return p;\n }\n }\n\n\n};\n\nexports.inverse = function(p) {\n p.x -= this.x0;\n p.y -= this.y0;\n var rh, z, sinz, cosz, lon, lat, con, e0, e1, e2, e3, Mlp, M, N1, psi, Az, cosAz, tmp, A, B, D, Ee, F;\n if (this.sphere) {\n rh = Math.sqrt(p.x * p.x + p.y * p.y);\n if (rh > (2 * HALF_PI * this.a)) {\n return;\n }\n z = rh / this.a;\n\n sinz = Math.sin(z);\n cosz = Math.cos(z);\n\n lon = this.long0;\n if (Math.abs(rh) <= EPSLN) {\n lat = this.lat0;\n }\n else {\n lat = asinz(cosz * this.sin_p12 + (p.y * sinz * this.cos_p12) / rh);\n con = Math.abs(this.lat0) - HALF_PI;\n if (Math.abs(con) <= EPSLN) {\n if (this.lat0 >= 0) {\n lon = adjust_lon(this.long0 + Math.atan2(p.x, - p.y));\n }\n else {\n lon = adjust_lon(this.long0 - Math.atan2(-p.x, p.y));\n }\n }\n else {\n /*con = cosz - this.sin_p12 * Math.sin(lat);\n if ((Math.abs(con) < EPSLN) && (Math.abs(p.x) < EPSLN)) {\n //no-op, just keep the lon value as is\n } else {\n var temp = Math.atan2((p.x * sinz * this.cos_p12), (con * rh));\n lon = adjust_lon(this.long0 + Math.atan2((p.x * sinz * this.cos_p12), (con * rh)));\n }*/\n lon = adjust_lon(this.long0 + Math.atan2(p.x * sinz, rh * this.cos_p12 * cosz - p.y * this.sin_p12 * sinz));\n }\n }\n\n p.x = lon;\n p.y = lat;\n return p;\n }\n else {\n e0 = e0fn(this.es);\n e1 = e1fn(this.es);\n e2 = e2fn(this.es);\n e3 = e3fn(this.es);\n if (Math.abs(this.sin_p12 - 1) <= EPSLN) {\n //North pole case\n Mlp = this.a * mlfn(e0, e1, e2, e3, HALF_PI);\n rh = Math.sqrt(p.x * p.x + p.y * p.y);\n M = Mlp - rh;\n lat = imlfn(M / this.a, e0, e1, e2, e3);\n lon = adjust_lon(this.long0 + Math.atan2(p.x, - 1 * p.y));\n p.x = lon;\n p.y = lat;\n return p;\n }\n else if (Math.abs(this.sin_p12 + 1) <= EPSLN) {\n //South pole case\n Mlp = this.a * mlfn(e0, e1, e2, e3, HALF_PI);\n rh = Math.sqrt(p.x * p.x + p.y * p.y);\n M = rh - Mlp;\n\n lat = imlfn(M / this.a, e0, e1, e2, e3);\n lon = adjust_lon(this.long0 + Math.atan2(p.x, p.y));\n p.x = lon;\n p.y = lat;\n return p;\n }\n else {\n //default case\n rh = Math.sqrt(p.x * p.x + p.y * p.y);\n Az = Math.atan2(p.x, p.y);\n N1 = gN(this.a, this.e, this.sin_p12);\n cosAz = Math.cos(Az);\n tmp = this.e * this.cos_p12 * cosAz;\n A = -tmp * tmp / (1 - this.es);\n B = 3 * this.es * (1 - A) * this.sin_p12 * this.cos_p12 * cosAz / (1 - this.es);\n D = rh / N1;\n Ee = D - A * (1 + A) * Math.pow(D, 3) / 6 - B * (1 + 3 * A) * Math.pow(D, 4) / 24;\n F = 1 - A * Ee * Ee / 2 - D * Ee * Ee * Ee / 6;\n psi = Math.asin(this.sin_p12 * Math.cos(Ee) + this.cos_p12 * Math.sin(Ee) * cosAz);\n lon = adjust_lon(this.long0 + Math.asin(Math.sin(Az) * Math.sin(Ee) / Math.cos(psi)));\n lat = Math.atan((1 - this.es * F * this.sin_p12 / Math.sin(psi)) * Math.tan(psi) / (1 - this.es));\n p.x = lon;\n p.y = lat;\n return p;\n }\n }\n\n};\nexports.names = [\"Azimuthal_Equidistant\", \"aeqd\"];\n","var adjust_lon = require('../common/adjust_lon');\nvar HALF_PI = Math.PI/2;\nvar EPSLN = 1.0e-10;\nvar asinz = require('../common/asinz');\n/* Initialize the Van Der Grinten projection\n ----------------------------------------*/\nexports.init = function() {\n //this.R = 6370997; //Radius of earth\n this.R = this.a;\n};\n\nexports.forward = function(p) {\n\n var lon = p.x;\n var lat = p.y;\n\n /* Forward equations\n -----------------*/\n var dlon = adjust_lon(lon - this.long0);\n var x, y;\n\n if (Math.abs(lat) <= EPSLN) {\n x = this.x0 + this.R * dlon;\n y = this.y0;\n }\n var theta = asinz(2 * Math.abs(lat / Math.PI));\n if ((Math.abs(dlon) <= EPSLN) || (Math.abs(Math.abs(lat) - HALF_PI) <= EPSLN)) {\n x = this.x0;\n if (lat >= 0) {\n y = this.y0 + Math.PI * this.R * Math.tan(0.5 * theta);\n }\n else {\n y = this.y0 + Math.PI * this.R * -Math.tan(0.5 * theta);\n }\n // return(OK);\n }\n var al = 0.5 * Math.abs((Math.PI / dlon) - (dlon / Math.PI));\n var asq = al * al;\n var sinth = Math.sin(theta);\n var costh = Math.cos(theta);\n\n var g = costh / (sinth + costh - 1);\n var gsq = g * g;\n var m = g * (2 / sinth - 1);\n var msq = m * m;\n var con = Math.PI * this.R * (al * (g - msq) + Math.sqrt(asq * (g - msq) * (g - msq) - (msq + asq) * (gsq - msq))) / (msq + asq);\n if (dlon < 0) {\n con = -con;\n }\n x = this.x0 + con;\n //con = Math.abs(con / (Math.PI * this.R));\n var q = asq + g;\n con = Math.PI * this.R * (m * q - al * Math.sqrt((msq + asq) * (asq + 1) - q * q)) / (msq + asq);\n if (lat >= 0) {\n //y = this.y0 + Math.PI * this.R * Math.sqrt(1 - con * con - 2 * al * con);\n y = this.y0 + con;\n }\n else {\n //y = this.y0 - Math.PI * this.R * Math.sqrt(1 - con * con - 2 * al * con);\n y = this.y0 - con;\n }\n p.x = x;\n p.y = y;\n return p;\n};\n\n/* Van Der Grinten inverse equations--mapping x,y to lat/long\n ---------------------------------------------------------*/\nexports.inverse = function(p) {\n var lon, lat;\n var xx, yy, xys, c1, c2, c3;\n var a1;\n var m1;\n var con;\n var th1;\n var d;\n\n /* inverse equations\n -----------------*/\n p.x -= this.x0;\n p.y -= this.y0;\n con = Math.PI * this.R;\n xx = p.x / con;\n yy = p.y / con;\n xys = xx * xx + yy * yy;\n c1 = -Math.abs(yy) * (1 + xys);\n c2 = c1 - 2 * yy * yy + xx * xx;\n c3 = -2 * c1 + 1 + 2 * yy * yy + xys * xys;\n d = yy * yy / c3 + (2 * c2 * c2 * c2 / c3 / c3 / c3 - 9 * c1 * c2 / c3 / c3) / 27;\n a1 = (c1 - c2 * c2 / 3 / c3) / c3;\n m1 = 2 * Math.sqrt(-a1 / 3);\n con = ((3 * d) / a1) / m1;\n if (Math.abs(con) > 1) {\n if (con >= 0) {\n con = 1;\n }\n else {\n con = -1;\n }\n }\n th1 = Math.acos(con) / 3;\n if (p.y >= 0) {\n lat = (-m1 * Math.cos(th1 + Math.PI / 3) - c2 / 3 / c3) * Math.PI;\n }\n else {\n lat = -(-m1 * Math.cos(th1 + Math.PI / 3) - c2 / 3 / c3) * Math.PI;\n }\n\n if (Math.abs(xx) < EPSLN) {\n lon = this.long0;\n }\n else {\n lon = adjust_lon(this.long0 + Math.PI * (xys - 1 + Math.sqrt(1 + 2 * (xx * xx - yy * yy) + xys * xys)) / 2 / xx);\n }\n\n p.x = lon;\n p.y = lat;\n return p;\n};\nexports.names = [\"Van_der_Grinten_I\", \"VanDerGrinten\", \"vandg\"];","var HALF_PI = Math.PI/2;\nvar sign = require('./sign');\n\nmodule.exports = function(x) {\n return (Math.abs(x) < HALF_PI) ? x : (x - (sign(x) * Math.PI));\n};","module.exports = function(eccent, sinphi, cosphi) {\n var con = eccent * sinphi;\n return cosphi / (Math.sqrt(1 - con * con));\n};","var e0fn = require('../common/e0fn');\nvar e1fn = require('../common/e1fn');\nvar e2fn = require('../common/e2fn');\nvar e3fn = require('../common/e3fn');\nvar msfnz = require('../common/msfnz');\nvar mlfn = require('../common/mlfn');\nvar adjust_lon = require('../common/adjust_lon');\nvar adjust_lat = require('../common/adjust_lat');\nvar imlfn = require('../common/imlfn');\nvar EPSLN = 1.0e-10;\nexports.init = function() {\n\n /* Place parameters in static storage for common use\n -------------------------------------------------*/\n // Standard Parallels cannot be equal and on opposite sides of the equator\n if (Math.abs(this.lat1 + this.lat2) < EPSLN) {\n return;\n }\n this.lat2 = this.lat2 || this.lat1;\n this.temp = this.b / this.a;\n this.es = 1 - Math.pow(this.temp, 2);\n this.e = Math.sqrt(this.es);\n this.e0 = e0fn(this.es);\n this.e1 = e1fn(this.es);\n this.e2 = e2fn(this.es);\n this.e3 = e3fn(this.es);\n\n this.sinphi = Math.sin(this.lat1);\n this.cosphi = Math.cos(this.lat1);\n\n this.ms1 = msfnz(this.e, this.sinphi, this.cosphi);\n this.ml1 = mlfn(this.e0, this.e1, this.e2, this.e3, this.lat1);\n\n if (Math.abs(this.lat1 - this.lat2) < EPSLN) {\n this.ns = this.sinphi;\n }\n else {\n this.sinphi = Math.sin(this.lat2);\n this.cosphi = Math.cos(this.lat2);\n this.ms2 = msfnz(this.e, this.sinphi, this.cosphi);\n this.ml2 = mlfn(this.e0, this.e1, this.e2, this.e3, this.lat2);\n this.ns = (this.ms1 - this.ms2) / (this.ml2 - this.ml1);\n }\n this.g = this.ml1 + this.ms1 / this.ns;\n this.ml0 = mlfn(this.e0, this.e1, this.e2, this.e3, this.lat0);\n this.rh = this.a * (this.g - this.ml0);\n};\n\n\n/* Equidistant Conic forward equations--mapping lat,long to x,y\n -----------------------------------------------------------*/\nexports.forward = function(p) {\n var lon = p.x;\n var lat = p.y;\n var rh1;\n\n /* Forward equations\n -----------------*/\n if (this.sphere) {\n rh1 = this.a * (this.g - lat);\n }\n else {\n var ml = mlfn(this.e0, this.e1, this.e2, this.e3, lat);\n rh1 = this.a * (this.g - ml);\n }\n var theta = this.ns * adjust_lon(lon - this.long0);\n var x = this.x0 + rh1 * Math.sin(theta);\n var y = this.y0 + this.rh - rh1 * Math.cos(theta);\n p.x = x;\n p.y = y;\n return p;\n};\n\n/* Inverse equations\n -----------------*/\nexports.inverse = function(p) {\n p.x -= this.x0;\n p.y = this.rh - p.y + this.y0;\n var con, rh1, lat, lon;\n if (this.ns >= 0) {\n rh1 = Math.sqrt(p.x * p.x + p.y * p.y);\n con = 1;\n }\n else {\n rh1 = -Math.sqrt(p.x * p.x + p.y * p.y);\n con = -1;\n }\n var theta = 0;\n if (rh1 !== 0) {\n theta = Math.atan2(con * p.x, con * p.y);\n }\n\n if (this.sphere) {\n lon = adjust_lon(this.long0 + theta / this.ns);\n lat = adjust_lat(this.g - rh1 / this.a);\n p.x = lon;\n p.y = lat;\n return p;\n }\n else {\n var ml = this.g - rh1 / this.a;\n lat = imlfn(ml, this.e0, this.e1, this.e2, this.e3);\n lon = adjust_lon(this.long0 + theta / this.ns);\n p.x = lon;\n p.y = lat;\n return p;\n }\n\n};\nexports.names = [\"Equidistant_Conic\", \"eqdc\"];\n","var adjust_lon = require('../common/adjust_lon');\nvar EPSLN = 1.0e-10;\nexports.init = function() {};\n\n/* Mollweide forward equations--mapping lat,long to x,y\n ----------------------------------------------------*/\nexports.forward = function(p) {\n\n /* Forward equations\n -----------------*/\n var lon = p.x;\n var lat = p.y;\n\n var delta_lon = adjust_lon(lon - this.long0);\n var theta = lat;\n var con = Math.PI * Math.sin(lat);\n\n /* Iterate using the Newton-Raphson method to find theta\n -----------------------------------------------------*/\n for (var i = 0; true; i++) {\n var delta_theta = -(theta + Math.sin(theta) - con) / (1 + Math.cos(theta));\n theta += delta_theta;\n if (Math.abs(delta_theta) < EPSLN) {\n break;\n }\n }\n theta /= 2;\n\n /* If the latitude is 90 deg, force the x coordinate to be \"0 + false easting\"\n this is done here because of precision problems with \"cos(theta)\"\n --------------------------------------------------------------------------*/\n if (Math.PI / 2 - Math.abs(lat) < EPSLN) {\n delta_lon = 0;\n }\n var x = 0.900316316158 * this.a * delta_lon * Math.cos(theta) + this.x0;\n var y = 1.4142135623731 * this.a * Math.sin(theta) + this.y0;\n\n p.x = x;\n p.y = y;\n return p;\n};\n\nexports.inverse = function(p) {\n var theta;\n var arg;\n\n /* Inverse equations\n -----------------*/\n p.x -= this.x0;\n p.y -= this.y0;\n arg = p.y / (1.4142135623731 * this.a);\n\n /* Because of division by zero problems, 'arg' can not be 1. Therefore\n a number very close to one is used instead.\n -------------------------------------------------------------------*/\n if (Math.abs(arg) > 0.999999999999) {\n arg = 0.999999999999;\n }\n theta = Math.asin(arg);\n var lon = adjust_lon(this.long0 + (p.x / (0.900316316158 * this.a * Math.cos(theta))));\n if (lon < (-Math.PI)) {\n lon = -Math.PI;\n }\n if (lon > Math.PI) {\n lon = Math.PI;\n }\n arg = (2 * theta + Math.sin(2 * theta)) / Math.PI;\n if (Math.abs(arg) > 1) {\n arg = 1;\n }\n var lat = Math.asin(arg);\n\n p.x = lon;\n p.y = lat;\n return p;\n};\nexports.names = [\"Mollweide\", \"moll\"];\n","module.exports = function(phi, sphi, cphi, en) {\n cphi *= sphi;\n sphi *= sphi;\n return (en[0] * phi - cphi * (en[1] + sphi * (en[2] + sphi * (en[3] + sphi * en[4]))));\n};","var pj_mlfn = require(\"./pj_mlfn\");\nvar EPSLN = 1.0e-10;\nvar MAX_ITER = 20;\nmodule.exports = function(arg, es, en) {\n var k = 1 / (1 - es);\n var phi = arg;\n for (var i = MAX_ITER; i; --i) { /* rarely goes over 2 iterations */\n var s = Math.sin(phi);\n var t = 1 - es * s * s;\n //t = this.pj_mlfn(phi, s, Math.cos(phi), en) - arg;\n //phi -= t * (t * Math.sqrt(t)) * k;\n t = (pj_mlfn(phi, s, Math.cos(phi), en) - arg) * (t * Math.sqrt(t)) * k;\n phi -= t;\n if (Math.abs(t) < EPSLN) {\n return phi;\n }\n }\n //..reportError(\"cass:pj_inv_mlfn: Convergence error\");\n return phi;\n};","var C00 = 1;\nvar C02 = 0.25;\nvar C04 = 0.046875;\nvar C06 = 0.01953125;\nvar C08 = 0.01068115234375;\nvar C22 = 0.75;\nvar C44 = 0.46875;\nvar C46 = 0.01302083333333333333;\nvar C48 = 0.00712076822916666666;\nvar C66 = 0.36458333333333333333;\nvar C68 = 0.00569661458333333333;\nvar C88 = 0.3076171875;\n\nmodule.exports = function(es) {\n var en = [];\n en[0] = C00 - es * (C02 + es * (C04 + es * (C06 + es * C08)));\n en[1] = es * (C22 - es * (C04 + es * (C06 + es * C08)));\n var t = es * es;\n en[2] = t * (C44 - es * (C46 + es * C48));\n t *= es;\n en[3] = t * (C66 - es * C68);\n en[4] = t * es * C88;\n return en;\n};","var adjust_lon = require('../common/adjust_lon');\nvar adjust_lat = require('../common/adjust_lat');\nvar pj_enfn = require('../common/pj_enfn');\nvar MAX_ITER = 20;\nvar pj_mlfn = require('../common/pj_mlfn');\nvar pj_inv_mlfn = require('../common/pj_inv_mlfn');\nvar HALF_PI = Math.PI/2;\nvar EPSLN = 1.0e-10;\nvar asinz = require('../common/asinz');\nexports.init = function() {\n /* Place parameters in static storage for common use\n -------------------------------------------------*/\n\n\n if (!this.sphere) {\n this.en = pj_enfn(this.es);\n }\n else {\n this.n = 1;\n this.m = 0;\n this.es = 0;\n this.C_y = Math.sqrt((this.m + 1) / this.n);\n this.C_x = this.C_y / (this.m + 1);\n }\n\n};\n\n/* Sinusoidal forward equations--mapping lat,long to x,y\n -----------------------------------------------------*/\nexports.forward = function(p) {\n var x, y;\n var lon = p.x;\n var lat = p.y;\n /* Forward equations\n -----------------*/\n lon = adjust_lon(lon - this.long0);\n\n if (this.sphere) {\n if (!this.m) {\n lat = this.n !== 1 ? Math.asin(this.n * Math.sin(lat)) : lat;\n }\n else {\n var k = this.n * Math.sin(lat);\n for (var i = MAX_ITER; i; --i) {\n var V = (this.m * lat + Math.sin(lat) - k) / (this.m + Math.cos(lat));\n lat -= V;\n if (Math.abs(V) < EPSLN) {\n break;\n }\n }\n }\n x = this.a * this.C_x * lon * (this.m + Math.cos(lat));\n y = this.a * this.C_y * lat;\n\n }\n else {\n\n var s = Math.sin(lat);\n var c = Math.cos(lat);\n y = this.a * pj_mlfn(lat, s, c, this.en);\n x = this.a * lon * c / Math.sqrt(1 - this.es * s * s);\n }\n\n p.x = x;\n p.y = y;\n return p;\n};\n\nexports.inverse = function(p) {\n var lat, temp, lon, s;\n\n p.x -= this.x0;\n lon = p.x / this.a;\n p.y -= this.y0;\n lat = p.y / this.a;\n\n if (this.sphere) {\n lat /= this.C_y;\n lon = lon / (this.C_x * (this.m + Math.cos(lat)));\n if (this.m) {\n lat = asinz((this.m * lat + Math.sin(lat)) / this.n);\n }\n else if (this.n !== 1) {\n lat = asinz(Math.sin(lat) / this.n);\n }\n lon = adjust_lon(lon + this.long0);\n lat = adjust_lat(lat);\n }\n else {\n lat = pj_inv_mlfn(p.y / this.a, this.es, this.en);\n s = Math.abs(lat);\n if (s < HALF_PI) {\n s = Math.sin(lat);\n temp = this.long0 + p.x * Math.sqrt(1 - this.es * s * s) / (this.a * Math.cos(lat));\n //temp = this.long0 + p.x / (this.a * Math.cos(lat));\n lon = adjust_lon(temp);\n }\n else if ((s - EPSLN) < HALF_PI) {\n lon = this.long0;\n }\n }\n p.x = lon;\n p.y = lat;\n return p;\n};\nexports.names = [\"Sinusoidal\", \"sinu\"];","var adjust_lon = require('../common/adjust_lon');\n/*\n reference\n \"New Equal-Area Map Projections for Noncircular Regions\", John P. Snyder,\n The American Cartographer, Vol 15, No. 4, October 1988, pp. 341-355.\n */\n\n\n/* Initialize the Miller Cylindrical projection\n -------------------------------------------*/\nexports.init = function() {\n //no-op\n};\n\n\n/* Miller Cylindrical forward equations--mapping lat,long to x,y\n ------------------------------------------------------------*/\nexports.forward = function(p) {\n var lon = p.x;\n var lat = p.y;\n /* Forward equations\n -----------------*/\n var dlon = adjust_lon(lon - this.long0);\n var x = this.x0 + this.a * dlon;\n var y = this.y0 + this.a * Math.log(Math.tan((Math.PI / 4) + (lat / 2.5))) * 1.25;\n\n p.x = x;\n p.y = y;\n return p;\n};\n\n/* Miller Cylindrical inverse equations--mapping x,y to lat/long\n ------------------------------------------------------------*/\nexports.inverse = function(p) {\n p.x -= this.x0;\n p.y -= this.y0;\n\n var lon = adjust_lon(this.long0 + p.x / this.a);\n var lat = 2.5 * (Math.atan(Math.exp(0.8 * p.y / this.a)) - Math.PI / 4);\n\n p.x = lon;\n p.y = lat;\n return p;\n};\nexports.names = [\"Miller_Cylindrical\", \"mill\"];\n","var SEC_TO_RAD = 4.84813681109535993589914102357e-6;\n/*\n reference\n Department of Land and Survey Technical Circular 1973/32\n http://www.linz.govt.nz/docs/miscellaneous/nz-map-definition.pdf\n OSG Technical Report 4.1\n http://www.linz.govt.nz/docs/miscellaneous/nzmg.pdf\n */\n\n/**\n * iterations: Number of iterations to refine inverse transform.\n * 0 -> km accuracy\n * 1 -> m accuracy -- suitable for most mapping applications\n * 2 -> mm accuracy\n */\nexports.iterations = 1;\n\nexports.init = function() {\n this.A = [];\n this.A[1] = 0.6399175073;\n this.A[2] = -0.1358797613;\n this.A[3] = 0.063294409;\n this.A[4] = -0.02526853;\n this.A[5] = 0.0117879;\n this.A[6] = -0.0055161;\n this.A[7] = 0.0026906;\n this.A[8] = -0.001333;\n this.A[9] = 0.00067;\n this.A[10] = -0.00034;\n\n this.B_re = [];\n this.B_im = [];\n this.B_re[1] = 0.7557853228;\n this.B_im[1] = 0;\n this.B_re[2] = 0.249204646;\n this.B_im[2] = 0.003371507;\n this.B_re[3] = -0.001541739;\n this.B_im[3] = 0.041058560;\n this.B_re[4] = -0.10162907;\n this.B_im[4] = 0.01727609;\n this.B_re[5] = -0.26623489;\n this.B_im[5] = -0.36249218;\n this.B_re[6] = -0.6870983;\n this.B_im[6] = -1.1651967;\n\n this.C_re = [];\n this.C_im = [];\n this.C_re[1] = 1.3231270439;\n this.C_im[1] = 0;\n this.C_re[2] = -0.577245789;\n this.C_im[2] = -0.007809598;\n this.C_re[3] = 0.508307513;\n this.C_im[3] = -0.112208952;\n this.C_re[4] = -0.15094762;\n this.C_im[4] = 0.18200602;\n this.C_re[5] = 1.01418179;\n this.C_im[5] = 1.64497696;\n this.C_re[6] = 1.9660549;\n this.C_im[6] = 2.5127645;\n\n this.D = [];\n this.D[1] = 1.5627014243;\n this.D[2] = 0.5185406398;\n this.D[3] = -0.03333098;\n this.D[4] = -0.1052906;\n this.D[5] = -0.0368594;\n this.D[6] = 0.007317;\n this.D[7] = 0.01220;\n this.D[8] = 0.00394;\n this.D[9] = -0.0013;\n};\n\n/**\n New Zealand Map Grid Forward - long/lat to x/y\n long/lat in radians\n */\nexports.forward = function(p) {\n var n;\n var lon = p.x;\n var lat = p.y;\n\n var delta_lat = lat - this.lat0;\n var delta_lon = lon - this.long0;\n\n // 1. Calculate d_phi and d_psi ... // and d_lambda\n // For this algorithm, delta_latitude is in seconds of arc x 10-5, so we need to scale to those units. Longitude is radians.\n var d_phi = delta_lat / SEC_TO_RAD * 1E-5;\n var d_lambda = delta_lon;\n var d_phi_n = 1; // d_phi^0\n\n var d_psi = 0;\n for (n = 1; n <= 10; n++) {\n d_phi_n = d_phi_n * d_phi;\n d_psi = d_psi + this.A[n] * d_phi_n;\n }\n\n // 2. Calculate theta\n var th_re = d_psi;\n var th_im = d_lambda;\n\n // 3. Calculate z\n var th_n_re = 1;\n var th_n_im = 0; // theta^0\n var th_n_re1;\n var th_n_im1;\n\n var z_re = 0;\n var z_im = 0;\n for (n = 1; n <= 6; n++) {\n th_n_re1 = th_n_re * th_re - th_n_im * th_im;\n th_n_im1 = th_n_im * th_re + th_n_re * th_im;\n th_n_re = th_n_re1;\n th_n_im = th_n_im1;\n z_re = z_re + this.B_re[n] * th_n_re - this.B_im[n] * th_n_im;\n z_im = z_im + this.B_im[n] * th_n_re + this.B_re[n] * th_n_im;\n }\n\n // 4. Calculate easting and northing\n p.x = (z_im * this.a) + this.x0;\n p.y = (z_re * this.a) + this.y0;\n\n return p;\n};\n\n\n/**\n New Zealand Map Grid Inverse - x/y to long/lat\n */\nexports.inverse = function(p) {\n var n;\n var x = p.x;\n var y = p.y;\n\n var delta_x = x - this.x0;\n var delta_y = y - this.y0;\n\n // 1. Calculate z\n var z_re = delta_y / this.a;\n var z_im = delta_x / this.a;\n\n // 2a. Calculate theta - first approximation gives km accuracy\n var z_n_re = 1;\n var z_n_im = 0; // z^0\n var z_n_re1;\n var z_n_im1;\n\n var th_re = 0;\n var th_im = 0;\n for (n = 1; n <= 6; n++) {\n z_n_re1 = z_n_re * z_re - z_n_im * z_im;\n z_n_im1 = z_n_im * z_re + z_n_re * z_im;\n z_n_re = z_n_re1;\n z_n_im = z_n_im1;\n th_re = th_re + this.C_re[n] * z_n_re - this.C_im[n] * z_n_im;\n th_im = th_im + this.C_im[n] * z_n_re + this.C_re[n] * z_n_im;\n }\n\n // 2b. Iterate to refine the accuracy of the calculation\n // 0 iterations gives km accuracy\n // 1 iteration gives m accuracy -- good enough for most mapping applications\n // 2 iterations bives mm accuracy\n for (var i = 0; i < this.iterations; i++) {\n var th_n_re = th_re;\n var th_n_im = th_im;\n var th_n_re1;\n var th_n_im1;\n\n var num_re = z_re;\n var num_im = z_im;\n for (n = 2; n <= 6; n++) {\n th_n_re1 = th_n_re * th_re - th_n_im * th_im;\n th_n_im1 = th_n_im * th_re + th_n_re * th_im;\n th_n_re = th_n_re1;\n th_n_im = th_n_im1;\n num_re = num_re + (n - 1) * (this.B_re[n] * th_n_re - this.B_im[n] * th_n_im);\n num_im = num_im + (n - 1) * (this.B_im[n] * th_n_re + this.B_re[n] * th_n_im);\n }\n\n th_n_re = 1;\n th_n_im = 0;\n var den_re = this.B_re[1];\n var den_im = this.B_im[1];\n for (n = 2; n <= 6; n++) {\n th_n_re1 = th_n_re * th_re - th_n_im * th_im;\n th_n_im1 = th_n_im * th_re + th_n_re * th_im;\n th_n_re = th_n_re1;\n th_n_im = th_n_im1;\n den_re = den_re + n * (this.B_re[n] * th_n_re - this.B_im[n] * th_n_im);\n den_im = den_im + n * (this.B_im[n] * th_n_re + this.B_re[n] * th_n_im);\n }\n\n // Complex division\n var den2 = den_re * den_re + den_im * den_im;\n th_re = (num_re * den_re + num_im * den_im) / den2;\n th_im = (num_im * den_re - num_re * den_im) / den2;\n }\n\n // 3. Calculate d_phi ... // and d_lambda\n var d_psi = th_re;\n var d_lambda = th_im;\n var d_psi_n = 1; // d_psi^0\n\n var d_phi = 0;\n for (n = 1; n <= 9; n++) {\n d_psi_n = d_psi_n * d_psi;\n d_phi = d_phi + this.D[n] * d_psi_n;\n }\n\n // 4. Calculate latitude and longitude\n // d_phi is calcuated in second of arc * 10^-5, so we need to scale back to radians. d_lambda is in radians.\n var lat = this.lat0 + (d_phi * SEC_TO_RAD * 1E5);\n var lon = this.long0 + d_lambda;\n\n p.x = lon;\n p.y = lat;\n\n return p;\n};\nexports.names = [\"New_Zealand_Map_Grid\", \"nzmg\"];","var e0fn = require('../common/e0fn');\nvar e1fn = require('../common/e1fn');\nvar e2fn = require('../common/e2fn');\nvar e3fn = require('../common/e3fn');\nvar adjust_lon = require('../common/adjust_lon');\nvar adjust_lat = require('../common/adjust_lat');\nvar mlfn = require('../common/mlfn');\nvar EPSLN = 1.0e-10;\nvar gN = require('../common/gN');\nvar MAX_ITER = 20;\nexports.init = function() {\n /* Place parameters in static storage for common use\n -------------------------------------------------*/\n this.temp = this.b / this.a;\n 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\n this.e = Math.sqrt(this.es);\n this.e0 = e0fn(this.es);\n this.e1 = e1fn(this.es);\n this.e2 = e2fn(this.es);\n this.e3 = e3fn(this.es);\n 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\n};\n\n\n/* Polyconic forward equations--mapping lat,long to x,y\n ---------------------------------------------------*/\nexports.forward = function(p) {\n var lon = p.x;\n var lat = p.y;\n var x, y, el;\n var dlon = adjust_lon(lon - this.long0);\n el = dlon * Math.sin(lat);\n if (this.sphere) {\n if (Math.abs(lat) <= EPSLN) {\n x = this.a * dlon;\n y = -1 * this.a * this.lat0;\n }\n else {\n x = this.a * Math.sin(el) / Math.tan(lat);\n y = this.a * (adjust_lat(lat - this.lat0) + (1 - Math.cos(el)) / Math.tan(lat));\n }\n }\n else {\n if (Math.abs(lat) <= EPSLN) {\n x = this.a * dlon;\n y = -1 * this.ml0;\n }\n else {\n var nl = gN(this.a, this.e, Math.sin(lat)) / Math.tan(lat);\n x = nl * Math.sin(el);\n y = this.a * mlfn(this.e0, this.e1, this.e2, this.e3, lat) - this.ml0 + nl * (1 - Math.cos(el));\n }\n\n }\n p.x = x + this.x0;\n p.y = y + this.y0;\n return p;\n};\n\n\n/* Inverse equations\n -----------------*/\nexports.inverse = function(p) {\n var lon, lat, x, y, i;\n var al, bl;\n var phi, dphi;\n x = p.x - this.x0;\n y = p.y - this.y0;\n\n if (this.sphere) {\n if (Math.abs(y + this.a * this.lat0) <= EPSLN) {\n lon = adjust_lon(x / this.a + this.long0);\n lat = 0;\n }\n else {\n al = this.lat0 + y / this.a;\n bl = x * x / this.a / this.a + al * al;\n phi = al;\n var tanphi;\n for (i = MAX_ITER; i; --i) {\n tanphi = Math.tan(phi);\n dphi = -1 * (al * (phi * tanphi + 1) - phi - 0.5 * (phi * phi + bl) * tanphi) / ((phi - al) / tanphi - 1);\n phi += dphi;\n if (Math.abs(dphi) <= EPSLN) {\n lat = phi;\n break;\n }\n }\n lon = adjust_lon(this.long0 + (Math.asin(x * Math.tan(phi) / this.a)) / Math.sin(lat));\n }\n }\n else {\n if (Math.abs(y + this.ml0) <= EPSLN) {\n lat = 0;\n lon = adjust_lon(this.long0 + x / this.a);\n }\n else {\n\n al = (this.ml0 + y) / this.a;\n bl = x * x / this.a / this.a + al * al;\n phi = al;\n var cl, mln, mlnp, ma;\n var con;\n for (i = MAX_ITER; i; --i) {\n con = this.e * Math.sin(phi);\n cl = Math.sqrt(1 - con * con) * Math.tan(phi);\n mln = this.a * mlfn(this.e0, this.e1, this.e2, this.e3, phi);\n mlnp = this.e0 - 2 * this.e1 * Math.cos(2 * phi) + 4 * this.e2 * Math.cos(4 * phi) - 6 * this.e3 * Math.cos(6 * phi);\n ma = mln / this.a;\n 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);\n phi -= dphi;\n if (Math.abs(dphi) <= EPSLN) {\n lat = phi;\n break;\n }\n }\n\n //lat=phi4z(this.e,this.e0,this.e1,this.e2,this.e3,al,bl,0,0);\n cl = Math.sqrt(1 - this.es * Math.pow(Math.sin(lat), 2)) * Math.tan(lat);\n lon = adjust_lon(this.long0 + Math.asin(x * cl / this.a) / Math.sin(lat));\n }\n }\n\n p.x = lon;\n p.y = lat;\n return p;\n};\nexports.names = [\"Polyconic\", \"poly\"];","var adjust_lon = require('../common/adjust_lon');\nvar adjust_lat = require('../common/adjust_lat');\nexports.init = function() {\n\n this.x0 = this.x0 || 0;\n this.y0 = this.y0 || 0;\n this.lat0 = this.lat0 || 0;\n this.long0 = this.long0 || 0;\n this.lat_ts = this.lat_ts || 0;\n this.title = this.title || \"Equidistant Cylindrical (Plate Carre)\";\n\n this.rc = Math.cos(this.lat_ts);\n};\n\n\n// forward equations--mapping lat,long to x,y\n// -----------------------------------------------------------------\nexports.forward = function(p) {\n\n var lon = p.x;\n var lat = p.y;\n\n var dlon = adjust_lon(lon - this.long0);\n var dlat = adjust_lat(lat - this.lat0);\n p.x = this.x0 + (this.a * dlon * this.rc);\n p.y = this.y0 + (this.a * dlat);\n return p;\n};\n\n// inverse equations--mapping x,y to lat/long\n// -----------------------------------------------------------------\nexports.inverse = function(p) {\n\n var x = p.x;\n var y = p.y;\n\n p.x = adjust_lon(this.long0 + ((x - this.x0) / (this.a * this.rc)));\n p.y = adjust_lat(this.lat0 + ((y - this.y0) / (this.a)));\n return p;\n};\nexports.names = [\"Equirectangular\", \"Equidistant_Cylindrical\", \"eqc\"];\n","var HALF_PI = Math.PI/2;\n\nmodule.exports = function(eccent, q) {\n var temp = 1 - (1 - eccent * eccent) / (2 * eccent) * Math.log((1 - eccent) / (1 + eccent));\n if (Math.abs(Math.abs(q) - temp) < 1.0E-6) {\n if (q < 0) {\n return (-1 * HALF_PI);\n }\n else {\n return HALF_PI;\n }\n }\n //var phi = 0.5* q/(1-eccent*eccent);\n var phi = Math.asin(0.5 * q);\n var dphi;\n var sin_phi;\n var cos_phi;\n var con;\n for (var i = 0; i < 30; i++) {\n sin_phi = Math.sin(phi);\n cos_phi = Math.cos(phi);\n con = eccent * sin_phi;\n 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)));\n phi += dphi;\n if (Math.abs(dphi) <= 0.0000000001) {\n return phi;\n }\n }\n\n //console.log(\"IQSFN-CONV:Latitude failed to converge after 30 iterations\");\n return NaN;\n};","module.exports = function(eccent, sinphi) {\n var con;\n if (eccent > 1.0e-7) {\n con = eccent * sinphi;\n return ((1 - eccent * eccent) * (sinphi / (1 - con * con) - (0.5 / eccent) * Math.log((1 - con) / (1 + con))));\n }\n else {\n return (2 * sinphi);\n }\n};","var adjust_lon = require('../common/adjust_lon');\nvar qsfnz = require('../common/qsfnz');\nvar msfnz = require('../common/msfnz');\nvar iqsfnz = require('../common/iqsfnz');\n/*\n reference: \n \"Cartographic Projection Procedures for the UNIX Environment-\n A User's Manual\" by Gerald I. Evenden,\n USGS Open File Report 90-284and Release 4 Interim Reports (2003)\n*/\nexports.init = function() {\n //no-op\n if (!this.sphere) {\n this.k0 = msfnz(this.e, Math.sin(this.lat_ts), Math.cos(this.lat_ts));\n }\n};\n\n\n/* Cylindrical Equal Area forward equations--mapping lat,long to x,y\n ------------------------------------------------------------*/\nexports.forward = function(p) {\n var lon = p.x;\n var lat = p.y;\n var x, y;\n /* Forward equations\n -----------------*/\n var dlon = adjust_lon(lon - this.long0);\n if (this.sphere) {\n x = this.x0 + this.a * dlon * Math.cos(this.lat_ts);\n y = this.y0 + this.a * Math.sin(lat) / Math.cos(this.lat_ts);\n }\n else {\n var qs = qsfnz(this.e, Math.sin(lat));\n x = this.x0 + this.a * this.k0 * dlon;\n y = this.y0 + this.a * qs * 0.5 / this.k0;\n }\n\n p.x = x;\n p.y = y;\n return p;\n};\n\n/* Cylindrical Equal Area inverse equations--mapping x,y to lat/long\n ------------------------------------------------------------*/\nexports.inverse = function(p) {\n p.x -= this.x0;\n p.y -= this.y0;\n var lon, lat;\n\n if (this.sphere) {\n lon = adjust_lon(this.long0 + (p.x / this.a) / Math.cos(this.lat_ts));\n lat = Math.asin((p.y / this.a) * Math.cos(this.lat_ts));\n }\n else {\n lat = iqsfnz(this.e, 2 * p.y * this.k0 / this.a);\n lon = adjust_lon(this.long0 + p.x / (this.a * this.k0));\n }\n\n p.x = lon;\n p.y = lat;\n return p;\n};\nexports.names = [\"cea\"];\n","var adjust_lon = require('../common/adjust_lon');\nvar EPSLN = 1.0e-10;\nvar asinz = require('../common/asinz');\n\n/*\n reference:\n Wolfram Mathworld \"Gnomonic Projection\"\n http://mathworld.wolfram.com/GnomonicProjection.html\n Accessed: 12th November 2009\n */\nexports.init = function() {\n\n /* Place parameters in static storage for common use\n -------------------------------------------------*/\n this.sin_p14 = Math.sin(this.lat0);\n this.cos_p14 = Math.cos(this.lat0);\n // Approximation for projecting points to the horizon (infinity)\n this.infinity_dist = 1000 * this.a;\n this.rc = 1;\n};\n\n\n/* Gnomonic forward equations--mapping lat,long to x,y\n ---------------------------------------------------*/\nexports.forward = function(p) {\n var sinphi, cosphi; /* sin and cos value */\n var dlon; /* delta longitude value */\n var coslon; /* cos of longitude */\n var ksp; /* scale factor */\n var g;\n var x, y;\n var lon = p.x;\n var lat = p.y;\n /* Forward equations\n -----------------*/\n dlon = adjust_lon(lon - this.long0);\n\n sinphi = Math.sin(lat);\n cosphi = Math.cos(lat);\n\n coslon = Math.cos(dlon);\n g = this.sin_p14 * sinphi + this.cos_p14 * cosphi * coslon;\n ksp = 1;\n if ((g > 0) || (Math.abs(g) <= EPSLN)) {\n x = this.x0 + this.a * ksp * cosphi * Math.sin(dlon) / g;\n y = this.y0 + this.a * ksp * (this.cos_p14 * sinphi - this.sin_p14 * cosphi * coslon) / g;\n }\n else {\n\n // Point is in the opposing hemisphere and is unprojectable\n // We still need to return a reasonable point, so we project \n // to infinity, on a bearing \n // equivalent to the northern hemisphere equivalent\n // This is a reasonable approximation for short shapes and lines that \n // straddle the horizon.\n\n x = this.x0 + this.infinity_dist * cosphi * Math.sin(dlon);\n y = this.y0 + this.infinity_dist * (this.cos_p14 * sinphi - this.sin_p14 * cosphi * coslon);\n\n }\n p.x = x;\n p.y = y;\n return p;\n};\n\n\nexports.inverse = function(p) {\n var rh; /* Rho */\n var sinc, cosc;\n var c;\n var lon, lat;\n\n /* Inverse equations\n -----------------*/\n p.x = (p.x - this.x0) / this.a;\n p.y = (p.y - this.y0) / this.a;\n\n p.x /= this.k0;\n p.y /= this.k0;\n\n if ((rh = Math.sqrt(p.x * p.x + p.y * p.y))) {\n c = Math.atan2(rh, this.rc);\n sinc = Math.sin(c);\n cosc = Math.cos(c);\n\n lat = asinz(cosc * this.sin_p14 + (p.y * sinc * this.cos_p14) / rh);\n lon = Math.atan2(p.x * sinc, rh * this.cos_p14 * cosc - p.y * this.sin_p14 * sinc);\n lon = adjust_lon(this.long0 + lon);\n }\n else {\n lat = this.phic0;\n lon = 0;\n }\n\n p.x = lon;\n p.y = lat;\n return p;\n};\nexports.names = [\"gnom\"];\n","var EPSLN = 1.0e-10;\nvar msfnz = require('../common/msfnz');\nvar qsfnz = require('../common/qsfnz');\nvar adjust_lon = require('../common/adjust_lon');\nvar asinz = require('../common/asinz');\nexports.init = function() {\n\n if (Math.abs(this.lat1 + this.lat2) < EPSLN) {\n return;\n }\n this.temp = this.b / this.a;\n this.es = 1 - Math.pow(this.temp, 2);\n this.e3 = Math.sqrt(this.es);\n\n this.sin_po = Math.sin(this.lat1);\n this.cos_po = Math.cos(this.lat1);\n this.t1 = this.sin_po;\n this.con = this.sin_po;\n this.ms1 = msfnz(this.e3, this.sin_po, this.cos_po);\n this.qs1 = qsfnz(this.e3, this.sin_po, this.cos_po);\n\n this.sin_po = Math.sin(this.lat2);\n this.cos_po = Math.cos(this.lat2);\n this.t2 = this.sin_po;\n this.ms2 = msfnz(this.e3, this.sin_po, this.cos_po);\n this.qs2 = qsfnz(this.e3, this.sin_po, this.cos_po);\n\n this.sin_po = Math.sin(this.lat0);\n this.cos_po = Math.cos(this.lat0);\n this.t3 = this.sin_po;\n this.qs0 = qsfnz(this.e3, this.sin_po, this.cos_po);\n\n if (Math.abs(this.lat1 - this.lat2) > EPSLN) {\n this.ns0 = (this.ms1 * this.ms1 - this.ms2 * this.ms2) / (this.qs2 - this.qs1);\n }\n else {\n this.ns0 = this.con;\n }\n this.c = this.ms1 * this.ms1 + this.ns0 * this.qs1;\n this.rh = this.a * Math.sqrt(this.c - this.ns0 * this.qs0) / this.ns0;\n};\n\n/* Albers Conical Equal Area forward equations--mapping lat,long to x,y\n -------------------------------------------------------------------*/\nexports.forward = function(p) {\n\n var lon = p.x;\n var lat = p.y;\n\n this.sin_phi = Math.sin(lat);\n this.cos_phi = Math.cos(lat);\n\n var qs = qsfnz(this.e3, this.sin_phi, this.cos_phi);\n var rh1 = this.a * Math.sqrt(this.c - this.ns0 * qs) / this.ns0;\n var theta = this.ns0 * adjust_lon(lon - this.long0);\n var x = rh1 * Math.sin(theta) + this.x0;\n var y = this.rh - rh1 * Math.cos(theta) + this.y0;\n\n p.x = x;\n p.y = y;\n return p;\n};\n\n\nexports.inverse = function(p) {\n var rh1, qs, con, theta, lon, lat;\n\n p.x -= this.x0;\n p.y = this.rh - p.y + this.y0;\n if (this.ns0 >= 0) {\n rh1 = Math.sqrt(p.x * p.x + p.y * p.y);\n con = 1;\n }\n else {\n rh1 = -Math.sqrt(p.x * p.x + p.y * p.y);\n con = -1;\n }\n theta = 0;\n if (rh1 !== 0) {\n theta = Math.atan2(con * p.x, con * p.y);\n }\n con = rh1 * this.ns0 / this.a;\n if (this.sphere) {\n lat = Math.asin((this.c - con * con) / (2 * this.ns0));\n }\n else {\n qs = (this.c - con * con) / this.ns0;\n lat = this.phi1z(this.e3, qs);\n }\n\n lon = adjust_lon(theta / this.ns0 + this.long0);\n p.x = lon;\n p.y = lat;\n return p;\n};\n\n/* Function to compute phi1, the latitude for the inverse of the\n Albers Conical Equal-Area projection.\n-------------------------------------------*/\nexports.phi1z = function(eccent, qs) {\n var sinphi, cosphi, con, com, dphi;\n var phi = asinz(0.5 * qs);\n if (eccent < EPSLN) {\n return phi;\n }\n\n var eccnts = eccent * eccent;\n for (var i = 1; i <= 25; i++) {\n sinphi = Math.sin(phi);\n cosphi = Math.cos(phi);\n con = eccent * sinphi;\n com = 1 - con * con;\n dphi = 0.5 * com * com / cosphi * (qs / (1 - eccnts) - sinphi / com + 0.5 / eccent * Math.log((1 - con) / (1 + con)));\n phi = phi + dphi;\n if (Math.abs(dphi) <= 1e-7) {\n return phi;\n }\n }\n return null;\n};\nexports.names = [\"Albers_Conic_Equal_Area\", \"Albers\", \"aea\"];\n","var HALF_PI = Math.PI/2;\nvar FORTPI = Math.PI/4;\nvar EPSLN = 1.0e-10;\nvar qsfnz = require('../common/qsfnz');\nvar adjust_lon = require('../common/adjust_lon');\n/*\n reference\n \"New Equal-Area Map Projections for Noncircular Regions\", John P. Snyder,\n The American Cartographer, Vol 15, No. 4, October 1988, pp. 341-355.\n */\n\nexports.S_POLE = 1;\nexports.N_POLE = 2;\nexports.EQUIT = 3;\nexports.OBLIQ = 4;\n\n\n/* Initialize the Lambert Azimuthal Equal Area projection\n ------------------------------------------------------*/\nexports.init = function() {\n var t = Math.abs(this.lat0);\n if (Math.abs(t - HALF_PI) < EPSLN) {\n this.mode = this.lat0 < 0 ? this.S_POLE : this.N_POLE;\n }\n else if (Math.abs(t) < EPSLN) {\n this.mode = this.EQUIT;\n }\n else {\n this.mode = this.OBLIQ;\n }\n if (this.es > 0) {\n var sinphi;\n\n this.qp = qsfnz(this.e, 1);\n this.mmf = 0.5 / (1 - this.es);\n this.apa = this.authset(this.es);\n switch (this.mode) {\n case this.N_POLE:\n this.dd = 1;\n break;\n case this.S_POLE:\n this.dd = 1;\n break;\n case this.EQUIT:\n this.rq = Math.sqrt(0.5 * this.qp);\n this.dd = 1 / this.rq;\n this.xmf = 1;\n this.ymf = 0.5 * this.qp;\n break;\n case this.OBLIQ:\n this.rq = Math.sqrt(0.5 * this.qp);\n sinphi = Math.sin(this.lat0);\n this.sinb1 = qsfnz(this.e, sinphi) / this.qp;\n this.cosb1 = Math.sqrt(1 - this.sinb1 * this.sinb1);\n this.dd = Math.cos(this.lat0) / (Math.sqrt(1 - this.es * sinphi * sinphi) * this.rq * this.cosb1);\n this.ymf = (this.xmf = this.rq) / this.dd;\n this.xmf *= this.dd;\n break;\n }\n }\n else {\n if (this.mode === this.OBLIQ) {\n this.sinph0 = Math.sin(this.lat0);\n this.cosph0 = Math.cos(this.lat0);\n }\n }\n};\n\n/* Lambert Azimuthal Equal Area forward equations--mapping lat,long to x,y\n -----------------------------------------------------------------------*/\nexports.forward = function(p) {\n\n /* Forward equations\n -----------------*/\n var x, y, coslam, sinlam, sinphi, q, sinb, cosb, b, cosphi;\n var lam = p.x;\n var phi = p.y;\n\n lam = adjust_lon(lam - this.long0);\n\n if (this.sphere) {\n sinphi = Math.sin(phi);\n cosphi = Math.cos(phi);\n coslam = Math.cos(lam);\n if (this.mode === this.OBLIQ || this.mode === this.EQUIT) {\n y = (this.mode === this.EQUIT) ? 1 + cosphi * coslam : 1 + this.sinph0 * sinphi + this.cosph0 * cosphi * coslam;\n if (y <= EPSLN) {\n return null;\n }\n y = Math.sqrt(2 / y);\n x = y * cosphi * Math.sin(lam);\n y *= (this.mode === this.EQUIT) ? sinphi : this.cosph0 * sinphi - this.sinph0 * cosphi * coslam;\n }\n else if (this.mode === this.N_POLE || this.mode === this.S_POLE) {\n if (this.mode === this.N_POLE) {\n coslam = -coslam;\n }\n if (Math.abs(phi + this.phi0) < EPSLN) {\n return null;\n }\n y = FORTPI - phi * 0.5;\n y = 2 * ((this.mode === this.S_POLE) ? Math.cos(y) : Math.sin(y));\n x = y * Math.sin(lam);\n y *= coslam;\n }\n }\n else {\n sinb = 0;\n cosb = 0;\n b = 0;\n coslam = Math.cos(lam);\n sinlam = Math.sin(lam);\n sinphi = Math.sin(phi);\n q = qsfnz(this.e, sinphi);\n if (this.mode === this.OBLIQ || this.mode === this.EQUIT) {\n sinb = q / this.qp;\n cosb = Math.sqrt(1 - sinb * sinb);\n }\n switch (this.mode) {\n case this.OBLIQ:\n b = 1 + this.sinb1 * sinb + this.cosb1 * cosb * coslam;\n break;\n case this.EQUIT:\n b = 1 + cosb * coslam;\n break;\n case this.N_POLE:\n b = HALF_PI + phi;\n q = this.qp - q;\n break;\n case this.S_POLE:\n b = phi - HALF_PI;\n q = this.qp + q;\n break;\n }\n if (Math.abs(b) < EPSLN) {\n return null;\n }\n switch (this.mode) {\n case this.OBLIQ:\n case this.EQUIT:\n b = Math.sqrt(2 / b);\n if (this.mode === this.OBLIQ) {\n y = this.ymf * b * (this.cosb1 * sinb - this.sinb1 * cosb * coslam);\n }\n else {\n y = (b = Math.sqrt(2 / (1 + cosb * coslam))) * sinb * this.ymf;\n }\n x = this.xmf * b * cosb * sinlam;\n break;\n case this.N_POLE:\n case this.S_POLE:\n if (q >= 0) {\n x = (b = Math.sqrt(q)) * sinlam;\n y = coslam * ((this.mode === this.S_POLE) ? b : -b);\n }\n else {\n x = y = 0;\n }\n break;\n }\n }\n\n p.x = this.a * x + this.x0;\n p.y = this.a * y + this.y0;\n return p;\n};\n\n/* Inverse equations\n -----------------*/\nexports.inverse = function(p) {\n p.x -= this.x0;\n p.y -= this.y0;\n var x = p.x / this.a;\n var y = p.y / this.a;\n var lam, phi, cCe, sCe, q, rho, ab;\n\n if (this.sphere) {\n var cosz = 0,\n rh, sinz = 0;\n\n rh = Math.sqrt(x * x + y * y);\n phi = rh * 0.5;\n if (phi > 1) {\n return null;\n }\n phi = 2 * Math.asin(phi);\n if (this.mode === this.OBLIQ || this.mode === this.EQUIT) {\n sinz = Math.sin(phi);\n cosz = Math.cos(phi);\n }\n switch (this.mode) {\n case this.EQUIT:\n phi = (Math.abs(rh) <= EPSLN) ? 0 : Math.asin(y * sinz / rh);\n x *= sinz;\n y = cosz * rh;\n break;\n case this.OBLIQ:\n phi = (Math.abs(rh) <= EPSLN) ? this.phi0 : Math.asin(cosz * this.sinph0 + y * sinz * this.cosph0 / rh);\n x *= sinz * this.cosph0;\n y = (cosz - Math.sin(phi) * this.sinph0) * rh;\n break;\n case this.N_POLE:\n y = -y;\n phi = HALF_PI - phi;\n break;\n case this.S_POLE:\n phi -= HALF_PI;\n break;\n }\n lam = (y === 0 && (this.mode === this.EQUIT || this.mode === this.OBLIQ)) ? 0 : Math.atan2(x, y);\n }\n else {\n ab = 0;\n if (this.mode === this.OBLIQ || this.mode === this.EQUIT) {\n x /= this.dd;\n y *= this.dd;\n rho = Math.sqrt(x * x + y * y);\n if (rho < EPSLN) {\n p.x = 0;\n p.y = this.phi0;\n return p;\n }\n sCe = 2 * Math.asin(0.5 * rho / this.rq);\n cCe = Math.cos(sCe);\n x *= (sCe = Math.sin(sCe));\n if (this.mode === this.OBLIQ) {\n ab = cCe * this.sinb1 + y * sCe * this.cosb1 / rho;\n q = this.qp * ab;\n y = rho * this.cosb1 * cCe - y * this.sinb1 * sCe;\n }\n else {\n ab = y * sCe / rho;\n q = this.qp * ab;\n y = rho * cCe;\n }\n }\n else if (this.mode === this.N_POLE || this.mode === this.S_POLE) {\n if (this.mode === this.N_POLE) {\n y = -y;\n }\n q = (x * x + y * y);\n if (!q) {\n p.x = 0;\n p.y = this.phi0;\n return p;\n }\n ab = 1 - q / this.qp;\n if (this.mode === this.S_POLE) {\n ab = -ab;\n }\n }\n lam = Math.atan2(x, y);\n phi = this.authlat(Math.asin(ab), this.apa);\n }\n\n\n p.x = adjust_lon(this.long0 + lam);\n p.y = phi;\n return p;\n};\n\n/* determine latitude from authalic latitude */\nexports.P00 = 0.33333333333333333333;\nexports.P01 = 0.17222222222222222222;\nexports.P02 = 0.10257936507936507936;\nexports.P10 = 0.06388888888888888888;\nexports.P11 = 0.06640211640211640211;\nexports.P20 = 0.01641501294219154443;\n\nexports.authset = function(es) {\n var t;\n var APA = [];\n APA[0] = es * this.P00;\n t = es * es;\n APA[0] += t * this.P01;\n APA[1] = t * this.P10;\n t *= es;\n APA[0] += t * this.P02;\n APA[1] += t * this.P11;\n APA[2] = t * this.P20;\n return APA;\n};\n\nexports.authlat = function(beta, APA) {\n var t = beta + beta;\n return (beta + APA[0] * Math.sin(t) + APA[1] * Math.sin(t + t) + APA[2] * Math.sin(t + t + t));\n};\nexports.names = [\"Lambert Azimuthal Equal Area\", \"Lambert_Azimuthal_Equal_Area\", \"laea\"];\n","var mlfn = require('../common/mlfn');\nvar e0fn = require('../common/e0fn');\nvar e1fn = require('../common/e1fn');\nvar e2fn = require('../common/e2fn');\nvar e3fn = require('../common/e3fn');\nvar gN = require('../common/gN');\nvar adjust_lon = require('../common/adjust_lon');\nvar adjust_lat = require('../common/adjust_lat');\nvar imlfn = require('../common/imlfn');\nvar HALF_PI = Math.PI/2;\nvar EPSLN = 1.0e-10;\nexports.init = function() {\n if (!this.sphere) {\n this.e0 = e0fn(this.es);\n this.e1 = e1fn(this.es);\n this.e2 = e2fn(this.es);\n this.e3 = e3fn(this.es);\n this.ml0 = this.a * mlfn(this.e0, this.e1, this.e2, this.e3, this.lat0);\n }\n};\n\n\n\n/* Cassini forward equations--mapping lat,long to x,y\n -----------------------------------------------------------------------*/\nexports.forward = function(p) {\n\n /* Forward equations\n -----------------*/\n var x, y;\n var lam = p.x;\n var phi = p.y;\n lam = adjust_lon(lam - this.long0);\n\n if (this.sphere) {\n x = this.a * Math.asin(Math.cos(phi) * Math.sin(lam));\n y = this.a * (Math.atan2(Math.tan(phi), Math.cos(lam)) - this.lat0);\n }\n else {\n //ellipsoid\n var sinphi = Math.sin(phi);\n var cosphi = Math.cos(phi);\n var nl = gN(this.a, this.e, sinphi);\n var tl = Math.tan(phi) * Math.tan(phi);\n var al = lam * Math.cos(phi);\n var asq = al * al;\n var cl = this.es * cosphi * cosphi / (1 - this.es);\n var ml = this.a * mlfn(this.e0, this.e1, this.e2, this.e3, phi);\n\n x = nl * al * (1 - asq * tl * (1 / 6 - (8 - tl + 8 * cl) * asq / 120));\n y = ml - this.ml0 + nl * sinphi / cosphi * asq * (0.5 + (5 - tl + 6 * cl) * asq / 24);\n\n\n }\n\n p.x = x + this.x0;\n p.y = y + this.y0;\n return p;\n};\n\n/* Inverse equations\n -----------------*/\nexports.inverse = function(p) {\n p.x -= this.x0;\n p.y -= this.y0;\n var x = p.x / this.a;\n var y = p.y / this.a;\n var phi, lam;\n\n if (this.sphere) {\n var dd = y + this.lat0;\n phi = Math.asin(Math.sin(dd) * Math.cos(x));\n lam = Math.atan2(Math.tan(x), Math.cos(dd));\n }\n else {\n /* ellipsoid */\n var ml1 = this.ml0 / this.a + y;\n var phi1 = imlfn(ml1, this.e0, this.e1, this.e2, this.e3);\n if (Math.abs(Math.abs(phi1) - HALF_PI) <= EPSLN) {\n p.x = this.long0;\n p.y = HALF_PI;\n if (y < 0) {\n p.y *= -1;\n }\n return p;\n }\n var nl1 = gN(this.a, this.e, Math.sin(phi1));\n\n var rl1 = nl1 * nl1 * nl1 / this.a / this.a * (1 - this.es);\n var tl1 = Math.pow(Math.tan(phi1), 2);\n var dl = x * this.a / nl1;\n var dsq = dl * dl;\n phi = phi1 - nl1 * Math.tan(phi1) / rl1 * dl * dl * (0.5 - (1 + 3 * tl1) * dl * dl / 24);\n lam = dl * (1 - dsq * (tl1 / 3 + (1 + 3 * tl1) * tl1 * dsq / 15)) / Math.cos(phi1);\n\n }\n\n p.x = adjust_lon(lam + this.long0);\n p.y = adjust_lat(phi);\n return p;\n\n};\nexports.names = [\"Cassini\", \"Cassini_Soldner\", \"cass\"];","var adjust_lon = require('../common/adjust_lon');\nexports.init = function() {\n this.a = 6377397.155;\n this.es = 0.006674372230614;\n this.e = Math.sqrt(this.es);\n if (!this.lat0) {\n this.lat0 = 0.863937979737193;\n }\n if (!this.long0) {\n this.long0 = 0.7417649320975901 - 0.308341501185665;\n }\n /* if scale not set default to 0.9999 */\n if (!this.k0) {\n this.k0 = 0.9999;\n }\n this.s45 = 0.785398163397448; /* 45 */\n this.s90 = 2 * this.s45;\n this.fi0 = this.lat0;\n this.e2 = this.es;\n this.e = Math.sqrt(this.e2);\n this.alfa = Math.sqrt(1 + (this.e2 * Math.pow(Math.cos(this.fi0), 4)) / (1 - this.e2));\n this.uq = 1.04216856380474;\n this.u0 = Math.asin(Math.sin(this.fi0) / this.alfa);\n this.g = Math.pow((1 + this.e * Math.sin(this.fi0)) / (1 - this.e * Math.sin(this.fi0)), this.alfa * this.e / 2);\n this.k = Math.tan(this.u0 / 2 + this.s45) / Math.pow(Math.tan(this.fi0 / 2 + this.s45), this.alfa) * this.g;\n this.k1 = this.k0;\n this.n0 = this.a * Math.sqrt(1 - this.e2) / (1 - this.e2 * Math.pow(Math.sin(this.fi0), 2));\n this.s0 = 1.37008346281555;\n this.n = Math.sin(this.s0);\n this.ro0 = this.k1 * this.n0 / Math.tan(this.s0);\n this.ad = this.s90 - this.uq;\n};\n\n/* ellipsoid */\n/* calculate xy from lat/lon */\n/* Constants, identical to inverse transform function */\nexports.forward = function(p) {\n var gfi, u, deltav, s, d, eps, ro;\n var lon = p.x;\n var lat = p.y;\n var delta_lon = adjust_lon(lon - this.long0);\n /* Transformation */\n gfi = Math.pow(((1 + this.e * Math.sin(lat)) / (1 - this.e * Math.sin(lat))), (this.alfa * this.e / 2));\n u = 2 * (Math.atan(this.k * Math.pow(Math.tan(lat / 2 + this.s45), this.alfa) / gfi) - this.s45);\n deltav = -delta_lon * this.alfa;\n s = Math.asin(Math.cos(this.ad) * Math.sin(u) + Math.sin(this.ad) * Math.cos(u) * Math.cos(deltav));\n d = Math.asin(Math.cos(u) * Math.sin(deltav) / Math.cos(s));\n eps = this.n * d;\n ro = this.ro0 * Math.pow(Math.tan(this.s0 / 2 + this.s45), this.n) / Math.pow(Math.tan(s / 2 + this.s45), this.n);\n p.y = ro * Math.cos(eps) / 1;\n p.x = ro * Math.sin(eps) / 1;\n\n if (!this.czech) {\n p.y *= -1;\n p.x *= -1;\n }\n return (p);\n};\n\n/* calculate lat/lon from xy */\nexports.inverse = function(p) {\n var u, deltav, s, d, eps, ro, fi1;\n var ok;\n\n /* Transformation */\n /* revert y, x*/\n var tmp = p.x;\n p.x = p.y;\n p.y = tmp;\n if (!this.czech) {\n p.y *= -1;\n p.x *= -1;\n }\n ro = Math.sqrt(p.x * p.x + p.y * p.y);\n eps = Math.atan2(p.y, p.x);\n d = eps / Math.sin(this.s0);\n s = 2 * (Math.atan(Math.pow(this.ro0 / ro, 1 / this.n) * Math.tan(this.s0 / 2 + this.s45)) - this.s45);\n u = Math.asin(Math.cos(this.ad) * Math.sin(s) - Math.sin(this.ad) * Math.cos(s) * Math.cos(d));\n deltav = Math.asin(Math.cos(s) * Math.sin(d) / Math.cos(u));\n p.x = this.long0 - deltav / this.alfa;\n fi1 = u;\n ok = 0;\n var iter = 0;\n do {\n 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);\n if (Math.abs(fi1 - p.y) < 0.0000000001) {\n ok = 1;\n }\n fi1 = p.y;\n iter += 1;\n } while (ok === 0 && iter < 15);\n if (iter >= 15) {\n return null;\n }\n\n return (p);\n};\nexports.names = [\"Krovak\", \"krovak\"];\n","var HALF_PI = Math.PI/2;\nmodule.exports = function(eccent, ts) {\n var eccnth = 0.5 * eccent;\n var con, dphi;\n var phi = HALF_PI - 2 * Math.atan(ts);\n for (var i = 0; i <= 15; i++) {\n con = eccent * Math.sin(phi);\n dphi = HALF_PI - 2 * Math.atan(ts * (Math.pow(((1 - con) / (1 + con)), eccnth))) - phi;\n phi += dphi;\n if (Math.abs(dphi) <= 0.0000000001) {\n return phi;\n }\n }\n //console.log(\"phi2z has NoConvergence\");\n return -9999;\n};","var HALF_PI = Math.PI/2;\n\nmodule.exports = function(eccent, phi, sinphi) {\n var con = eccent * sinphi;\n var com = 0.5 * eccent;\n con = Math.pow(((1 - con) / (1 + con)), com);\n return (Math.tan(0.5 * (HALF_PI - phi)) / con);\n};","var EPSLN = 1.0e-10;\nvar msfnz = require('../common/msfnz');\nvar tsfnz = require('../common/tsfnz');\nvar HALF_PI = Math.PI/2;\nvar sign = require('../common/sign');\nvar adjust_lon = require('../common/adjust_lon');\nvar phi2z = require('../common/phi2z');\nexports.init = function() {\n\n // array of: r_maj,r_min,lat1,lat2,c_lon,c_lat,false_east,false_north\n //double c_lat; /* center latitude */\n //double c_lon; /* center longitude */\n //double lat1; /* first standard parallel */\n //double lat2; /* second standard parallel */\n //double r_maj; /* major axis */\n //double r_min; /* minor axis */\n //double false_east; /* x offset in meters */\n //double false_north; /* y offset in meters */\n\n if (!this.lat2) {\n this.lat2 = this.lat1;\n } //if lat2 is not defined\n if (!this.k0) {\n this.k0 = 1;\n }\n this.x0 = this.x0 || 0;\n this.y0 = this.y0 || 0;\n // Standard Parallels cannot be equal and on opposite sides of the equator\n if (Math.abs(this.lat1 + this.lat2) < EPSLN) {\n return;\n }\n\n var temp = this.b / this.a;\n this.e = Math.sqrt(1 - temp * temp);\n\n var sin1 = Math.sin(this.lat1);\n var cos1 = Math.cos(this.lat1);\n var ms1 = msfnz(this.e, sin1, cos1);\n var ts1 = tsfnz(this.e, this.lat1, sin1);\n\n var sin2 = Math.sin(this.lat2);\n var cos2 = Math.cos(this.lat2);\n var ms2 = msfnz(this.e, sin2, cos2);\n var ts2 = tsfnz(this.e, this.lat2, sin2);\n\n var ts0 = tsfnz(this.e, this.lat0, Math.sin(this.lat0));\n\n if (Math.abs(this.lat1 - this.lat2) > EPSLN) {\n this.ns = Math.log(ms1 / ms2) / Math.log(ts1 / ts2);\n }\n else {\n this.ns = sin1;\n }\n if (isNaN(this.ns)) {\n this.ns = sin1;\n }\n this.f0 = ms1 / (this.ns * Math.pow(ts1, this.ns));\n this.rh = this.a * this.f0 * Math.pow(ts0, this.ns);\n if (!this.title) {\n this.title = \"Lambert Conformal Conic\";\n }\n};\n\n\n// Lambert Conformal conic forward equations--mapping lat,long to x,y\n// -----------------------------------------------------------------\nexports.forward = function(p) {\n\n var lon = p.x;\n var lat = p.y;\n\n // singular cases :\n if (Math.abs(2 * Math.abs(lat) - Math.PI) <= EPSLN) {\n lat = sign(lat) * (HALF_PI - 2 * EPSLN);\n }\n\n var con = Math.abs(Math.abs(lat) - HALF_PI);\n var ts, rh1;\n if (con > EPSLN) {\n ts = tsfnz(this.e, lat, Math.sin(lat));\n rh1 = this.a * this.f0 * Math.pow(ts, this.ns);\n }\n else {\n con = lat * this.ns;\n if (con <= 0) {\n return null;\n }\n rh1 = 0;\n }\n var theta = this.ns * adjust_lon(lon - this.long0);\n p.x = this.k0 * (rh1 * Math.sin(theta)) + this.x0;\n p.y = this.k0 * (this.rh - rh1 * Math.cos(theta)) + this.y0;\n\n return p;\n};\n\n// Lambert Conformal Conic inverse equations--mapping x,y to lat/long\n// -----------------------------------------------------------------\nexports.inverse = function(p) {\n\n var rh1, con, ts;\n var lat, lon;\n var x = (p.x - this.x0) / this.k0;\n var y = (this.rh - (p.y - this.y0) / this.k0);\n if (this.ns > 0) {\n rh1 = Math.sqrt(x * x + y * y);\n con = 1;\n }\n else {\n rh1 = -Math.sqrt(x * x + y * y);\n con = -1;\n }\n var theta = 0;\n if (rh1 !== 0) {\n theta = Math.atan2((con * x), (con * y));\n }\n if ((rh1 !== 0) || (this.ns > 0)) {\n con = 1 / this.ns;\n ts = Math.pow((rh1 / (this.a * this.f0)), con);\n lat = phi2z(this.e, ts);\n if (lat === -9999) {\n return null;\n }\n }\n else {\n lat = -HALF_PI;\n }\n lon = adjust_lon(theta / this.ns + this.long0);\n\n p.x = lon;\n p.y = lat;\n return p;\n};\n\nexports.names = [\"Lambert Tangential Conformal Conic Projection\", \"Lambert_Conformal_Conic\", \"Lambert_Conformal_Conic_2SP\", \"lcc\"];\n","var tsfnz = require('../common/tsfnz');\nvar adjust_lon = require('../common/adjust_lon');\nvar phi2z = require('../common/phi2z');\nvar HALF_PI = Math.PI/2;\nvar FORTPI = Math.PI/4;\nvar EPSLN = 1.0e-10;\n\n/* Initialize the Oblique Mercator projection\n ------------------------------------------*/\nexports.init = function() {\n this.no_off = this.no_off || false;\n this.no_rot = this.no_rot || false;\n\n if (isNaN(this.k0)) {\n this.k0 = 1;\n }\n var sinlat = Math.sin(this.lat0);\n var coslat = Math.cos(this.lat0);\n var con = this.e * sinlat;\n\n this.bl = Math.sqrt(1 + this.es / (1 - this.es) * Math.pow(coslat, 4));\n this.al = this.a * this.bl * this.k0 * Math.sqrt(1 - this.es) / (1 - con * con);\n var t0 = tsfnz(this.e, this.lat0, sinlat);\n var dl = this.bl / coslat * Math.sqrt((1 - this.es) / (1 - con * con));\n if (dl * dl < 1) {\n dl = 1;\n }\n var fl;\n var gl;\n if (!isNaN(this.longc)) {\n //Central point and azimuth method\n\n if (this.lat0 >= 0) {\n fl = dl + Math.sqrt(dl * dl - 1);\n }\n else {\n fl = dl - Math.sqrt(dl * dl - 1);\n }\n this.el = fl * Math.pow(t0, this.bl);\n gl = 0.5 * (fl - 1 / fl);\n this.gamma0 = Math.asin(Math.sin(this.alpha) / dl);\n this.long0 = this.longc - Math.asin(gl * Math.tan(this.gamma0)) / this.bl;\n\n }\n else {\n //2 points method\n var t1 = tsfnz(this.e, this.lat1, Math.sin(this.lat1));\n var t2 = tsfnz(this.e, this.lat2, Math.sin(this.lat2));\n if (this.lat0 >= 0) {\n this.el = (dl + Math.sqrt(dl * dl - 1)) * Math.pow(t0, this.bl);\n }\n else {\n this.el = (dl - Math.sqrt(dl * dl - 1)) * Math.pow(t0, this.bl);\n }\n var hl = Math.pow(t1, this.bl);\n var ll = Math.pow(t2, this.bl);\n fl = this.el / hl;\n gl = 0.5 * (fl - 1 / fl);\n var jl = (this.el * this.el - ll * hl) / (this.el * this.el + ll * hl);\n var pl = (ll - hl) / (ll + hl);\n var dlon12 = adjust_lon(this.long1 - this.long2);\n this.long0 = 0.5 * (this.long1 + this.long2) - Math.atan(jl * Math.tan(0.5 * this.bl * (dlon12)) / pl) / this.bl;\n this.long0 = adjust_lon(this.long0);\n var dlon10 = adjust_lon(this.long1 - this.long0);\n this.gamma0 = Math.atan(Math.sin(this.bl * (dlon10)) / gl);\n this.alpha = Math.asin(dl * Math.sin(this.gamma0));\n }\n\n if (this.no_off) {\n this.uc = 0;\n }\n else {\n if (this.lat0 >= 0) {\n this.uc = this.al / this.bl * Math.atan2(Math.sqrt(dl * dl - 1), Math.cos(this.alpha));\n }\n else {\n this.uc = -1 * this.al / this.bl * Math.atan2(Math.sqrt(dl * dl - 1), Math.cos(this.alpha));\n }\n }\n\n};\n\n\n/* Oblique Mercator forward equations--mapping lat,long to x,y\n ----------------------------------------------------------*/\nexports.forward = function(p) {\n var lon = p.x;\n var lat = p.y;\n var dlon = adjust_lon(lon - this.long0);\n var us, vs;\n var con;\n if (Math.abs(Math.abs(lat) - HALF_PI) <= EPSLN) {\n if (lat > 0) {\n con = -1;\n }\n else {\n con = 1;\n }\n vs = this.al / this.bl * Math.log(Math.tan(FORTPI + con * this.gamma0 * 0.5));\n us = -1 * con * HALF_PI * this.al / this.bl;\n }\n else {\n var t = tsfnz(this.e, lat, Math.sin(lat));\n var ql = this.el / Math.pow(t, this.bl);\n var sl = 0.5 * (ql - 1 / ql);\n var tl = 0.5 * (ql + 1 / ql);\n var vl = Math.sin(this.bl * (dlon));\n var ul = (sl * Math.sin(this.gamma0) - vl * Math.cos(this.gamma0)) / tl;\n if (Math.abs(Math.abs(ul) - 1) <= EPSLN) {\n vs = Number.POSITIVE_INFINITY;\n }\n else {\n vs = 0.5 * this.al * Math.log((1 - ul) / (1 + ul)) / this.bl;\n }\n if (Math.abs(Math.cos(this.bl * (dlon))) <= EPSLN) {\n us = this.al * this.bl * (dlon);\n }\n else {\n us = this.al * Math.atan2(sl * Math.cos(this.gamma0) + vl * Math.sin(this.gamma0), Math.cos(this.bl * dlon)) / this.bl;\n }\n }\n\n if (this.no_rot) {\n p.x = this.x0 + us;\n p.y = this.y0 + vs;\n }\n else {\n\n us -= this.uc;\n p.x = this.x0 + vs * Math.cos(this.alpha) + us * Math.sin(this.alpha);\n p.y = this.y0 + us * Math.cos(this.alpha) - vs * Math.sin(this.alpha);\n }\n return p;\n};\n\nexports.inverse = function(p) {\n var us, vs;\n if (this.no_rot) {\n vs = p.y - this.y0;\n us = p.x - this.x0;\n }\n else {\n vs = (p.x - this.x0) * Math.cos(this.alpha) - (p.y - this.y0) * Math.sin(this.alpha);\n us = (p.y - this.y0) * Math.cos(this.alpha) + (p.x - this.x0) * Math.sin(this.alpha);\n us += this.uc;\n }\n var qp = Math.exp(-1 * this.bl * vs / this.al);\n var sp = 0.5 * (qp - 1 / qp);\n var tp = 0.5 * (qp + 1 / qp);\n var vp = Math.sin(this.bl * us / this.al);\n var up = (vp * Math.cos(this.gamma0) + sp * Math.sin(this.gamma0)) / tp;\n var ts = Math.pow(this.el / Math.sqrt((1 + up) / (1 - up)), 1 / this.bl);\n if (Math.abs(up - 1) < EPSLN) {\n p.x = this.long0;\n p.y = HALF_PI;\n }\n else if (Math.abs(up + 1) < EPSLN) {\n p.x = this.long0;\n p.y = -1 * HALF_PI;\n }\n else {\n p.y = phi2z(this.e, ts);\n 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);\n }\n return p;\n};\n\nexports.names = [\"Hotine_Oblique_Mercator\", \"Hotine Oblique Mercator\", \"Hotine_Oblique_Mercator_Azimuth_Natural_Origin\", \"Hotine_Oblique_Mercator_Azimuth_Center\", \"omerc\"];","/*\n references:\n Formules et constantes pour le Calcul pour la\n projection cylindrique conforme à axe oblique et pour la transformation entre\n des systèmes de référence.\n http://www.swisstopo.admin.ch/internet/swisstopo/fr/home/topics/survey/sys/refsys/switzerland.parsysrelated1.31216.downloadList.77004.DownloadFile.tmp/swissprojectionfr.pdf\n */\nexports.init = function() {\n var phy0 = this.lat0;\n this.lambda0 = this.long0;\n var sinPhy0 = Math.sin(phy0);\n var semiMajorAxis = this.a;\n var invF = this.rf;\n var flattening = 1 / invF;\n var e2 = 2 * flattening - Math.pow(flattening, 2);\n var e = this.e = Math.sqrt(e2);\n this.R = this.k0 * semiMajorAxis * Math.sqrt(1 - e2) / (1 - e2 * Math.pow(sinPhy0, 2));\n this.alpha = Math.sqrt(1 + e2 / (1 - e2) * Math.pow(Math.cos(phy0), 4));\n this.b0 = Math.asin(sinPhy0 / this.alpha);\n var k1 = Math.log(Math.tan(Math.PI / 4 + this.b0 / 2));\n var k2 = Math.log(Math.tan(Math.PI / 4 + phy0 / 2));\n var k3 = Math.log((1 + e * sinPhy0) / (1 - e * sinPhy0));\n this.K = k1 - this.alpha * k2 + this.alpha * e / 2 * k3;\n};\n\n\nexports.forward = function(p) {\n var Sa1 = Math.log(Math.tan(Math.PI / 4 - p.y / 2));\n var Sa2 = this.e / 2 * Math.log((1 + this.e * Math.sin(p.y)) / (1 - this.e * Math.sin(p.y)));\n var S = -this.alpha * (Sa1 + Sa2) + this.K;\n\n // spheric latitude\n var b = 2 * (Math.atan(Math.exp(S)) - Math.PI / 4);\n\n // spheric longitude\n var I = this.alpha * (p.x - this.lambda0);\n\n // psoeudo equatorial rotation\n var rotI = Math.atan(Math.sin(I) / (Math.sin(this.b0) * Math.tan(b) + Math.cos(this.b0) * Math.cos(I)));\n\n var rotB = Math.asin(Math.cos(this.b0) * Math.sin(b) - Math.sin(this.b0) * Math.cos(b) * Math.cos(I));\n\n p.y = this.R / 2 * Math.log((1 + Math.sin(rotB)) / (1 - Math.sin(rotB))) + this.y0;\n p.x = this.R * rotI + this.x0;\n return p;\n};\n\nexports.inverse = function(p) {\n var Y = p.x - this.x0;\n var X = p.y - this.y0;\n\n var rotI = Y / this.R;\n var rotB = 2 * (Math.atan(Math.exp(X / this.R)) - Math.PI / 4);\n\n var b = Math.asin(Math.cos(this.b0) * Math.sin(rotB) + Math.sin(this.b0) * Math.cos(rotB) * Math.cos(rotI));\n var I = Math.atan(Math.sin(rotI) / (Math.cos(this.b0) * Math.cos(rotI) - Math.sin(this.b0) * Math.tan(rotB)));\n\n var lambda = this.lambda0 + I / this.alpha;\n\n var S = 0;\n var phy = b;\n var prevPhy = -1000;\n var iteration = 0;\n while (Math.abs(phy - prevPhy) > 0.0000001) {\n if (++iteration > 20) {\n //...reportError(\"omercFwdInfinity\");\n return;\n }\n //S = Math.log(Math.tan(Math.PI / 4 + phy / 2));\n 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));\n prevPhy = phy;\n phy = 2 * Math.atan(Math.exp(S)) - Math.PI / 2;\n }\n\n p.x = lambda;\n p.y = phy;\n return p;\n};\n\nexports.names = [\"somerc\"];\n","var HALF_PI = Math.PI/2;\nvar EPSLN = 1.0e-10;\nvar sign = require('../common/sign');\nvar msfnz = require('../common/msfnz');\nvar tsfnz = require('../common/tsfnz');\nvar phi2z = require('../common/phi2z');\nvar adjust_lon = require('../common/adjust_lon');\nexports.ssfn_ = function(phit, sinphi, eccen) {\n sinphi *= eccen;\n return (Math.tan(0.5 * (HALF_PI + phit)) * Math.pow((1 - sinphi) / (1 + sinphi), 0.5 * eccen));\n};\n\nexports.init = function() {\n this.coslat0 = Math.cos(this.lat0);\n this.sinlat0 = Math.sin(this.lat0);\n if (this.sphere) {\n if (this.k0 === 1 && !isNaN(this.lat_ts) && Math.abs(this.coslat0) <= EPSLN) {\n this.k0 = 0.5 * (1 + sign(this.lat0) * Math.sin(this.lat_ts));\n }\n }\n else {\n if (Math.abs(this.coslat0) <= EPSLN) {\n if (this.lat0 > 0) {\n //North pole\n //trace('stere:north pole');\n this.con = 1;\n }\n else {\n //South pole\n //trace('stere:south pole');\n this.con = -1;\n }\n }\n this.cons = Math.sqrt(Math.pow(1 + this.e, 1 + this.e) * Math.pow(1 - this.e, 1 - this.e));\n if (this.k0 === 1 && !isNaN(this.lat_ts) && Math.abs(this.coslat0) <= EPSLN) {\n 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));\n }\n this.ms1 = msfnz(this.e, this.sinlat0, this.coslat0);\n this.X0 = 2 * Math.atan(this.ssfn_(this.lat0, this.sinlat0, this.e)) - HALF_PI;\n this.cosX0 = Math.cos(this.X0);\n this.sinX0 = Math.sin(this.X0);\n }\n};\n\n// Stereographic forward equations--mapping lat,long to x,y\nexports.forward = function(p) {\n var lon = p.x;\n var lat = p.y;\n var sinlat = Math.sin(lat);\n var coslat = Math.cos(lat);\n var A, X, sinX, cosX, ts, rh;\n var dlon = adjust_lon(lon - this.long0);\n\n if (Math.abs(Math.abs(lon - this.long0) - Math.PI) <= EPSLN && Math.abs(lat + this.lat0) <= EPSLN) {\n //case of the origine point\n //trace('stere:this is the origin point');\n p.x = NaN;\n p.y = NaN;\n return p;\n }\n if (this.sphere) {\n //trace('stere:sphere case');\n A = 2 * this.k0 / (1 + this.sinlat0 * sinlat + this.coslat0 * coslat * Math.cos(dlon));\n p.x = this.a * A * coslat * Math.sin(dlon) + this.x0;\n p.y = this.a * A * (this.coslat0 * sinlat - this.sinlat0 * coslat * Math.cos(dlon)) + this.y0;\n return p;\n }\n else {\n X = 2 * Math.atan(this.ssfn_(lat, sinlat, this.e)) - HALF_PI;\n cosX = Math.cos(X);\n sinX = Math.sin(X);\n if (Math.abs(this.coslat0) <= EPSLN) {\n ts = tsfnz(this.e, lat * this.con, this.con * sinlat);\n rh = 2 * this.a * this.k0 * ts / this.cons;\n p.x = this.x0 + rh * Math.sin(lon - this.long0);\n p.y = this.y0 - this.con * rh * Math.cos(lon - this.long0);\n //trace(p.toString());\n return p;\n }\n else if (Math.abs(this.sinlat0) < EPSLN) {\n //Eq\n //trace('stere:equateur');\n A = 2 * this.a * this.k0 / (1 + cosX * Math.cos(dlon));\n p.y = A * sinX;\n }\n else {\n //other case\n //trace('stere:normal case');\n A = 2 * this.a * this.k0 * this.ms1 / (this.cosX0 * (1 + this.sinX0 * sinX + this.cosX0 * cosX * Math.cos(dlon)));\n p.y = A * (this.cosX0 * sinX - this.sinX0 * cosX * Math.cos(dlon)) + this.y0;\n }\n p.x = A * cosX * Math.sin(dlon) + this.x0;\n }\n //trace(p.toString());\n return p;\n};\n\n\n//* Stereographic inverse equations--mapping x,y to lat/long\nexports.inverse = function(p) {\n p.x -= this.x0;\n p.y -= this.y0;\n var lon, lat, ts, ce, Chi;\n var rh = Math.sqrt(p.x * p.x + p.y * p.y);\n if (this.sphere) {\n var c = 2 * Math.atan(rh / (0.5 * this.a * this.k0));\n lon = this.long0;\n lat = this.lat0;\n if (rh <= EPSLN) {\n p.x = lon;\n p.y = lat;\n return p;\n }\n lat = Math.asin(Math.cos(c) * this.sinlat0 + p.y * Math.sin(c) * this.coslat0 / rh);\n if (Math.abs(this.coslat0) < EPSLN) {\n if (this.lat0 > 0) {\n lon = adjust_lon(this.long0 + Math.atan2(p.x, - 1 * p.y));\n }\n else {\n lon = adjust_lon(this.long0 + Math.atan2(p.x, p.y));\n }\n }\n else {\n 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)));\n }\n p.x = lon;\n p.y = lat;\n return p;\n }\n else {\n if (Math.abs(this.coslat0) <= EPSLN) {\n if (rh <= EPSLN) {\n lat = this.lat0;\n lon = this.long0;\n p.x = lon;\n p.y = lat;\n //trace(p.toString());\n return p;\n }\n p.x *= this.con;\n p.y *= this.con;\n ts = rh * this.cons / (2 * this.a * this.k0);\n lat = this.con * phi2z(this.e, ts);\n lon = this.con * adjust_lon(this.con * this.long0 + Math.atan2(p.x, - 1 * p.y));\n }\n else {\n ce = 2 * Math.atan(rh * this.cosX0 / (2 * this.a * this.k0 * this.ms1));\n lon = this.long0;\n if (rh <= EPSLN) {\n Chi = this.X0;\n }\n else {\n Chi = Math.asin(Math.cos(ce) * this.sinX0 + p.y * Math.sin(ce) * this.cosX0 / rh);\n 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)));\n }\n lat = -1 * phi2z(this.e, Math.tan(0.5 * (HALF_PI + Chi)));\n }\n }\n p.x = lon;\n p.y = lat;\n\n //trace(p.toString());\n return p;\n\n};\nexports.names = [\"stere\", \"Stereographic_South_Pole\", \"Polar Stereographic (variant B)\"];\n","module.exports = function(esinp, exp) {\n return (Math.pow((1 - esinp) / (1 + esinp), exp));\n};","var FORTPI = Math.PI/4;\nvar srat = require('../common/srat');\nvar HALF_PI = Math.PI/2;\nvar MAX_ITER = 20;\nexports.init = function() {\n var sphi = Math.sin(this.lat0);\n var cphi = Math.cos(this.lat0);\n cphi *= cphi;\n this.rc = Math.sqrt(1 - this.es) / (1 - this.es * sphi * sphi);\n this.C = Math.sqrt(1 + this.es * cphi * cphi / (1 - this.es));\n this.phic0 = Math.asin(sphi / this.C);\n this.ratexp = 0.5 * this.C * this.e;\n 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));\n};\n\nexports.forward = function(p) {\n var lon = p.x;\n var lat = p.y;\n\n 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;\n p.x = this.C * lon;\n return p;\n};\n\nexports.inverse = function(p) {\n var DEL_TOL = 1e-14;\n var lon = p.x / this.C;\n var lat = p.y;\n var num = Math.pow(Math.tan(0.5 * lat + FORTPI) / this.K, 1 / this.C);\n for (var i = MAX_ITER; i > 0; --i) {\n lat = 2 * Math.atan(num * srat(this.e * Math.sin(p.y), - 0.5 * this.e)) - HALF_PI;\n if (Math.abs(lat - p.y) < DEL_TOL) {\n break;\n }\n p.y = lat;\n }\n /* convergence failed */\n if (!i) {\n return null;\n }\n p.x = lon;\n p.y = lat;\n return p;\n};\nexports.names = [\"gauss\"];\n","var gauss = require('./gauss');\nvar adjust_lon = require('../common/adjust_lon');\nexports.init = function() {\n gauss.init.apply(this);\n if (!this.rc) {\n return;\n }\n this.sinc0 = Math.sin(this.phic0);\n this.cosc0 = Math.cos(this.phic0);\n this.R2 = 2 * this.rc;\n if (!this.title) {\n this.title = \"Oblique Stereographic Alternative\";\n }\n};\n\nexports.forward = function(p) {\n var sinc, cosc, cosl, k;\n p.x = adjust_lon(p.x - this.long0);\n gauss.forward.apply(this, [p]);\n sinc = Math.sin(p.y);\n cosc = Math.cos(p.y);\n cosl = Math.cos(p.x);\n k = this.k0 * this.R2 / (1 + this.sinc0 * sinc + this.cosc0 * cosc * cosl);\n p.x = k * cosc * Math.sin(p.x);\n p.y = k * (this.cosc0 * sinc - this.sinc0 * cosc * cosl);\n p.x = this.a * p.x + this.x0;\n p.y = this.a * p.y + this.y0;\n return p;\n};\n\nexports.inverse = function(p) {\n var sinc, cosc, lon, lat, rho;\n p.x = (p.x - this.x0) / this.a;\n p.y = (p.y - this.y0) / this.a;\n\n p.x /= this.k0;\n p.y /= this.k0;\n if ((rho = Math.sqrt(p.x * p.x + p.y * p.y))) {\n var c = 2 * Math.atan2(rho, this.R2);\n sinc = Math.sin(c);\n cosc = Math.cos(c);\n lat = Math.asin(cosc * this.sinc0 + p.y * sinc * this.cosc0 / rho);\n lon = Math.atan2(p.x * sinc, rho * this.cosc0 * cosc - p.y * this.sinc0 * sinc);\n }\n else {\n lat = this.phic0;\n lon = 0;\n }\n\n p.x = lon;\n p.y = lat;\n gauss.inverse.apply(this, [p]);\n p.x = adjust_lon(p.x + this.long0);\n return p;\n};\n\nexports.names = [\"Stereographic_North_Pole\", \"Oblique_Stereographic\", \"Polar_Stereographic\", \"sterea\",\"Oblique Stereographic Alternative\"];\n","var e0fn = require('../common/e0fn');\nvar e1fn = require('../common/e1fn');\nvar e2fn = require('../common/e2fn');\nvar e3fn = require('../common/e3fn');\nvar mlfn = require('../common/mlfn');\nvar adjust_lon = require('../common/adjust_lon');\nvar HALF_PI = Math.PI/2;\nvar EPSLN = 1.0e-10;\nvar sign = require('../common/sign');\nvar asinz = require('../common/asinz');\n\nexports.init = function() {\n this.e0 = e0fn(this.es);\n this.e1 = e1fn(this.es);\n this.e2 = e2fn(this.es);\n this.e3 = e3fn(this.es);\n this.ml0 = this.a * mlfn(this.e0, this.e1, this.e2, this.e3, this.lat0);\n};\n\n/**\n Transverse Mercator Forward - long/lat to x/y\n long/lat in radians\n */\nexports.forward = function(p) {\n var lon = p.x;\n var lat = p.y;\n\n var delta_lon = adjust_lon(lon - this.long0);\n var con;\n var x, y;\n var sin_phi = Math.sin(lat);\n var cos_phi = Math.cos(lat);\n\n if (this.sphere) {\n var b = cos_phi * Math.sin(delta_lon);\n if ((Math.abs(Math.abs(b) - 1)) < 0.0000000001) {\n return (93);\n }\n else {\n x = 0.5 * this.a * this.k0 * Math.log((1 + b) / (1 - b));\n con = Math.acos(cos_phi * Math.cos(delta_lon) / Math.sqrt(1 - b * b));\n if (lat < 0) {\n con = -con;\n }\n y = this.a * this.k0 * (con - this.lat0);\n }\n }\n else {\n var al = cos_phi * delta_lon;\n var als = Math.pow(al, 2);\n var c = this.ep2 * Math.pow(cos_phi, 2);\n var tq = Math.tan(lat);\n var t = Math.pow(tq, 2);\n con = 1 - this.es * Math.pow(sin_phi, 2);\n var n = this.a / Math.sqrt(con);\n var ml = this.a * mlfn(this.e0, this.e1, this.e2, this.e3, lat);\n\n 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;\n 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;\n\n }\n p.x = x;\n p.y = y;\n return p;\n};\n\n/**\n Transverse Mercator Inverse - x/y to long/lat\n */\nexports.inverse = function(p) {\n var con, phi;\n var delta_phi;\n var i;\n var max_iter = 6;\n var lat, lon;\n\n if (this.sphere) {\n var f = Math.exp(p.x / (this.a * this.k0));\n var g = 0.5 * (f - 1 / f);\n var temp = this.lat0 + p.y / (this.a * this.k0);\n var h = Math.cos(temp);\n con = Math.sqrt((1 - h * h) / (1 + g * g));\n lat = asinz(con);\n if (temp < 0) {\n lat = -lat;\n }\n if ((g === 0) && (h === 0)) {\n lon = this.long0;\n }\n else {\n lon = adjust_lon(Math.atan2(g, h) + this.long0);\n }\n }\n else { // ellipsoidal form\n var x = p.x - this.x0;\n var y = p.y - this.y0;\n\n con = (this.ml0 + y / this.k0) / this.a;\n phi = con;\n for (i = 0; true; i++) {\n delta_phi = ((con + this.e1 * Math.sin(2 * phi) - this.e2 * Math.sin(4 * phi) + this.e3 * Math.sin(6 * phi)) / this.e0) - phi;\n phi += delta_phi;\n if (Math.abs(delta_phi) <= EPSLN) {\n break;\n }\n if (i >= max_iter) {\n return (95);\n }\n } // for()\n if (Math.abs(phi) < HALF_PI) {\n var sin_phi = Math.sin(phi);\n var cos_phi = Math.cos(phi);\n var tan_phi = Math.tan(phi);\n var c = this.ep2 * Math.pow(cos_phi, 2);\n var cs = Math.pow(c, 2);\n var t = Math.pow(tan_phi, 2);\n var ts = Math.pow(t, 2);\n con = 1 - this.es * Math.pow(sin_phi, 2);\n var n = this.a / Math.sqrt(con);\n var r = n * (1 - this.es) / con;\n var d = x / (n * this.k0);\n var ds = Math.pow(d, 2);\n 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)));\n 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));\n }\n else {\n lat = HALF_PI * sign(y);\n lon = this.long0;\n }\n }\n p.x = lon;\n p.y = lat;\n return p;\n};\nexports.names = [\"Transverse_Mercator\", \"Transverse Mercator\", \"tmerc\"];\n","var D2R = 0.01745329251994329577;\nvar tmerc = require('./tmerc');\nexports.dependsOn = 'tmerc';\nexports.init = function() {\n if (!this.zone) {\n return;\n }\n this.lat0 = 0;\n this.long0 = ((6 * Math.abs(this.zone)) - 183) * D2R;\n this.x0 = 500000;\n this.y0 = this.utmSouth ? 10000000 : 0;\n this.k0 = 0.9996;\n\n tmerc.init.apply(this);\n this.forward = tmerc.forward;\n this.inverse = tmerc.inverse;\n};\nexports.names = [\"Universal Transverse Mercator System\", \"utm\"];\n","var projs = [\n require('./projections/tmerc'),\n require('./projections/utm'),\n require('./projections/sterea'),\n require('./projections/stere'),\n require('./projections/somerc'),\n require('./projections/omerc'),\n require('./projections/lcc'),\n require('./projections/krovak'),\n require('./projections/cass'),\n require('./projections/laea'),\n require('./projections/aea'),\n require('./projections/gnom'),\n require('./projections/cea'),\n require('./projections/eqc'),\n require('./projections/poly'),\n require('./projections/nzmg'),\n require('./projections/mill'),\n require('./projections/sinu'),\n require('./projections/moll'),\n require('./projections/eqdc'),\n require('./projections/vandg'),\n require('./projections/aeqd')\n];\nmodule.exports = function(proj4){\n projs.forEach(function(proj){\n proj4.Proj.projections.add(proj);\n });\n};","{\n \"name\": \"proj4\",\n \"version\": \"2.3.14\",\n \"description\": \"Proj4js is a JavaScript library to transform point coordinates from one coordinate system to another, including datum transformations.\",\n \"main\": \"lib/index.js\",\n \"directories\": {\n \"test\": \"test\",\n \"doc\": \"docs\"\n },\n \"scripts\": {\n \"test\": \"./node_modules/istanbul/lib/cli.js test ./node_modules/mocha/bin/_mocha test/test.js\"\n },\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"git://github.com/proj4js/proj4js.git\"\n },\n \"author\": \"\",\n \"license\": \"MIT\",\n \"jam\": {\n \"main\": \"dist/proj4.js\",\n \"include\": [\n \"dist/proj4.js\",\n \"README.md\",\n \"AUTHORS\",\n \"LICENSE.md\"\n ]\n },\n \"devDependencies\": {\n \"grunt-cli\": \"~0.1.13\",\n \"grunt\": \"~0.4.2\",\n \"grunt-contrib-connect\": \"~0.6.0\",\n \"grunt-contrib-jshint\": \"~0.8.0\",\n \"chai\": \"~1.8.1\",\n \"mocha\": \"~1.17.1\",\n \"grunt-mocha-phantomjs\": \"~0.4.0\",\n \"browserify\": \"~12.0.1\",\n \"grunt-browserify\": \"~4.0.1\",\n \"grunt-contrib-uglify\": \"~0.11.1\",\n \"curl\": \"git://github.com/cujojs/curl.git\",\n \"istanbul\": \"~0.2.4\",\n \"tin\": \"~0.4.0\"\n },\n \"dependencies\": {\n \"mgrs\": \"~0.0.2\"\n },\n \"contributors\": [\n {\n \"name\": \"Mike Adair\",\n \"email\": \"madair@dmsolutions.ca\"\n },\n {\n \"name\": \"Richard Greenwood\",\n \"email\": \"rich@greenwoodmap.com\"\n },\n {\n \"name\": \"Calvin Metcalf\",\n \"email\": \"calvin.metcalf@gmail.com\"\n },\n {\n \"name\": \"Richard Marsden\",\n \"url\": \"http://www.winwaed.com\"\n },\n {\n \"name\": \"T. Mittan\"\n },\n {\n \"name\": \"D. Steinwand\"\n },\n {\n \"name\": \"S. Nelson\"\n }\n ],\n \"gitHead\": \"7619c8a63df1eae5bad0b9ad31ca1d87b0549243\",\n \"bugs\": {\n \"url\": \"https://github.com/proj4js/proj4js/issues\"\n },\n \"homepage\": \"https://github.com/proj4js/proj4js#readme\",\n \"_id\": \"proj4@2.3.14\",\n \"_shasum\": \"928906144388980c914c5a357fc493aba59a747a\",\n \"_from\": \"proj4@>=2.3.14 <3.0.0\",\n \"_npmVersion\": \"2.14.12\",\n \"_nodeVersion\": \"4.2.6\",\n \"_npmUser\": {\n \"name\": \"ahocevar\",\n \"email\": \"andreas.hocevar@gmail.com\"\n },\n \"dist\": {\n \"shasum\": \"928906144388980c914c5a357fc493aba59a747a\",\n \"tarball\": \"https://registry.npmjs.org/proj4/-/proj4-2.3.14.tgz\"\n },\n \"maintainers\": [\n {\n \"name\": \"cwmma\",\n \"email\": \"calvin.metcalf@gmail.com\"\n },\n {\n \"name\": \"ahocevar\",\n \"email\": \"andreas.hocevar@gmail.com\"\n }\n ],\n \"_npmOperationalInternal\": {\n \"host\": \"packages-13-west.internal.npmjs.com\",\n \"tmp\": \"tmp/proj4-2.3.14.tgz_1457689264880_0.9409773757215589\"\n },\n \"_resolved\": \"https://registry.npmjs.org/proj4/-/proj4-2.3.14.tgz\",\n \"readme\": \"ERROR: No README data found!\"\n}\n","\n\n\n/**\n * UTM zones are grouped, and assigned to one of a group of 6\n * sets.\n *\n * {int} @private\n */\nvar NUM_100K_SETS = 6;\n\n/**\n * The column letters (for easting) of the lower left value, per\n * set.\n *\n * {string} @private\n */\nvar SET_ORIGIN_COLUMN_LETTERS = 'AJSAJS';\n\n/**\n * The row letters (for northing) of the lower left value, per\n * set.\n *\n * {string} @private\n */\nvar SET_ORIGIN_ROW_LETTERS = 'AFAFAF';\n\nvar A = 65; // A\nvar I = 73; // I\nvar O = 79; // O\nvar V = 86; // V\nvar Z = 90; // Z\n\n/**\n * Conversion of lat/lon to MGRS.\n *\n * @param {object} ll Object literal with lat and lon properties on a\n * WGS84 ellipsoid.\n * @param {int} accuracy Accuracy in digits (5 for 1 m, 4 for 10 m, 3 for\n * 100 m, 2 for 1000 m or 1 for 10000 m). Optional, default is 5.\n * @return {string} the MGRS string for the given location and accuracy.\n */\nexports.forward = function(ll, accuracy) {\n accuracy = accuracy || 5; // default accuracy 1m\n return encode(LLtoUTM({\n lat: ll[1],\n lon: ll[0]\n }), accuracy);\n};\n\n/**\n * Conversion of MGRS to lat/lon.\n *\n * @param {string} mgrs MGRS string.\n * @return {array} An array with left (longitude), bottom (latitude), right\n * (longitude) and top (latitude) values in WGS84, representing the\n * bounding box for the provided MGRS reference.\n */\nexports.inverse = function(mgrs) {\n var bbox = UTMtoLL(decode(mgrs.toUpperCase()));\n if (bbox.lat && bbox.lon) {\n return [bbox.lon, bbox.lat, bbox.lon, bbox.lat];\n }\n return [bbox.left, bbox.bottom, bbox.right, bbox.top];\n};\n\nexports.toPoint = function(mgrs) {\n var bbox = UTMtoLL(decode(mgrs.toUpperCase()));\n if (bbox.lat && bbox.lon) {\n return [bbox.lon, bbox.lat];\n }\n return [(bbox.left + bbox.right) / 2, (bbox.top + bbox.bottom) / 2];\n};\n/**\n * Conversion from degrees to radians.\n *\n * @private\n * @param {number} deg the angle in degrees.\n * @return {number} the angle in radians.\n */\nfunction degToRad(deg) {\n return (deg * (Math.PI / 180.0));\n}\n\n/**\n * Conversion from radians to degrees.\n *\n * @private\n * @param {number} rad the angle in radians.\n * @return {number} the angle in degrees.\n */\nfunction radToDeg(rad) {\n return (180.0 * (rad / Math.PI));\n}\n\n/**\n * Converts a set of Longitude and Latitude co-ordinates to UTM\n * using the WGS84 ellipsoid.\n *\n * @private\n * @param {object} ll Object literal with lat and lon properties\n * representing the WGS84 coordinate to be converted.\n * @return {object} Object literal containing the UTM value with easting,\n * northing, zoneNumber and zoneLetter properties, and an optional\n * accuracy property in digits. Returns null if the conversion failed.\n */\nfunction LLtoUTM(ll) {\n var Lat = ll.lat;\n var Long = ll.lon;\n var a = 6378137.0; //ellip.radius;\n var eccSquared = 0.00669438; //ellip.eccsq;\n var k0 = 0.9996;\n var LongOrigin;\n var eccPrimeSquared;\n var N, T, C, A, M;\n var LatRad = degToRad(Lat);\n var LongRad = degToRad(Long);\n var LongOriginRad;\n var ZoneNumber;\n // (int)\n ZoneNumber = Math.floor((Long + 180) / 6) + 1;\n\n //Make sure the longitude 180.00 is in Zone 60\n if (Long === 180) {\n ZoneNumber = 60;\n }\n\n // Special zone for Norway\n if (Lat >= 56.0 && Lat < 64.0 && Long >= 3.0 && Long < 12.0) {\n ZoneNumber = 32;\n }\n\n // Special zones for Svalbard\n if (Lat >= 72.0 && Lat < 84.0) {\n if (Long >= 0.0 && Long < 9.0) {\n ZoneNumber = 31;\n }\n else if (Long >= 9.0 && Long < 21.0) {\n ZoneNumber = 33;\n }\n else if (Long >= 21.0 && Long < 33.0) {\n ZoneNumber = 35;\n }\n else if (Long >= 33.0 && Long < 42.0) {\n ZoneNumber = 37;\n }\n }\n\n LongOrigin = (ZoneNumber - 1) * 6 - 180 + 3; //+3 puts origin\n // in middle of\n // zone\n LongOriginRad = degToRad(LongOrigin);\n\n eccPrimeSquared = (eccSquared) / (1 - eccSquared);\n\n N = a / Math.sqrt(1 - eccSquared * Math.sin(LatRad) * Math.sin(LatRad));\n T = Math.tan(LatRad) * Math.tan(LatRad);\n C = eccPrimeSquared * Math.cos(LatRad) * Math.cos(LatRad);\n A = Math.cos(LatRad) * (LongRad - LongOriginRad);\n\n 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));\n\n 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);\n\n 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)));\n if (Lat < 0.0) {\n UTMNorthing += 10000000.0; //10000000 meter offset for\n // southern hemisphere\n }\n\n return {\n northing: Math.round(UTMNorthing),\n easting: Math.round(UTMEasting),\n zoneNumber: ZoneNumber,\n zoneLetter: getLetterDesignator(Lat)\n };\n}\n\n/**\n * Converts UTM coords to lat/long, using the WGS84 ellipsoid. This is a convenience\n * class where the Zone can be specified as a single string eg.\"60N\" which\n * is then broken down into the ZoneNumber and ZoneLetter.\n *\n * @private\n * @param {object} utm An object literal with northing, easting, zoneNumber\n * and zoneLetter properties. If an optional accuracy property is\n * provided (in meters), a bounding box will be returned instead of\n * latitude and longitude.\n * @return {object} An object literal containing either lat and lon values\n * (if no accuracy was provided), or top, right, bottom and left values\n * for the bounding box calculated according to the provided accuracy.\n * Returns null if the conversion failed.\n */\nfunction UTMtoLL(utm) {\n\n var UTMNorthing = utm.northing;\n var UTMEasting = utm.easting;\n var zoneLetter = utm.zoneLetter;\n var zoneNumber = utm.zoneNumber;\n // check the ZoneNummber is valid\n if (zoneNumber < 0 || zoneNumber > 60) {\n return null;\n }\n\n var k0 = 0.9996;\n var a = 6378137.0; //ellip.radius;\n var eccSquared = 0.00669438; //ellip.eccsq;\n var eccPrimeSquared;\n var e1 = (1 - Math.sqrt(1 - eccSquared)) / (1 + Math.sqrt(1 - eccSquared));\n var N1, T1, C1, R1, D, M;\n var LongOrigin;\n var mu, phi1Rad;\n\n // remove 500,000 meter offset for longitude\n var x = UTMEasting - 500000.0;\n var y = UTMNorthing;\n\n // We must know somehow if we are in the Northern or Southern\n // hemisphere, this is the only time we use the letter So even\n // if the Zone letter isn't exactly correct it should indicate\n // the hemisphere correctly\n if (zoneLetter < 'N') {\n y -= 10000000.0; // remove 10,000,000 meter offset used\n // for southern hemisphere\n }\n\n // There are 60 zones with zone 1 being at West -180 to -174\n LongOrigin = (zoneNumber - 1) * 6 - 180 + 3; // +3 puts origin\n // in middle of\n // zone\n\n eccPrimeSquared = (eccSquared) / (1 - eccSquared);\n\n M = y / k0;\n mu = M / (a * (1 - eccSquared / 4 - 3 * eccSquared * eccSquared / 64 - 5 * eccSquared * eccSquared * eccSquared / 256));\n\n 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);\n // double phi1 = ProjMath.radToDeg(phi1Rad);\n\n N1 = a / Math.sqrt(1 - eccSquared * Math.sin(phi1Rad) * Math.sin(phi1Rad));\n T1 = Math.tan(phi1Rad) * Math.tan(phi1Rad);\n C1 = eccPrimeSquared * Math.cos(phi1Rad) * Math.cos(phi1Rad);\n R1 = a * (1 - eccSquared) / Math.pow(1 - eccSquared * Math.sin(phi1Rad) * Math.sin(phi1Rad), 1.5);\n D = x / (N1 * k0);\n\n 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);\n lat = radToDeg(lat);\n\n 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);\n lon = LongOrigin + radToDeg(lon);\n\n var result;\n if (utm.accuracy) {\n var topRight = UTMtoLL({\n northing: utm.northing + utm.accuracy,\n easting: utm.easting + utm.accuracy,\n zoneLetter: utm.zoneLetter,\n zoneNumber: utm.zoneNumber\n });\n result = {\n top: topRight.lat,\n right: topRight.lon,\n bottom: lat,\n left: lon\n };\n }\n else {\n result = {\n lat: lat,\n lon: lon\n };\n }\n return result;\n}\n\n/**\n * Calculates the MGRS letter designator for the given latitude.\n *\n * @private\n * @param {number} lat The latitude in WGS84 to get the letter designator\n * for.\n * @return {char} The letter designator.\n */\nfunction getLetterDesignator(lat) {\n //This is here as an error flag to show that the Latitude is\n //outside MGRS limits\n var LetterDesignator = 'Z';\n\n if ((84 >= lat) && (lat >= 72)) {\n LetterDesignator = 'X';\n }\n else if ((72 > lat) && (lat >= 64)) {\n LetterDesignator = 'W';\n }\n else if ((64 > lat) && (lat >= 56)) {\n LetterDesignator = 'V';\n }\n else if ((56 > lat) && (lat >= 48)) {\n LetterDesignator = 'U';\n }\n else if ((48 > lat) && (lat >= 40)) {\n LetterDesignator = 'T';\n }\n else if ((40 > lat) && (lat >= 32)) {\n LetterDesignator = 'S';\n }\n else if ((32 > lat) && (lat >= 24)) {\n LetterDesignator = 'R';\n }\n else if ((24 > lat) && (lat >= 16)) {\n LetterDesignator = 'Q';\n }\n else if ((16 > lat) && (lat >= 8)) {\n LetterDesignator = 'P';\n }\n else if ((8 > lat) && (lat >= 0)) {\n LetterDesignator = 'N';\n }\n else if ((0 > lat) && (lat >= -8)) {\n LetterDesignator = 'M';\n }\n else if ((-8 > lat) && (lat >= -16)) {\n LetterDesignator = 'L';\n }\n else if ((-16 > lat) && (lat >= -24)) {\n LetterDesignator = 'K';\n }\n else if ((-24 > lat) && (lat >= -32)) {\n LetterDesignator = 'J';\n }\n else if ((-32 > lat) && (lat >= -40)) {\n LetterDesignator = 'H';\n }\n else if ((-40 > lat) && (lat >= -48)) {\n LetterDesignator = 'G';\n }\n else if ((-48 > lat) && (lat >= -56)) {\n LetterDesignator = 'F';\n }\n else if ((-56 > lat) && (lat >= -64)) {\n LetterDesignator = 'E';\n }\n else if ((-64 > lat) && (lat >= -72)) {\n LetterDesignator = 'D';\n }\n else if ((-72 > lat) && (lat >= -80)) {\n LetterDesignator = 'C';\n }\n return LetterDesignator;\n}\n\n/**\n * Encodes a UTM location as MGRS string.\n *\n * @private\n * @param {object} utm An object literal with easting, northing,\n * zoneLetter, zoneNumber\n * @param {number} accuracy Accuracy in digits (1-5).\n * @return {string} MGRS string for the given UTM location.\n */\nfunction encode(utm, accuracy) {\n // prepend with leading zeroes\n var seasting = \"00000\" + utm.easting,\n snorthing = \"00000\" + utm.northing;\n\n return utm.zoneNumber + utm.zoneLetter + get100kID(utm.easting, utm.northing, utm.zoneNumber) + seasting.substr(seasting.length - 5, accuracy) + snorthing.substr(snorthing.length - 5, accuracy);\n}\n\n/**\n * Get the two letter 100k designator for a given UTM easting,\n * northing and zone number value.\n *\n * @private\n * @param {number} easting\n * @param {number} northing\n * @param {number} zoneNumber\n * @return the two letter 100k designator for the given UTM location.\n */\nfunction get100kID(easting, northing, zoneNumber) {\n var setParm = get100kSetForZone(zoneNumber);\n var setColumn = Math.floor(easting / 100000);\n var setRow = Math.floor(northing / 100000) % 20;\n return getLetter100kID(setColumn, setRow, setParm);\n}\n\n/**\n * Given a UTM zone number, figure out the MGRS 100K set it is in.\n *\n * @private\n * @param {number} i An UTM zone number.\n * @return {number} the 100k set the UTM zone is in.\n */\nfunction get100kSetForZone(i) {\n var setParm = i % NUM_100K_SETS;\n if (setParm === 0) {\n setParm = NUM_100K_SETS;\n }\n\n return setParm;\n}\n\n/**\n * Get the two-letter MGRS 100k designator given information\n * translated from the UTM northing, easting and zone number.\n *\n * @private\n * @param {number} column the column index as it relates to the MGRS\n * 100k set spreadsheet, created from the UTM easting.\n * Values are 1-8.\n * @param {number} row the row index as it relates to the MGRS 100k set\n * spreadsheet, created from the UTM northing value. Values\n * are from 0-19.\n * @param {number} parm the set block, as it relates to the MGRS 100k set\n * spreadsheet, created from the UTM zone. Values are from\n * 1-60.\n * @return two letter MGRS 100k code.\n */\nfunction getLetter100kID(column, row, parm) {\n // colOrigin and rowOrigin are the letters at the origin of the set\n var index = parm - 1;\n var colOrigin = SET_ORIGIN_COLUMN_LETTERS.charCodeAt(index);\n var rowOrigin = SET_ORIGIN_ROW_LETTERS.charCodeAt(index);\n\n // colInt and rowInt are the letters to build to return\n var colInt = colOrigin + column - 1;\n var rowInt = rowOrigin + row;\n var rollover = false;\n\n if (colInt > Z) {\n colInt = colInt - Z + A - 1;\n rollover = true;\n }\n\n if (colInt === I || (colOrigin < I && colInt > I) || ((colInt > I || colOrigin < I) && rollover)) {\n colInt++;\n }\n\n if (colInt === O || (colOrigin < O && colInt > O) || ((colInt > O || colOrigin < O) && rollover)) {\n colInt++;\n\n if (colInt === I) {\n colInt++;\n }\n }\n\n if (colInt > Z) {\n colInt = colInt - Z + A - 1;\n }\n\n if (rowInt > V) {\n rowInt = rowInt - V + A - 1;\n rollover = true;\n }\n else {\n rollover = false;\n }\n\n if (((rowInt === I) || ((rowOrigin < I) && (rowInt > I))) || (((rowInt > I) || (rowOrigin < I)) && rollover)) {\n rowInt++;\n }\n\n if (((rowInt === O) || ((rowOrigin < O) && (rowInt > O))) || (((rowInt > O) || (rowOrigin < O)) && rollover)) {\n rowInt++;\n\n if (rowInt === I) {\n rowInt++;\n }\n }\n\n if (rowInt > V) {\n rowInt = rowInt - V + A - 1;\n }\n\n var twoLetter = String.fromCharCode(colInt) + String.fromCharCode(rowInt);\n return twoLetter;\n}\n\n/**\n * Decode the UTM parameters from a MGRS string.\n *\n * @private\n * @param {string} mgrsString an UPPERCASE coordinate string is expected.\n * @return {object} An object literal with easting, northing, zoneLetter,\n * zoneNumber and accuracy (in meters) properties.\n */\nfunction decode(mgrsString) {\n\n if (mgrsString && mgrsString.length === 0) {\n throw (\"MGRSPoint coverting from nothing\");\n }\n\n var length = mgrsString.length;\n\n var hunK = null;\n var sb = \"\";\n var testChar;\n var i = 0;\n\n // get Zone number\n while (!(/[A-Z]/).test(testChar = mgrsString.charAt(i))) {\n if (i >= 2) {\n throw (\"MGRSPoint bad conversion from: \" + mgrsString);\n }\n sb += testChar;\n i++;\n }\n\n var zoneNumber = parseInt(sb, 10);\n\n if (i === 0 || i + 3 > length) {\n // A good MGRS string has to be 4-5 digits long,\n // ##AAA/#AAA at least.\n throw (\"MGRSPoint bad conversion from: \" + mgrsString);\n }\n\n var zoneLetter = mgrsString.charAt(i++);\n\n // Should we check the zone letter here? Why not.\n if (zoneLetter <= 'A' || zoneLetter === 'B' || zoneLetter === 'Y' || zoneLetter >= 'Z' || zoneLetter === 'I' || zoneLetter === 'O') {\n throw (\"MGRSPoint zone letter \" + zoneLetter + \" not handled: \" + mgrsString);\n }\n\n hunK = mgrsString.substring(i, i += 2);\n\n var set = get100kSetForZone(zoneNumber);\n\n var east100k = getEastingFromChar(hunK.charAt(0), set);\n var north100k = getNorthingFromChar(hunK.charAt(1), set);\n\n // We have a bug where the northing may be 2000000 too low.\n // How\n // do we know when to roll over?\n\n while (north100k < getMinNorthing(zoneLetter)) {\n north100k += 2000000;\n }\n\n // calculate the char index for easting/northing separator\n var remainder = length - i;\n\n if (remainder % 2 !== 0) {\n 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);\n }\n\n var sep = remainder / 2;\n\n var sepEasting = 0.0;\n var sepNorthing = 0.0;\n var accuracyBonus, sepEastingString, sepNorthingString, easting, northing;\n if (sep > 0) {\n accuracyBonus = 100000.0 / Math.pow(10, sep);\n sepEastingString = mgrsString.substring(i, i + sep);\n sepEasting = parseFloat(sepEastingString) * accuracyBonus;\n sepNorthingString = mgrsString.substring(i + sep);\n sepNorthing = parseFloat(sepNorthingString) * accuracyBonus;\n }\n\n easting = sepEasting + east100k;\n northing = sepNorthing + north100k;\n\n return {\n easting: easting,\n northing: northing,\n zoneLetter: zoneLetter,\n zoneNumber: zoneNumber,\n accuracy: accuracyBonus\n };\n}\n\n/**\n * Given the first letter from a two-letter MGRS 100k zone, and given the\n * MGRS table set for the zone number, figure out the easting value that\n * should be added to the other, secondary easting value.\n *\n * @private\n * @param {char} e The first letter from a two-letter MGRS 100´k zone.\n * @param {number} set The MGRS table set for the zone number.\n * @return {number} The easting value for the given letter and set.\n */\nfunction getEastingFromChar(e, set) {\n // colOrigin is the letter at the origin of the set for the\n // column\n var curCol = SET_ORIGIN_COLUMN_LETTERS.charCodeAt(set - 1);\n var eastingValue = 100000.0;\n var rewindMarker = false;\n\n while (curCol !== e.charCodeAt(0)) {\n curCol++;\n if (curCol === I) {\n curCol++;\n }\n if (curCol === O) {\n curCol++;\n }\n if (curCol > Z) {\n if (rewindMarker) {\n throw (\"Bad character: \" + e);\n }\n curCol = A;\n rewindMarker = true;\n }\n eastingValue += 100000.0;\n }\n\n return eastingValue;\n}\n\n/**\n * Given the second letter from a two-letter MGRS 100k zone, and given the\n * MGRS table set for the zone number, figure out the northing value that\n * should be added to the other, secondary northing value. You have to\n * remember that Northings are determined from the equator, and the vertical\n * cycle of letters mean a 2000000 additional northing meters. This happens\n * approx. every 18 degrees of latitude. This method does *NOT* count any\n * additional northings. You have to figure out how many 2000000 meters need\n * to be added for the zone letter of the MGRS coordinate.\n *\n * @private\n * @param {char} n Second letter of the MGRS 100k zone\n * @param {number} set The MGRS table set number, which is dependent on the\n * UTM zone number.\n * @return {number} The northing value for the given letter and set.\n */\nfunction getNorthingFromChar(n, set) {\n\n if (n > 'V') {\n throw (\"MGRSPoint given invalid Northing \" + n);\n }\n\n // rowOrigin is the letter at the origin of the set for the\n // column\n var curRow = SET_ORIGIN_ROW_LETTERS.charCodeAt(set - 1);\n var northingValue = 0.0;\n var rewindMarker = false;\n\n while (curRow !== n.charCodeAt(0)) {\n curRow++;\n if (curRow === I) {\n curRow++;\n }\n if (curRow === O) {\n curRow++;\n }\n // fixing a bug making whole application hang in this loop\n // when 'n' is a wrong character\n if (curRow > V) {\n if (rewindMarker) { // making sure that this loop ends\n throw (\"Bad character: \" + n);\n }\n curRow = A;\n rewindMarker = true;\n }\n northingValue += 100000.0;\n }\n\n return northingValue;\n}\n\n/**\n * The function getMinNorthing returns the minimum northing value of a MGRS\n * zone.\n *\n * Ported from Geotrans' c Lattitude_Band_Value structure table.\n *\n * @private\n * @param {char} zoneLetter The MGRS zone to get the min northing for.\n * @return {number}\n */\nfunction getMinNorthing(zoneLetter) {\n var northing;\n switch (zoneLetter) {\n case 'C':\n northing = 1100000.0;\n break;\n case 'D':\n northing = 2000000.0;\n break;\n case 'E':\n northing = 2800000.0;\n break;\n case 'F':\n northing = 3700000.0;\n break;\n case 'G':\n northing = 4600000.0;\n break;\n case 'H':\n northing = 5500000.0;\n break;\n case 'J':\n northing = 6400000.0;\n break;\n case 'K':\n northing = 7300000.0;\n break;\n case 'L':\n northing = 8200000.0;\n break;\n case 'M':\n northing = 9100000.0;\n break;\n case 'N':\n northing = 0.0;\n break;\n case 'P':\n northing = 800000.0;\n break;\n case 'Q':\n northing = 1700000.0;\n break;\n case 'R':\n northing = 2600000.0;\n break;\n case 'S':\n northing = 3500000.0;\n break;\n case 'T':\n northing = 4400000.0;\n break;\n case 'U':\n northing = 5300000.0;\n break;\n case 'V':\n northing = 6200000.0;\n break;\n case 'W':\n northing = 7000000.0;\n break;\n case 'X':\n northing = 7900000.0;\n break;\n default:\n northing = -1.0;\n }\n if (northing >= 0.0) {\n return northing;\n }\n else {\n throw (\"Invalid zone letter: \" + zoneLetter);\n }\n\n}\n","module.exports = function (array){\n var out = {\n x: array[0],\n y: array[1]\n };\n if (array.length>2) {\n out.z = array[2];\n }\n if (array.length>3) {\n out.m = array[3];\n }\n return out;\n};","var HALF_PI = Math.PI/2;\nvar PJD_3PARAM = 1;\nvar PJD_7PARAM = 2;\nvar PJD_GRIDSHIFT = 3;\nvar PJD_WGS84 = 4; // WGS84 or equivalent\nvar PJD_NODATUM = 5; // WGS84 or equivalent\nvar SEC_TO_RAD = 4.84813681109535993589914102357e-6;\nvar AD_C = 1.0026000;\nvar COS_67P5 = 0.38268343236508977;\nvar datum = function(proj) {\n if (!(this instanceof datum)) {\n return new datum(proj);\n }\n this.datum_type = PJD_WGS84; //default setting\n if (!proj) {\n return;\n }\n if (proj.datumCode && proj.datumCode === 'none') {\n this.datum_type = PJD_NODATUM;\n }\n\n if (proj.datum_params) {\n this.datum_params = proj.datum_params.map(parseFloat);\n if (this.datum_params[0] !== 0 || this.datum_params[1] !== 0 || this.datum_params[2] !== 0) {\n this.datum_type = PJD_3PARAM;\n }\n if (this.datum_params.length > 3) {\n if (this.datum_params[3] !== 0 || this.datum_params[4] !== 0 || this.datum_params[5] !== 0 || this.datum_params[6] !== 0) {\n this.datum_type = PJD_7PARAM;\n this.datum_params[3] *= SEC_TO_RAD;\n this.datum_params[4] *= SEC_TO_RAD;\n this.datum_params[5] *= SEC_TO_RAD;\n this.datum_params[6] = (this.datum_params[6] / 1000000.0) + 1.0;\n }\n }\n }\n\n // DGR 2011-03-21 : nadgrids support\n this.datum_type = proj.grids ? PJD_GRIDSHIFT : this.datum_type;\n\n this.a = proj.a; //datum object also uses these values\n this.b = proj.b;\n this.es = proj.es;\n this.ep2 = proj.ep2;\n if (this.datum_type === PJD_GRIDSHIFT) {\n this.grids = proj.grids;\n }\n};\ndatum.prototype = {\n\n\n /****************************************************************/\n // cs_compare_datums()\n // Returns TRUE if the two datums match, otherwise FALSE.\n compare_datums: function(dest) {\n if (this.datum_type !== dest.datum_type) {\n return false; // false, datums are not equal\n }\n else if (this.a !== dest.a || Math.abs(this.es - dest.es) > 0.000000000050) {\n // the tolerence for es is to ensure that GRS80 and WGS84\n // are considered identical\n return false;\n }\n else if (this.datum_type === PJD_3PARAM) {\n 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]);\n }\n else if (this.datum_type === PJD_7PARAM) {\n 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]);\n }\n else if (this.datum_type === PJD_GRIDSHIFT || dest.datum_type === PJD_GRIDSHIFT) {\n //alert(\"ERROR: Grid shift transformations are not implemented.\");\n //return false\n //DGR 2012-07-29 lazy ...\n return this.nadgrids === dest.nadgrids;\n }\n else {\n return true; // datums are equal\n }\n }, // cs_compare_datums()\n\n /*\n * The function Convert_Geodetic_To_Geocentric converts geodetic coordinates\n * (latitude, longitude, and height) to geocentric coordinates (X, Y, Z),\n * according to the current ellipsoid parameters.\n *\n * Latitude : Geodetic latitude in radians (input)\n * Longitude : Geodetic longitude in radians (input)\n * Height : Geodetic height, in meters (input)\n * X : Calculated Geocentric X coordinate, in meters (output)\n * Y : Calculated Geocentric Y coordinate, in meters (output)\n * Z : Calculated Geocentric Z coordinate, in meters (output)\n *\n */\n geodetic_to_geocentric: function(p) {\n var Longitude = p.x;\n var Latitude = p.y;\n var Height = p.z ? p.z : 0; //Z value not always supplied\n var X; // output\n var Y;\n var Z;\n\n var Error_Code = 0; // GEOCENT_NO_ERROR;\n var Rn; /* Earth radius at location */\n var Sin_Lat; /* Math.sin(Latitude) */\n var Sin2_Lat; /* Square of Math.sin(Latitude) */\n var Cos_Lat; /* Math.cos(Latitude) */\n\n /*\n ** Don't blow up if Latitude is just a little out of the value\n ** range as it may just be a rounding issue. Also removed longitude\n ** test, it should be wrapped by Math.cos() and Math.sin(). NFW for PROJ.4, Sep/2001.\n */\n if (Latitude < -HALF_PI && Latitude > -1.001 * HALF_PI) {\n Latitude = -HALF_PI;\n }\n else if (Latitude > HALF_PI && Latitude < 1.001 * HALF_PI) {\n Latitude = HALF_PI;\n }\n else if ((Latitude < -HALF_PI) || (Latitude > HALF_PI)) {\n /* Latitude out of range */\n //..reportError('geocent:lat out of range:' + Latitude);\n return null;\n }\n\n if (Longitude > Math.PI) {\n Longitude -= (2 * Math.PI);\n }\n Sin_Lat = Math.sin(Latitude);\n Cos_Lat = Math.cos(Latitude);\n Sin2_Lat = Sin_Lat * Sin_Lat;\n Rn = this.a / (Math.sqrt(1.0e0 - this.es * Sin2_Lat));\n X = (Rn + Height) * Cos_Lat * Math.cos(Longitude);\n Y = (Rn + Height) * Cos_Lat * Math.sin(Longitude);\n Z = ((Rn * (1 - this.es)) + Height) * Sin_Lat;\n\n p.x = X;\n p.y = Y;\n p.z = Z;\n return Error_Code;\n }, // cs_geodetic_to_geocentric()\n\n\n geocentric_to_geodetic: function(p) {\n /* local defintions and variables */\n /* end-criterium of loop, accuracy of sin(Latitude) */\n var genau = 1e-12;\n var genau2 = (genau * genau);\n var maxiter = 30;\n\n var P; /* distance between semi-minor axis and location */\n var RR; /* distance between center and location */\n var CT; /* sin of geocentric latitude */\n var ST; /* cos of geocentric latitude */\n var RX;\n var RK;\n var RN; /* Earth radius at location */\n var CPHI0; /* cos of start or old geodetic latitude in iterations */\n var SPHI0; /* sin of start or old geodetic latitude in iterations */\n var CPHI; /* cos of searched geodetic latitude */\n var SPHI; /* sin of searched geodetic latitude */\n var SDPHI; /* end-criterium: addition-theorem of sin(Latitude(iter)-Latitude(iter-1)) */\n var At_Pole; /* indicates location is in polar region */\n var iter; /* # of continous iteration, max. 30 is always enough (s.a.) */\n\n var X = p.x;\n var Y = p.y;\n var Z = p.z ? p.z : 0.0; //Z value not always supplied\n var Longitude;\n var Latitude;\n var Height;\n\n At_Pole = false;\n P = Math.sqrt(X * X + Y * Y);\n RR = Math.sqrt(X * X + Y * Y + Z * Z);\n\n /* special cases for latitude and longitude */\n if (P / this.a < genau) {\n\n /* special case, if P=0. (X=0., Y=0.) */\n At_Pole = true;\n Longitude = 0.0;\n\n /* if (X,Y,Z)=(0.,0.,0.) then Height becomes semi-minor axis\n * of ellipsoid (=center of mass), Latitude becomes PI/2 */\n if (RR / this.a < genau) {\n Latitude = HALF_PI;\n Height = -this.b;\n return;\n }\n }\n else {\n /* ellipsoidal (geodetic) longitude\n * interval: -PI < Longitude <= +PI */\n Longitude = Math.atan2(Y, X);\n }\n\n /* --------------------------------------------------------------\n * Following iterative algorithm was developped by\n * \"Institut for Erdmessung\", University of Hannover, July 1988.\n * Internet: www.ife.uni-hannover.de\n * Iterative computation of CPHI,SPHI and Height.\n * Iteration of CPHI and SPHI to 10**-12 radian resp.\n * 2*10**-7 arcsec.\n * --------------------------------------------------------------\n */\n CT = Z / RR;\n ST = P / RR;\n RX = 1.0 / Math.sqrt(1.0 - this.es * (2.0 - this.es) * ST * ST);\n CPHI0 = ST * (1.0 - this.es) * RX;\n SPHI0 = CT * RX;\n iter = 0;\n\n /* loop to find sin(Latitude) resp. Latitude\n * until |sin(Latitude(iter)-Latitude(iter-1))| < genau */\n do {\n iter++;\n RN = this.a / Math.sqrt(1.0 - this.es * SPHI0 * SPHI0);\n\n /* ellipsoidal (geodetic) height */\n Height = P * CPHI0 + Z * SPHI0 - RN * (1.0 - this.es * SPHI0 * SPHI0);\n\n RK = this.es * RN / (RN + Height);\n RX = 1.0 / Math.sqrt(1.0 - RK * (2.0 - RK) * ST * ST);\n CPHI = ST * (1.0 - RK) * RX;\n SPHI = CT * RX;\n SDPHI = SPHI * CPHI0 - CPHI * SPHI0;\n CPHI0 = CPHI;\n SPHI0 = SPHI;\n }\n while (SDPHI * SDPHI > genau2 && iter < maxiter);\n\n /* ellipsoidal (geodetic) latitude */\n Latitude = Math.atan(SPHI / Math.abs(CPHI));\n\n p.x = Longitude;\n p.y = Latitude;\n p.z = Height;\n return p;\n }, // cs_geocentric_to_geodetic()\n\n /** Convert_Geocentric_To_Geodetic\n * The method used here is derived from 'An Improved Algorithm for\n * Geocentric to Geodetic Coordinate Conversion', by Ralph Toms, Feb 1996\n */\n geocentric_to_geodetic_noniter: function(p) {\n var X = p.x;\n var Y = p.y;\n var Z = p.z ? p.z : 0; //Z value not always supplied\n var Longitude;\n var Latitude;\n var Height;\n\n var W; /* distance from Z axis */\n var W2; /* square of distance from Z axis */\n var T0; /* initial estimate of vertical component */\n var T1; /* corrected estimate of vertical component */\n var S0; /* initial estimate of horizontal component */\n var S1; /* corrected estimate of horizontal component */\n var Sin_B0; /* Math.sin(B0), B0 is estimate of Bowring aux variable */\n var Sin3_B0; /* cube of Math.sin(B0) */\n var Cos_B0; /* Math.cos(B0) */\n var Sin_p1; /* Math.sin(phi1), phi1 is estimated latitude */\n var Cos_p1; /* Math.cos(phi1) */\n var Rn; /* Earth radius at location */\n var Sum; /* numerator of Math.cos(phi1) */\n var At_Pole; /* indicates location is in polar region */\n\n X = parseFloat(X); // cast from string to float\n Y = parseFloat(Y);\n Z = parseFloat(Z);\n\n At_Pole = false;\n if (X !== 0.0) {\n Longitude = Math.atan2(Y, X);\n }\n else {\n if (Y > 0) {\n Longitude = HALF_PI;\n }\n else if (Y < 0) {\n Longitude = -HALF_PI;\n }\n else {\n At_Pole = true;\n Longitude = 0.0;\n if (Z > 0.0) { /* north pole */\n Latitude = HALF_PI;\n }\n else if (Z < 0.0) { /* south pole */\n Latitude = -HALF_PI;\n }\n else { /* center of earth */\n Latitude = HALF_PI;\n Height = -this.b;\n return;\n }\n }\n }\n W2 = X * X + Y * Y;\n W = Math.sqrt(W2);\n T0 = Z * AD_C;\n S0 = Math.sqrt(T0 * T0 + W2);\n Sin_B0 = T0 / S0;\n Cos_B0 = W / S0;\n Sin3_B0 = Sin_B0 * Sin_B0 * Sin_B0;\n T1 = Z + this.b * this.ep2 * Sin3_B0;\n Sum = W - this.a * this.es * Cos_B0 * Cos_B0 * Cos_B0;\n S1 = Math.sqrt(T1 * T1 + Sum * Sum);\n Sin_p1 = T1 / S1;\n Cos_p1 = Sum / S1;\n Rn = this.a / Math.sqrt(1.0 - this.es * Sin_p1 * Sin_p1);\n if (Cos_p1 >= COS_67P5) {\n Height = W / Cos_p1 - Rn;\n }\n else if (Cos_p1 <= -COS_67P5) {\n Height = W / -Cos_p1 - Rn;\n }\n else {\n Height = Z / Sin_p1 + Rn * (this.es - 1.0);\n }\n if (At_Pole === false) {\n Latitude = Math.atan(Sin_p1 / Cos_p1);\n }\n\n p.x = Longitude;\n p.y = Latitude;\n p.z = Height;\n return p;\n }, // geocentric_to_geodetic_noniter()\n\n /****************************************************************/\n // pj_geocentic_to_wgs84( p )\n // p = point to transform in geocentric coordinates (x,y,z)\n geocentric_to_wgs84: function(p) {\n\n if (this.datum_type === PJD_3PARAM) {\n // if( x[io] === HUGE_VAL )\n // continue;\n p.x += this.datum_params[0];\n p.y += this.datum_params[1];\n p.z += this.datum_params[2];\n\n }\n else if (this.datum_type === PJD_7PARAM) {\n var Dx_BF = this.datum_params[0];\n var Dy_BF = this.datum_params[1];\n var Dz_BF = this.datum_params[2];\n var Rx_BF = this.datum_params[3];\n var Ry_BF = this.datum_params[4];\n var Rz_BF = this.datum_params[5];\n var M_BF = this.datum_params[6];\n // if( x[io] === HUGE_VAL )\n // continue;\n var x_out = M_BF * (p.x - Rz_BF * p.y + Ry_BF * p.z) + Dx_BF;\n var y_out = M_BF * (Rz_BF * p.x + p.y - Rx_BF * p.z) + Dy_BF;\n var z_out = M_BF * (-Ry_BF * p.x + Rx_BF * p.y + p.z) + Dz_BF;\n p.x = x_out;\n p.y = y_out;\n p.z = z_out;\n }\n }, // cs_geocentric_to_wgs84\n\n /****************************************************************/\n // pj_geocentic_from_wgs84()\n // coordinate system definition,\n // point to transform in geocentric coordinates (x,y,z)\n geocentric_from_wgs84: function(p) {\n\n if (this.datum_type === PJD_3PARAM) {\n //if( x[io] === HUGE_VAL )\n // continue;\n p.x -= this.datum_params[0];\n p.y -= this.datum_params[1];\n p.z -= this.datum_params[2];\n\n }\n else if (this.datum_type === PJD_7PARAM) {\n var Dx_BF = this.datum_params[0];\n var Dy_BF = this.datum_params[1];\n var Dz_BF = this.datum_params[2];\n var Rx_BF = this.datum_params[3];\n var Ry_BF = this.datum_params[4];\n var Rz_BF = this.datum_params[5];\n var M_BF = this.datum_params[6];\n var x_tmp = (p.x - Dx_BF) / M_BF;\n var y_tmp = (p.y - Dy_BF) / M_BF;\n var z_tmp = (p.z - Dz_BF) / M_BF;\n //if( x[io] === HUGE_VAL )\n // continue;\n\n p.x = x_tmp + Rz_BF * y_tmp - Ry_BF * z_tmp;\n p.y = -Rz_BF * x_tmp + y_tmp + Rx_BF * z_tmp;\n p.z = Ry_BF * x_tmp - Rx_BF * y_tmp + z_tmp;\n } //cs_geocentric_from_wgs84()\n }\n};\n\n/** point object, nothing fancy, just allows values to be\n passed back and forth by reference rather than by value.\n Other point classes may be used as long as they have\n x and y properties, which will get modified in the transform method.\n*/\nmodule.exports = datum;\n","module.exports = function(destination, source) {\n destination = destination || {};\n var value, property;\n if (!source) {\n return destination;\n }\n for (property in source) {\n value = source[property];\n if (value !== undefined) {\n destination[property] = value;\n }\n }\n return destination;\n};\n","exports.MERIT = {\n a: 6378137.0,\n rf: 298.257,\n ellipseName: \"MERIT 1983\"\n};\nexports.SGS85 = {\n a: 6378136.0,\n rf: 298.257,\n ellipseName: \"Soviet Geodetic System 85\"\n};\nexports.GRS80 = {\n a: 6378137.0,\n rf: 298.257222101,\n ellipseName: \"GRS 1980(IUGG, 1980)\"\n};\nexports.IAU76 = {\n a: 6378140.0,\n rf: 298.257,\n ellipseName: \"IAU 1976\"\n};\nexports.airy = {\n a: 6377563.396,\n b: 6356256.910,\n ellipseName: \"Airy 1830\"\n};\nexports.APL4 = {\n a: 6378137,\n rf: 298.25,\n ellipseName: \"Appl. Physics. 1965\"\n};\nexports.NWL9D = {\n a: 6378145.0,\n rf: 298.25,\n ellipseName: \"Naval Weapons Lab., 1965\"\n};\nexports.mod_airy = {\n a: 6377340.189,\n b: 6356034.446,\n ellipseName: \"Modified Airy\"\n};\nexports.andrae = {\n a: 6377104.43,\n rf: 300.0,\n ellipseName: \"Andrae 1876 (Den., Iclnd.)\"\n};\nexports.aust_SA = {\n a: 6378160.0,\n rf: 298.25,\n ellipseName: \"Australian Natl & S. Amer. 1969\"\n};\nexports.GRS67 = {\n a: 6378160.0,\n rf: 298.2471674270,\n ellipseName: \"GRS 67(IUGG 1967)\"\n};\nexports.bessel = {\n a: 6377397.155,\n rf: 299.1528128,\n ellipseName: \"Bessel 1841\"\n};\nexports.bess_nam = {\n a: 6377483.865,\n rf: 299.1528128,\n ellipseName: \"Bessel 1841 (Namibia)\"\n};\nexports.clrk66 = {\n a: 6378206.4,\n b: 6356583.8,\n ellipseName: \"Clarke 1866\"\n};\nexports.clrk80 = {\n a: 6378249.145,\n rf: 293.4663,\n ellipseName: \"Clarke 1880 mod.\"\n};\nexports.clrk58 = {\n a: 6378293.645208759,\n rf: 294.2606763692654,\n ellipseName: \"Clarke 1858\"\n};\nexports.CPM = {\n a: 6375738.7,\n rf: 334.29,\n ellipseName: \"Comm. des Poids et Mesures 1799\"\n};\nexports.delmbr = {\n a: 6376428.0,\n rf: 311.5,\n ellipseName: \"Delambre 1810 (Belgium)\"\n};\nexports.engelis = {\n a: 6378136.05,\n rf: 298.2566,\n ellipseName: \"Engelis 1985\"\n};\nexports.evrst30 = {\n a: 6377276.345,\n rf: 300.8017,\n ellipseName: \"Everest 1830\"\n};\nexports.evrst48 = {\n a: 6377304.063,\n rf: 300.8017,\n ellipseName: \"Everest 1948\"\n};\nexports.evrst56 = {\n a: 6377301.243,\n rf: 300.8017,\n ellipseName: \"Everest 1956\"\n};\nexports.evrst69 = {\n a: 6377295.664,\n rf: 300.8017,\n ellipseName: \"Everest 1969\"\n};\nexports.evrstSS = {\n a: 6377298.556,\n rf: 300.8017,\n ellipseName: \"Everest (Sabah & Sarawak)\"\n};\nexports.fschr60 = {\n a: 6378166.0,\n rf: 298.3,\n ellipseName: \"Fischer (Mercury Datum) 1960\"\n};\nexports.fschr60m = {\n a: 6378155.0,\n rf: 298.3,\n ellipseName: \"Fischer 1960\"\n};\nexports.fschr68 = {\n a: 6378150.0,\n rf: 298.3,\n ellipseName: \"Fischer 1968\"\n};\nexports.helmert = {\n a: 6378200.0,\n rf: 298.3,\n ellipseName: \"Helmert 1906\"\n};\nexports.hough = {\n a: 6378270.0,\n rf: 297.0,\n ellipseName: \"Hough\"\n};\nexports.intl = {\n a: 6378388.0,\n rf: 297.0,\n ellipseName: \"International 1909 (Hayford)\"\n};\nexports.kaula = {\n a: 6378163.0,\n rf: 298.24,\n ellipseName: \"Kaula 1961\"\n};\nexports.lerch = {\n a: 6378139.0,\n rf: 298.257,\n ellipseName: \"Lerch 1979\"\n};\nexports.mprts = {\n a: 6397300.0,\n rf: 191.0,\n ellipseName: \"Maupertius 1738\"\n};\nexports.new_intl = {\n a: 6378157.5,\n b: 6356772.2,\n ellipseName: \"New International 1967\"\n};\nexports.plessis = {\n a: 6376523.0,\n rf: 6355863.0,\n ellipseName: \"Plessis 1817 (France)\"\n};\nexports.krass = {\n a: 6378245.0,\n rf: 298.3,\n ellipseName: \"Krassovsky, 1942\"\n};\nexports.SEasia = {\n a: 6378155.0,\n b: 6356773.3205,\n ellipseName: \"Southeast Asia\"\n};\nexports.walbeck = {\n a: 6376896.0,\n b: 6355834.8467,\n ellipseName: \"Walbeck\"\n};\nexports.WGS60 = {\n a: 6378165.0,\n rf: 298.3,\n ellipseName: \"WGS 60\"\n};\nexports.WGS66 = {\n a: 6378145.0,\n rf: 298.25,\n ellipseName: \"WGS 66\"\n};\nexports.WGS7 = {\n a: 6378135.0,\n rf: 298.26,\n ellipseName: \"WGS 72\"\n};\nexports.WGS84 = {\n a: 6378137.0,\n rf: 298.257223563,\n ellipseName: \"WGS 84\"\n};\nexports.sphere = {\n a: 6370997.0,\n b: 6370997.0,\n ellipseName: \"Normal Sphere (r=6370997)\"\n};","exports.wgs84 = {\n towgs84: \"0,0,0\",\n ellipse: \"WGS84\",\n datumName: \"WGS84\"\n};\nexports.ch1903 = {\n towgs84: \"674.374,15.056,405.346\",\n ellipse: \"bessel\",\n datumName: \"swiss\"\n};\nexports.ggrs87 = {\n towgs84: \"-199.87,74.79,246.62\",\n ellipse: \"GRS80\",\n datumName: \"Greek_Geodetic_Reference_System_1987\"\n};\nexports.nad83 = {\n towgs84: \"0,0,0\",\n ellipse: \"GRS80\",\n datumName: \"North_American_Datum_1983\"\n};\nexports.nad27 = {\n nadgrids: \"@conus,@alaska,@ntv2_0.gsb,@ntv1_can.dat\",\n ellipse: \"clrk66\",\n datumName: \"North_American_Datum_1927\"\n};\nexports.potsdam = {\n towgs84: \"606.0,23.0,413.0\",\n ellipse: \"bessel\",\n datumName: \"Potsdam Rauenberg 1950 DHDN\"\n};\nexports.carthage = {\n towgs84: \"-263.0,6.0,431.0\",\n ellipse: \"clark80\",\n datumName: \"Carthage 1934 Tunisia\"\n};\nexports.hermannskogel = {\n towgs84: \"653.0,-212.0,449.0\",\n ellipse: \"bessel\",\n datumName: \"Hermannskogel\"\n};\nexports.ire65 = {\n towgs84: \"482.530,-130.596,564.557,-1.042,-0.214,-0.631,8.15\",\n ellipse: \"mod_airy\",\n datumName: \"Ireland 1965\"\n};\nexports.rassadiran = {\n towgs84: \"-133.63,-157.5,-158.62\",\n ellipse: \"intl\",\n datumName: \"Rassadiran\"\n};\nexports.nzgd49 = {\n towgs84: \"59.47,-5.04,187.44,0.47,-0.1,1.024,-4.5993\",\n ellipse: \"intl\",\n datumName: \"New Zealand Geodetic Datum 1949\"\n};\nexports.osgb36 = {\n towgs84: \"446.448,-125.157,542.060,0.1502,0.2470,0.8421,-20.4894\",\n ellipse: \"airy\",\n datumName: \"Airy 1830\"\n};\nexports.s_jtsk = {\n towgs84: \"589,76,480\",\n ellipse: 'bessel',\n datumName: 'S-JTSK (Ferro)'\n};\nexports.beduaram = {\n towgs84: '-106,-87,188',\n ellipse: 'clrk80',\n datumName: 'Beduaram'\n};\nexports.gunung_segara = {\n towgs84: '-403,684,41',\n ellipse: 'bessel',\n datumName: 'Gunung Segara Jakarta'\n};\nexports.rnb72 = {\n towgs84: \"106.869,-52.2978,103.724,-0.33657,0.456955,-1.84218,1\",\n ellipse: \"intl\",\n datumName: \"Reseau National Belge 1972\"\n};","var Datum = require('./constants/Datum');\nvar Ellipsoid = require('./constants/Ellipsoid');\nvar extend = require('./extend');\nvar datum = require('./datum');\nvar EPSLN = 1.0e-10;\n// ellipoid pj_set_ell.c\nvar SIXTH = 0.1666666666666666667;\n/* 1/6 */\nvar RA4 = 0.04722222222222222222;\n/* 17/360 */\nvar RA6 = 0.02215608465608465608;\nmodule.exports = function(json) {\n // DGR 2011-03-20 : nagrids -> nadgrids\n if (json.datumCode && json.datumCode !== 'none') {\n var datumDef = Datum[json.datumCode];\n if (datumDef) {\n json.datum_params = datumDef.towgs84 ? datumDef.towgs84.split(',') : null;\n json.ellps = datumDef.ellipse;\n json.datumName = datumDef.datumName ? datumDef.datumName : json.datumCode;\n }\n }\n if (!json.a) { // do we have an ellipsoid?\n var ellipse = Ellipsoid[json.ellps] ? Ellipsoid[json.ellps] : Ellipsoid.WGS84;\n extend(json, ellipse);\n }\n if (json.rf && !json.b) {\n json.b = (1.0 - 1.0 / json.rf) * json.a;\n }\n if (json.rf === 0 || Math.abs(json.a - json.b) < EPSLN) {\n json.sphere = true;\n json.b = json.a;\n }\n json.a2 = json.a * json.a; // used in geocentric\n json.b2 = json.b * json.b; // used in geocentric\n json.es = (json.a2 - json.b2) / json.a2; // e ^ 2\n json.e = Math.sqrt(json.es); // eccentricity\n if (json.R_A) {\n json.a *= 1 - json.es * (SIXTH + json.es * (RA4 + json.es * RA6));\n json.a2 = json.a * json.a;\n json.b2 = json.b * json.b;\n json.es = 0;\n }\n json.ep2 = (json.a2 - json.b2) / json.b2; // used in geocentric\n if (!json.k0) {\n json.k0 = 1.0; //default value\n }\n //DGR 2010-11-12: axis\n if (!json.axis) {\n json.axis = \"enu\";\n }\n\n if (!json.datum) {\n json.datum = datum(json);\n }\n return json;\n};\n","exports.init = function() {\n //no-op for longlat\n};\n\nfunction identity(pt) {\n return pt;\n}\nexports.forward = identity;\nexports.inverse = identity;\nexports.names = [\"longlat\", \"identity\"];\n","var msfnz = require('../common/msfnz');\nvar HALF_PI = Math.PI/2;\nvar EPSLN = 1.0e-10;\nvar R2D = 57.29577951308232088;\nvar adjust_lon = require('../common/adjust_lon');\nvar FORTPI = Math.PI/4;\nvar tsfnz = require('../common/tsfnz');\nvar phi2z = require('../common/phi2z');\nexports.init = function() {\n var con = this.b / this.a;\n this.es = 1 - con * con;\n if(!('x0' in this)){\n this.x0 = 0;\n }\n if(!('y0' in this)){\n this.y0 = 0;\n }\n this.e = Math.sqrt(this.es);\n if (this.lat_ts) {\n if (this.sphere) {\n this.k0 = Math.cos(this.lat_ts);\n }\n else {\n this.k0 = msfnz(this.e, Math.sin(this.lat_ts), Math.cos(this.lat_ts));\n }\n }\n else {\n if (!this.k0) {\n if (this.k) {\n this.k0 = this.k;\n }\n else {\n this.k0 = 1;\n }\n }\n }\n};\n\n/* Mercator forward equations--mapping lat,long to x,y\n --------------------------------------------------*/\n\nexports.forward = function(p) {\n var lon = p.x;\n var lat = p.y;\n // convert to radians\n if (lat * R2D > 90 && lat * R2D < -90 && lon * R2D > 180 && lon * R2D < -180) {\n return null;\n }\n\n var x, y;\n if (Math.abs(Math.abs(lat) - HALF_PI) <= EPSLN) {\n return null;\n }\n else {\n if (this.sphere) {\n x = this.x0 + this.a * this.k0 * adjust_lon(lon - this.long0);\n y = this.y0 + this.a * this.k0 * Math.log(Math.tan(FORTPI + 0.5 * lat));\n }\n else {\n var sinphi = Math.sin(lat);\n var ts = tsfnz(this.e, lat, sinphi);\n x = this.x0 + this.a * this.k0 * adjust_lon(lon - this.long0);\n y = this.y0 - this.a * this.k0 * Math.log(ts);\n }\n p.x = x;\n p.y = y;\n return p;\n }\n};\n\n\n/* Mercator inverse equations--mapping x,y to lat/long\n --------------------------------------------------*/\nexports.inverse = function(p) {\n\n var x = p.x - this.x0;\n var y = p.y - this.y0;\n var lon, lat;\n\n if (this.sphere) {\n lat = HALF_PI - 2 * Math.atan(Math.exp(-y / (this.a * this.k0)));\n }\n else {\n var ts = Math.exp(-y / (this.a * this.k0));\n lat = phi2z(this.e, ts);\n if (lat === -9999) {\n return null;\n }\n }\n lon = adjust_lon(this.long0 + x / (this.a * this.k0));\n\n p.x = lon;\n p.y = lat;\n return p;\n};\n\nexports.names = [\"Mercator\", \"Popular Visualisation Pseudo Mercator\", \"Mercator_1SP\", \"Mercator_Auxiliary_Sphere\", \"merc\"];\n","var projs = [\n require('./projections/merc'),\n require('./projections/longlat')\n];\nvar names = {};\nvar projStore = [];\n\nfunction add(proj, i) {\n var len = projStore.length;\n if (!proj.names) {\n console.log(i);\n return true;\n }\n projStore[len] = proj;\n proj.names.forEach(function(n) {\n names[n.toLowerCase()] = len;\n });\n return this;\n}\n\nexports.add = add;\n\nexports.get = function(name) {\n if (!name) {\n return false;\n }\n var n = name.toLowerCase();\n if (typeof names[n] !== 'undefined' && projStore[names[n]]) {\n return projStore[names[n]];\n }\n};\nexports.start = function() {\n projs.forEach(add);\n};\n","exports.ft = {to_meter: 0.3048};\nexports['us-ft'] = {to_meter: 1200 / 3937};\n","exports.greenwich = 0.0; //\"0dE\",\nexports.lisbon = -9.131906111111; //\"9d07'54.862\\\"W\",\nexports.paris = 2.337229166667; //\"2d20'14.025\\\"E\",\nexports.bogota = -74.080916666667; //\"74d04'51.3\\\"W\",\nexports.madrid = -3.687938888889; //\"3d41'16.58\\\"W\",\nexports.rome = 12.452333333333; //\"12d27'8.4\\\"E\",\nexports.bern = 7.439583333333; //\"7d26'22.5\\\"E\",\nexports.jakarta = 106.807719444444; //\"106d48'27.79\\\"E\",\nexports.ferro = -17.666666666667; //\"17d40'W\",\nexports.brussels = 4.367975; //\"4d22'4.71\\\"E\",\nexports.stockholm = 18.058277777778; //\"18d3'29.8\\\"E\",\nexports.athens = 23.7163375; //\"23d42'58.815\\\"E\",\nexports.oslo = 10.722916666667; //\"10d43'22.5\\\"E\"","var D2R = 0.01745329251994329577;\nvar PrimeMeridian = require('./constants/PrimeMeridian');\nvar units = require('./constants/units');\n\nmodule.exports = function(defData) {\n var self = {};\n var paramObj = {};\n defData.split(\"+\").map(function(v) {\n return v.trim();\n }).filter(function(a) {\n return a;\n }).forEach(function(a) {\n var split = a.split(\"=\");\n split.push(true);\n paramObj[split[0].toLowerCase()] = split[1];\n });\n var paramName, paramVal, paramOutname;\n var params = {\n proj: 'projName',\n datum: 'datumCode',\n rf: function(v) {\n self.rf = parseFloat(v);\n },\n lat_0: function(v) {\n self.lat0 = v * D2R;\n },\n lat_1: function(v) {\n self.lat1 = v * D2R;\n },\n lat_2: function(v) {\n self.lat2 = v * D2R;\n },\n lat_ts: function(v) {\n self.lat_ts = v * D2R;\n },\n lon_0: function(v) {\n self.long0 = v * D2R;\n },\n lon_1: function(v) {\n self.long1 = v * D2R;\n },\n lon_2: function(v) {\n self.long2 = v * D2R;\n },\n alpha: function(v) {\n self.alpha = parseFloat(v) * D2R;\n },\n lonc: function(v) {\n self.longc = v * D2R;\n },\n x_0: function(v) {\n self.x0 = parseFloat(v);\n },\n y_0: function(v) {\n self.y0 = parseFloat(v);\n },\n k_0: function(v) {\n self.k0 = parseFloat(v);\n },\n k: function(v) {\n self.k0 = parseFloat(v);\n },\n a: function(v) {\n self.a = parseFloat(v);\n },\n b: function(v) {\n self.b = parseFloat(v);\n },\n r_a: function() {\n self.R_A = true;\n },\n zone: function(v) {\n self.zone = parseInt(v, 10);\n },\n south: function() {\n self.utmSouth = true;\n },\n towgs84: function(v) {\n self.datum_params = v.split(\",\").map(function(a) {\n return parseFloat(a);\n });\n },\n to_meter: function(v) {\n self.to_meter = parseFloat(v);\n },\n units: function(v) {\n self.units = v;\n if (units[v]) {\n self.to_meter = units[v].to_meter;\n }\n },\n from_greenwich: function(v) {\n self.from_greenwich = v * D2R;\n },\n pm: function(v) {\n self.from_greenwich = (PrimeMeridian[v] ? PrimeMeridian[v] : parseFloat(v)) * D2R;\n },\n nadgrids: function(v) {\n if (v === '@null') {\n self.datumCode = 'none';\n }\n else {\n self.nadgrids = v;\n }\n },\n axis: function(v) {\n var legalAxis = \"ewnsud\";\n 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) {\n self.axis = v;\n }\n }\n };\n for (paramName in paramObj) {\n paramVal = paramObj[paramName];\n if (paramName in params) {\n paramOutname = params[paramName];\n if (typeof paramOutname === 'function') {\n paramOutname(paramVal);\n }\n else {\n self[paramOutname] = paramVal;\n }\n }\n else {\n self[paramName] = paramVal;\n }\n }\n if(typeof self.datumCode === 'string' && self.datumCode !== \"WGS84\"){\n self.datumCode = self.datumCode.toLowerCase();\n }\n return self;\n};\n","var D2R = 0.01745329251994329577;\nvar extend = require('./extend');\n\nfunction mapit(obj, key, v) {\n obj[key] = v.map(function(aa) {\n var o = {};\n sExpr(aa, o);\n return o;\n }).reduce(function(a, b) {\n return extend(a, b);\n }, {});\n}\n\nfunction sExpr(v, obj) {\n var key;\n if (!Array.isArray(v)) {\n obj[v] = true;\n return;\n }\n else {\n key = v.shift();\n if (key === 'PARAMETER') {\n key = v.shift();\n }\n if (v.length === 1) {\n if (Array.isArray(v[0])) {\n obj[key] = {};\n sExpr(v[0], obj[key]);\n }\n else {\n obj[key] = v[0];\n }\n }\n else if (!v.length) {\n obj[key] = true;\n }\n else if (key === 'TOWGS84') {\n obj[key] = v;\n }\n else {\n obj[key] = {};\n if (['UNIT', 'PRIMEM', 'VERT_DATUM'].indexOf(key) > -1) {\n obj[key] = {\n name: v[0].toLowerCase(),\n convert: v[1]\n };\n if (v.length === 3) {\n obj[key].auth = v[2];\n }\n }\n else if (key === 'SPHEROID') {\n obj[key] = {\n name: v[0],\n a: v[1],\n rf: v[2]\n };\n if (v.length === 4) {\n obj[key].auth = v[3];\n }\n }\n else if (['GEOGCS', 'GEOCCS', 'DATUM', 'VERT_CS', 'COMPD_CS', 'LOCAL_CS', 'FITTED_CS', 'LOCAL_DATUM'].indexOf(key) > -1) {\n v[0] = ['name', v[0]];\n mapit(obj, key, v);\n }\n else if (v.every(function(aa) {\n return Array.isArray(aa);\n })) {\n mapit(obj, key, v);\n }\n else {\n sExpr(v, obj[key]);\n }\n }\n }\n}\n\nfunction rename(obj, params) {\n var outName = params[0];\n var inName = params[1];\n if (!(outName in obj) && (inName in obj)) {\n obj[outName] = obj[inName];\n if (params.length === 3) {\n obj[outName] = params[2](obj[outName]);\n }\n }\n}\n\nfunction d2r(input) {\n return input * D2R;\n}\n\nfunction cleanWKT(wkt) {\n if (wkt.type === 'GEOGCS') {\n wkt.projName = 'longlat';\n }\n else if (wkt.type === 'LOCAL_CS') {\n wkt.projName = 'identity';\n wkt.local = true;\n }\n else {\n if (typeof wkt.PROJECTION === \"object\") {\n wkt.projName = Object.keys(wkt.PROJECTION)[0];\n }\n else {\n wkt.projName = wkt.PROJECTION;\n }\n }\n if (wkt.UNIT) {\n wkt.units = wkt.UNIT.name.toLowerCase();\n if (wkt.units === 'metre') {\n wkt.units = 'meter';\n }\n if (wkt.UNIT.convert) {\n if (wkt.type === 'GEOGCS') {\n if (wkt.DATUM && wkt.DATUM.SPHEROID) {\n wkt.to_meter = parseFloat(wkt.UNIT.convert, 10)*wkt.DATUM.SPHEROID.a;\n }\n } else {\n wkt.to_meter = parseFloat(wkt.UNIT.convert, 10);\n }\n }\n }\n\n if (wkt.GEOGCS) {\n //if(wkt.GEOGCS.PRIMEM&&wkt.GEOGCS.PRIMEM.convert){\n // wkt.from_greenwich=wkt.GEOGCS.PRIMEM.convert*D2R;\n //}\n if (wkt.GEOGCS.DATUM) {\n wkt.datumCode = wkt.GEOGCS.DATUM.name.toLowerCase();\n }\n else {\n wkt.datumCode = wkt.GEOGCS.name.toLowerCase();\n }\n if (wkt.datumCode.slice(0, 2) === 'd_') {\n wkt.datumCode = wkt.datumCode.slice(2);\n }\n if (wkt.datumCode === 'new_zealand_geodetic_datum_1949' || wkt.datumCode === 'new_zealand_1949') {\n wkt.datumCode = 'nzgd49';\n }\n if (wkt.datumCode === \"wgs_1984\") {\n if (wkt.PROJECTION === 'Mercator_Auxiliary_Sphere') {\n wkt.sphere = true;\n }\n wkt.datumCode = 'wgs84';\n }\n if (wkt.datumCode.slice(-6) === '_ferro') {\n wkt.datumCode = wkt.datumCode.slice(0, - 6);\n }\n if (wkt.datumCode.slice(-8) === '_jakarta') {\n wkt.datumCode = wkt.datumCode.slice(0, - 8);\n }\n if (~wkt.datumCode.indexOf('belge')) {\n wkt.datumCode = \"rnb72\";\n }\n if (wkt.GEOGCS.DATUM && wkt.GEOGCS.DATUM.SPHEROID) {\n wkt.ellps = wkt.GEOGCS.DATUM.SPHEROID.name.replace('_19', '').replace(/[Cc]larke\\_18/, 'clrk');\n if (wkt.ellps.toLowerCase().slice(0, 13) === \"international\") {\n wkt.ellps = 'intl';\n }\n\n wkt.a = wkt.GEOGCS.DATUM.SPHEROID.a;\n wkt.rf = parseFloat(wkt.GEOGCS.DATUM.SPHEROID.rf, 10);\n }\n if (~wkt.datumCode.indexOf('osgb_1936')) {\n wkt.datumCode = \"osgb36\";\n }\n }\n if (wkt.b && !isFinite(wkt.b)) {\n wkt.b = wkt.a;\n }\n\n function toMeter(input) {\n var ratio = wkt.to_meter || 1;\n return parseFloat(input, 10) * ratio;\n }\n var renamer = function(a) {\n return rename(wkt, a);\n };\n var list = [\n ['standard_parallel_1', 'Standard_Parallel_1'],\n ['standard_parallel_2', 'Standard_Parallel_2'],\n ['false_easting', 'False_Easting'],\n ['false_northing', 'False_Northing'],\n ['central_meridian', 'Central_Meridian'],\n ['latitude_of_origin', 'Latitude_Of_Origin'],\n ['latitude_of_origin', 'Central_Parallel'],\n ['scale_factor', 'Scale_Factor'],\n ['k0', 'scale_factor'],\n ['latitude_of_center', 'Latitude_of_center'],\n ['lat0', 'latitude_of_center', d2r],\n ['longitude_of_center', 'Longitude_Of_Center'],\n ['longc', 'longitude_of_center', d2r],\n ['x0', 'false_easting', toMeter],\n ['y0', 'false_northing', toMeter],\n ['long0', 'central_meridian', d2r],\n ['lat0', 'latitude_of_origin', d2r],\n ['lat0', 'standard_parallel_1', d2r],\n ['lat1', 'standard_parallel_1', d2r],\n ['lat2', 'standard_parallel_2', d2r],\n ['alpha', 'azimuth', d2r],\n ['srsCode', 'name']\n ];\n list.forEach(renamer);\n if (!wkt.long0 && wkt.longc && (wkt.projName === 'Albers_Conic_Equal_Area' || wkt.projName === \"Lambert_Azimuthal_Equal_Area\")) {\n wkt.long0 = wkt.longc;\n }\n if (!wkt.lat_ts && wkt.lat1 && (wkt.projName === 'Stereographic_South_Pole' || wkt.projName === 'Polar Stereographic (variant B)')) {\n wkt.lat0 = d2r(wkt.lat1 > 0 ? 90 : -90);\n wkt.lat_ts = wkt.lat1;\n }\n}\nmodule.exports = function(wkt, self) {\n 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\".+/,''));\n var type = lisp.shift();\n var name = lisp.shift();\n lisp.unshift(['name', name]);\n lisp.unshift(['type', type]);\n lisp.unshift('output');\n var obj = {};\n sExpr(lisp, obj);\n cleanWKT(obj.output);\n return extend(self, obj.output);\n};\n","module.exports = function(defs) {\n defs('EPSG:4326', \"+title=WGS 84 (long/lat) +proj=longlat +ellps=WGS84 +datum=WGS84 +units=degrees\");\n defs('EPSG:4269', \"+title=NAD83 (long/lat) +proj=longlat +a=6378137.0 +b=6356752.31414036 +ellps=GRS80 +datum=NAD83 +units=degrees\");\n 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\");\n\n defs.WGS84 = defs['EPSG:4326'];\n defs['EPSG:3785'] = defs['EPSG:3857']; // maintain backward compat, official code is 3857\n defs.GOOGLE = defs['EPSG:3857'];\n defs['EPSG:900913'] = defs['EPSG:3857'];\n defs['EPSG:102113'] = defs['EPSG:3857'];\n};\n","var globals = require('./global');\nvar parseProj = require('./projString');\nvar wkt = require('./wkt');\n\nfunction defs(name) {\n /*global console*/\n var that = this;\n if (arguments.length === 2) {\n var def = arguments[1];\n if (typeof def === 'string') {\n if (def.charAt(0) === '+') {\n defs[name] = parseProj(arguments[1]);\n }\n else {\n defs[name] = wkt(arguments[1]);\n }\n } else {\n defs[name] = def;\n }\n }\n else if (arguments.length === 1) {\n if (Array.isArray(name)) {\n return name.map(function(v) {\n if (Array.isArray(v)) {\n defs.apply(that, v);\n }\n else {\n defs(v);\n }\n });\n }\n else if (typeof name === 'string') {\n if (name in defs) {\n return defs[name];\n }\n }\n else if ('EPSG' in name) {\n defs['EPSG:' + name.EPSG] = name;\n }\n else if ('ESRI' in name) {\n defs['ESRI:' + name.ESRI] = name;\n }\n else if ('IAU2000' in name) {\n defs['IAU2000:' + name.IAU2000] = name;\n }\n else {\n console.log(name);\n }\n return;\n }\n\n\n}\nglobals(defs);\nmodule.exports = defs;\n","var defs = require('./defs');\nvar wkt = require('./wkt');\nvar projStr = require('./projString');\nfunction testObj(code){\n return typeof code === 'string';\n}\nfunction testDef(code){\n return code in defs;\n}\nfunction testWKT(code){\n var codeWords = ['GEOGCS','GEOCCS','PROJCS','LOCAL_CS'];\n return codeWords.reduce(function(a,b){\n return a+1+code.indexOf(b);\n },0);\n}\nfunction testProj(code){\n return code[0] === '+';\n}\nfunction parse(code){\n if (testObj(code)) {\n //check to see if this is a WKT string\n if (testDef(code)) {\n return defs[code];\n }\n else if (testWKT(code)) {\n return wkt(code);\n }\n else if (testProj(code)) {\n return projStr(code);\n }\n }else{\n return code;\n }\n}\n\nmodule.exports = parse;","var parseCode = require(\"./parseCode\");\nvar extend = require('./extend');\nvar projections = require('./projections');\nvar deriveConstants = require('./deriveConstants');\n\nfunction Projection(srsCode,callback) {\n if (!(this instanceof Projection)) {\n return new Projection(srsCode);\n }\n callback = callback || function(error){\n if(error){\n throw error;\n }\n };\n var json = parseCode(srsCode);\n if(typeof json !== 'object'){\n callback(srsCode);\n return;\n }\n var modifiedJSON = deriveConstants(json);\n var ourProj = Projection.projections.get(modifiedJSON.projName);\n if(ourProj){\n extend(this, modifiedJSON);\n extend(this, ourProj);\n this.init();\n callback(null, this);\n }else{\n callback(srsCode);\n }\n}\nProjection.projections = projections;\nProjection.projections.start();\nmodule.exports = Projection;\n","module.exports = function(crs, denorm, point) {\n var xin = point.x,\n yin = point.y,\n zin = point.z || 0.0;\n var v, t, i;\n for (i = 0; i < 3; i++) {\n if (denorm && i === 2 && point.z === undefined) {\n continue;\n }\n if (i === 0) {\n v = xin;\n t = 'x';\n }\n else if (i === 1) {\n v = yin;\n t = 'y';\n }\n else {\n v = zin;\n t = 'z';\n }\n switch (crs.axis[i]) {\n case 'e':\n point[t] = v;\n break;\n case 'w':\n point[t] = -v;\n break;\n case 'n':\n point[t] = v;\n break;\n case 's':\n point[t] = -v;\n break;\n case 'u':\n if (point[t] !== undefined) {\n point.z = v;\n }\n break;\n case 'd':\n if (point[t] !== undefined) {\n point.z = -v;\n }\n break;\n default:\n //console.log(\"ERROR: unknow axis (\"+crs.axis[i]+\") - check definition of \"+crs.projName);\n return null;\n }\n }\n return point;\n};\n","var PJD_3PARAM = 1;\nvar PJD_7PARAM = 2;\nvar PJD_GRIDSHIFT = 3;\nvar PJD_NODATUM = 5; // WGS84 or equivalent\nvar SRS_WGS84_SEMIMAJOR = 6378137; // only used in grid shift transforms\nvar SRS_WGS84_ESQUARED = 0.006694379990141316; //DGR: 2012-07-29\nmodule.exports = function(source, dest, point) {\n var wp, i, l;\n\n function checkParams(fallback) {\n return (fallback === PJD_3PARAM || fallback === PJD_7PARAM);\n }\n // Short cut if the datums are identical.\n if (source.compare_datums(dest)) {\n return point; // in this case, zero is sucess,\n // whereas cs_compare_datums returns 1 to indicate TRUE\n // confusing, should fix this\n }\n\n // Explicitly skip datum transform by setting 'datum=none' as parameter for either source or dest\n if (source.datum_type === PJD_NODATUM || dest.datum_type === PJD_NODATUM) {\n return point;\n }\n\n //DGR: 2012-07-29 : add nadgrids support (begin)\n var src_a = source.a;\n var src_es = source.es;\n\n var dst_a = dest.a;\n var dst_es = dest.es;\n\n var fallback = source.datum_type;\n // If this datum requires grid shifts, then apply it to geodetic coordinates.\n if (fallback === PJD_GRIDSHIFT) {\n if (this.apply_gridshift(source, 0, point) === 0) {\n source.a = SRS_WGS84_SEMIMAJOR;\n source.es = SRS_WGS84_ESQUARED;\n }\n else {\n // try 3 or 7 params transformation or nothing ?\n if (!source.datum_params) {\n source.a = src_a;\n source.es = source.es;\n return point;\n }\n wp = 1;\n for (i = 0, l = source.datum_params.length; i < l; i++) {\n wp *= source.datum_params[i];\n }\n if (wp === 0) {\n source.a = src_a;\n source.es = source.es;\n return point;\n }\n if (source.datum_params.length > 3) {\n fallback = PJD_7PARAM;\n }\n else {\n fallback = PJD_3PARAM;\n }\n }\n }\n if (dest.datum_type === PJD_GRIDSHIFT) {\n dest.a = SRS_WGS84_SEMIMAJOR;\n dest.es = SRS_WGS84_ESQUARED;\n }\n // Do we need to go through geocentric coordinates?\n if (source.es !== dest.es || source.a !== dest.a || checkParams(fallback) || checkParams(dest.datum_type)) {\n //DGR: 2012-07-29 : add nadgrids support (end)\n // Convert to geocentric coordinates.\n source.geodetic_to_geocentric(point);\n // CHECK_RETURN;\n // Convert between datums\n if (checkParams(source.datum_type)) {\n source.geocentric_to_wgs84(point);\n // CHECK_RETURN;\n }\n if (checkParams(dest.datum_type)) {\n dest.geocentric_from_wgs84(point);\n // CHECK_RETURN;\n }\n // Convert back to geodetic coordinates\n dest.geocentric_to_geodetic(point);\n // CHECK_RETURN;\n }\n // Apply grid shift to destination if required\n if (dest.datum_type === PJD_GRIDSHIFT) {\n this.apply_gridshift(dest, 1, point);\n // CHECK_RETURN;\n }\n\n source.a = src_a;\n source.es = src_es;\n dest.a = dst_a;\n dest.es = dst_es;\n\n return point;\n};\n\n","var D2R = 0.01745329251994329577;\nvar R2D = 57.29577951308232088;\nvar PJD_3PARAM = 1;\nvar PJD_7PARAM = 2;\nvar datum_transform = require('./datum_transform');\nvar adjust_axis = require('./adjust_axis');\nvar proj = require('./Proj');\nvar toPoint = require('./common/toPoint');\nmodule.exports = function transform(source, dest, point) {\n var wgs84;\n if (Array.isArray(point)) {\n point = toPoint(point);\n }\n function checkNotWGS(source, dest) {\n return ((source.datum.datum_type === PJD_3PARAM || source.datum.datum_type === PJD_7PARAM) && dest.datumCode !== \"WGS84\");\n }\n\n // Workaround for datum shifts towgs84, if either source or destination projection is not wgs84\n if (source.datum && dest.datum && (checkNotWGS(source, dest) || checkNotWGS(dest, source))) {\n wgs84 = new proj('WGS84');\n transform(source, wgs84, point);\n source = wgs84;\n }\n // DGR, 2010/11/12\n if (source.axis !== \"enu\") {\n adjust_axis(source, false, point);\n }\n // Transform source points to long/lat, if they aren't already.\n if (source.projName === \"longlat\") {\n point.x *= D2R; // convert degrees to radians\n point.y *= D2R;\n }\n else {\n if (source.to_meter) {\n point.x *= source.to_meter;\n point.y *= source.to_meter;\n }\n source.inverse(point); // Convert Cartesian to longlat\n }\n // Adjust for the prime meridian if necessary\n if (source.from_greenwich) {\n point.x += source.from_greenwich;\n }\n\n // Convert datums if needed, and if possible.\n point = datum_transform(source.datum, dest.datum, point);\n\n // Adjust for the prime meridian if necessary\n if (dest.from_greenwich) {\n point.x -= dest.from_greenwich;\n }\n\n if (dest.projName === \"longlat\") {\n // convert radians to decimal degrees\n point.x *= R2D;\n point.y *= R2D;\n }\n else { // else project\n dest.forward(point);\n if (dest.to_meter) {\n point.x /= dest.to_meter;\n point.y /= dest.to_meter;\n }\n }\n\n // DGR, 2010/11/12\n if (dest.axis !== \"enu\") {\n adjust_axis(dest, true, point);\n }\n\n return point;\n};","var mgrs = require('mgrs');\n\nfunction Point(x, y, z) {\n if (!(this instanceof Point)) {\n return new Point(x, y, z);\n }\n if (Array.isArray(x)) {\n this.x = x[0];\n this.y = x[1];\n this.z = x[2] || 0.0;\n } else if(typeof x === 'object') {\n this.x = x.x;\n this.y = x.y;\n this.z = x.z || 0.0;\n } else if (typeof x === 'string' && typeof y === 'undefined') {\n var coords = x.split(',');\n this.x = parseFloat(coords[0], 10);\n this.y = parseFloat(coords[1], 10);\n this.z = parseFloat(coords[2], 10) || 0.0;\n } else {\n this.x = x;\n this.y = y;\n this.z = z || 0.0;\n }\n console.warn('proj4.Point will be removed in version 3, use proj4.toPoint');\n}\n\nPoint.fromMGRS = function(mgrsStr) {\n return new Point(mgrs.toPoint(mgrsStr));\n};\nPoint.prototype.toMGRS = function(accuracy) {\n return mgrs.forward([this.x, this.y], accuracy);\n};\nmodule.exports = Point;\n","var proj = require('./Proj');\nvar transform = require('./transform');\nvar wgs84 = proj('WGS84');\n\nfunction transformer(from, to, coords) {\n var transformedArray;\n if (Array.isArray(coords)) {\n transformedArray = transform(from, to, coords);\n if (coords.length === 3) {\n return [transformedArray.x, transformedArray.y, transformedArray.z];\n }\n else {\n return [transformedArray.x, transformedArray.y];\n }\n }\n else {\n return transform(from, to, coords);\n }\n}\n\nfunction checkProj(item) {\n if (item instanceof proj) {\n return item;\n }\n if (item.oProj) {\n return item.oProj;\n }\n return proj(item);\n}\nfunction proj4(fromProj, toProj, coord) {\n fromProj = checkProj(fromProj);\n var single = false;\n var obj;\n if (typeof toProj === 'undefined') {\n toProj = fromProj;\n fromProj = wgs84;\n single = true;\n }\n else if (typeof toProj.x !== 'undefined' || Array.isArray(toProj)) {\n coord = toProj;\n toProj = fromProj;\n fromProj = wgs84;\n single = true;\n }\n toProj = checkProj(toProj);\n if (coord) {\n return transformer(fromProj, toProj, coord);\n }\n else {\n obj = {\n forward: function(coords) {\n return transformer(fromProj, toProj, coords);\n },\n inverse: function(coords) {\n return transformer(toProj, fromProj, coords);\n }\n };\n if (single) {\n obj.oProj = toProj;\n }\n return obj;\n }\n}\nmodule.exports = proj4;","var proj4 = require('./core');\nproj4.defaultDatum = 'WGS84'; //default datum\nproj4.Proj = require('./Proj');\nproj4.WGS84 = new proj4.Proj('WGS84');\nproj4.Point = require('./Point');\nproj4.toPoint = require(\"./common/toPoint\");\nproj4.defs = require('./defs');\nproj4.transform = require('./transform');\nproj4.mgrs = require('mgrs');\nproj4.version = require('../package.json').version;\nrequire('./includedProjections')(proj4);\nmodule.exports = proj4;","(function(self) {\n 'use strict';\n\n if (self.fetch) {\n return\n }\n\n var support = {\n searchParams: 'URLSearchParams' in self,\n iterable: 'Symbol' in self && 'iterator' in Symbol,\n blob: 'FileReader' in self && 'Blob' in self && (function() {\n try {\n new Blob()\n return true\n } catch(e) {\n return false\n }\n })(),\n formData: 'FormData' in self,\n arrayBuffer: 'ArrayBuffer' in self\n }\n\n function normalizeName(name) {\n if (typeof name !== 'string') {\n name = String(name)\n }\n if (/[^a-z0-9\\-#$%&'*+.\\^_`|~]/i.test(name)) {\n throw new TypeError('Invalid character in header field name')\n }\n return name.toLowerCase()\n }\n\n function normalizeValue(value) {\n if (typeof value !== 'string') {\n value = String(value)\n }\n return value\n }\n\n // Build a destructive iterator for the value list\n function iteratorFor(items) {\n var iterator = {\n next: function() {\n var value = items.shift()\n return {done: value === undefined, value: value}\n }\n }\n\n if (support.iterable) {\n iterator[Symbol.iterator] = function() {\n return iterator\n }\n }\n\n return iterator\n }\n\n function Headers(headers) {\n this.map = {}\n\n if (headers instanceof Headers) {\n headers.forEach(function(value, name) {\n this.append(name, value)\n }, this)\n\n } else if (headers) {\n Object.getOwnPropertyNames(headers).forEach(function(name) {\n this.append(name, headers[name])\n }, this)\n }\n }\n\n Headers.prototype.append = function(name, value) {\n name = normalizeName(name)\n value = normalizeValue(value)\n var list = this.map[name]\n if (!list) {\n list = []\n this.map[name] = list\n }\n list.push(value)\n }\n\n Headers.prototype['delete'] = function(name) {\n delete this.map[normalizeName(name)]\n }\n\n Headers.prototype.get = function(name) {\n var values = this.map[normalizeName(name)]\n return values ? values[0] : null\n }\n\n Headers.prototype.getAll = function(name) {\n return this.map[normalizeName(name)] || []\n }\n\n Headers.prototype.has = function(name) {\n return this.map.hasOwnProperty(normalizeName(name))\n }\n\n Headers.prototype.set = function(name, value) {\n this.map[normalizeName(name)] = [normalizeValue(value)]\n }\n\n Headers.prototype.forEach = function(callback, thisArg) {\n Object.getOwnPropertyNames(this.map).forEach(function(name) {\n this.map[name].forEach(function(value) {\n callback.call(thisArg, value, name, this)\n }, this)\n }, this)\n }\n\n Headers.prototype.keys = function() {\n var items = []\n this.forEach(function(value, name) { items.push(name) })\n return iteratorFor(items)\n }\n\n Headers.prototype.values = function() {\n var items = []\n this.forEach(function(value) { items.push(value) })\n return iteratorFor(items)\n }\n\n Headers.prototype.entries = function() {\n var items = []\n this.forEach(function(value, name) { items.push([name, value]) })\n return iteratorFor(items)\n }\n\n if (support.iterable) {\n Headers.prototype[Symbol.iterator] = Headers.prototype.entries\n }\n\n function consumed(body) {\n if (body.bodyUsed) {\n return Promise.reject(new TypeError('Already read'))\n }\n body.bodyUsed = true\n }\n\n function fileReaderReady(reader) {\n return new Promise(function(resolve, reject) {\n reader.onload = function() {\n resolve(reader.result)\n }\n reader.onerror = function() {\n reject(reader.error)\n }\n })\n }\n\n function readBlobAsArrayBuffer(blob) {\n var reader = new FileReader()\n reader.readAsArrayBuffer(blob)\n return fileReaderReady(reader)\n }\n\n function readBlobAsText(blob) {\n var reader = new FileReader()\n reader.readAsText(blob)\n return fileReaderReady(reader)\n }\n\n function Body() {\n this.bodyUsed = false\n\n this._initBody = function(body) {\n this._bodyInit = body\n if (typeof body === 'string') {\n this._bodyText = body\n } else if (support.blob && Blob.prototype.isPrototypeOf(body)) {\n this._bodyBlob = body\n } else if (support.formData && FormData.prototype.isPrototypeOf(body)) {\n this._bodyFormData = body\n } else if (support.searchParams && URLSearchParams.prototype.isPrototypeOf(body)) {\n this._bodyText = body.toString()\n } else if (!body) {\n this._bodyText = ''\n } else if (support.arrayBuffer && ArrayBuffer.prototype.isPrototypeOf(body)) {\n // Only support ArrayBuffers for POST method.\n // Receiving ArrayBuffers happens via Blobs, instead.\n } else {\n throw new Error('unsupported BodyInit type')\n }\n\n if (!this.headers.get('content-type')) {\n if (typeof body === 'string') {\n this.headers.set('content-type', 'text/plain;charset=UTF-8')\n } else if (this._bodyBlob && this._bodyBlob.type) {\n this.headers.set('content-type', this._bodyBlob.type)\n } else if (support.searchParams && URLSearchParams.prototype.isPrototypeOf(body)) {\n this.headers.set('content-type', 'application/x-www-form-urlencoded;charset=UTF-8')\n }\n }\n }\n\n if (support.blob) {\n this.blob = function() {\n var rejected = consumed(this)\n if (rejected) {\n return rejected\n }\n\n if (this._bodyBlob) {\n return Promise.resolve(this._bodyBlob)\n } else if (this._bodyFormData) {\n throw new Error('could not read FormData body as blob')\n } else {\n return Promise.resolve(new Blob([this._bodyText]))\n }\n }\n\n this.arrayBuffer = function() {\n return this.blob().then(readBlobAsArrayBuffer)\n }\n\n this.text = function() {\n var rejected = consumed(this)\n if (rejected) {\n return rejected\n }\n\n if (this._bodyBlob) {\n return readBlobAsText(this._bodyBlob)\n } else if (this._bodyFormData) {\n throw new Error('could not read FormData body as text')\n } else {\n return Promise.resolve(this._bodyText)\n }\n }\n } else {\n this.text = function() {\n var rejected = consumed(this)\n return rejected ? rejected : Promise.resolve(this._bodyText)\n }\n }\n\n if (support.formData) {\n this.formData = function() {\n return this.text().then(decode)\n }\n }\n\n this.json = function() {\n return this.text().then(JSON.parse)\n }\n\n return this\n }\n\n // HTTP methods whose capitalization should be normalized\n var methods = ['DELETE', 'GET', 'HEAD', 'OPTIONS', 'POST', 'PUT']\n\n function normalizeMethod(method) {\n var upcased = method.toUpperCase()\n return (methods.indexOf(upcased) > -1) ? upcased : method\n }\n\n function Request(input, options) {\n options = options || {}\n var body = options.body\n if (Request.prototype.isPrototypeOf(input)) {\n if (input.bodyUsed) {\n throw new TypeError('Already read')\n }\n this.url = input.url\n this.credentials = input.credentials\n if (!options.headers) {\n this.headers = new Headers(input.headers)\n }\n this.method = input.method\n this.mode = input.mode\n if (!body) {\n body = input._bodyInit\n input.bodyUsed = true\n }\n } else {\n this.url = input\n }\n\n this.credentials = options.credentials || this.credentials || 'omit'\n if (options.headers || !this.headers) {\n this.headers = new Headers(options.headers)\n }\n this.method = normalizeMethod(options.method || this.method || 'GET')\n this.mode = options.mode || this.mode || null\n this.referrer = null\n\n if ((this.method === 'GET' || this.method === 'HEAD') && body) {\n throw new TypeError('Body not allowed for GET or HEAD requests')\n }\n this._initBody(body)\n }\n\n Request.prototype.clone = function() {\n return new Request(this)\n }\n\n function decode(body) {\n var form = new FormData()\n body.trim().split('&').forEach(function(bytes) {\n if (bytes) {\n var split = bytes.split('=')\n var name = split.shift().replace(/\\+/g, ' ')\n var value = split.join('=').replace(/\\+/g, ' ')\n form.append(decodeURIComponent(name), decodeURIComponent(value))\n }\n })\n return form\n }\n\n function headers(xhr) {\n var head = new Headers()\n var pairs = (xhr.getAllResponseHeaders() || '').trim().split('\\n')\n pairs.forEach(function(header) {\n var split = header.trim().split(':')\n var key = split.shift().trim()\n var value = split.join(':').trim()\n head.append(key, value)\n })\n return head\n }\n\n Body.call(Request.prototype)\n\n function Response(bodyInit, options) {\n if (!options) {\n options = {}\n }\n\n this.type = 'default'\n this.status = options.status\n this.ok = this.status >= 200 && this.status < 300\n this.statusText = options.statusText\n this.headers = options.headers instanceof Headers ? options.headers : new Headers(options.headers)\n this.url = options.url || ''\n this._initBody(bodyInit)\n }\n\n Body.call(Response.prototype)\n\n Response.prototype.clone = function() {\n return new Response(this._bodyInit, {\n status: this.status,\n statusText: this.statusText,\n headers: new Headers(this.headers),\n url: this.url\n })\n }\n\n Response.error = function() {\n var response = new Response(null, {status: 0, statusText: ''})\n response.type = 'error'\n return response\n }\n\n var redirectStatuses = [301, 302, 303, 307, 308]\n\n Response.redirect = function(url, status) {\n if (redirectStatuses.indexOf(status) === -1) {\n throw new RangeError('Invalid status code')\n }\n\n return new Response(null, {status: status, headers: {location: url}})\n }\n\n self.Headers = Headers\n self.Request = Request\n self.Response = Response\n\n self.fetch = function(input, init) {\n return new Promise(function(resolve, reject) {\n var request\n if (Request.prototype.isPrototypeOf(input) && !init) {\n request = input\n } else {\n request = new Request(input, init)\n }\n\n var xhr = new XMLHttpRequest()\n\n function responseURL() {\n if ('responseURL' in xhr) {\n return xhr.responseURL\n }\n\n // Avoid security warnings on getResponseHeader when not allowed by CORS\n if (/^X-Request-URL:/m.test(xhr.getAllResponseHeaders())) {\n return xhr.getResponseHeader('X-Request-URL')\n }\n\n return\n }\n\n xhr.onload = function() {\n var options = {\n status: xhr.status,\n statusText: xhr.statusText,\n headers: headers(xhr),\n url: responseURL()\n }\n var body = 'response' in xhr ? xhr.response : xhr.responseText\n resolve(new Response(body, options))\n }\n\n xhr.onerror = function() {\n reject(new TypeError('Network request failed'))\n }\n\n xhr.ontimeout = function() {\n reject(new TypeError('Network request failed'))\n }\n\n xhr.open(request.method, request.url, true)\n\n if (request.credentials === 'include') {\n xhr.withCredentials = true\n }\n\n if ('responseType' in xhr && support.blob) {\n xhr.responseType = 'blob'\n }\n\n request.headers.forEach(function(value, name) {\n xhr.setRequestHeader(name, value)\n })\n\n xhr.send(typeof request._bodyInit === 'undefined' ? null : request._bodyInit)\n })\n }\n self.fetch.polyfill = true\n})(typeof self !== 'undefined' ? self : this);\n","'use strict';\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.get = get;\nexports.load = load;\nexports.set = set;\n\nrequire('whatwg-fetch');\n\nvar _proj = require('proj4');\n\nvar _proj2 = _interopRequireDefault(_proj);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nfunction _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; }\n\nvar ROOT_PREFIX = 'http://www.opengis.net/def/crs/';\nvar OGC_PREFIX = ROOT_PREFIX + 'OGC/';\nvar EPSG_PREFIX = ROOT_PREFIX + 'EPSG/0/';\n\n/**\r\n * @typedef {Object} Projection\r\n * @property {function(lonlat: Array<number>): Array<number>} forward\r\n * Transforms a geographic WGS84 [longitude, latitude] coordinate to an [x, y] projection coordinate.\r\n * @property {function(xy: Array<number>): Array<number>} inverse\r\n * Transforms an [x, y] projection coordinate to a geographic WGS84 [longitude, latitude] coordinate.\r\n */\n\n// a cache of URI string -> Projection object mappings\nvar projCache = {};\n\n// work-arounds for incorrect epsg.io / proj4 behaviour\nvar needsAxesReordering = _defineProperty({}, EPSG_PREFIX + 4326, true);\n\n// store some built-in projections which are not available on epsg.io\nvar LONLAT = (0, _proj2.default)('+proj=longlat +datum=WGS84 +no_defs');\nset(OGC_PREFIX + '1.3/CRS84', LONLAT);\nset(EPSG_PREFIX + 4979, reverseAxes(LONLAT));\n\n/**\r\n * Returns a stored {@link Projection} for a given URI, or {@link undefined} if no {@link Projection} is stored for that URI.\r\n * \r\n * @param {string} crsUri The CRS URI for which to return a {@link Projection}.\r\n * @return {Projection|undefined} A {@link Projection} object, or {@link undefined} if not stored by {@link load} or {@link set}.\r\n * \r\n * @example\r\n * // has to be stored previously via load() or set()\r\n * var proj = uriproj.get('http://www.opengis.net/def/crs/EPSG/0/27700')\r\n * var [longitude, latitude] = [-1.54, 55.5]\r\n * var [easting,northing] = proj.forward([longitude, latitude])\r\n */\nfunction get(crsUri) {\n return projCache[crsUri];\n}\n\n/**\r\n * Returns a {@link Promise} that succeeds with an already stored {@link Projection} or, if not stored,\r\n * that remotely loads the {@link Projection} (currently using https://epsg.io), stores it, and then succeeds with it.\r\n * \r\n * @param {string} crsUri The CRS URI for which to return a projection.\r\n * @return {Promise<Projection,Error>} A {@link Promise} object succeeding with a {@link Projection} object,\r\n * and failing with an {@link Error} object in case of network or PROJ.4 parsing problems.\r\n * \r\n * @example <caption>Loading a single projection</caption>\r\n * uriproj.load('http://www.opengis.net/def/crs/EPSG/0/27700').then(proj => {\r\n * var [longitude, latitude] = [-1.54, 55.5]\r\n * var [easting,northing] = proj.forward([longitude, latitude])\r\n * })\r\n * \r\n * @example <caption>Loading multiple projections</caption>\r\n * var uris = [\r\n * 'http://www.opengis.net/def/crs/EPSG/0/27700',\r\n * 'http://www.opengis.net/def/crs/EPSG/0/7376',\r\n * 'http://www.opengis.net/def/crs/EPSG/0/7375']\r\n * Promise.all(uris.map(uriproj.load)).then(projs => {\r\n * // all projections are loaded and stored now\r\n * \r\n * // get the first projection\r\n * var proj1 = projs[0]\r\n * // or:\r\n * var proj1 = uriproj.get(uris[0])\r\n * })\r\n * \r\n */\nfunction load(crsUri) {\n if (crsUri in projCache) {\n return Promise.resolve(projCache[crsUri]);\n }\n\n var epsg = crsUriToEPSG(crsUri);\n var url = 'https://epsg.io/' + epsg + '.proj4';\n\n return fetch(url).then(function (response) {\n if (!response.ok) {\n throw new Error('HTTP response code: ' + response.status);\n }\n return response.text();\n }).then(function (proj4string) {\n return set(crsUri, proj4string, { reverseAxes: crsUri in needsAxesReordering });\n });\n}\n\n/**\r\n * Stores a given projection for a given URI that can then be accessed via {@link get} and {@link load}.\r\n * \r\n * @param {string} crsUri The CRS URI for which to store the projection.\r\n * @param {string|Projection} proj A proj4 string or a {@link Projection} object.\r\n * @param {Object} [options] Options object.\r\n * @param {boolean} [options.reverseAxes=false] If proj is a proj4 string, whether to reverse the projection axes.\r\n * @return {Projection} The newly stored projection.\r\n * @throws {Error} If crsUri or proj is missing, or if a PROJ.4 string cannot be parsed by proj4js. \r\n * \r\n * @example <caption>Storing a projection using a PROJ.4 string</caption>\r\n * var uri = 'http://www.opengis.net/def/crs/EPSG/0/27700'\r\n * var proj4 = '+proj=tmerc +lat_0=49 +lon_0=-2 +k=0.9996012717 +x_0=400000 +y_0=-100000 ' +\r\n * '+ellps=airy +towgs84=446.448,-125.157,542.06,0.15,0.247,0.842,-20.489 +units=m +no_defs'\r\n * uriproj.set(uri, proj4)\r\n * \r\n * @example <caption>Storing a projection using a Projection object</caption>\r\n * var uri = 'http://www.opengis.net/def/crs/EPSG/0/27700'\r\n * var proj = {\r\n * forward: ([lon,lat]) => [..., ...],\r\n * inverse: ([x,y]) => [..., ...]\r\n * }\r\n * uriproj.set(uri, proj)\r\n */\nfunction set(crsUri, proj) {\n var options = arguments.length <= 2 || arguments[2] === undefined ? {} : arguments[2];\n\n if (!crsUri || !proj) {\n throw new Error('crsUri and proj cannot be empty');\n }\n var projobj = void 0;\n if (typeof proj === 'string') {\n projobj = (0, _proj2.default)(proj);\n if (!projobj) {\n throw new Error('Unsupported proj4 string: ' + proj);\n }\n if (options.reverseAxes) {\n projobj = reverseAxes(projobj);\n }\n } else {\n projobj = proj;\n }\n projCache[crsUri] = projobj;\n return projobj;\n}\n\n/**\r\n * Return the EPSG code of an OGC CRS URI of the form\r\n * http://www.opengis.net/def/crs/EPSG/0/1234 (would return 1234).\r\n * \r\n * @param {string} crsUri The CRS URI for which to return the EPSG code.\r\n * @return {string} The EPSG code.\r\n */\nfunction crsUriToEPSG(uri) {\n var epsg = void 0;\n if (uri.indexOf(EPSG_PREFIX) === 0) {\n epsg = uri.substr(EPSG_PREFIX.length);\n } else {\n throw new Error('Unsupported CRS URI: ' + uri);\n }\n\n return epsg;\n}\n\n/**\r\n * Reverses projection axis order.\r\n * \r\n * For example, a projection with lon, lat axis order is turned into one with lat, lon order.\r\n * This is necessary since geographic projections in proj4 can only be defined with\r\n * lon,lat order, however some CRSs have lat,lon order (like EPSG4326).\r\n * Incorrectly, epsg.io returns a proj4 string (with lon,lat order) even if the CRS\r\n * has lat,lon order. This function manually flips the axis order of a given projection.\r\n * See also `needsAxesReordering` above.\r\n * \r\n * @param {Projection} proj The projection whose axis order to revert.\r\n * @return {Projection} The projection with reversed axis order.\r\n */\nfunction reverseAxes(proj) {\n return {\n forward: function forward(pos) {\n return proj.forward(pos).reverse();\n },\n inverse: function inverse(pos) {\n return proj.inverse([pos[1], pos[0]]);\n }\n };\n}","import * as uriproj from 'uriproj'\r\nimport { COVJSON_DATATYPE_TUPLE, COVJSON_DATATYPE_POLYGON } from '../constants.js'\r\n\r\nconst OPENGIS_CRS_PREFIX = 'http://www.opengis.net/def/crs/'\r\n\r\n/** 3D WGS84 in lat-lon-height order */\r\nconst EPSG4979 = OPENGIS_CRS_PREFIX + 'EPSG/0/4979'\r\n\r\n/** 2D WGS84 in lat-lon order */\r\nconst EPSG4326 = OPENGIS_CRS_PREFIX + 'EPSG/0/4326'\r\n\r\n/** 2D WGS84 in lon-lat order */\r\nconst CRS84 = OPENGIS_CRS_PREFIX + 'OGC/1.3/CRS84'\r\n\r\n/** CRSs in which position is specified by geodetic latitude and longitude */\r\nconst GeographicCRSs = [EPSG4979, EPSG4326, CRS84]\r\n\r\n/** Position of longitude axis */\r\nconst LongitudeAxisIndex = {\r\n [EPSG4979]: 1,\r\n [EPSG4326]: 1,\r\n [CRS84]: 0\r\n}\r\n\r\n/**\r\n * Return the reference system connection object for the given domain coordinate ID,\r\n * or undefined if none exists.\r\n */\r\nexport function getReferenceObject (domain, coordinateId) {\r\n let ref = domain.referencing.find(ref => ref.coordinates.indexOf(coordinateId) !== -1)\r\n return ref\r\n}\r\n\r\n/**\r\n * Return the reference system connection object of the horizontal CRS of the domain,\r\n * or ``undefined`` if none found.\r\n * A horizontal CRS is either geodetic (typically ellipsoidal, meaning lat/lon)\r\n * or projected, and may be 2D or 3D (including height).\r\n */\r\nexport function getHorizontalCRSReferenceObject (domain) {\r\n let isHorizontal = ref =>\r\n ['GeodeticCRS', 'GeographicCRS', 'GeocentricCRS', 'ProjectedCRS'].indexOf(ref.system.type) !== -1\r\n let ref = domain.referencing.find(isHorizontal)\r\n return ref\r\n}\r\n\r\n/**\r\n * Return whether the reference system is a CRS in which\r\n * horizontal position is specified by geodetic latitude and longitude.\r\n */\r\nexport function isEllipsoidalCRS (rs) {\r\n return rs.type === 'GeographicCRS' || GeographicCRSs.indexOf(rs.id) !== -1\r\n}\r\n\r\n/**\r\n * Return a projection object based on the CRS found in the coverage domain.\r\n * If no CRS is found or it is unsupported, then ``undefined`` is returned.\r\n * For non-built-in projections, this function returns already-cached projections\r\n * that were loaded via {@link loadProjection}.\r\n *\r\n * A projection converts between geodetic lat/lon and projected x/y values.\r\n *\r\n * For lat/lon CRSs the projection is defined such that an input lat/lon\r\n * position gets projected/wrapped to the longitude range used in the domain, for example\r\n * [0,360]. The purpose of this is to make intercomparison between different coverages easier.\r\n *\r\n * The following limitations currently apply:\r\n * - only primitive axes and Tuple/Polygon composite axes are supported for lat/lon CRSs\r\n *\r\n * @param {Domain} domain A coverage domain object.\r\n * @return {IProjection} A stripped-down Leaflet IProjection object.\r\n */\r\nexport function getProjection (domain) {\r\n let isEllipsoidal = domain.referencing.some(ref => isEllipsoidalCRS(ref.system))\r\n if (isEllipsoidal) {\r\n return getLonLatProjection(domain)\r\n }\r\n\r\n // try to get projection via uriproj library\r\n let ref = getHorizontalCRSReferenceObject(domain)\r\n if (!ref) {\r\n throw new Error('No horizontal CRS found in coverage domain')\r\n }\r\n\r\n let uri = ref.system.id\r\n let proj = uriproj.get(uri)\r\n if (!proj) {\r\n throw new Error('Projection ' + uri + ' not cached in uriproj, use loadProjection() instead')\r\n }\r\n return wrapProj4(proj)\r\n}\r\n\r\n/**\r\n * Like {@link getProjection} but will also try to remotely load a projection definition via the uriproj library.\r\n * On success, the loaded projection is automatically cached for later use and can be directly requested\r\n * with {@link getProjection}.\r\n *\r\n * @param {Domain} domain A coverage domain object.\r\n * @return {Promise<IProjection>} A Promise succeeding with a stripped-down Leaflet IProjection object.\r\n */\r\nexport function loadProjection (domain) {\r\n try {\r\n // we try the local one first so that we get our special lon/lat projection (which doesn't exist in uriproj)\r\n return getProjection(domain)\r\n } catch (e) {}\r\n\r\n // try to load projection remotely via uriproj library\r\n let ref = getHorizontalCRSReferenceObject(domain)\r\n if (!ref) {\r\n throw new Error('No horizontal CRS found in coverage domain')\r\n }\r\n\r\n let uri = ref.system.id\r\n return uriproj.load(uri).then(proj => wrapProj4(proj))\r\n}\r\n\r\n/**\r\n * Return the coordinate IDs of the horizontal CRS of the domain.\r\n *\r\n * @deprecated use getHorizontalCRSCoordinateIDs\r\n * @example\r\n * var [xComp,yComp] = getHorizontalCRSComponents(domain)\r\n */\r\nexport function getHorizontalCRSComponents (domain) {\r\n return getHorizontalCRSCoordinateIDs(domain)\r\n}\r\n\r\n/**\r\n * Return the coordinate IDs of the horizontal CRS of the domain.\r\n *\r\n * @example\r\n * var [xComp,yComp] = getHorizontalCRSCoordinateIDs(domain)\r\n */\r\nexport function getHorizontalCRSCoordinateIDs (domain) {\r\n let ref = getHorizontalCRSReferenceObject(domain)\r\n return ref.coordinates\r\n}\r\n\r\n/**\r\n * Wraps a proj4 Projection object into an IProjection object.\r\n */\r\nfunction wrapProj4 (proj) {\r\n return {\r\n project: ({lon, lat}) => {\r\n let [x, y] = proj.forward([lon, lat])\r\n return {x, y}\r\n },\r\n unproject: ({x, y}) => {\r\n let [lon, lat] = proj.inverse([x, y])\r\n return {lon, lat}\r\n }\r\n }\r\n}\r\n\r\nfunction getLonLatProjection (domain) {\r\n let ref = domain.referencing.find(ref => isEllipsoidalCRS(ref.system))\r\n let lonIdx = LongitudeAxisIndex[ref.system.id]\r\n if (lonIdx > 1) {\r\n // this should never happen as longitude is always the first or second axis\r\n throw new Error()\r\n }\r\n\r\n let lonComponent = ref.coordinates[lonIdx]\r\n\r\n // we find the min and max longitude occuring in the domain by inspecting the axis values\r\n // Note: this is inefficient for big composite axes.\r\n // In that case, something like a domain extent might help which has the min/max values for each component.\r\n // TODO handle bounds\r\n let lonMin, lonMax\r\n if (domain.axes.has(lonComponent)) {\r\n // longitude is a grid axis\r\n let lonAxisName = lonComponent\r\n let lonAxisVals = domain.axes.get(lonAxisName).values\r\n lonMin = lonAxisVals[0]\r\n lonMax = lonAxisVals[lonAxisVals.length - 1]\r\n if (lonMin > lonMax) {\r\n [lonMin, lonMax] = [lonMax, lonMin]\r\n }\r\n } else {\r\n // TODO there should be no dependency to CovJSON\r\n\r\n // longitude is not a primitive grid axis but a component of a composite axis\r\n\r\n // find the composite axis containing the longitude component\r\n let axes = [...domain.axes.values()]\r\n let axis = axes.find(axis => axis.coordinates.indexOf(lonComponent) !== -1)\r\n let lonCompIdx = axis.coordinates.indexOf(lonComponent)\r\n\r\n // scan the composite axis for min/max longitude values\r\n lonMin = Infinity\r\n lonMax = -Infinity\r\n if (axis.dataType === COVJSON_DATATYPE_TUPLE) {\r\n for (let tuple of axis.values) {\r\n let lon = tuple[lonCompIdx]\r\n lonMin = Math.min(lon, lonMin)\r\n lonMax = Math.max(lon, lonMax)\r\n }\r\n } else if (axis.dataType === COVJSON_DATATYPE_POLYGON) {\r\n for (let poly of axis.values) {\r\n for (let ring of poly) {\r\n for (let point of ring) {\r\n let lon = point[lonCompIdx]\r\n lonMin = Math.min(lon, lonMin)\r\n lonMax = Math.max(lon, lonMax)\r\n }\r\n }\r\n }\r\n } else {\r\n throw new Error('Unsupported data type: ' + axis.dataType)\r\n }\r\n }\r\n\r\n let lonMid = (lonMax + lonMin) / 2\r\n let lonMinExtended = lonMid - 180\r\n let lonMaxExtended = lonMid + 180\r\n\r\n return {\r\n project: ({lon, lat}) => {\r\n let lonProjected\r\n if (lonMinExtended <= lon && lon <= lonMaxExtended) {\r\n // use unchanged to avoid introducing rounding errors\r\n lonProjected = lon\r\n } else {\r\n lonProjected = ((lon - lonMinExtended) % 360 + 360) % 360 + lonMinExtended\r\n }\r\n\r\n let [x, y] = lonIdx === 0 ? [lonProjected, lat] : [lat, lonProjected]\r\n return {x, y}\r\n },\r\n unproject: ({x, y}) => {\r\n let [lon, lat] = lonIdx === 0 ? [x, y] : [y, x]\r\n return {lon, lat}\r\n }\r\n }\r\n}\r\n\r\n/**\r\n * Reprojects coordinates from one projection to another.\r\n */\r\nexport function reprojectCoords (pos, fromProjection, toProjection) {\r\n return toProjection.project(fromProjection.unproject(pos))\r\n}\r\n\r\n/**\r\n * Returns a function which converts an arbitrary longitude to the\r\n * longitude extent used in the coverage domain.\r\n * This only supports primitive axes since this is what subsetByValue supports.\r\n * The longitude extent is extended to 360 degrees if the actual extent is smaller.\r\n * The extension is done equally on both sides of the extent.\r\n *\r\n * For example, the domain may have longitudes within [0,360].\r\n * An input longitude of -70 is converted to 290.\r\n * All longitudes within [0,360] are returned unchanged.\r\n *\r\n * If the domain has longitudes within [10,50] then the\r\n * extended longitude range is [-150,210] (-+180 from the middle point).\r\n * An input longitude of -170 is converted to 190.\r\n * All longitudes within [-150,210] are returned unchanged.\r\n *\r\n * @ignore\r\n */\r\nexport function getLongitudeWrapper (domain, axisName) {\r\n // TODO deprecate this in favour of getProjection, check leaflet-coverage\r\n\r\n // for primitive axes, the axis identifier = component identifier\r\n if (!isLongitudeAxis(domain, axisName)) {\r\n throw new Error(`'${axisName}' is not a longitude axis`)\r\n }\r\n\r\n let vals = domain.axes.get(axisName).values\r\n let lon_min = vals[0]\r\n let lon_max = vals[vals.length - 1]\r\n if (lon_min > lon_max) {\r\n [lon_min, lon_max] = [lon_max, lon_min]\r\n }\r\n\r\n let x_mid = (lon_max + lon_min) / 2\r\n let x_min = x_mid - 180\r\n let x_max = x_mid + 180\r\n\r\n return lon => {\r\n if (x_min <= lon && lon <= x_max) {\r\n // directly return to avoid introducing rounding errors\r\n return lon\r\n } else {\r\n return ((lon - x_min) % 360 + 360) % 360 + x_min\r\n }\r\n }\r\n}\r\n\r\n/**\r\n * Return whether the given domain axis represents longitudes.\r\n *\r\n * @ignore\r\n */\r\nexport function isLongitudeAxis (domain, axisName) {\r\n let ref = getReferenceObject(domain, axisName)\r\n if (!ref) {\r\n return false\r\n }\r\n\r\n let crsId = ref.system.id\r\n // TODO should support unknown CRSs with embedded axis information\r\n if (GeographicCRSs.indexOf(crsId) === -1) {\r\n // this also covers the case when there is no ID property\r\n return false\r\n }\r\n\r\n let compIdx = ref.coordinates.indexOf(axisName)\r\n let isLongitude = LongitudeAxisIndex[crsId] === compIdx\r\n return isLongitude\r\n}\r\n\r\n/**\r\n * Returns true if the given axis has ISO8601 date strings\r\n * as axis values.\r\n */\r\nexport function isISODateAxis (domain, axisName) {\r\n let val = domain.axes.get(axisName).values[0]\r\n if (typeof val !== 'string') {\r\n return false\r\n }\r\n return !isNaN(new Date(val).getTime())\r\n}\r\n\r\nexport function asTime (inp) {\r\n let res\r\n let err = false\r\n if (typeof inp === 'string') {\r\n res = new Date(inp).getTime()\r\n } else if (inp instanceof Date) {\r\n res = inp.getTime()\r\n } else {\r\n err = true\r\n }\r\n if (isNaN(res)) {\r\n err = true\r\n }\r\n if (err) {\r\n throw new Error('Invalid date: ' + inp)\r\n }\r\n return res\r\n}\r\n","import { DOMAIN } from '../constants.js'\r\n\r\n/**\r\n * After normalization, all constraints are start,stop,step objects.\r\n * It holds that stop > start, step > 0, start >= 0, stop >= 1.\r\n * For each axis, a constraint exists.\r\n */\r\nexport function normalizeIndexSubsetConstraints (domain, constraints) {\r\n // check and normalize constraints to simplify code\r\n let normalizedConstraints = {}\r\n for (let axisName in constraints) {\r\n if (!domain.axes.has(axisName)) {\r\n // TODO clarify cov behaviour in the JS API spec\r\n continue\r\n }\r\n if (constraints[axisName] === undefined || constraints[axisName] === null) {\r\n continue\r\n }\r\n if (typeof constraints[axisName] === 'number') {\r\n let constraint = constraints[axisName]\r\n normalizedConstraints[axisName] = {start: constraint, stop: constraint + 1}\r\n } else {\r\n normalizedConstraints[axisName] = constraints[axisName]\r\n }\r\n\r\n let { start = 0, stop = domain.axes.get(axisName).values.length, step = 1 } = normalizedConstraints[axisName]\r\n if (step <= 0) {\r\n throw new Error(`Invalid constraint for ${axisName}: step=${step} must be > 0`)\r\n }\r\n if (start >= stop || start < 0) {\r\n throw new Error(`Invalid constraint for ${axisName}: stop=${stop} must be > start=${start} and both >= 0`)\r\n }\r\n normalizedConstraints[axisName] = {start, stop, step}\r\n }\r\n for (let axisName of domain.axes.keys()) {\r\n if (!(axisName in normalizedConstraints)) {\r\n let len = domain.axes.get(axisName).values.length\r\n normalizedConstraints[axisName] = {start: 0, stop: len, step: 1}\r\n }\r\n }\r\n return normalizedConstraints\r\n}\r\n\r\nexport function subsetDomainByIndex (domain, constraints) {\r\n constraints = normalizeIndexSubsetConstraints(domain, constraints)\r\n\r\n // subset the axis arrays of the domain (immediately + cached)\r\n let newdomain = {\r\n type: DOMAIN,\r\n domainType: domain.domainType,\r\n axes: new Map(domain.axes),\r\n referencing: domain.referencing\r\n }\r\n\r\n for (let axisName of Object.keys(constraints)) {\r\n let axis = domain.axes.get(axisName)\r\n let coords = axis.values\r\n let bounds = axis.bounds\r\n let constraint = constraints[axisName]\r\n let newcoords\r\n let newbounds\r\n\r\n let {start, stop, step} = constraint\r\n if (start === 0 && stop === coords.length && step === 1) {\r\n newcoords = coords\r\n newbounds = bounds\r\n } else if (step === 1) {\r\n // TypedArray has subarray which creates a view, while Array has slice which makes a copy\r\n if (coords.subarray) {\r\n newcoords = coords.subarray(start, stop)\r\n } else {\r\n newcoords = coords.slice(start, stop)\r\n }\r\n if (bounds) {\r\n newbounds = {\r\n get: i => bounds.get(start + i)\r\n }\r\n }\r\n } else {\r\n let q = Math.trunc((stop - start) / step)\r\n let r = (stop - start) % step\r\n let len = q + r\r\n newcoords = new coords.constructor(len) // array or typed array\r\n for (let i = start, j = 0; i < stop; i += step, j++) {\r\n newcoords[j] = coords[i]\r\n }\r\n if (bounds) {\r\n newbounds = {\r\n get: i => bounds.get(start + i * step)\r\n }\r\n }\r\n }\r\n\r\n let newaxis = {\r\n dataType: axis.dataType,\r\n coordinates: axis.coordinates,\r\n values: newcoords,\r\n bounds: newbounds\r\n }\r\n newdomain.axes.set(axisName, newaxis)\r\n }\r\n\r\n return newdomain\r\n}\r\n","import { isISODateAxis, isLongitudeAxis, getLongitudeWrapper, asTime } from '../domain/referencing.js'\r\nimport { normalizeIndexSubsetConstraints, subsetDomainByIndex } from '../domain/subset.js'\r\nimport { indexOfNearest, indicesOfNearest } from '../array.js'\r\nimport { COVERAGE } from '../constants.js'\r\n\r\n/**\r\n * Returns a copy of the grid coverage subsetted to the given bounding box.\r\n *\r\n * Any grid cell is included which intersects with the bounding box.\r\n *\r\n * @param {Coverage} cov A Coverage object with domain Grid.\r\n * @param {array} bbox [xmin,ymin,xmax,ymax] in native CRS coordinates.\r\n * @param {array} [axes=['x','y']] Axis names [x,y].\r\n * @returns {Promise<Coverage>} A promise with a Coverage object as result.\r\n */\r\nexport function subsetByBbox (cov, bbox, axes = ['x', 'y']) {\r\n let [xmin, ymin, xmax, ymax] = bbox\r\n return cov.subsetByValue({[axes[0]]: {start: xmin, stop: xmax}, [axes[1]]: {start: ymin, stop: ymax}})\r\n}\r\n\r\n/**\r\n * Generic subsetByIndex function that can be used when building new Coverage objects.\r\n *\r\n * @example\r\n * var cov = {\r\n * type: 'Coverage',\r\n * ...\r\n * subsetByIndex: constraints => CovUtils.subsetByIndex(cov, constraints)\r\n * }\r\n */\r\nexport function subsetByIndex (cov, constraints) {\r\n return cov.loadDomain().then(domain => {\r\n constraints = normalizeIndexSubsetConstraints(domain, constraints)\r\n let newdomain = subsetDomainByIndex(domain, constraints)\r\n\r\n // subset ranges (on request)\r\n let rangeWrapper = range => {\r\n let newrange = {\r\n dataType: range.dataType,\r\n get: obj => {\r\n // translate subsetted to original indices\r\n let newobj = {}\r\n for (let axisName of Object.keys(obj)) {\r\n let {start, step} = constraints[axisName]\r\n newobj[axisName] = start + obj[axisName] * step\r\n }\r\n return range.get(newobj)\r\n }\r\n }\r\n newrange.shape = new Map()\r\n for (let axisName of domain.axes.keys()) {\r\n let size = newdomain.axes.get(axisName).values.length\r\n newrange.shape.set(axisName, size)\r\n }\r\n return newrange\r\n }\r\n\r\n let loadRange = key => cov.loadRange(key).then(rangeWrapper)\r\n\r\n let loadRanges = keys => cov.loadRanges(keys).then(ranges => new Map([...ranges].map(([key, range]) => [key, rangeWrapper(range)]))\r\n )\r\n\r\n // assemble everything to a new coverage\r\n let newcov = {\r\n type: COVERAGE,\r\n domainType: cov.domainType,\r\n parameters: cov.parameters,\r\n loadDomain: () => Promise.resolve(newdomain),\r\n loadRange,\r\n loadRanges\r\n }\r\n newcov.subsetByIndex = subsetByIndex.bind(null, newcov)\r\n newcov.subsetByValue = subsetByValue.bind(null, newcov)\r\n return newcov\r\n })\r\n}\r\n\r\n/**\r\n * Generic subsetByValue function that can be used when building new Coverage objects.\r\n * Requires cov.subsetByIndex function.\r\n *\r\n * @example\r\n * var cov = {\r\n * type: 'Coverage',\r\n * ...\r\n * subsetByValue: constraints => CovUtils.subsetByValue(cov, constraints)\r\n * }\r\n */\r\nexport function subsetByValue (cov, constraints) {\r\n return cov.loadDomain().then(domain => {\r\n // calculate indices and use subsetByIndex\r\n let indexConstraints = {}\r\n\r\n for (let axisName of Object.keys(constraints)) {\r\n let spec = constraints[axisName]\r\n if (spec === undefined || spec === null || !domain.axes.has(axisName)) {\r\n continue\r\n }\r\n let axis = domain.axes.get(axisName)\r\n let vals = axis.values\r\n\r\n // special-case handling\r\n let isISODate = isISODateAxis(domain, axisName)\r\n let isLongitude = isLongitudeAxis(domain, axisName)\r\n\r\n // wrap input longitudes into longitude range of domain axis\r\n let lonWrapper = isLongitude ? getLongitudeWrapper(domain, axisName) : undefined\r\n\r\n if (typeof spec === 'number' || typeof spec === 'string' || spec instanceof Date) {\r\n let match = spec\r\n if (isISODate) {\r\n // convert times to numbers before searching\r\n match = asTime(match)\r\n vals = vals.map(v => new Date(v).getTime())\r\n } else if (isLongitude) {\r\n match = lonWrapper(match)\r\n }\r\n let i\r\n // older browsers don't have TypedArray.prototype.indexOf\r\n if (vals.indexOf) {\r\n i = vals.indexOf(match)\r\n } else {\r\n i = Array.prototype.indexOf.call(vals, match)\r\n }\r\n if (i === -1) {\r\n throw new Error('Domain value not found: ' + spec)\r\n }\r\n indexConstraints[axisName] = i\r\n } else if ('target' in spec) {\r\n // find index of value closest to target\r\n let target = spec.target\r\n if (isISODate) {\r\n // convert times to numbers before searching\r\n target = asTime(target)\r\n vals = vals.map(v => new Date(v).getTime())\r\n } else if (isLongitude) {\r\n target = lonWrapper(target)\r\n } else if (typeof vals[0] !== 'number' || typeof target !== 'number') {\r\n throw new Error('Invalid axis or constraint value type')\r\n }\r\n let i = indexOfNearest(vals, target)\r\n indexConstraints[axisName] = i\r\n } else if ('start' in spec && 'stop' in spec) {\r\n // TODO what about bounds?\r\n\r\n let {start, stop} = spec\r\n if (isISODate) {\r\n // convert times to numbers before searching\r\n [start, stop] = [asTime(start), asTime(stop)]\r\n vals = vals.map(v => new Date(v).getTime())\r\n } else if (isLongitude) {\r\n [start, stop] = [lonWrapper(start), lonWrapper(stop)]\r\n } else if (typeof vals[0] !== 'number' || typeof start !== 'number') {\r\n throw new Error('Invalid axis or constraint value type')\r\n }\r\n\r\n let [lo1, hi1] = indicesOfNearest(vals, start)\r\n let [lo2, hi2] = indicesOfNearest(vals, stop)\r\n\r\n // cov is a bit arbitrary and may include one or two indices too much\r\n // (but since we don't handle bounds it doesn't matter that much)\r\n let imin = Math.min(lo1, hi1, lo2, hi2)\r\n let imax = Math.max(lo1, hi1, lo2, hi2) + 1 // subsetByIndex is exclusive\r\n\r\n indexConstraints[axisName] = {start: imin, stop: imax}\r\n } else {\r\n throw new Error('Invalid subset constraints')\r\n }\r\n }\r\n\r\n return cov.subsetByIndex(indexConstraints)\r\n })\r\n}\r\n","import { COVERAGE, DOMAIN } from '../constants.js'\r\nimport { checkDomain, checkCoverage } from '../validate.js'\r\nimport { subsetByIndex, subsetByValue } from './subset.js'\r\n\r\n/**\r\n * Wraps a Domain into a Coverage object by adding dummy parameter and range data.\r\n *\r\n * @param {Domain} domain the Domain object\r\n * @param {array} [options.gridAxes] The horizontal grid axis names, used for checkerboard pattern.\r\n * @return {Coverage}\r\n */\r\nexport function fromDomain (domain, options = {}) {\r\n checkDomain(domain)\r\n\r\n let {gridAxes: [x, y] = ['x', 'y']} = options\r\n\r\n let dummyKey = 'domain'\r\n let dummyLabel = 'Domain'\r\n\r\n let assumeGrid = domain.axes.has(x) && domain.axes.has(y) &&\r\n (domain.axes.get(x).values.length > 1 || domain.axes.get(y).values.length > 1)\r\n let categories\r\n let categoryEncoding\r\n const a = 'a'\r\n const av = 0\r\n const b = 'b'\r\n const bv = 1\r\n if (assumeGrid) {\r\n categories = [{\r\n id: a,\r\n label: {en: 'A'}\r\n }, {\r\n id: b,\r\n label: {en: 'B'}\r\n }]\r\n categoryEncoding = new Map([[a, [av]], [b, [bv]]])\r\n } else {\r\n categories = [{\r\n id: a,\r\n label: {en: 'X'}\r\n }]\r\n categoryEncoding = new Map([[a, [av]]])\r\n }\r\n\r\n let parameters = new Map()\r\n parameters.set(dummyKey, {\r\n key: dummyKey,\r\n observedProperty: {\r\n label: {en: dummyLabel},\r\n categories\r\n },\r\n categoryEncoding\r\n })\r\n\r\n let shape = new Map([...domain.axes].map(([name, axis]) => [name, axis.values.length]))\r\n\r\n let get\r\n if (assumeGrid) {\r\n // checkerboard pattern to see grid cells\r\n let isOdd = n => n % 2\r\n get = ({ x = 0, y = 0 }) => isOdd(x + y) ? av : bv\r\n } else {\r\n get = () => av\r\n }\r\n\r\n let loadRange = () => Promise.resolve({\r\n shape,\r\n dataType: 'integer',\r\n get\r\n })\r\n\r\n let cov = {\r\n type: COVERAGE,\r\n domainType: domain.domainType,\r\n parameters,\r\n loadDomain: () => Promise.resolve(domain),\r\n loadRange\r\n }\r\n addLoadRangesFunction(cov)\r\n addSubsetFunctions(cov)\r\n return cov\r\n}\r\n\r\n/**\r\n * Creates a Coverage with a single parameter from an xndarray object.\r\n *\r\n * @example\r\n * var arr = xndarray(new Float64Array(\r\n * [ 1,2,3,\r\n * 4,5,6 ]), {\r\n * shape: [2,3],\r\n * names: ['y','x'],\r\n * coords: {\r\n * y: [10,12,14],\r\n * x: [100,101,102],\r\n * t: [new Date('2001-01-01')]\r\n * }\r\n * })\r\n * var cov = CovUtils.fromXndarray(arr, {\r\n * parameter: {\r\n * key: 'temperature',\r\n * observedProperty: {\r\n * label: {en: 'Air temperature'}\r\n * },\r\n * unit: { symbol: '°C' }\r\n * }\r\n * })\r\n * let param = cov.parameters.get('temperature')\r\n * let unit = param.unit.symbol // °C\r\n * cov.loadRange('temperature').then(temps => {\r\n * let val = temps.get({x:0, y:1}) // val == 4\r\n * })\r\n *\r\n * @param {xndarray} xndarr - Coordinates must be primitive, not tuples etc.\r\n * @param {object} [options] Options object.\r\n * @param {Parameter} [options.parameter] Specifies the parameter, default parameter has a key of 'p1'.\r\n * @param {string} [options.domainType] A domain type URI.\r\n * @param {Array<object>} [options.referencing] Optional referencing system info,\r\n * defaults to longitude/latitude in WGS84 for x/y axes and ISO8601 time strings for t axis.\r\n * @return {Coverage}\r\n */\r\nexport function fromXndarray (xndarr, options = {}) {\r\n let { parameter = {\r\n key: 'p1',\r\n observedProperty: {\r\n label: {en: 'Parameter 1'}\r\n }\r\n }, referencing, domainType} = options\r\n\r\n let parameters = new Map()\r\n parameters.set(parameter.key, parameter)\r\n\r\n // assume lon/lat/ISO time for x/y/t by default, for convenience\r\n if (!referencing) {\r\n referencing = []\r\n if (xndarr.coords.has('x') && xndarr.coords.has('y')) {\r\n referencing.push({\r\n coordinates: ['x', 'y'],\r\n system: {\r\n type: 'GeographicCRS',\r\n id: 'http://www.opengis.net/def/crs/OGC/1.3/CRS84'\r\n }\r\n })\r\n }\r\n if (xndarr.coords.has('t')) {\r\n referencing.push({\r\n coordinates: ['t'],\r\n system: {\r\n type: 'TemporalRS',\r\n calendar: 'Gregorian'\r\n }\r\n })\r\n }\r\n }\r\n\r\n let axes = new Map()\r\n for (let [axisName, vals1Dnd] of xndarr.coords) {\r\n let values = new Array(vals1Dnd.size)\r\n for (let i = 0; i < vals1Dnd.size; i++) {\r\n values[i] = vals1Dnd.get(i)\r\n }\r\n axes.set(axisName, {\r\n key: axisName,\r\n coordinates: [axisName],\r\n values\r\n })\r\n }\r\n\r\n let domain = {\r\n type: DOMAIN,\r\n domainType,\r\n referencing,\r\n axes\r\n }\r\n\r\n let shape = new Map([...domain.axes].map(([name, axis]) => [name, axis.values.length]))\r\n let dataType = xndarr.dtype.indexOf('int') !== -1 ? 'integer' : 'float'\r\n\r\n let loadRange = () => Promise.resolve({\r\n shape,\r\n dataType,\r\n get: xndarr.xget.bind(xndarr)\r\n })\r\n\r\n let cov = {\r\n type: COVERAGE,\r\n domainType,\r\n parameters,\r\n loadDomain: () => Promise.resolve(domain),\r\n loadRange\r\n }\r\n addLoadRangesFunction(cov)\r\n addSubsetFunctions(cov)\r\n return cov\r\n}\r\n\r\nexport function addSubsetFunctions (cov) {\r\n checkCoverage(cov)\r\n cov.subsetByIndex = subsetByIndex.bind(null, cov)\r\n cov.subsetByValue = subsetByValue.bind(null, cov)\r\n}\r\n\r\nexport function addLoadRangesFunction (cov) {\r\n checkCoverage(cov)\r\n function loadRanges (keys) {\r\n if (!keys) {\r\n keys = cov.parameters.keys()\r\n }\r\n return Promise.all([...keys].map(cov.loadRange)).then(ranges => new Map(keys.map((key, i) => [key, ranges[i]]))\r\n )\r\n }\r\n cov.loadRanges = loadRanges\r\n}\r\n","/**\r\n * Shallow clone a given object.\r\n *\r\n * Note: This does *not* handle all kinds of objects!\r\n *\r\n * @ignore\r\n */\r\nexport function shallowcopy (obj) {\r\n let copy\r\n if (obj instanceof Map) {\r\n copy = new Map(obj)\r\n } else {\r\n copy = Object.create(Object.getPrototypeOf(obj))\r\n for (let prop in obj) {\r\n copy[prop] = obj[prop]\r\n }\r\n }\r\n return copy\r\n}\r\n","import { shallowcopy } from '../util.js'\r\nimport { COVJSON_DATATYPE_TUPLE, COVERAGE, DOMAIN } from '../constants.js'\r\nimport { getHorizontalCRSReferenceObject, getProjection } from '../domain/referencing.js'\r\n\r\n/**\r\n * Reproject a coverage.\r\n *\r\n * Reprojecting means returning a new coverage where the horizontal CRS is replaced\r\n * and the horizontal domain coordinates are reprojected.\r\n *\r\n * Current limitations:\r\n * - only point-type coverage domains are supported (Tuple only)\r\n * - only horizontal CRSs (2-dimensional) are supported\r\n * - non-lat/lon CRSs have to be pre-cached with loadProjection()\r\n *\r\n * @param {Coverage} cov The Coverage object to reproject.\r\n * @param {Domain} refDomain The reference domain from which the horizontal CRS is used.\r\n * @returns {Promise<Coverage>} A promise with the reprojected Coverage object as result.\r\n */\r\nexport function reproject (cov, refDomain) {\r\n return cov.loadDomain().then(sourceDomain => {\r\n let sourceRef = getHorizontalCRSReferenceObject(sourceDomain)\r\n if (sourceRef.coordinates.length > 2) {\r\n throw new Error('Reprojection not supported for >2D CRSs')\r\n }\r\n // check that the CRS coordinate IDs don't refer to grid axes\r\n if (sourceRef.coordinates.some(sourceDomain.axes.has)) {\r\n throw new Error('Grid reprojection not supported yet')\r\n }\r\n let [xComp, yComp] = sourceRef.coordinates\r\n\r\n // TODO reproject bounds\r\n\r\n // find the composite axis that contains the horizontal coordinates\r\n let axes = [...sourceDomain.axes.values()]\r\n let axis = axes.find(axis => sourceRef.coordinates.every(comp => axis.coordinates.indexOf(comp) !== -1))\r\n let [xCompIdx, yCompIdx] = [axis.coordinates.indexOf(xComp), axis.coordinates.indexOf(yComp)]\r\n\r\n // find the target CRS and get the projection\r\n let sourceProjection = getProjection(sourceDomain)\r\n let targetProjection = getProjection(refDomain)\r\n\r\n // reproject the x/y part of every axis value\r\n // this is done by unprojecting to lon/lat, followed by projecting to the target x/y\r\n let values\r\n if (axis.dataType === COVJSON_DATATYPE_TUPLE) {\r\n // make a deep copy of the axis values and replace x,y values by the reprojected ones\r\n values = axis.values.map(tuple => tuple.slice())\r\n for (let tuple of values) {\r\n let [sourceX, sourceY] = [tuple[xCompIdx], tuple[yCompIdx]]\r\n let latlon = sourceProjection.unproject({x: sourceX, y: sourceY})\r\n let {x, y} = targetProjection.project(latlon)\r\n tuple[xCompIdx] = x\r\n tuple[yCompIdx] = y\r\n }\r\n } else {\r\n throw new Error('Unsupported data type: ' + axis.dataType)\r\n }\r\n\r\n // assemble reprojected coverage\r\n let newAxes = new Map(sourceDomain.axes)\r\n let newAxis = shallowcopy(axis)\r\n delete newAxis.bounds\r\n newAxis.values = values\r\n newAxes.set(axis.key, newAxis)\r\n\r\n let targetRef = getHorizontalCRSReferenceObject(refDomain)\r\n if (targetRef.coordinates.length > 2) {\r\n throw new Error('Reprojection not supported for >2D CRSs')\r\n }\r\n let newReferencing = sourceDomain.referencing.map(ref => {\r\n if (ref === sourceRef) {\r\n return {\r\n coordinates: sourceRef.coordinates,\r\n system: targetRef.system\r\n }\r\n } else {\r\n return ref\r\n }\r\n })\r\n\r\n let newDomain = {\r\n type: DOMAIN,\r\n domainType: sourceDomain.domainType,\r\n axes: newAxes,\r\n referencing: newReferencing\r\n }\r\n\r\n let newCoverage = {\r\n type: COVERAGE,\r\n domainType: cov.domainType,\r\n parameters: cov.parameters,\r\n loadDomain: () => Promise.resolve(newDomain),\r\n loadRange: paramKey => cov.loadRange(paramKey),\r\n loadRanges: paramKeys => cov.loadRanges(paramKeys),\r\n subsetByIndex: constraints => cov.subsetByIndex(constraints).then(sub => reproject(sub, refDomain)),\r\n subsetByValue: constraints => cov.subsetByValue(constraints).then(sub => reproject(sub, refDomain))\r\n }\r\n return newCoverage\r\n })\r\n}\r\n","import { COVERAGE, DOMAIN } from '../constants.js'\r\nimport { checkCoverage } from '../validate.js'\r\nimport { shallowcopy } from '../util.js'\r\nimport { addLoadRangesFunction } from './create.js'\r\n\r\n/**\r\n * Returns a copy of the given Coverage object with the parameters\r\n * replaced by the supplied ones.\r\n *\r\n * Note that this is a low-level function and no checks are done on the supplied parameters.\r\n */\r\nexport function withParameters (cov, params) {\r\n let newcov = {\r\n type: COVERAGE,\r\n domainType: cov.domainType,\r\n parameters: params,\r\n loadDomain: () => cov.loadDomain(),\r\n loadRange: key => cov.loadRange(key),\r\n loadRanges: keys => cov.loadRanges(keys),\r\n subsetByIndex: constraints => cov.subsetByIndex(constraints).then(sub => withParameters(sub, params)),\r\n subsetByValue: constraints => cov.subsetByValue(constraints).then(sub => withParameters(sub, params))\r\n }\r\n return newcov\r\n}\r\n\r\n/**\r\n * Returns a copy of the given Coverage object with the categories\r\n * of a given parameter replaced by the supplied ones and the encoding\r\n * adapted to the given mapping from old to new.\r\n *\r\n * @param {Coverage} cov The Coverage object.\r\n * @param {String} key The key of the parameter to work with.\r\n * @param {object} observedProperty The new observed property including the new array of category objects\r\n * that will be part of the returned coverage.\r\n * @param {Map<String,String>} mapping A mapping from source category id to destination category id.\r\n * @returns {Coverage}\r\n */\r\nexport function withCategories (cov, key, observedProperty, mapping) {\r\n /* check breaks with Babel, see https://github.com/jspm/jspm-cli/issues/1348\r\n if (!(mapping instanceof Map)) {\r\n throw new Error('mapping parameter must be a Map from/to category ID')\r\n }\r\n */\r\n checkCoverage(cov)\r\n if (observedProperty.categories.some(c => !c.id)) {\r\n throw new Error('At least one category object is missing the \"id\" property')\r\n }\r\n let newparams = shallowcopy(cov.parameters)\r\n let newparam = shallowcopy(newparams.get(key))\r\n newparams.set(key, newparam)\r\n newparams.get(key).observedProperty = observedProperty\r\n\r\n let fromCatEnc = cov.parameters.get(key).categoryEncoding\r\n let catEncoding = new Map()\r\n let categories = observedProperty.categories\r\n for (let category of categories) {\r\n let vals = []\r\n for (let [fromCatId, toCatId] of mapping) {\r\n if (toCatId === category.id && fromCatEnc.has(fromCatId)) {\r\n vals.push(...fromCatEnc.get(fromCatId))\r\n }\r\n }\r\n if (vals.length > 0) {\r\n catEncoding.set(category.id, vals)\r\n }\r\n }\r\n newparams.get(key).categoryEncoding = catEncoding\r\n\r\n let newcov = withParameters(cov, newparams)\r\n return newcov\r\n}\r\n\r\n/**\r\n * Returns a new coverage where the domainType field of the coverage and the domain\r\n * is set to the given one.\r\n *\r\n * @param {Coverage} cov The Coverage object.\r\n * @param {String} domainType The new domain type.\r\n * @returns {Coverage}\r\n */\r\nexport function withDomainType (cov, domainType) {\r\n checkCoverage(cov)\r\n\r\n let domainWrapper = domain => {\r\n let newdomain = {\r\n type: DOMAIN,\r\n domainType,\r\n axes: domain.axes,\r\n referencing: domain.referencing\r\n }\r\n return newdomain\r\n }\r\n\r\n let newcov = {\r\n type: COVERAGE,\r\n domainType,\r\n parameters: cov.parameters,\r\n loadDomain: () => cov.loadDomain().then(domainWrapper),\r\n loadRange: key => cov.loadRange(key),\r\n loadRanges: keys => cov.loadRanges(keys),\r\n subsetByIndex: constraints => cov.subsetByIndex(constraints).then(sub => withDomainType(sub, domainType)),\r\n subsetByValue: constraints => cov.subsetByValue(constraints).then(sub => withDomainType(sub, domainType))\r\n }\r\n return newcov\r\n}\r\n\r\n/**\r\n * Tries to transform the given Coverage object into a new one that\r\n * conforms to one of the CovJSON domain types.\r\n * If multiple domain types match, then the \"smaller\" one is preferred,\r\n * for example, Point instead of Grid.\r\n *\r\n * The transformation consists of:\r\n * - Setting domainType in coverage and domain object\r\n * - Renaming domain axes\r\n *\r\n * @see https://github.com/Reading-eScience-Centre/coveragejson/blob/master/domain-types.md\r\n *\r\n * @param {Coverage} cov The Coverage object.\r\n * @returns {Promise<Coverage>}\r\n * A Promise succeeding with the transformed coverage,\r\n * or failing if no CovJSON domain type matched the input coverage.\r\n */\r\nexport function asCovJSONDomainType (cov) {\r\n return cov.loadDomain().then(domain => {\r\n\r\n // TODO implement me\r\n\r\n })\r\n}\r\n\r\n/**\r\n * @example\r\n * var cov = ...\r\n * var mapping = new Map()\r\n * mapping.set('lat', 'y').set('lon', 'x')\r\n * var newcov = CovUtils.renameAxes(cov, mapping)\r\n *\r\n * @param {Coverage} cov The coverage.\r\n * @param {Map<String,String>} mapping\r\n * @returns {Coverage}\r\n */\r\nexport function renameAxes (cov, mapping) {\r\n checkCoverage(cov)\r\n mapping = new Map(mapping)\r\n for (let axisName of cov.axes.keys()) {\r\n if (!mapping.has(axisName)) {\r\n mapping.set(axisName, axisName)\r\n }\r\n }\r\n\r\n let domainWrapper = domain => {\r\n let newaxes = new Map()\r\n for (let [from, to] of mapping) {\r\n let {dataType, coordinates, values, bounds} = domain.axes.get(from)\r\n let newaxis = {\r\n key: to,\r\n dataType,\r\n coordinates: coordinates.map(c => mapping.has(c) ? mapping.get(c) : c),\r\n values,\r\n bounds\r\n }\r\n newaxes.set(to, newaxis)\r\n }\r\n\r\n let newreferencing = domain.referencing.map(({coordinates, system}) => ({\r\n coordinates: coordinates.map(c => mapping.has(c) ? mapping.get(c) : c),\r\n system\r\n }))\r\n\r\n let newdomain = {\r\n type: DOMAIN,\r\n domainType: domain.domainType,\r\n axes: newaxes,\r\n referencing: newreferencing\r\n }\r\n return newdomain\r\n }\r\n\r\n // pre-compile for efficiency\r\n // get({['lat']: obj['y'], ['lon']: obj['x']})\r\n let getObjStr = [...mapping].map(([from, to]) => `['${from}']:obj['${to}']`).join(',')\r\n\r\n let rangeWrapper = range => {\r\n let get = new Function('range', 'return function get (obj){return range.get({' + getObjStr + '})}')(range) // eslint-disable-line\r\n let newrange = {\r\n shape: new Map([...range.shape].map(([name, len]) => [mapping.get(name), len])),\r\n dataType: range.dataType,\r\n get\r\n }\r\n return newrange\r\n }\r\n\r\n let loadRange = paramKey => cov.loadRange(paramKey).then(rangeWrapper)\r\n\r\n let loadRanges = paramKeys => cov.loadRanges(paramKeys)\r\n .then(ranges => new Map([...ranges].map(([paramKey, range]) => [paramKey, rangeWrapper(range)])))\r\n\r\n let newcov = {\r\n type: COVERAGE,\r\n domainType: cov.domainType,\r\n parameters: cov.parameters,\r\n loadDomain: () => cov.loadDomain().then(domainWrapper),\r\n loadRange,\r\n loadRanges,\r\n subsetByIndex: constraints => cov.subsetByIndex(constraints).then(sub => renameAxes(sub, mapping)),\r\n subsetByValue: constraints => cov.subsetByValue(constraints).then(sub => renameAxes(sub, mapping))\r\n }\r\n\r\n return newcov\r\n}\r\n\r\n/**\r\n * @param {Coverage} cov The coverage.\r\n * @param {String} key The key of the parameter for which the mapping should be applied.\r\n * @param {Function} fn A function getting called as fn(obj, range) where obj is the axis indices object\r\n * and range is the original range object.\r\n * @param {String} [dataType] The new data type to use for the range. If omitted, the original type is used.\r\n * @returns {Coverage}\r\n */\r\nexport function mapRange (cov, key, fn, dataType) {\r\n checkCoverage(cov)\r\n\r\n let rangeWrapper = range => {\r\n let newrange = {\r\n shape: range.shape,\r\n dataType: dataType || range.dataType,\r\n get: obj => fn(obj, range)\r\n }\r\n return newrange\r\n }\r\n\r\n let loadRange = paramKey => key === paramKey ? cov.loadRange(paramKey).then(rangeWrapper) : cov.loadRange(paramKey)\r\n\r\n let loadRanges = paramKeys => cov.loadRanges(paramKeys)\r\n .then(ranges => new Map([...ranges].map(([paramKey, range]) => [paramKey, key === paramKey ? rangeWrapper(range) : range])))\r\n\r\n let newcov = {\r\n type: COVERAGE,\r\n domainType: cov.domainType,\r\n parameters: cov.parameters,\r\n loadDomain: () => cov.loadDomain(),\r\n loadRange,\r\n loadRanges,\r\n subsetByIndex: constraints => cov.subsetByIndex(constraints).then(sub => mapRange(sub, key, fn, dataType)),\r\n subsetByValue: constraints => cov.subsetByValue(constraints).then(sub => mapRange(sub, key, fn, dataType))\r\n }\r\n\r\n return newcov\r\n}\r\n\r\n/**\r\n *\r\n * @example\r\n * var cov = ... // has parameters 'NIR', 'red', 'green', 'blue'\r\n * var newcov = CovUtils.withDerivedParameter(cov, {\r\n * parameter: {\r\n * key: 'NDVI',\r\n * observedProperty: {\r\n * label: { en: 'Normalized Differenced Vegetation Index' }\r\n * }\r\n * },\r\n * inputParameters: ['NIR','red'],\r\n * dataType: 'float',\r\n * fn: function (obj, nirRange, redRange) {\r\n * var nir = nirRange.get(obj)\r\n * var red = redRange.get(obj)\r\n * if (nir === null || red === null) return null\r\n * return (nir - red) / (nir + red)\r\n * }\r\n * })\r\n */\r\nexport function withDerivedParameter (cov, options) {\r\n checkCoverage(cov)\r\n let {parameter, inputParameters, dataType = 'float', fn} = options\r\n\r\n let parameters = new Map(cov.parameters)\r\n parameters.set(parameter.key, parameter)\r\n\r\n let loadDerivedRange = () => cov.loadRanges(inputParameters).then(inputRanges => {\r\n let inputRangesArr = inputParameters.map(key => inputRanges.get(key))\r\n let shape = inputRangesArr[0].shape\r\n let range = {\r\n shape,\r\n dataType,\r\n get: obj => fn(obj, ...inputRangesArr)\r\n }\r\n return range\r\n })\r\n\r\n let loadRange = paramKey => parameter.key === paramKey ? loadDerivedRange() : cov.loadRange(paramKey)\r\n\r\n let newcov = {\r\n type: COVERAGE,\r\n domainType: cov.domainType,\r\n parameters,\r\n loadDomain: () => cov.loadDomain(),\r\n loadRange,\r\n subsetByIndex: constraints => cov.subsetByIndex(constraints).then(sub => withDerivedParameter(sub, options)),\r\n subsetByValue: constraints => cov.subsetByValue(constraints).then(sub => withDerivedParameter(sub, options))\r\n }\r\n addLoadRangesFunction(newcov)\r\n\r\n return newcov\r\n}\r\n\r\n/**\r\n *\r\n * @example\r\n * var cov = ... // has parameters 'NIR', 'red', 'green', 'blue'\r\n * var newcov = CovUtils.withSimpleDerivedParameter(cov, {\r\n * parameter: {\r\n * key: 'NDVI',\r\n * observedProperty: {\r\n * label: { en: 'Normalized Differenced Vegetation Index' }\r\n * }\r\n * },\r\n * inputParameters: ['NIR','red'],\r\n * dataType: 'float',\r\n * fn: function (nir, red) {\r\n * return (nir - red) / (nir + red)\r\n * }\r\n * })\r\n */\r\nexport function withSimpleDerivedParameter (cov, options) {\r\n let {parameter, inputParameters, dataType, fn} = options\r\n let options_ = {\r\n parameter,\r\n inputParameters,\r\n dataType,\r\n // TODO pre-compile if too slow\r\n fn: (obj, ...ranges) => {\r\n let vals = inputParameters.map((_, i) => ranges[i].get(obj))\r\n if (vals.some(val => val === null)) {\r\n return null\r\n }\r\n return fn(...vals)\r\n }\r\n }\r\n return withDerivedParameter(cov, options_)\r\n}\r\n","import { COVERAGECOLLECTION } from '../constants.js'\r\nimport { asTime, isISODateAxis, isLongitudeAxis, getLongitudeWrapper } from '../domain/referencing.js'\r\n\r\n/**\r\n * Adds a basic query() function to the coverage collection object.\r\n * Note that this does not support paging.\r\n */\r\nexport function addCollectionQueryFunction (collection) {\r\n if (collection.paging) {\r\n throw new Error('Paged collections not supported')\r\n }\r\n collection.query = () => new CollectionQuery(collection)\r\n}\r\n\r\nexport class CollectionQuery {\r\n /**\r\n * @param {CoverageCollection} collection\r\n */\r\n constructor (collection) {\r\n this._collection = collection\r\n this._filter = {}\r\n this._subset = {}\r\n }\r\n\r\n /**\r\n * Matching mode: intersect\r\n *\r\n * Supports ISO8601 date string axes.\r\n * All other string-type axes are compared alphabetically.\r\n *\r\n * @example\r\n * collection.query().filter({\r\n * 't': {start: '2015-01-01T01:00:00', stop: '2015-01-01T02:00:00'}\r\n * }).execute().then(filteredCollection => {\r\n * console.log(filteredCollection.coverages.length)\r\n * })\r\n * @param {Object} spec\r\n * @return {CollectionQuery}\r\n */\r\n filter (spec) {\r\n mergeInto(spec, this._filter)\r\n return this\r\n }\r\n\r\n /**\r\n * Subset coverages by domain values.\r\n *\r\n * Equivalent to calling {@link Coverage.subsetByValue}(spec) on each\r\n * coverage in the collection.\r\n *\r\n * @param {Object} spec\r\n * @return {CollectionQuery}\r\n */\r\n subset (spec) {\r\n mergeInto(spec, this._subset)\r\n return this\r\n }\r\n\r\n /**\r\n * Applies the query operators and returns\r\n * a Promise that succeeds with a new CoverageCollection.\r\n *\r\n * @return {Promise<CoverageCollection>}\r\n */\r\n execute () {\r\n let coll = this._collection\r\n let newcoll = {\r\n type: COVERAGECOLLECTION,\r\n coverages: [],\r\n parameters: coll.parameters,\r\n domainType: coll.domainType\r\n }\r\n\r\n let promises = []\r\n for (let cov of coll.coverages) {\r\n promises.push(cov.loadDomain().then(domain => {\r\n if (!matchesFilter(domain, this._filter)) {\r\n return\r\n }\r\n\r\n if (Object.keys(this._subset).length === 0) {\r\n newcoll.coverages.push(cov)\r\n } else {\r\n return cov.subsetByValue(this._subset).then(subsetted => {\r\n newcoll.coverages.push(subsetted)\r\n })\r\n }\r\n }))\r\n }\r\n return Promise.all(promises).then(() => {\r\n newcoll.query = () => new CollectionQuery(newcoll)\r\n return newcoll\r\n })\r\n }\r\n}\r\n\r\nfunction matchesFilter (domain, filter) {\r\n for (let axisName of Object.keys(filter)) {\r\n let condition = filter[axisName]\r\n if (!domain.axes.has(axisName)) {\r\n throw new Error('Axis \"' + axisName + '\" does not exist')\r\n }\r\n let axis = domain.axes.get(axisName)\r\n let vals = axis.values\r\n\r\n let [min, max] = [vals[0], vals[vals.length - 1]]\r\n if (typeof min !== 'number' && typeof min !== 'string') {\r\n throw new Error('Can only filter primitive axis values')\r\n }\r\n let {start, stop} = condition\r\n\r\n // special handling\r\n if (isISODateAxis(domain, axisName)) {\r\n [min, max] = [asTime(min), asTime(max)]\r\n ;[start, stop] = [asTime(start), asTime(stop)]\r\n } else if (isLongitudeAxis(domain, axisName)) {\r\n let lonWrapper = getLongitudeWrapper(domain, axisName)\r\n ;[start, stop] = [lonWrapper(start), lonWrapper(stop)]\r\n }\r\n\r\n if (min > max) {\r\n [min, max] = [max, min]\r\n }\r\n if (max < start || stop < min) {\r\n return false\r\n }\r\n }\r\n\r\n return true\r\n}\r\n\r\nfunction mergeInto (inputObj, targetObj) {\r\n for (let k of Object.keys(inputObj)) {\r\n targetObj[k] = inputObj[k]\r\n }\r\n}\r\n","\"use strict\"\n\nfunction compileSearch(funcName, predicate, reversed, extraArgs, useNdarray, earlyOut) {\n var code = [\n \"function \", funcName, \"(a,l,h,\", extraArgs.join(\",\"), \"){\",\nearlyOut ? \"\" : \"var i=\", (reversed ? \"l-1\" : \"h+1\"),\n\";while(l<=h){\\\nvar m=(l+h)>>>1,x=a\", useNdarray ? \".get(m)\" : \"[m]\"]\n if(earlyOut) {\n if(predicate.indexOf(\"c\") < 0) {\n code.push(\";if(x===y){return m}else if(x<=y){\")\n } else {\n code.push(\";var p=c(x,y);if(p===0){return m}else if(p<=0){\")\n }\n } else {\n code.push(\";if(\", predicate, \"){i=m;\")\n }\n if(reversed) {\n code.push(\"l=m+1}else{h=m-1}\")\n } else {\n code.push(\"h=m-1}else{l=m+1}\")\n }\n code.push(\"}\")\n if(earlyOut) {\n code.push(\"return -1};\")\n } else {\n code.push(\"return i};\")\n }\n return code.join(\"\")\n}\n\nfunction compileBoundsSearch(predicate, reversed, suffix, earlyOut) {\n var result = new Function([\n compileSearch(\"A\", \"x\" + predicate + \"y\", reversed, [\"y\"], false, earlyOut),\n compileSearch(\"B\", \"x\" + predicate + \"y\", reversed, [\"y\"], true, earlyOut),\n compileSearch(\"P\", \"c(x,y)\" + predicate + \"0\", reversed, [\"y\", \"c\"], false, earlyOut),\n compileSearch(\"Q\", \"c(x,y)\" + predicate + \"0\", reversed, [\"y\", \"c\"], true, earlyOut),\n\"function dispatchBsearch\", suffix, \"(a,y,c,l,h){\\\nif(a.shape){\\\nif(typeof(c)==='function'){\\\nreturn Q(a,(l===undefined)?0:l|0,(h===undefined)?a.shape[0]-1:h|0,y,c)\\\n}else{\\\nreturn B(a,(c===undefined)?0:c|0,(l===undefined)?a.shape[0]-1:l|0,y)\\\n}}else{\\\nif(typeof(c)==='function'){\\\nreturn P(a,(l===undefined)?0:l|0,(h===undefined)?a.length-1:h|0,y,c)\\\n}else{\\\nreturn A(a,(c===undefined)?0:c|0,(l===undefined)?a.length-1:l|0,y)\\\n}}}\\\nreturn dispatchBsearch\", suffix].join(\"\"))\n return result()\n}\n\nmodule.exports = {\n ge: compileBoundsSearch(\">=\", false, \"GE\"),\n gt: compileBoundsSearch(\">\", false, \"GT\"),\n lt: compileBoundsSearch(\"<\", true, \"LT\"),\n le: compileBoundsSearch(\"<=\", true, \"LE\"),\n eq: compileBoundsSearch(\"-\", true, \"EQ\", true)\n}\n","\"use strict\"\n\nvar bounds = require(\"binary-search-bounds\")\n\nvar NOT_FOUND = 0\nvar SUCCESS = 1\nvar EMPTY = 2\n\nmodule.exports = createWrapper\n\nfunction IntervalTreeNode(mid, left, right, leftPoints, rightPoints) {\n this.mid = mid\n this.left = left\n this.right = right\n this.leftPoints = leftPoints\n this.rightPoints = rightPoints\n this.count = (left ? left.count : 0) + (right ? right.count : 0) + leftPoints.length\n}\n\nvar proto = IntervalTreeNode.prototype\n\nfunction copy(a, b) {\n a.mid = b.mid\n a.left = b.left\n a.right = b.right\n a.leftPoints = b.leftPoints\n a.rightPoints = b.rightPoints\n a.count = b.count\n}\n\nfunction rebuild(node, intervals) {\n var ntree = createIntervalTree(intervals)\n node.mid = ntree.mid\n node.left = ntree.left\n node.right = ntree.right\n node.leftPoints = ntree.leftPoints\n node.rightPoints = ntree.rightPoints\n node.count = ntree.count\n}\n\nfunction rebuildWithInterval(node, interval) {\n var intervals = node.intervals([])\n intervals.push(interval)\n rebuild(node, intervals) \n}\n\nfunction rebuildWithoutInterval(node, interval) {\n var intervals = node.intervals([])\n var idx = intervals.indexOf(interval)\n if(idx < 0) {\n return NOT_FOUND\n }\n intervals.splice(idx, 1)\n rebuild(node, intervals)\n return SUCCESS\n}\n\nproto.intervals = function(result) {\n result.push.apply(result, this.leftPoints)\n if(this.left) {\n this.left.intervals(result)\n }\n if(this.right) {\n this.right.intervals(result)\n }\n return result\n}\n\nproto.insert = function(interval) {\n var weight = this.count - this.leftPoints.length\n this.count += 1\n if(interval[1] < this.mid) {\n if(this.left) {\n if(4*(this.left.count+1) > 3*(weight+1)) {\n rebuildWithInterval(this, interval)\n } else {\n this.left.insert(interval)\n }\n } else {\n this.left = createIntervalTree([interval])\n }\n } else if(interval[0] > this.mid) {\n if(this.right) {\n if(4*(this.right.count+1) > 3*(weight+1)) {\n rebuildWithInterval(this, interval)\n } else {\n this.right.insert(interval)\n }\n } else {\n this.right = createIntervalTree([interval])\n }\n } else {\n var l = bounds.ge(this.leftPoints, interval, compareBegin)\n var r = bounds.ge(this.rightPoints, interval, compareEnd)\n this.leftPoints.splice(l, 0, interval)\n this.rightPoints.splice(r, 0, interval)\n }\n}\n\nproto.remove = function(interval) {\n var weight = this.count - this.leftPoints\n if(interval[1] < this.mid) {\n if(!this.left) {\n return NOT_FOUND\n }\n var rw = this.right ? this.right.count : 0\n if(4 * rw > 3 * (weight-1)) {\n return rebuildWithoutInterval(this, interval)\n }\n var r = this.left.remove(interval)\n if(r === EMPTY) {\n this.left = null\n this.count -= 1\n return SUCCESS\n } else if(r === SUCCESS) {\n this.count -= 1\n }\n return r\n } else if(interval[0] > this.mid) {\n if(!this.right) {\n return NOT_FOUND\n }\n var lw = this.left ? this.left.count : 0\n if(4 * lw > 3 * (weight-1)) {\n return rebuildWithoutInterval(this, interval)\n }\n var r = this.right.remove(interval)\n if(r === EMPTY) {\n this.right = null\n this.count -= 1\n return SUCCESS\n } else if(r === SUCCESS) {\n this.count -= 1\n }\n return r\n } else {\n if(this.count === 1) {\n if(this.leftPoints[0] === interval) {\n return EMPTY\n } else {\n return NOT_FOUND\n }\n }\n if(this.leftPoints.length === 1 && this.leftPoints[0] === interval) {\n if(this.left && this.right) {\n var p = this\n var n = this.left\n while(n.right) {\n p = n\n n = n.right\n }\n if(p === this) {\n n.right = this.right\n } else {\n var l = this.left\n var r = this.right\n p.count -= n.count\n p.right = n.left\n n.left = l\n n.right = r\n }\n copy(this, n)\n this.count = (this.left?this.left.count:0) + (this.right?this.right.count:0) + this.leftPoints.length\n } else if(this.left) {\n copy(this, this.left)\n } else {\n copy(this, this.right)\n }\n return SUCCESS\n }\n for(var l = bounds.ge(this.leftPoints, interval, compareBegin); l<this.leftPoints.length; ++l) {\n if(this.leftPoints[l][0] !== interval[0]) {\n break\n }\n if(this.leftPoints[l] === interval) {\n this.count -= 1\n this.leftPoints.splice(l, 1)\n for(var r = bounds.ge(this.rightPoints, interval, compareEnd); r<this.rightPoints.length; ++r) {\n if(this.rightPoints[r][1] !== interval[1]) {\n break\n } else if(this.rightPoints[r] === interval) {\n this.rightPoints.splice(r, 1)\n return SUCCESS\n }\n }\n }\n }\n return NOT_FOUND\n }\n}\n\nfunction reportLeftRange(arr, hi, cb) {\n for(var i=0; i<arr.length && arr[i][0] <= hi; ++i) {\n var r = cb(arr[i])\n if(r) { return r }\n }\n}\n\nfunction reportRightRange(arr, lo, cb) {\n for(var i=arr.length-1; i>=0 && arr[i][1] >= lo; --i) {\n var r = cb(arr[i])\n if(r) { return r }\n }\n}\n\nfunction reportRange(arr, cb) {\n for(var i=0; i<arr.length; ++i) {\n var r = cb(arr[i])\n if(r) { return r }\n }\n}\n\nproto.queryPoint = function(x, cb) {\n if(x < this.mid) {\n if(this.left) {\n var r = this.left.queryPoint(x, cb)\n if(r) { return r }\n }\n return reportLeftRange(this.leftPoints, x, cb)\n } else if(x > this.mid) {\n if(this.right) {\n var r = this.right.queryPoint(x, cb)\n if(r) { return r }\n }\n return reportRightRange(this.rightPoints, x, cb)\n } else {\n return reportRange(this.leftPoints, cb)\n }\n}\n\nproto.queryInterval = function(lo, hi, cb) {\n if(lo < this.mid && this.left) {\n var r = this.left.queryInterval(lo, hi, cb)\n if(r) { return r }\n }\n if(hi > this.mid && this.right) {\n var r = this.right.queryInterval(lo, hi, cb)\n if(r) { return r }\n }\n if(hi < this.mid) {\n return reportLeftRange(this.leftPoints, hi, cb)\n } else if(lo > this.mid) {\n return reportRightRange(this.rightPoints, lo, cb)\n } else {\n return reportRange(this.leftPoints, cb)\n }\n}\n\nfunction compareNumbers(a, b) {\n return a - b\n}\n\nfunction compareBegin(a, b) {\n var d = a[0] - b[0]\n if(d) { return d }\n return a[1] - b[1]\n}\n\nfunction compareEnd(a, b) {\n var d = a[1] - b[1]\n if(d) { return d }\n return a[0] - b[0]\n}\n\nfunction createIntervalTree(intervals) {\n if(intervals.length === 0) {\n return null\n }\n var pts = []\n for(var i=0; i<intervals.length; ++i) {\n pts.push(intervals[i][0], intervals[i][1])\n }\n pts.sort(compareNumbers)\n\n var mid = pts[pts.length>>1]\n\n var leftIntervals = []\n var rightIntervals = []\n var centerIntervals = []\n for(var i=0; i<intervals.length; ++i) {\n var s = intervals[i]\n if(s[1] < mid) {\n leftIntervals.push(s)\n } else if(mid < s[0]) {\n rightIntervals.push(s)\n } else {\n centerIntervals.push(s)\n }\n }\n\n //Split center intervals\n var leftPoints = centerIntervals\n var rightPoints = centerIntervals.slice()\n leftPoints.sort(compareBegin)\n rightPoints.sort(compareEnd)\n\n return new IntervalTreeNode(mid, \n createIntervalTree(leftIntervals),\n createIntervalTree(rightIntervals),\n leftPoints,\n rightPoints)\n}\n\n//User friendly wrapper that makes it possible to support empty trees\nfunction IntervalTree(root) {\n this.root = root\n}\n\nvar tproto = IntervalTree.prototype\n\ntproto.insert = function(interval) {\n if(this.root) {\n this.root.insert(interval)\n } else {\n this.root = new IntervalTreeNode(interval[0], null, null, [interval], [interval])\n }\n}\n\ntproto.remove = function(interval) {\n if(this.root) {\n var r = this.root.remove(interval)\n if(r === EMPTY) {\n this.root = null\n }\n return r !== NOT_FOUND\n }\n return false\n}\n\ntproto.queryPoint = function(p, cb) {\n if(this.root) {\n return this.root.queryPoint(p, cb)\n }\n}\n\ntproto.queryInterval = function(lo, hi, cb) {\n if(lo <= hi && this.root) {\n return this.root.queryInterval(lo, hi, cb)\n }\n}\n\nObject.defineProperty(tproto, \"count\", {\n get: function() {\n if(this.root) {\n return this.root.count\n }\n return 0\n }\n})\n\nObject.defineProperty(tproto, \"intervals\", {\n get: function() {\n if(this.root) {\n return this.root.intervals([])\n }\n return []\n }\n})\n\nfunction createWrapper(intervals) {\n if(!intervals || intervals.length === 0) {\n return new IntervalTree(null)\n }\n return new IntervalTree(createIntervalTree(intervals))\n}\n","\"use strict\"\n\nmodule.exports = robustSubtract\n\n//Easy case: Add two scalars\nfunction scalarScalar(a, b) {\n var x = a + b\n var bv = x - a\n var av = x - bv\n var br = b - bv\n var ar = a - av\n var y = ar + br\n if(y) {\n return [y, x]\n }\n return [x]\n}\n\nfunction robustSubtract(e, f) {\n var ne = e.length|0\n var nf = f.length|0\n if(ne === 1 && nf === 1) {\n return scalarScalar(e[0], -f[0])\n }\n var n = ne + nf\n var g = new Array(n)\n var count = 0\n var eptr = 0\n var fptr = 0\n var abs = Math.abs\n var ei = e[eptr]\n var ea = abs(ei)\n var fi = -f[fptr]\n var fa = abs(fi)\n var a, b\n if(ea < fa) {\n b = ei\n eptr += 1\n if(eptr < ne) {\n ei = e[eptr]\n ea = abs(ei)\n }\n } else {\n b = fi\n fptr += 1\n if(fptr < nf) {\n fi = -f[fptr]\n fa = abs(fi)\n }\n }\n if((eptr < ne && ea < fa) || (fptr >= nf)) {\n a = ei\n eptr += 1\n if(eptr < ne) {\n ei = e[eptr]\n ea = abs(ei)\n }\n } else {\n a = fi\n fptr += 1\n if(fptr < nf) {\n fi = -f[fptr]\n fa = abs(fi)\n }\n }\n var x = a + b\n var bv = x - a\n var y = b - bv\n var q0 = y\n var q1 = x\n var _x, _bv, _av, _br, _ar\n while(eptr < ne && fptr < nf) {\n if(ea < fa) {\n a = ei\n eptr += 1\n if(eptr < ne) {\n ei = e[eptr]\n ea = abs(ei)\n }\n } else {\n a = fi\n fptr += 1\n if(fptr < nf) {\n fi = -f[fptr]\n fa = abs(fi)\n }\n }\n b = q0\n x = a + b\n bv = x - a\n y = b - bv\n if(y) {\n g[count++] = y\n }\n _x = q1 + x\n _bv = _x - q1\n _av = _x - _bv\n _br = x - _bv\n _ar = q1 - _av\n q0 = _ar + _br\n q1 = _x\n }\n while(eptr < ne) {\n a = ei\n b = q0\n x = a + b\n bv = x - a\n y = b - bv\n if(y) {\n g[count++] = y\n }\n _x = q1 + x\n _bv = _x - q1\n _av = _x - _bv\n _br = x - _bv\n _ar = q1 - _av\n q0 = _ar + _br\n q1 = _x\n eptr += 1\n if(eptr < ne) {\n ei = e[eptr]\n }\n }\n while(fptr < nf) {\n a = fi\n b = q0\n x = a + b\n bv = x - a\n y = b - bv\n if(y) {\n g[count++] = y\n } \n _x = q1 + x\n _bv = _x - q1\n _av = _x - _bv\n _br = x - _bv\n _ar = q1 - _av\n q0 = _ar + _br\n q1 = _x\n fptr += 1\n if(fptr < nf) {\n fi = -f[fptr]\n }\n }\n if(q0) {\n g[count++] = q0\n }\n if(q1) {\n g[count++] = q1\n }\n if(!count) {\n g[count++] = 0.0 \n }\n g.length = count\n return g\n}","\"use strict\"\n\nmodule.exports = fastTwoSum\n\nfunction fastTwoSum(a, b, result) {\n\tvar x = a + b\n\tvar bv = x - a\n\tvar av = x - bv\n\tvar br = b - bv\n\tvar ar = a - av\n\tif(result) {\n\t\tresult[0] = ar + br\n\t\tresult[1] = x\n\t\treturn result\n\t}\n\treturn [ar+br, x]\n}","\"use strict\"\n\nmodule.exports = twoProduct\n\nvar SPLITTER = +(Math.pow(2, 27) + 1.0)\n\nfunction twoProduct(a, b, result) {\n var x = a * b\n\n var c = SPLITTER * a\n var abig = c - a\n var ahi = c - abig\n var alo = a - ahi\n\n var d = SPLITTER * b\n var bbig = d - b\n var bhi = d - bbig\n var blo = b - bhi\n\n var err1 = x - (ahi * bhi)\n var err2 = err1 - (alo * bhi)\n var err3 = err2 - (ahi * blo)\n\n var y = alo * blo - err3\n\n if(result) {\n result[0] = y\n result[1] = x\n return result\n }\n\n return [ y, x ]\n}","\"use strict\"\n\nvar twoProduct = require(\"two-product\")\nvar twoSum = require(\"two-sum\")\n\nmodule.exports = scaleLinearExpansion\n\nfunction scaleLinearExpansion(e, scale) {\n var n = e.length\n if(n === 1) {\n var ts = twoProduct(e[0], scale)\n if(ts[0]) {\n return ts\n }\n return [ ts[1] ]\n }\n var g = new Array(2 * n)\n var q = [0.1, 0.1]\n var t = [0.1, 0.1]\n var count = 0\n twoProduct(e[0], scale, q)\n if(q[0]) {\n g[count++] = q[0]\n }\n for(var i=1; i<n; ++i) {\n twoProduct(e[i], scale, t)\n var pq = q[1]\n twoSum(pq, t[0], q)\n if(q[0]) {\n g[count++] = q[0]\n }\n var a = t[1]\n var b = q[1]\n var x = a + b\n var bv = x - a\n var y = b - bv\n q[1] = x\n if(y) {\n g[count++] = y\n }\n }\n if(q[1]) {\n g[count++] = q[1]\n }\n if(count === 0) {\n g[count++] = 0.0\n }\n g.length = count\n return g\n}","\"use strict\"\n\nmodule.exports = linearExpansionSum\n\n//Easy case: Add two scalars\nfunction scalarScalar(a, b) {\n var x = a + b\n var bv = x - a\n var av = x - bv\n var br = b - bv\n var ar = a - av\n var y = ar + br\n if(y) {\n return [y, x]\n }\n return [x]\n}\n\nfunction linearExpansionSum(e, f) {\n var ne = e.length|0\n var nf = f.length|0\n if(ne === 1 && nf === 1) {\n return scalarScalar(e[0], f[0])\n }\n var n = ne + nf\n var g = new Array(n)\n var count = 0\n var eptr = 0\n var fptr = 0\n var abs = Math.abs\n var ei = e[eptr]\n var ea = abs(ei)\n var fi = f[fptr]\n var fa = abs(fi)\n var a, b\n if(ea < fa) {\n b = ei\n eptr += 1\n if(eptr < ne) {\n ei = e[eptr]\n ea = abs(ei)\n }\n } else {\n b = fi\n fptr += 1\n if(fptr < nf) {\n fi = f[fptr]\n fa = abs(fi)\n }\n }\n if((eptr < ne && ea < fa) || (fptr >= nf)) {\n a = ei\n eptr += 1\n if(eptr < ne) {\n ei = e[eptr]\n ea = abs(ei)\n }\n } else {\n a = fi\n fptr += 1\n if(fptr < nf) {\n fi = f[fptr]\n fa = abs(fi)\n }\n }\n var x = a + b\n var bv = x - a\n var y = b - bv\n var q0 = y\n var q1 = x\n var _x, _bv, _av, _br, _ar\n while(eptr < ne && fptr < nf) {\n if(ea < fa) {\n a = ei\n eptr += 1\n if(eptr < ne) {\n ei = e[eptr]\n ea = abs(ei)\n }\n } else {\n a = fi\n fptr += 1\n if(fptr < nf) {\n fi = f[fptr]\n fa = abs(fi)\n }\n }\n b = q0\n x = a + b\n bv = x - a\n y = b - bv\n if(y) {\n g[count++] = y\n }\n _x = q1 + x\n _bv = _x - q1\n _av = _x - _bv\n _br = x - _bv\n _ar = q1 - _av\n q0 = _ar + _br\n q1 = _x\n }\n while(eptr < ne) {\n a = ei\n b = q0\n x = a + b\n bv = x - a\n y = b - bv\n if(y) {\n g[count++] = y\n }\n _x = q1 + x\n _bv = _x - q1\n _av = _x - _bv\n _br = x - _bv\n _ar = q1 - _av\n q0 = _ar + _br\n q1 = _x\n eptr += 1\n if(eptr < ne) {\n ei = e[eptr]\n }\n }\n while(fptr < nf) {\n a = fi\n b = q0\n x = a + b\n bv = x - a\n y = b - bv\n if(y) {\n g[count++] = y\n } \n _x = q1 + x\n _bv = _x - q1\n _av = _x - _bv\n _br = x - _bv\n _ar = q1 - _av\n q0 = _ar + _br\n q1 = _x\n fptr += 1\n if(fptr < nf) {\n fi = f[fptr]\n }\n }\n if(q0) {\n g[count++] = q0\n }\n if(q1) {\n g[count++] = q1\n }\n if(!count) {\n g[count++] = 0.0 \n }\n g.length = count\n return g\n}","\"use strict\"\n\nvar twoProduct = require(\"two-product\")\nvar robustSum = require(\"robust-sum\")\nvar robustScale = require(\"robust-scale\")\nvar robustSubtract = require(\"robust-subtract\")\n\nvar NUM_EXPAND = 5\n\nvar EPSILON = 1.1102230246251565e-16\nvar ERRBOUND3 = (3.0 + 16.0 * EPSILON) * EPSILON\nvar ERRBOUND4 = (7.0 + 56.0 * EPSILON) * EPSILON\n\nfunction cofactor(m, c) {\n var result = new Array(m.length-1)\n for(var i=1; i<m.length; ++i) {\n var r = result[i-1] = new Array(m.length-1)\n for(var j=0,k=0; j<m.length; ++j) {\n if(j === c) {\n continue\n }\n r[k++] = m[i][j]\n }\n }\n return result\n}\n\nfunction matrix(n) {\n var result = new Array(n)\n for(var i=0; i<n; ++i) {\n result[i] = new Array(n)\n for(var j=0; j<n; ++j) {\n result[i][j] = [\"m\", j, \"[\", (n-i-1), \"]\"].join(\"\")\n }\n }\n return result\n}\n\nfunction sign(n) {\n if(n & 1) {\n return \"-\"\n }\n return \"\"\n}\n\nfunction generateSum(expr) {\n if(expr.length === 1) {\n return expr[0]\n } else if(expr.length === 2) {\n return [\"sum(\", expr[0], \",\", expr[1], \")\"].join(\"\")\n } else {\n var m = expr.length>>1\n return [\"sum(\", generateSum(expr.slice(0, m)), \",\", generateSum(expr.slice(m)), \")\"].join(\"\")\n }\n}\n\nfunction determinant(m) {\n if(m.length === 2) {\n return [[\"sum(prod(\", m[0][0], \",\", m[1][1], \"),prod(-\", m[0][1], \",\", m[1][0], \"))\"].join(\"\")]\n } else {\n var expr = []\n for(var i=0; i<m.length; ++i) {\n expr.push([\"scale(\", generateSum(determinant(cofactor(m, i))), \",\", sign(i), m[0][i], \")\"].join(\"\"))\n }\n return expr\n }\n}\n\nfunction orientation(n) {\n var pos = []\n var neg = []\n var m = matrix(n)\n var args = []\n for(var i=0; i<n; ++i) {\n if((i&1)===0) {\n pos.push.apply(pos, determinant(cofactor(m, i)))\n } else {\n neg.push.apply(neg, determinant(cofactor(m, i)))\n }\n args.push(\"m\" + i)\n }\n var posExpr = generateSum(pos)\n var negExpr = generateSum(neg)\n var funcName = \"orientation\" + n + \"Exact\"\n var code = [\"function \", funcName, \"(\", args.join(), \"){var p=\", posExpr, \",n=\", negExpr, \",d=sub(p,n);\\\nreturn d[d.length-1];};return \", funcName].join(\"\")\n var proc = new Function(\"sum\", \"prod\", \"scale\", \"sub\", code)\n return proc(robustSum, twoProduct, robustScale, robustSubtract)\n}\n\nvar orientation3Exact = orientation(3)\nvar orientation4Exact = orientation(4)\n\nvar CACHED = [\n function orientation0() { return 0 },\n function orientation1() { return 0 },\n function orientation2(a, b) { \n return b[0] - a[0]\n },\n function orientation3(a, b, c) {\n var l = (a[1] - c[1]) * (b[0] - c[0])\n var r = (a[0] - c[0]) * (b[1] - c[1])\n var det = l - r\n var s\n if(l > 0) {\n if(r <= 0) {\n return det\n } else {\n s = l + r\n }\n } else if(l < 0) {\n if(r >= 0) {\n return det\n } else {\n s = -(l + r)\n }\n } else {\n return det\n }\n var tol = ERRBOUND3 * s\n if(det >= tol || det <= -tol) {\n return det\n }\n return orientation3Exact(a, b, c)\n },\n function orientation4(a,b,c,d) {\n var adx = a[0] - d[0]\n var bdx = b[0] - d[0]\n var cdx = c[0] - d[0]\n var ady = a[1] - d[1]\n var bdy = b[1] - d[1]\n var cdy = c[1] - d[1]\n var adz = a[2] - d[2]\n var bdz = b[2] - d[2]\n var cdz = c[2] - d[2]\n var bdxcdy = bdx * cdy\n var cdxbdy = cdx * bdy\n var cdxady = cdx * ady\n var adxcdy = adx * cdy\n var adxbdy = adx * bdy\n var bdxady = bdx * ady\n var det = adz * (bdxcdy - cdxbdy) \n + bdz * (cdxady - adxcdy)\n + cdz * (adxbdy - bdxady)\n var permanent = (Math.abs(bdxcdy) + Math.abs(cdxbdy)) * Math.abs(adz)\n + (Math.abs(cdxady) + Math.abs(adxcdy)) * Math.abs(bdz)\n + (Math.abs(adxbdy) + Math.abs(bdxady)) * Math.abs(cdz)\n var tol = ERRBOUND4 * permanent\n if ((det > tol) || (-det > tol)) {\n return det\n }\n return orientation4Exact(a,b,c,d)\n }\n]\n\nfunction slowOrient(args) {\n var proc = CACHED[args.length]\n if(!proc) {\n proc = CACHED[args.length] = orientation(args.length)\n }\n return proc.apply(undefined, args)\n}\n\nfunction generateOrientationProc() {\n while(CACHED.length <= NUM_EXPAND) {\n CACHED.push(orientation(CACHED.length))\n }\n var args = []\n var procArgs = [\"slow\"]\n for(var i=0; i<=NUM_EXPAND; ++i) {\n args.push(\"a\" + i)\n procArgs.push(\"o\" + i)\n }\n var code = [\n \"function getOrientation(\", args.join(), \"){switch(arguments.length){case 0:case 1:return 0;\"\n ]\n for(var i=2; i<=NUM_EXPAND; ++i) {\n code.push(\"case \", i, \":return o\", i, \"(\", args.slice(0, i).join(), \");\")\n }\n code.push(\"}var s=new Array(arguments.length);for(var i=0;i<arguments.length;++i){s[i]=arguments[i]};return slow(s);}return getOrientation\")\n procArgs.push(code.join(\"\"))\n\n var proc = Function.apply(undefined, procArgs)\n module.exports = proc.apply(undefined, [slowOrient].concat(CACHED))\n for(var i=0; i<=NUM_EXPAND; ++i) {\n module.exports[i] = CACHED[i]\n }\n}\n\ngenerateOrientationProc()","\"use strict\"\n\nmodule.exports = orderSegments\n\nvar orient = require(\"robust-orientation\")\n\nfunction horizontalOrder(a, b) {\n var bl, br\n if(b[0][0] < b[1][0]) {\n bl = b[0]\n br = b[1]\n } else if(b[0][0] > b[1][0]) {\n bl = b[1]\n br = b[0]\n } else {\n var alo = Math.min(a[0][1], a[1][1])\n var ahi = Math.max(a[0][1], a[1][1])\n var blo = Math.min(b[0][1], b[1][1])\n var bhi = Math.max(b[0][1], b[1][1])\n if(ahi < blo) {\n return ahi - blo\n }\n if(alo > bhi) {\n return alo - bhi\n }\n return ahi - bhi\n }\n var al, ar\n if(a[0][1] < a[1][1]) {\n al = a[0]\n ar = a[1]\n } else {\n al = a[1]\n ar = a[0]\n }\n var d = orient(br, bl, al)\n if(d) {\n return d\n }\n d = orient(br, bl, ar)\n if(d) {\n return d\n }\n return ar - br\n}\n\nfunction orderSegments(b, a) {\n var al, ar\n if(a[0][0] < a[1][0]) {\n al = a[0]\n ar = a[1]\n } else if(a[0][0] > a[1][0]) {\n al = a[1]\n ar = a[0]\n } else {\n return horizontalOrder(a, b)\n }\n var bl, br\n if(b[0][0] < b[1][0]) {\n bl = b[0]\n br = b[1]\n } else if(b[0][0] > b[1][0]) {\n bl = b[1]\n br = b[0]\n } else {\n return -horizontalOrder(b, a)\n }\n var d1 = orient(al, ar, br)\n var d2 = orient(al, ar, bl)\n if(d1 < 0) {\n if(d2 <= 0) {\n return d1\n }\n } else if(d1 > 0) {\n if(d2 >= 0) {\n return d1\n }\n } else if(d2) {\n return d2\n }\n d1 = orient(br, bl, ar)\n d2 = orient(br, bl, al)\n if(d1 < 0) {\n if(d2 <= 0) {\n return d1\n }\n } else if(d1 > 0) {\n if(d2 >= 0) {\n return d1\n }\n } else if(d2) {\n return d2\n }\n return ar[0] - br[0]\n}","\"use strict\"\n\nmodule.exports = createRBTree\n\nvar RED = 0\nvar BLACK = 1\n\nfunction RBNode(color, key, value, left, right, count) {\n this._color = color\n this.key = key\n this.value = value\n this.left = left\n this.right = right\n this._count = count\n}\n\nfunction cloneNode(node) {\n return new RBNode(node._color, node.key, node.value, node.left, node.right, node._count)\n}\n\nfunction repaint(color, node) {\n return new RBNode(color, node.key, node.value, node.left, node.right, node._count)\n}\n\nfunction recount(node) {\n node._count = 1 + (node.left ? node.left._count : 0) + (node.right ? node.right._count : 0)\n}\n\nfunction RedBlackTree(compare, root) {\n this._compare = compare\n this.root = root\n}\n\nvar proto = RedBlackTree.prototype\n\nObject.defineProperty(proto, \"keys\", {\n get: function() {\n var result = []\n this.forEach(function(k,v) {\n result.push(k)\n })\n return result\n }\n})\n\nObject.defineProperty(proto, \"values\", {\n get: function() {\n var result = []\n this.forEach(function(k,v) {\n result.push(v)\n })\n return result\n }\n})\n\n//Returns the number of nodes in the tree\nObject.defineProperty(proto, \"length\", {\n get: function() {\n if(this.root) {\n return this.root._count\n }\n return 0\n }\n})\n\n//Insert a new item into the tree\nproto.insert = function(key, value) {\n var cmp = this._compare\n //Find point to insert new node at\n var n = this.root\n var n_stack = []\n var d_stack = []\n while(n) {\n var d = cmp(key, n.key)\n n_stack.push(n)\n d_stack.push(d)\n if(d <= 0) {\n n = n.left\n } else {\n n = n.right\n }\n }\n //Rebuild path to leaf node\n n_stack.push(new RBNode(RED, key, value, null, null, 1))\n for(var s=n_stack.length-2; s>=0; --s) {\n var n = n_stack[s]\n if(d_stack[s] <= 0) {\n n_stack[s] = new RBNode(n._color, n.key, n.value, n_stack[s+1], n.right, n._count+1)\n } else {\n n_stack[s] = new RBNode(n._color, n.key, n.value, n.left, n_stack[s+1], n._count+1)\n }\n }\n //Rebalance tree using rotations\n //console.log(\"start insert\", key, d_stack)\n for(var s=n_stack.length-1; s>1; --s) {\n var p = n_stack[s-1]\n var n = n_stack[s]\n if(p._color === BLACK || n._color === BLACK) {\n break\n }\n var pp = n_stack[s-2]\n if(pp.left === p) {\n if(p.left === n) {\n var y = pp.right\n if(y && y._color === RED) {\n //console.log(\"LLr\")\n p._color = BLACK\n pp.right = repaint(BLACK, y)\n pp._color = RED\n s -= 1\n } else {\n //console.log(\"LLb\")\n pp._color = RED\n pp.left = p.right\n p._color = BLACK\n p.right = pp\n n_stack[s-2] = p\n n_stack[s-1] = n\n recount(pp)\n recount(p)\n if(s >= 3) {\n var ppp = n_stack[s-3]\n if(ppp.left === pp) {\n ppp.left = p\n } else {\n ppp.right = p\n }\n }\n break\n }\n } else {\n var y = pp.right\n if(y && y._color === RED) {\n //console.log(\"LRr\")\n p._color = BLACK\n pp.right = repaint(BLACK, y)\n pp._color = RED\n s -= 1\n } else {\n //console.log(\"LRb\")\n p.right = n.left\n pp._color = RED\n pp.left = n.right\n n._color = BLACK\n n.left = p\n n.right = pp\n n_stack[s-2] = n\n n_stack[s-1] = p\n recount(pp)\n recount(p)\n recount(n)\n if(s >= 3) {\n var ppp = n_stack[s-3]\n if(ppp.left === pp) {\n ppp.left = n\n } else {\n ppp.right = n\n }\n }\n break\n }\n }\n } else {\n if(p.right === n) {\n var y = pp.left\n if(y && y._color === RED) {\n //console.log(\"RRr\", y.key)\n p._color = BLACK\n pp.left = repaint(BLACK, y)\n pp._color = RED\n s -= 1\n } else {\n //console.log(\"RRb\")\n pp._color = RED\n pp.right = p.left\n p._color = BLACK\n p.left = pp\n n_stack[s-2] = p\n n_stack[s-1] = n\n recount(pp)\n recount(p)\n if(s >= 3) {\n var ppp = n_stack[s-3]\n if(ppp.right === pp) {\n ppp.right = p\n } else {\n ppp.left = p\n }\n }\n break\n }\n } else {\n var y = pp.left\n if(y && y._color === RED) {\n //console.log(\"RLr\")\n p._color = BLACK\n pp.left = repaint(BLACK, y)\n pp._color = RED\n s -= 1\n } else {\n //console.log(\"RLb\")\n p.left = n.right\n pp._color = RED\n pp.right = n.left\n n._color = BLACK\n n.right = p\n n.left = pp\n n_stack[s-2] = n\n n_stack[s-1] = p\n recount(pp)\n recount(p)\n recount(n)\n if(s >= 3) {\n var ppp = n_stack[s-3]\n if(ppp.right === pp) {\n ppp.right = n\n } else {\n ppp.left = n\n }\n }\n break\n }\n }\n }\n }\n //Return new tree\n n_stack[0]._color = BLACK\n return new RedBlackTree(cmp, n_stack[0])\n}\n\n\n//Visit all nodes inorder\nfunction doVisitFull(visit, node) {\n if(node.left) {\n var v = doVisitFull(visit, node.left)\n if(v) { return v }\n }\n var v = visit(node.key, node.value)\n if(v) { return v }\n if(node.right) {\n return doVisitFull(visit, node.right)\n }\n}\n\n//Visit half nodes in order\nfunction doVisitHalf(lo, compare, visit, node) {\n var l = compare(lo, node.key)\n if(l <= 0) {\n if(node.left) {\n var v = doVisitHalf(lo, compare, visit, node.left)\n if(v) { return v }\n }\n var v = visit(node.key, node.value)\n if(v) { return v }\n }\n if(node.right) {\n return doVisitHalf(lo, compare, visit, node.right)\n }\n}\n\n//Visit all nodes within a range\nfunction doVisit(lo, hi, compare, visit, node) {\n var l = compare(lo, node.key)\n var h = compare(hi, node.key)\n var v\n if(l <= 0) {\n if(node.left) {\n v = doVisit(lo, hi, compare, visit, node.left)\n if(v) { return v }\n }\n if(h > 0) {\n v = visit(node.key, node.value)\n if(v) { return v }\n }\n }\n if(h > 0 && node.right) {\n return doVisit(lo, hi, compare, visit, node.right)\n }\n}\n\n\nproto.forEach = function rbTreeForEach(visit, lo, hi) {\n if(!this.root) {\n return\n }\n switch(arguments.length) {\n case 1:\n return doVisitFull(visit, this.root)\n break\n\n case 2:\n return doVisitHalf(lo, this._compare, visit, this.root)\n break\n\n case 3:\n if(this._compare(lo, hi) >= 0) {\n return\n }\n return doVisit(lo, hi, this._compare, visit, this.root)\n break\n }\n}\n\n//First item in list\nObject.defineProperty(proto, \"begin\", {\n get: function() {\n var stack = []\n var n = this.root\n while(n) {\n stack.push(n)\n n = n.left\n }\n return new RedBlackTreeIterator(this, stack)\n }\n})\n\n//Last item in list\nObject.defineProperty(proto, \"end\", {\n get: function() {\n var stack = []\n var n = this.root\n while(n) {\n stack.push(n)\n n = n.right\n }\n return new RedBlackTreeIterator(this, stack)\n }\n})\n\n//Find the ith item in the tree\nproto.at = function(idx) {\n if(idx < 0) {\n return new RedBlackTreeIterator(this, [])\n }\n var n = this.root\n var stack = []\n while(true) {\n stack.push(n)\n if(n.left) {\n if(idx < n.left._count) {\n n = n.left\n continue\n }\n idx -= n.left._count\n }\n if(!idx) {\n return new RedBlackTreeIterator(this, stack)\n }\n idx -= 1\n if(n.right) {\n if(idx >= n.right._count) {\n break\n }\n n = n.right\n } else {\n break\n }\n }\n return new RedBlackTreeIterator(this, [])\n}\n\nproto.ge = function(key) {\n var cmp = this._compare\n var n = this.root\n var stack = []\n var last_ptr = 0\n while(n) {\n var d = cmp(key, n.key)\n stack.push(n)\n if(d <= 0) {\n last_ptr = stack.length\n }\n if(d <= 0) {\n n = n.left\n } else {\n n = n.right\n }\n }\n stack.length = last_ptr\n return new RedBlackTreeIterator(this, stack)\n}\n\nproto.gt = function(key) {\n var cmp = this._compare\n var n = this.root\n var stack = []\n var last_ptr = 0\n while(n) {\n var d = cmp(key, n.key)\n stack.push(n)\n if(d < 0) {\n last_ptr = stack.length\n }\n if(d < 0) {\n n = n.left\n } else {\n n = n.right\n }\n }\n stack.length = last_ptr\n return new RedBlackTreeIterator(this, stack)\n}\n\nproto.lt = function(key) {\n var cmp = this._compare\n var n = this.root\n var stack = []\n var last_ptr = 0\n while(n) {\n var d = cmp(key, n.key)\n stack.push(n)\n if(d > 0) {\n last_ptr = stack.length\n }\n if(d <= 0) {\n n = n.left\n } else {\n n = n.right\n }\n }\n stack.length = last_ptr\n return new RedBlackTreeIterator(this, stack)\n}\n\nproto.le = function(key) {\n var cmp = this._compare\n var n = this.root\n var stack = []\n var last_ptr = 0\n while(n) {\n var d = cmp(key, n.key)\n stack.push(n)\n if(d >= 0) {\n last_ptr = stack.length\n }\n if(d < 0) {\n n = n.left\n } else {\n n = n.right\n }\n }\n stack.length = last_ptr\n return new RedBlackTreeIterator(this, stack)\n}\n\n//Finds the item with key if it exists\nproto.find = function(key) {\n var cmp = this._compare\n var n = this.root\n var stack = []\n while(n) {\n var d = cmp(key, n.key)\n stack.push(n)\n if(d === 0) {\n return new RedBlackTreeIterator(this, stack)\n }\n if(d <= 0) {\n n = n.left\n } else {\n n = n.right\n }\n }\n return new RedBlackTreeIterator(this, [])\n}\n\n//Removes item with key from tree\nproto.remove = function(key) {\n var iter = this.find(key)\n if(iter) {\n return iter.remove()\n }\n return this\n}\n\n//Returns the item at `key`\nproto.get = function(key) {\n var cmp = this._compare\n var n = this.root\n while(n) {\n var d = cmp(key, n.key)\n if(d === 0) {\n return n.value\n }\n if(d <= 0) {\n n = n.left\n } else {\n n = n.right\n }\n }\n return\n}\n\n//Iterator for red black tree\nfunction RedBlackTreeIterator(tree, stack) {\n this.tree = tree\n this._stack = stack\n}\n\nvar iproto = RedBlackTreeIterator.prototype\n\n//Test if iterator is valid\nObject.defineProperty(iproto, \"valid\", {\n get: function() {\n return this._stack.length > 0\n }\n})\n\n//Node of the iterator\nObject.defineProperty(iproto, \"node\", {\n get: function() {\n if(this._stack.length > 0) {\n return this._stack[this._stack.length-1]\n }\n return null\n },\n enumerable: true\n})\n\n//Makes a copy of an iterator\niproto.clone = function() {\n return new RedBlackTreeIterator(this.tree, this._stack.slice())\n}\n\n//Swaps two nodes\nfunction swapNode(n, v) {\n n.key = v.key\n n.value = v.value\n n.left = v.left\n n.right = v.right\n n._color = v._color\n n._count = v._count\n}\n\n//Fix up a double black node in a tree\nfunction fixDoubleBlack(stack) {\n var n, p, s, z\n for(var i=stack.length-1; i>=0; --i) {\n n = stack[i]\n if(i === 0) {\n n._color = BLACK\n return\n }\n //console.log(\"visit node:\", n.key, i, stack[i].key, stack[i-1].key)\n p = stack[i-1]\n if(p.left === n) {\n //console.log(\"left child\")\n s = p.right\n if(s.right && s.right._color === RED) {\n //console.log(\"case 1: right sibling child red\")\n s = p.right = cloneNode(s)\n z = s.right = cloneNode(s.right)\n p.right = s.left\n s.left = p\n s.right = z\n s._color = p._color\n n._color = BLACK\n p._color = BLACK\n z._color = BLACK\n recount(p)\n recount(s)\n if(i > 1) {\n var pp = stack[i-2]\n if(pp.left === p) {\n pp.left = s\n } else {\n pp.right = s\n }\n }\n stack[i-1] = s\n return\n } else if(s.left && s.left._color === RED) {\n //console.log(\"case 1: left sibling child red\")\n s = p.right = cloneNode(s)\n z = s.left = cloneNode(s.left)\n p.right = z.left\n s.left = z.right\n z.left = p\n z.right = s\n z._color = p._color\n p._color = BLACK\n s._color = BLACK\n n._color = BLACK\n recount(p)\n recount(s)\n recount(z)\n if(i > 1) {\n var pp = stack[i-2]\n if(pp.left === p) {\n pp.left = z\n } else {\n pp.right = z\n }\n }\n stack[i-1] = z\n return\n }\n if(s._color === BLACK) {\n if(p._color === RED) {\n //console.log(\"case 2: black sibling, red parent\", p.right.value)\n p._color = BLACK\n p.right = repaint(RED, s)\n return\n } else {\n //console.log(\"case 2: black sibling, black parent\", p.right.value)\n p.right = repaint(RED, s)\n continue \n }\n } else {\n //console.log(\"case 3: red sibling\")\n s = cloneNode(s)\n p.right = s.left\n s.left = p\n s._color = p._color\n p._color = RED\n recount(p)\n recount(s)\n if(i > 1) {\n var pp = stack[i-2]\n if(pp.left === p) {\n pp.left = s\n } else {\n pp.right = s\n }\n }\n stack[i-1] = s\n stack[i] = p\n if(i+1 < stack.length) {\n stack[i+1] = n\n } else {\n stack.push(n)\n }\n i = i+2\n }\n } else {\n //console.log(\"right child\")\n s = p.left\n if(s.left && s.left._color === RED) {\n //console.log(\"case 1: left sibling child red\", p.value, p._color)\n s = p.left = cloneNode(s)\n z = s.left = cloneNode(s.left)\n p.left = s.right\n s.right = p\n s.left = z\n s._color = p._color\n n._color = BLACK\n p._color = BLACK\n z._color = BLACK\n recount(p)\n recount(s)\n if(i > 1) {\n var pp = stack[i-2]\n if(pp.right === p) {\n pp.right = s\n } else {\n pp.left = s\n }\n }\n stack[i-1] = s\n return\n } else if(s.right && s.right._color === RED) {\n //console.log(\"case 1: right sibling child red\")\n s = p.left = cloneNode(s)\n z = s.right = cloneNode(s.right)\n p.left = z.right\n s.right = z.left\n z.right = p\n z.left = s\n z._color = p._color\n p._color = BLACK\n s._color = BLACK\n n._color = BLACK\n recount(p)\n recount(s)\n recount(z)\n if(i > 1) {\n var pp = stack[i-2]\n if(pp.right === p) {\n pp.right = z\n } else {\n pp.left = z\n }\n }\n stack[i-1] = z\n return\n }\n if(s._color === BLACK) {\n if(p._color === RED) {\n //console.log(\"case 2: black sibling, red parent\")\n p._color = BLACK\n p.left = repaint(RED, s)\n return\n } else {\n //console.log(\"case 2: black sibling, black parent\")\n p.left = repaint(RED, s)\n continue \n }\n } else {\n //console.log(\"case 3: red sibling\")\n s = cloneNode(s)\n p.left = s.right\n s.right = p\n s._color = p._color\n p._color = RED\n recount(p)\n recount(s)\n if(i > 1) {\n var pp = stack[i-2]\n if(pp.right === p) {\n pp.right = s\n } else {\n pp.left = s\n }\n }\n stack[i-1] = s\n stack[i] = p\n if(i+1 < stack.length) {\n stack[i+1] = n\n } else {\n stack.push(n)\n }\n i = i+2\n }\n }\n }\n}\n\n//Removes item at iterator from tree\niproto.remove = function() {\n var stack = this._stack\n if(stack.length === 0) {\n return this.tree\n }\n //First copy path to node\n var cstack = new Array(stack.length)\n var n = stack[stack.length-1]\n cstack[cstack.length-1] = new RBNode(n._color, n.key, n.value, n.left, n.right, n._count)\n for(var i=stack.length-2; i>=0; --i) {\n var n = stack[i]\n if(n.left === stack[i+1]) {\n cstack[i] = new RBNode(n._color, n.key, n.value, cstack[i+1], n.right, n._count)\n } else {\n cstack[i] = new RBNode(n._color, n.key, n.value, n.left, cstack[i+1], n._count)\n }\n }\n\n //Get node\n n = cstack[cstack.length-1]\n //console.log(\"start remove: \", n.value)\n\n //If not leaf, then swap with previous node\n if(n.left && n.right) {\n //console.log(\"moving to leaf\")\n\n //First walk to previous leaf\n var split = cstack.length\n n = n.left\n while(n.right) {\n cstack.push(n)\n n = n.right\n }\n //Copy path to leaf\n var v = cstack[split-1]\n cstack.push(new RBNode(n._color, v.key, v.value, n.left, n.right, n._count))\n cstack[split-1].key = n.key\n cstack[split-1].value = n.value\n\n //Fix up stack\n for(var i=cstack.length-2; i>=split; --i) {\n n = cstack[i]\n cstack[i] = new RBNode(n._color, n.key, n.value, n.left, cstack[i+1], n._count)\n }\n cstack[split-1].left = cstack[split]\n }\n //console.log(\"stack=\", cstack.map(function(v) { return v.value }))\n\n //Remove leaf node\n n = cstack[cstack.length-1]\n if(n._color === RED) {\n //Easy case: removing red leaf\n //console.log(\"RED leaf\")\n var p = cstack[cstack.length-2]\n if(p.left === n) {\n p.left = null\n } else if(p.right === n) {\n p.right = null\n }\n cstack.pop()\n for(var i=0; i<cstack.length; ++i) {\n cstack[i]._count--\n }\n return new RedBlackTree(this.tree._compare, cstack[0])\n } else {\n if(n.left || n.right) {\n //Second easy case: Single child black parent\n //console.log(\"BLACK single child\")\n if(n.left) {\n swapNode(n, n.left)\n } else if(n.right) {\n swapNode(n, n.right)\n }\n //Child must be red, so repaint it black to balance color\n n._color = BLACK\n for(var i=0; i<cstack.length-1; ++i) {\n cstack[i]._count--\n }\n return new RedBlackTree(this.tree._compare, cstack[0])\n } else if(cstack.length === 1) {\n //Third easy case: root\n //console.log(\"ROOT\")\n return new RedBlackTree(this.tree._compare, null)\n } else {\n //Hard case: Repaint n, and then do some nasty stuff\n //console.log(\"BLACK leaf no children\")\n for(var i=0; i<cstack.length; ++i) {\n cstack[i]._count--\n }\n var parent = cstack[cstack.length-2]\n fixDoubleBlack(cstack)\n //Fix up links\n if(parent.left === n) {\n parent.left = null\n } else {\n parent.right = null\n }\n }\n }\n return new RedBlackTree(this.tree._compare, cstack[0])\n}\n\n//Returns key\nObject.defineProperty(iproto, \"key\", {\n get: function() {\n if(this._stack.length > 0) {\n return this._stack[this._stack.length-1].key\n }\n return\n },\n enumerable: true\n})\n\n//Returns value\nObject.defineProperty(iproto, \"value\", {\n get: function() {\n if(this._stack.length > 0) {\n return this._stack[this._stack.length-1].value\n }\n return\n },\n enumerable: true\n})\n\n\n//Returns the position of this iterator in the sorted list\nObject.defineProperty(iproto, \"index\", {\n get: function() {\n var idx = 0\n var stack = this._stack\n if(stack.length === 0) {\n var r = this.tree.root\n if(r) {\n return r._count\n }\n return 0\n } else if(stack[stack.length-1].left) {\n idx = stack[stack.length-1].left._count\n }\n for(var s=stack.length-2; s>=0; --s) {\n if(stack[s+1] === stack[s].right) {\n ++idx\n if(stack[s].left) {\n idx += stack[s].left._count\n }\n }\n }\n return idx\n },\n enumerable: true\n})\n\n//Advances iterator to next element in list\niproto.next = function() {\n var stack = this._stack\n if(stack.length === 0) {\n return\n }\n var n = stack[stack.length-1]\n if(n.right) {\n n = n.right\n while(n) {\n stack.push(n)\n n = n.left\n }\n } else {\n stack.pop()\n while(stack.length > 0 && stack[stack.length-1].right === n) {\n n = stack[stack.length-1]\n stack.pop()\n }\n }\n}\n\n//Checks if iterator is at end of tree\nObject.defineProperty(iproto, \"hasNext\", {\n get: function() {\n var stack = this._stack\n if(stack.length === 0) {\n return false\n }\n if(stack[stack.length-1].right) {\n return true\n }\n for(var s=stack.length-1; s>0; --s) {\n if(stack[s-1].left === stack[s]) {\n return true\n }\n }\n return false\n }\n})\n\n//Update value\niproto.update = function(value) {\n var stack = this._stack\n if(stack.length === 0) {\n throw new Error(\"Can't update empty node!\")\n }\n var cstack = new Array(stack.length)\n var n = stack[stack.length-1]\n cstack[cstack.length-1] = new RBNode(n._color, n.key, value, n.left, n.right, n._count)\n for(var i=stack.length-2; i>=0; --i) {\n n = stack[i]\n if(n.left === stack[i+1]) {\n cstack[i] = new RBNode(n._color, n.key, n.value, cstack[i+1], n.right, n._count)\n } else {\n cstack[i] = new RBNode(n._color, n.key, n.value, n.left, cstack[i+1], n._count)\n }\n }\n return new RedBlackTree(this.tree._compare, cstack[0])\n}\n\n//Moves iterator backward one element\niproto.prev = function() {\n var stack = this._stack\n if(stack.length === 0) {\n return\n }\n var n = stack[stack.length-1]\n if(n.left) {\n n = n.left\n while(n) {\n stack.push(n)\n n = n.right\n }\n } else {\n stack.pop()\n while(stack.length > 0 && stack[stack.length-1].left === n) {\n n = stack[stack.length-1]\n stack.pop()\n }\n }\n}\n\n//Checks if iterator is at start of tree\nObject.defineProperty(iproto, \"hasPrev\", {\n get: function() {\n var stack = this._stack\n if(stack.length === 0) {\n return false\n }\n if(stack[stack.length-1].left) {\n return true\n }\n for(var s=stack.length-1; s>0; --s) {\n if(stack[s-1].right === stack[s]) {\n return true\n }\n }\n return false\n }\n})\n\n//Default comparison function\nfunction defaultCompare(a, b) {\n if(a < b) {\n return -1\n }\n if(a > b) {\n return 1\n }\n return 0\n}\n\n//Build a tree\nfunction createRBTree(compare) {\n return new RedBlackTree(compare || defaultCompare, null)\n}","\"use strict\"\n\nmodule.exports = createSlabDecomposition\n\nvar bounds = require(\"binary-search-bounds\")\nvar createRBTree = require(\"functional-red-black-tree\")\nvar orient = require(\"robust-orientation\")\nvar orderSegments = require(\"./lib/order-segments\")\n\nfunction SlabDecomposition(slabs, coordinates, horizontal) {\n this.slabs = slabs\n this.coordinates = coordinates\n this.horizontal = horizontal\n}\n\nvar proto = SlabDecomposition.prototype\n\nfunction compareHorizontal(e, y) {\n return e.y - y\n}\n\nfunction searchBucket(root, p) {\n var lastNode = null\n while(root) {\n var seg = root.key\n var l, r\n if(seg[0][0] < seg[1][0]) {\n l = seg[0]\n r = seg[1]\n } else {\n l = seg[1]\n r = seg[0]\n }\n var o = orient(l, r, p)\n if(o < 0) {\n root = root.left\n } else if(o > 0) {\n if(p[0] !== seg[1][0]) {\n lastNode = root\n root = root.right\n } else {\n var val = searchBucket(root.right, p)\n if(val) {\n return val\n }\n root = root.left\n }\n } else {\n if(p[0] !== seg[1][0]) {\n return root\n } else {\n var val = searchBucket(root.right, p)\n if(val) {\n return val\n }\n root = root.left\n }\n }\n }\n return lastNode\n}\n\nproto.castUp = function(p) {\n var bucket = bounds.le(this.coordinates, p[0])\n if(bucket < 0) {\n return -1\n }\n var root = this.slabs[bucket]\n var hitNode = searchBucket(this.slabs[bucket], p)\n var lastHit = -1\n if(hitNode) {\n lastHit = hitNode.value\n }\n //Edge case: need to handle horizontal segments (sucks)\n if(this.coordinates[bucket] === p[0]) {\n var lastSegment = null\n if(hitNode) {\n lastSegment = hitNode.key\n }\n if(bucket > 0) {\n var otherHitNode = searchBucket(this.slabs[bucket-1], p)\n if(otherHitNode) {\n if(lastSegment) {\n if(orderSegments(otherHitNode.key, lastSegment) > 0) {\n lastSegment = otherHitNode.key\n lastHit = otherHitNode.value\n }\n } else {\n lastHit = otherHitNode.value\n lastSegment = otherHitNode.key\n }\n }\n }\n var horiz = this.horizontal[bucket]\n if(horiz.length > 0) {\n var hbucket = bounds.ge(horiz, p[1], compareHorizontal)\n if(hbucket < horiz.length) {\n var e = horiz[hbucket]\n if(p[1] === e.y) {\n if(e.closed) {\n return e.index\n } else {\n while(hbucket < horiz.length-1 && horiz[hbucket+1].y === p[1]) {\n hbucket = hbucket+1\n e = horiz[hbucket]\n if(e.closed) {\n return e.index\n }\n }\n if(e.y === p[1] && !e.start) {\n hbucket = hbucket+1\n if(hbucket >= horiz.length) {\n return lastHit\n }\n e = horiz[hbucket]\n }\n }\n }\n //Check if e is above/below last segment\n if(e.start) {\n if(lastSegment) {\n var o = orient(lastSegment[0], lastSegment[1], [p[0], e.y])\n if(lastSegment[0][0] > lastSegment[1][0]) {\n o = -o\n }\n if(o > 0) {\n lastHit = e.index\n }\n } else {\n lastHit = e.index\n }\n } else if(e.y !== p[1]) {\n lastHit = e.index\n }\n }\n }\n }\n return lastHit\n}\n\nfunction IntervalSegment(y, index, start, closed) {\n this.y = y\n this.index = index\n this.start = start\n this.closed = closed\n}\n\nfunction Event(x, segment, create, index) {\n this.x = x\n this.segment = segment\n this.create = create\n this.index = index\n}\n\n\nfunction createSlabDecomposition(segments) {\n var numSegments = segments.length\n var numEvents = 2 * numSegments\n var events = new Array(numEvents)\n for(var i=0; i<numSegments; ++i) {\n var s = segments[i]\n var f = s[0][0] < s[1][0]\n events[2*i] = new Event(s[0][0], s, f, i)\n events[2*i+1] = new Event(s[1][0], s, !f, i)\n }\n events.sort(function(a,b) {\n var d = a.x - b.x\n if(d) {\n return d\n }\n d = a.create - b.create\n if(d) {\n return d\n }\n return Math.min(a.segment[0][1], a.segment[1][1]) - Math.min(b.segment[0][1], b.segment[1][1])\n })\n var tree = createRBTree(orderSegments)\n var slabs = []\n var lines = []\n var horizontal = []\n var lastX = -Infinity\n for(var i=0; i<numEvents; ) {\n var x = events[i].x\n var horiz = []\n while(i < numEvents) {\n var e = events[i]\n if(e.x !== x) {\n break\n }\n i += 1\n if(e.segment[0][0] === e.x && e.segment[1][0] === e.x) {\n if(e.create) {\n if(e.segment[0][1] < e.segment[1][1]) {\n horiz.push(new IntervalSegment(\n e.segment[0][1],\n e.index,\n true,\n true))\n horiz.push(new IntervalSegment(\n e.segment[1][1],\n e.index,\n false,\n false))\n } else {\n horiz.push(new IntervalSegment(\n e.segment[1][1],\n e.index,\n true,\n false))\n horiz.push(new IntervalSegment(\n e.segment[0][1],\n e.index,\n false,\n true))\n }\n }\n } else {\n if(e.create) {\n tree = tree.insert(e.segment, e.index)\n } else {\n tree = tree.remove(e.segment)\n }\n }\n }\n slabs.push(tree.root)\n lines.push(x)\n horizontal.push(horiz)\n }\n return new SlabDecomposition(slabs, lines, horizontal)\n}","module.exports = preprocessPolygon\n\nvar orient = require('robust-orientation')[3]\nvar makeSlabs = require('slab-decomposition')\nvar makeIntervalTree = require('interval-tree-1d')\nvar bsearch = require('binary-search-bounds')\n\nfunction visitInterval() {\n return true\n}\n\nfunction intervalSearch(table) {\n return function(x, y) {\n var tree = table[x]\n if(tree) {\n return !!tree.queryPoint(y, visitInterval)\n }\n return false\n }\n}\n\nfunction buildVerticalIndex(segments) {\n var table = {}\n for(var i=0; i<segments.length; ++i) {\n var s = segments[i]\n var x = s[0][0]\n var y0 = s[0][1]\n var y1 = s[1][1]\n var p = [ Math.min(y0, y1), Math.max(y0, y1) ]\n if(x in table) {\n table[x].push(p)\n } else {\n table[x] = [ p ]\n }\n }\n var intervalTable = {}\n var keys = Object.keys(table)\n for(var i=0; i<keys.length; ++i) {\n var segs = table[keys[i]]\n intervalTable[keys[i]] = makeIntervalTree(segs)\n }\n return intervalSearch(intervalTable)\n}\n\nfunction buildSlabSearch(slabs, coordinates) {\n return function(p) {\n var bucket = bsearch.le(coordinates, p[0])\n if(bucket < 0) {\n return 1\n }\n var root = slabs[bucket]\n if(!root) {\n if(bucket > 0 && coordinates[bucket] === p[0]) {\n root = slabs[bucket-1]\n } else {\n return 1\n }\n }\n var lastOrientation = 1\n while(root) {\n var s = root.key\n var o = orient(p, s[0], s[1])\n if(s[0][0] < s[1][0]) {\n if(o < 0) {\n root = root.left\n } else if(o > 0) {\n lastOrientation = -1\n root = root.right\n } else {\n return 0\n }\n } else {\n if(o > 0) {\n root = root.left\n } else if(o < 0) {\n lastOrientation = 1\n root = root.right\n } else {\n return 0\n }\n }\n }\n return lastOrientation\n }\n}\n\nfunction classifyEmpty(p) {\n return 1\n}\n\nfunction createClassifyVertical(testVertical) {\n return function classify(p) {\n if(testVertical(p[0], p[1])) {\n return 0\n }\n return 1\n }\n}\n\nfunction createClassifyPointDegen(testVertical, testNormal) {\n return function classify(p) {\n if(testVertical(p[0], p[1])) {\n return 0\n }\n return testNormal(p)\n }\n}\n\nfunction preprocessPolygon(loops) {\n //Compute number of loops\n var numLoops = loops.length\n\n //Unpack segments\n var segments = []\n var vsegments = []\n var ptr = 0\n for(var i=0; i<numLoops; ++i) {\n var loop = loops[i]\n var numVertices = loop.length\n for(var s=numVertices-1,t=0; t<numVertices; s=(t++)) {\n var a = loop[s]\n var b = loop[t]\n if(a[0] === b[0]) {\n vsegments.push([a,b])\n } else {\n segments.push([a,b])\n }\n }\n }\n\n //Degenerate case: All loops are empty\n if(segments.length === 0) {\n if(vsegments.length === 0) {\n return classifyEmpty\n } else {\n return createClassifyVertical(buildVerticalIndex(vsegments))\n }\n }\n\n //Build slab decomposition\n var slabs = makeSlabs(segments)\n var testSlab = buildSlabSearch(slabs.slabs, slabs.coordinates)\n\n if(vsegments.length === 0) {\n return testSlab\n