Initial commit
This commit is contained in:
commit
b7d90b9afe
16245 files changed
+3396666
No files matched your search
+2
@@ -0,0 +1,2 @@
|
||||
/index.js
|
||||
node_modules
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
language: node_js
|
||||
sudo: false
|
||||
node_js: 'node'
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
# Change log
|
||||
|
||||
## [1.1.1] - 2017-06-27
|
||||
### Fixed
|
||||
- Fix UTM zone number longitude boundaries (fixes [Turbo87/utm#19])
|
||||
|
||||
## [1.1.0] - 2016-11-07
|
||||
### Added
|
||||
- An option to disable range checking of easting and northing
|
||||
|
||||
### Fixed
|
||||
- Fix case when `northern` is `false` (fixes [#3]; thanks go to **[@perhallstroem]**)
|
||||
|
||||
## [1.0.1] - 2016-07-01
|
||||
### Fixed
|
||||
- Fix `northern` never getting set (fixes [#1]; thanks go to **[@danielsiwiec]**)
|
||||
|
||||
## 1.0.0 - 2015-10-25
|
||||
### Added
|
||||
- Initial release
|
||||
|
||||
[1.1.1]: https://github.com/TimothyGu/utm/compare/v1.1.0...v1.1.1
|
||||
[1.1.0]: https://github.com/TimothyGu/utm/compare/v1.0.1...v1.1.0
|
||||
[1.0.1]: https://github.com/TimothyGu/utm/compare/v1.0.0...v1.0.1
|
||||
[Turbo87/utm#19]: https://github.com/Turbo87/utm/issues/19
|
||||
[#3]: https://github.com/TimothyGu/utm/issues/3
|
||||
[#1]: https://github.com/TimothyGu/utm/issues/1
|
||||
[@danielsiwiec]: https://github.com/danielsiwiec
|
||||
[@perhallstroem]: https://github.com/perhallstroem
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
Copyright (C) 2012 Tobias Bieniek <Tobias.Bieniek@gmx.de>
|
||||
Copyright (c) 2015 Tiancheng “Timothy” Gu
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
# utm
|
||||
|
||||
Bidirectional UTM-WGS84 converter for JavaScript.
|
||||
|
||||
[](https://www.npmjs.org/package/utm)
|
||||
[](https://travis-ci.org/TimothyGu/utm)
|
||||
|
||||
Translated directly from [Tobias Bieniek's implementation in Python](https://github.com/Turbo87/utm).
|
||||
|
||||
## Usage
|
||||
|
||||
```js
|
||||
var utm = require('utm')
|
||||
```
|
||||
|
||||
### `utm.toLatLon(easting, northing, zoneNum, zoneLetter, northern, strict = true)`
|
||||
|
||||
Convert from UTM-WGS84 to latitude/longitude coordinates. One and only one of
|
||||
`zoneLetter` and `northern` must be specified. `strict` option specifies
|
||||
whether easting and northing are checked against their respective ranges.
|
||||
|
||||
Returns `{ latitude, longitude }`.
|
||||
|
||||
### `utm.fromLatLon(latitude, longitude[, zoneNum])`
|
||||
|
||||
Convert from latitude/longitude coordinates to UTM-WGS84. `zoneNum` can be set
|
||||
to force a specific zone number.
|
||||
|
||||
Returns `{ easting, northing, zoneNum, zoneLetter }`.
|
||||
+203
@@ -0,0 +1,203 @@
|
||||
'use strict'
|
||||
|
||||
var K0 = 0.9996;
|
||||
|
||||
var E = 0.00669438;
|
||||
var E2 = Math.pow(E, 2);
|
||||
var E3 = Math.pow(E, 3);
|
||||
var E_P2 = E / (1 - E);
|
||||
|
||||
var SQRT_E = Math.sqrt(1 - E);
|
||||
var _E = (1 - SQRT_E) / (1 + SQRT_E);
|
||||
var _E2 = Math.pow(_E, 2);
|
||||
var _E3 = Math.pow(_E, 3);
|
||||
var _E4 = Math.pow(_E, 4);
|
||||
var _E5 = Math.pow(_E, 5);
|
||||
|
||||
var M1 = 1 - E / 4 - 3 * E2 / 64 - 5 * E3 / 256;
|
||||
var M2 = 3 * E / 8 + 3 * E2 / 32 + 45 * E3 / 1024;
|
||||
var M3 = 15 * E2 / 256 + 45 * E3 / 1024;
|
||||
var M4 = 35 * E3 / 3072;
|
||||
|
||||
var P2 = 3 / 2 * _E - 27 / 32 * _E3 + 269 / 512 * _E5;
|
||||
var P3 = 21 / 16 * _E2 - 55 / 32 * _E4;
|
||||
var P4 = 151 / 96 * _E3 - 417 / 128 * _E5;
|
||||
var P5 = 1097 / 512 * _E4;
|
||||
|
||||
var R = 6378137;
|
||||
|
||||
var ZONE_LETTERS = 'CDEFGHJKLMNPQRSTUVWXX';
|
||||
|
||||
export function toLatLon(easting, northing, zoneNum, zoneLetter, northern, strict) {
|
||||
strict = strict !== undefined ? strict : true;
|
||||
|
||||
if (!zoneLetter && northern === undefined) {
|
||||
throw new Error('either zoneLetter or northern needs to be set');
|
||||
} else if (zoneLetter && northern !== undefined) {
|
||||
throw new Error('set either zoneLetter or northern, but not both');
|
||||
}
|
||||
|
||||
if (strict) {
|
||||
if (easting < 100000 || 1000000 <= easting) {
|
||||
throw new RangeError('easting out of range (must be between 100 000 m and 999 999 m)');
|
||||
}
|
||||
if (northing < 0 || northing > 10000000) {
|
||||
throw new RangeError('northing out of range (must be between 0 m and 10 000 000 m)');
|
||||
}
|
||||
}
|
||||
if (zoneNum < 1 || zoneNum > 60) {
|
||||
throw new RangeError('zone number out of range (must be between 1 and 60)');
|
||||
}
|
||||
if (zoneLetter) {
|
||||
zoneLetter = zoneLetter.toUpperCase();
|
||||
if (zoneLetter.length !== 1 || ZONE_LETTERS.indexOf(zoneLetter) === -1) {
|
||||
throw new RangeError('zone letter out of range (must be between C and X)');
|
||||
}
|
||||
northern = zoneLetter >= 'N';
|
||||
}
|
||||
|
||||
var x = easting - 500000;
|
||||
var y = northing;
|
||||
|
||||
if (!northern) y -= 1e7;
|
||||
|
||||
var m = y / K0;
|
||||
var mu = m / (R * M1);
|
||||
|
||||
var pRad = mu +
|
||||
P2 * Math.sin(2 * mu) +
|
||||
P3 * Math.sin(4 * mu) +
|
||||
P4 * Math.sin(6 * mu) +
|
||||
P5 * Math.sin(8 * mu);
|
||||
|
||||
var pSin = Math.sin(pRad);
|
||||
var pSin2 = Math.pow(pSin, 2);
|
||||
|
||||
var pCos = Math.cos(pRad);
|
||||
|
||||
var pTan = Math.tan(pRad);
|
||||
var pTan2 = Math.pow(pTan, 2);
|
||||
var pTan4 = Math.pow(pTan, 4);
|
||||
|
||||
var epSin = 1 - E * pSin2;
|
||||
var epSinSqrt = Math.sqrt(epSin);
|
||||
|
||||
var n = R / epSinSqrt;
|
||||
var r = (1 - E) / epSin;
|
||||
|
||||
var c = _E * pCos * pCos;
|
||||
var c2 = c * c;
|
||||
|
||||
var d = x / (n * K0);
|
||||
var d2 = Math.pow(d, 2);
|
||||
var d3 = Math.pow(d, 3);
|
||||
var d4 = Math.pow(d, 4);
|
||||
var d5 = Math.pow(d, 5);
|
||||
var d6 = Math.pow(d, 6);
|
||||
|
||||
var latitude = pRad - (pTan / r) *
|
||||
(d2 / 2 -
|
||||
d4 / 24 * (5 + 3 * pTan2 + 10 * c - 4 * c2 - 9 * E_P2)) +
|
||||
d6 / 720 * (61 + 90 * pTan2 + 298 * c + 45 * pTan4 - 252 * E_P2 - 3 * c2);
|
||||
var longitude = (d -
|
||||
d3 / 6 * (1 + 2 * pTan2 + c) +
|
||||
d5 / 120 * (5 - 2 * c + 28 * pTan2 - 3 * c2 + 8 * E_P2 + 24 * pTan4)) / pCos;
|
||||
|
||||
return {
|
||||
latitude: toDegrees(latitude),
|
||||
longitude: toDegrees(longitude) + zoneNumberToCentralLongitude(zoneNum)
|
||||
};
|
||||
}
|
||||
|
||||
export function fromLatLon(latitude, longitude, forceZoneNum) {
|
||||
if (latitude > 84 || latitude < -80) {
|
||||
throw new RangeError('latitude out of range (must be between 80 deg S and 84 deg N)');
|
||||
}
|
||||
if (longitude > 180 || longitude < -180) {
|
||||
throw new RangeError('longitude out of range (must be between 180 deg W and 180 deg E)');
|
||||
}
|
||||
|
||||
var latRad = toRadians(latitude);
|
||||
var latSin = Math.sin(latRad);
|
||||
var latCos = Math.cos(latRad);
|
||||
|
||||
var latTan = Math.tan(latRad);
|
||||
var latTan2 = Math.pow(latTan, 2);
|
||||
var latTan4 = Math.pow(latTan, 4);
|
||||
|
||||
var zoneNum;
|
||||
|
||||
if (forceZoneNum === undefined) {
|
||||
zoneNum = latLonToZoneNumber(latitude, longitude);
|
||||
} else {
|
||||
zoneNum = forceZoneNum;
|
||||
}
|
||||
|
||||
var zoneLetter = latitudeToZoneLetter(latitude);
|
||||
|
||||
var lonRad = toRadians(longitude);
|
||||
var centralLon = zoneNumberToCentralLongitude(zoneNum);
|
||||
var centralLonRad = toRadians(centralLon);
|
||||
|
||||
var n = R / Math.sqrt(1 - E * latSin * latSin);
|
||||
var c = E_P2 * latCos * latCos;
|
||||
|
||||
var a = latCos * (lonRad - centralLonRad);
|
||||
var a2 = Math.pow(a, 2);
|
||||
var a3 = Math.pow(a, 3);
|
||||
var a4 = Math.pow(a, 4);
|
||||
var a5 = Math.pow(a, 5);
|
||||
var a6 = Math.pow(a, 6);
|
||||
|
||||
var m = R * (M1 * latRad -
|
||||
M2 * Math.sin(2 * latRad) +
|
||||
M3 * Math.sin(4 * latRad) -
|
||||
M4 * Math.sin(6 * latRad));
|
||||
var easting = K0 * n * (a +
|
||||
a3 / 6 * (1 - latTan2 + c) +
|
||||
a5 / 120 * (5 - 18 * latTan2 + latTan4 + 72 * c - 58 * E_P2)) + 500000;
|
||||
var northing = K0 * (m + n * latTan * (a2 / 2 +
|
||||
a4 / 24 * (5 - latTan2 + 9 * c + 4 * c * c) +
|
||||
a6 / 720 * (61 - 58 * latTan2 + latTan4 + 600 * c - 330 * E_P2)));
|
||||
if (latitude < 0) northing += 1e7;
|
||||
|
||||
return {
|
||||
easting: easting,
|
||||
northing: northing,
|
||||
zoneNum: zoneNum,
|
||||
zoneLetter: zoneLetter
|
||||
};
|
||||
}
|
||||
|
||||
function latitudeToZoneLetter(latitude) {
|
||||
if (-80 <= latitude && latitude <= 84) {
|
||||
return ZONE_LETTERS[Math.floor((latitude + 80) / 8)];
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
function latLonToZoneNumber(latitude, longitude) {
|
||||
if (56 <= latitude && latitude < 64 && 3 <= longitude && longitude < 12) return 32;
|
||||
|
||||
if (72 <= latitude && latitude <= 84 && longitude >= 0) {
|
||||
if (longitude < 9) return 31;
|
||||
if (longitude < 21) return 33;
|
||||
if (longitude < 33) return 35;
|
||||
if (longitude < 42) return 37;
|
||||
}
|
||||
|
||||
return Math.floor((longitude + 180) / 6) + 1;
|
||||
}
|
||||
|
||||
function zoneNumberToCentralLongitude(zoneNum) {
|
||||
return (zoneNum - 1) * 6 - 180 + 3;
|
||||
}
|
||||
|
||||
function toDegrees(rad) {
|
||||
return rad / Math.PI * 180;
|
||||
}
|
||||
|
||||
function toRadians(deg) {
|
||||
return deg * Math.PI / 180;
|
||||
}
|
||||
+208
@@ -0,0 +1,208 @@
|
||||
'use strict';
|
||||
|
||||
Object.defineProperty(exports, '__esModule', { value: true });
|
||||
|
||||
var K0 = 0.9996;
|
||||
|
||||
var E = 0.00669438;
|
||||
var E2 = Math.pow(E, 2);
|
||||
var E3 = Math.pow(E, 3);
|
||||
var E_P2 = E / (1 - E);
|
||||
|
||||
var SQRT_E = Math.sqrt(1 - E);
|
||||
var _E = (1 - SQRT_E) / (1 + SQRT_E);
|
||||
var _E2 = Math.pow(_E, 2);
|
||||
var _E3 = Math.pow(_E, 3);
|
||||
var _E4 = Math.pow(_E, 4);
|
||||
var _E5 = Math.pow(_E, 5);
|
||||
|
||||
var M1 = 1 - E / 4 - 3 * E2 / 64 - 5 * E3 / 256;
|
||||
var M2 = 3 * E / 8 + 3 * E2 / 32 + 45 * E3 / 1024;
|
||||
var M3 = 15 * E2 / 256 + 45 * E3 / 1024;
|
||||
var M4 = 35 * E3 / 3072;
|
||||
|
||||
var P2 = 3 / 2 * _E - 27 / 32 * _E3 + 269 / 512 * _E5;
|
||||
var P3 = 21 / 16 * _E2 - 55 / 32 * _E4;
|
||||
var P4 = 151 / 96 * _E3 - 417 / 128 * _E5;
|
||||
var P5 = 1097 / 512 * _E4;
|
||||
|
||||
var R = 6378137;
|
||||
|
||||
var ZONE_LETTERS = 'CDEFGHJKLMNPQRSTUVWXX';
|
||||
|
||||
function toLatLon(easting, northing, zoneNum, zoneLetter, northern, strict) {
|
||||
strict = strict !== undefined ? strict : true;
|
||||
|
||||
if (!zoneLetter && northern === undefined) {
|
||||
throw new Error('either zoneLetter or northern needs to be set');
|
||||
} else if (zoneLetter && northern !== undefined) {
|
||||
throw new Error('set either zoneLetter or northern, but not both');
|
||||
}
|
||||
|
||||
if (strict) {
|
||||
if (easting < 100000 || 1000000 <= easting) {
|
||||
throw new RangeError('easting out of range (must be between 100 000 m and 999 999 m)');
|
||||
}
|
||||
if (northing < 0 || northing > 10000000) {
|
||||
throw new RangeError('northing out of range (must be between 0 m and 10 000 000 m)');
|
||||
}
|
||||
}
|
||||
if (zoneNum < 1 || zoneNum > 60) {
|
||||
throw new RangeError('zone number out of range (must be between 1 and 60)');
|
||||
}
|
||||
if (zoneLetter) {
|
||||
zoneLetter = zoneLetter.toUpperCase();
|
||||
if (zoneLetter.length !== 1 || ZONE_LETTERS.indexOf(zoneLetter) === -1) {
|
||||
throw new RangeError('zone letter out of range (must be between C and X)');
|
||||
}
|
||||
northern = zoneLetter >= 'N';
|
||||
}
|
||||
|
||||
var x = easting - 500000;
|
||||
var y = northing;
|
||||
|
||||
if (!northern) y -= 1e7;
|
||||
|
||||
var m = y / K0;
|
||||
var mu = m / (R * M1);
|
||||
|
||||
var pRad = mu +
|
||||
P2 * Math.sin(2 * mu) +
|
||||
P3 * Math.sin(4 * mu) +
|
||||
P4 * Math.sin(6 * mu) +
|
||||
P5 * Math.sin(8 * mu);
|
||||
|
||||
var pSin = Math.sin(pRad);
|
||||
var pSin2 = Math.pow(pSin, 2);
|
||||
|
||||
var pCos = Math.cos(pRad);
|
||||
|
||||
var pTan = Math.tan(pRad);
|
||||
var pTan2 = Math.pow(pTan, 2);
|
||||
var pTan4 = Math.pow(pTan, 4);
|
||||
|
||||
var epSin = 1 - E * pSin2;
|
||||
var epSinSqrt = Math.sqrt(epSin);
|
||||
|
||||
var n = R / epSinSqrt;
|
||||
var r = (1 - E) / epSin;
|
||||
|
||||
var c = _E * pCos * pCos;
|
||||
var c2 = c * c;
|
||||
|
||||
var d = x / (n * K0);
|
||||
var d2 = Math.pow(d, 2);
|
||||
var d3 = Math.pow(d, 3);
|
||||
var d4 = Math.pow(d, 4);
|
||||
var d5 = Math.pow(d, 5);
|
||||
var d6 = Math.pow(d, 6);
|
||||
|
||||
var latitude = pRad - (pTan / r) *
|
||||
(d2 / 2 -
|
||||
d4 / 24 * (5 + 3 * pTan2 + 10 * c - 4 * c2 - 9 * E_P2)) +
|
||||
d6 / 720 * (61 + 90 * pTan2 + 298 * c + 45 * pTan4 - 252 * E_P2 - 3 * c2);
|
||||
var longitude = (d -
|
||||
d3 / 6 * (1 + 2 * pTan2 + c) +
|
||||
d5 / 120 * (5 - 2 * c + 28 * pTan2 - 3 * c2 + 8 * E_P2 + 24 * pTan4)) / pCos;
|
||||
|
||||
return {
|
||||
latitude: toDegrees(latitude),
|
||||
longitude: toDegrees(longitude) + zoneNumberToCentralLongitude(zoneNum)
|
||||
};
|
||||
}
|
||||
|
||||
function fromLatLon(latitude, longitude, forceZoneNum) {
|
||||
if (latitude > 84 || latitude < -80) {
|
||||
throw new RangeError('latitude out of range (must be between 80 deg S and 84 deg N)');
|
||||
}
|
||||
if (longitude > 180 || longitude < -180) {
|
||||
throw new RangeError('longitude out of range (must be between 180 deg W and 180 deg E)');
|
||||
}
|
||||
|
||||
var latRad = toRadians(latitude);
|
||||
var latSin = Math.sin(latRad);
|
||||
var latCos = Math.cos(latRad);
|
||||
|
||||
var latTan = Math.tan(latRad);
|
||||
var latTan2 = Math.pow(latTan, 2);
|
||||
var latTan4 = Math.pow(latTan, 4);
|
||||
|
||||
var zoneNum;
|
||||
|
||||
if (forceZoneNum === undefined) {
|
||||
zoneNum = latLonToZoneNumber(latitude, longitude);
|
||||
} else {
|
||||
zoneNum = forceZoneNum;
|
||||
}
|
||||
|
||||
var zoneLetter = latitudeToZoneLetter(latitude);
|
||||
|
||||
var lonRad = toRadians(longitude);
|
||||
var centralLon = zoneNumberToCentralLongitude(zoneNum);
|
||||
var centralLonRad = toRadians(centralLon);
|
||||
|
||||
var n = R / Math.sqrt(1 - E * latSin * latSin);
|
||||
var c = E_P2 * latCos * latCos;
|
||||
|
||||
var a = latCos * (lonRad - centralLonRad);
|
||||
var a2 = Math.pow(a, 2);
|
||||
var a3 = Math.pow(a, 3);
|
||||
var a4 = Math.pow(a, 4);
|
||||
var a5 = Math.pow(a, 5);
|
||||
var a6 = Math.pow(a, 6);
|
||||
|
||||
var m = R * (M1 * latRad -
|
||||
M2 * Math.sin(2 * latRad) +
|
||||
M3 * Math.sin(4 * latRad) -
|
||||
M4 * Math.sin(6 * latRad));
|
||||
var easting = K0 * n * (a +
|
||||
a3 / 6 * (1 - latTan2 + c) +
|
||||
a5 / 120 * (5 - 18 * latTan2 + latTan4 + 72 * c - 58 * E_P2)) + 500000;
|
||||
var northing = K0 * (m + n * latTan * (a2 / 2 +
|
||||
a4 / 24 * (5 - latTan2 + 9 * c + 4 * c * c) +
|
||||
a6 / 720 * (61 - 58 * latTan2 + latTan4 + 600 * c - 330 * E_P2)));
|
||||
if (latitude < 0) northing += 1e7;
|
||||
|
||||
return {
|
||||
easting: easting,
|
||||
northing: northing,
|
||||
zoneNum: zoneNum,
|
||||
zoneLetter: zoneLetter
|
||||
};
|
||||
}
|
||||
|
||||
function latitudeToZoneLetter(latitude) {
|
||||
if (-80 <= latitude && latitude <= 84) {
|
||||
return ZONE_LETTERS[Math.floor((latitude + 80) / 8)];
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
function latLonToZoneNumber(latitude, longitude) {
|
||||
if (56 <= latitude && latitude < 64 && 3 <= longitude && longitude < 12) return 32;
|
||||
|
||||
if (72 <= latitude && latitude <= 84 && longitude >= 0) {
|
||||
if (longitude < 9) return 31;
|
||||
if (longitude < 21) return 33;
|
||||
if (longitude < 33) return 35;
|
||||
if (longitude < 42) return 37;
|
||||
}
|
||||
|
||||
return Math.floor((longitude + 180) / 6) + 1;
|
||||
}
|
||||
|
||||
function zoneNumberToCentralLongitude(zoneNum) {
|
||||
return (zoneNum - 1) * 6 - 180 + 3;
|
||||
}
|
||||
|
||||
function toDegrees(rad) {
|
||||
return rad / Math.PI * 180;
|
||||
}
|
||||
|
||||
function toRadians(deg) {
|
||||
return deg * Math.PI / 180;
|
||||
}
|
||||
|
||||
exports.toLatLon = toLatLon;
|
||||
exports.fromLatLon = fromLatLon;
|
||||
+63
@@ -0,0 +1,63 @@
|
||||
{
|
||||
"_args": [
|
||||
[
|
||||
"utm@1.1.1",
|
||||
"/shd/CTC/TOOLS/TDS/TDS-source/Lts/Tools/ArAssetsV2"
|
||||
]
|
||||
],
|
||||
"_development": true,
|
||||
"_from": "utm@1.1.1",
|
||||
"_id": "utm@1.1.1",
|
||||
"_inBundle": false,
|
||||
"_integrity": "sha512-rJIv6i1u86OVy91Burh/6oRFfE8zOCd6Unc8fvA0N7fjQT43ogqhVeUp5NByaZPe278QyiA5wMMEaAU9Jx6QRA==",
|
||||
"_location": "/utm",
|
||||
"_phantomChildren": {},
|
||||
"_requested": {
|
||||
"type": "version",
|
||||
"registry": true,
|
||||
"raw": "utm@1.1.1",
|
||||
"name": "utm",
|
||||
"escapedName": "utm",
|
||||
"rawSpec": "1.1.1",
|
||||
"saveSpec": null,
|
||||
"fetchSpec": "1.1.1"
|
||||
},
|
||||
"_requiredBy": [
|
||||
"#DEV:/"
|
||||
],
|
||||
"_resolved": "https://registry.npmjs.org/utm/-/utm-1.1.1.tgz",
|
||||
"_spec": "1.1.1",
|
||||
"_where": "/shd/CTC/TOOLS/TDS/TDS-source/Lts/Tools/ArAssetsV2",
|
||||
"author": {
|
||||
"name": "Timothy Gu",
|
||||
"email": "timothygu99@gmail.com"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/timothygu/utm/issues"
|
||||
},
|
||||
"description": "Bidirectional UTM-WGS84 converter",
|
||||
"devDependencies": {
|
||||
"chai": "^4.0.2",
|
||||
"rollup": "^0.43.0",
|
||||
"testit": "^2.1.2"
|
||||
},
|
||||
"homepage": "https://github.com/timothygu/utm#readme",
|
||||
"jsnext:main": "index.es.js",
|
||||
"keywords": [
|
||||
"utm",
|
||||
"latlon"
|
||||
],
|
||||
"license": "MIT",
|
||||
"main": "index.js",
|
||||
"module": "index.es.js",
|
||||
"name": "utm",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/timothygu/utm.git"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "rollup -o index.js -f cjs index.es.js",
|
||||
"test": "npm run build && node test.js"
|
||||
},
|
||||
"version": "1.1.1"
|
||||
}
|
||||
+244
@@ -0,0 +1,244 @@
|
||||
const testit = require('testit');
|
||||
const { fromLatLon, toLatLon } = require('.');
|
||||
const { expect } = require('chai');
|
||||
|
||||
// Arbitrary
|
||||
const DELTA = 3e-5;
|
||||
|
||||
testit('normal conversions', () => {
|
||||
for (const [
|
||||
name,
|
||||
[lat, lon],
|
||||
[easting, northing, zoneNum, zoneLetter, northern]
|
||||
] of [
|
||||
[
|
||||
'Aachen, Germany',
|
||||
[50.77535, 6.08389],
|
||||
[294409, 5628898, 32, 'U', true]
|
||||
],
|
||||
[
|
||||
'New York, USA',
|
||||
[40.71435, -74.00597],
|
||||
[583960, 4507523, 18, 'T', true]
|
||||
],
|
||||
[
|
||||
'Wellington, New Zealand',
|
||||
[-41.28646, 174.77624],
|
||||
[313784, 5427057, 60, 'G', false]
|
||||
],
|
||||
[
|
||||
'Capetown, South Africa',
|
||||
[-33.92487, 18.42406],
|
||||
[261878, 6243186, 34, 'H', false]
|
||||
],
|
||||
[
|
||||
'Mendoza, Argentina',
|
||||
[-32.89018, -68.84405],
|
||||
[514586, 6360877, 19, 'h', false]
|
||||
],
|
||||
[
|
||||
'Fairbanks, Alaska, USA',
|
||||
[64.83778, -147.71639],
|
||||
[466013, 7190568, 6, 'W', true]
|
||||
],
|
||||
[
|
||||
'Ben Nevis, Scotland, UK',
|
||||
[56.79680, -5.00601],
|
||||
[377486, 6296562, 30, 'V', true]
|
||||
],
|
||||
[
|
||||
'Latitude 84',
|
||||
[84, -5.00601],
|
||||
[476594, 9328501, 30, 'X', true]
|
||||
]
|
||||
]) {
|
||||
testit(`${name} fromLatLon`, () => {
|
||||
check(fromLatLon(lat, lon));
|
||||
check(fromLatLon(lat, lon, zoneNum));
|
||||
|
||||
function check(actual) {
|
||||
expect(actual.easting).to.be.closeTo(easting, 0.5);
|
||||
expect(actual.northing).to.be.closeTo(northing, 0.5);
|
||||
expect(actual.zoneNum).to.equal(zoneNum);
|
||||
expect(actual.zoneLetter).to.equal(zoneLetter.toUpperCase());
|
||||
}
|
||||
});
|
||||
|
||||
testit(`${name} toLatLon`, () => {
|
||||
check(toLatLon(easting, northing, zoneNum, zoneLetter));
|
||||
check(toLatLon(easting, northing, zoneNum, undefined, northern));
|
||||
|
||||
function check(actual) {
|
||||
expect(actual.latitude).to.be.closeTo(lat, DELTA);
|
||||
expect(actual.longitude).to.be.closeTo(lon, DELTA);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
testit('range check', () => {
|
||||
testit('fromLatLon bad range', () => {
|
||||
for (const args of [
|
||||
[-100, 0],
|
||||
[-80.1, 0],
|
||||
[84.1, 0],
|
||||
[100, 0],
|
||||
[0, -300],
|
||||
[0, -180.1],
|
||||
[0, 180.1],
|
||||
[0, 300],
|
||||
[-100, -300],
|
||||
[100, -300],
|
||||
[-100, 300],
|
||||
[100, 300]
|
||||
]) {
|
||||
expect(() => fromLatLon(...args)).to.throw(RangeError);
|
||||
}
|
||||
});
|
||||
|
||||
testit('fromLatLon good range', () => {
|
||||
for (const i of range(-80, 84, 0.01)) {
|
||||
fromLatLon(i, 0);
|
||||
}
|
||||
for (const i of range(-180, 180, 0.01)) {
|
||||
fromLatLon(0, i);
|
||||
}
|
||||
});
|
||||
|
||||
testit('toLatLon bad range', () => {
|
||||
for (const args of [
|
||||
// test easting range
|
||||
[0, 5000000, 32, 'U'],
|
||||
[99999, 5000000, 32, 'U'],
|
||||
[1000000, 5000000, 32, 'U'],
|
||||
[100000000000, 5000000, 32, 'U'],
|
||||
|
||||
// test northing range
|
||||
[500000, -100000, 32, 'U'],
|
||||
[500000, -1, 32, 'U'],
|
||||
[500000, 10000001, 32, 'U'],
|
||||
[500000, 50000000, 32, 'U'],
|
||||
|
||||
// test zone numbers
|
||||
[500000, 5000000, 0, 'U'],
|
||||
[500000, 5000000, 61, 'U'],
|
||||
[500000, 5000000, 1000, 'U'],
|
||||
|
||||
// test zone letters
|
||||
[500000, 5000000, 32, 'A'],
|
||||
[500000, 5000000, 32, 'B'],
|
||||
[500000, 5000000, 32, 'I'],
|
||||
[500000, 5000000, 32, 'O'],
|
||||
[500000, 5000000, 32, 'Y'],
|
||||
[500000, 5000000, 32, 'Z']
|
||||
]) {
|
||||
expect(() => toLatLon(...args)).to.throw(RangeError);
|
||||
}
|
||||
});
|
||||
|
||||
testit('toLatLon good range', () => {
|
||||
for (const i of range(100000, 999999, 1000)) {
|
||||
toLatLon(i, 5000000, 32, 'U');
|
||||
}
|
||||
for (const i of range(10, 10000000, 1000)) {
|
||||
toLatLon(500000, i, 32, 'U');
|
||||
}
|
||||
for (const i of range(1, 60)) {
|
||||
toLatLon(500000, 5000000, i, 'U');
|
||||
}
|
||||
for (const i of range('C'.codePointAt(0), 'X'.codePointAt(0) + 1)) {
|
||||
const ch = String.fromCodePoint(i);
|
||||
if (ch !== 'I' && ch !== 'O') {
|
||||
toLatLon(500000, 5000000, 32, ch);
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
testit('special cases', () => {
|
||||
testit('zone 32', () => {
|
||||
for (const [lat, lon, zoneNum, zoneLetter] of [
|
||||
// inside
|
||||
[56, 3, 32, 'V'],
|
||||
[56, 6, 32, 'V'],
|
||||
[56, 9, 32, 'V'],
|
||||
[56, 11.999999, 32, 'V'],
|
||||
|
||||
[60, 3, 32, 'V'],
|
||||
[60, 6, 32, 'V'],
|
||||
[60, 9, 32, 'V'],
|
||||
[60, 11.999999, 32, 'V'],
|
||||
|
||||
[63.999999, 3, 32, 'V'],
|
||||
[63.999999, 6, 32, 'V'],
|
||||
[63.999999, 9, 32, 'V'],
|
||||
[63.999999, 11.999999, 32, 'V'],
|
||||
|
||||
// left of
|
||||
[55.999999, 2.999999, 31, 'U'],
|
||||
[56, 2.999999, 31, 'V'],
|
||||
[60, 2.999999, 31, 'V'],
|
||||
[63.999999, 2.999999, 31, 'V'],
|
||||
[64, 2.999999, 31, 'W'],
|
||||
|
||||
// right of
|
||||
[55.999999, 12, 33, 'U'],
|
||||
[56, 12, 33, 'V'],
|
||||
[60, 12, 33, 'V'],
|
||||
[63.999999, 12, 33, 'V'],
|
||||
[64, 12, 33, 'W'],
|
||||
|
||||
// below
|
||||
[55.999999, 3, 31, 'U'],
|
||||
[55.999999, 6, 32, 'U'],
|
||||
[55.999999, 9, 32, 'U'],
|
||||
[55.999999, 11.999999, 32, 'U'],
|
||||
[55.999999, 12, 33, 'U'],
|
||||
|
||||
// above
|
||||
[64, 3, 31, 'W'],
|
||||
[64, 6, 32, 'W'],
|
||||
[64, 9, 32, 'W'],
|
||||
[64, 11.999999, 32, 'W'],
|
||||
[64, 12, 33, 'W']
|
||||
]) {
|
||||
const results = fromLatLon(lat, lon);
|
||||
expect(results.zoneNum).to.equal(zoneNum);
|
||||
expect(results.zoneLetter).to.equal(zoneLetter.toUpperCase());
|
||||
}
|
||||
});
|
||||
|
||||
testit('right boundaries', () => {
|
||||
for (const [lat, lon, zoneNum] of [
|
||||
[40, 0, 31],
|
||||
[40, 5.999999, 31],
|
||||
[40, 6, 32],
|
||||
|
||||
[72, 0, 31],
|
||||
[72, 5.999999, 31],
|
||||
[72, 6, 31],
|
||||
[72, 8.999999, 31],
|
||||
[72, 9, 33]
|
||||
]) {
|
||||
const results = fromLatLon(lat, lon);
|
||||
expect(results.zoneNum).to.equal(zoneNum);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
function* range(start, stop, step = 1) {
|
||||
if (arguments.length === 1) {
|
||||
stop = start;
|
||||
start = 0;
|
||||
}
|
||||
|
||||
if (step === 0) {
|
||||
throw new RangeError('step must not be zero');
|
||||
}
|
||||
|
||||
let cur = start;
|
||||
while (step > 0 ? cur < stop : cur > stop) {
|
||||
yield cur;
|
||||
cur += step;
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user