node-geometry-library
Advanced tools
Comparing version 1.1.1 to 1.2.0
@@ -1,2 +0,2 @@ | ||
import {SphericalUtil, PolyUtil} from "./src"; | ||
import {SphericalUtil, PolyUtil} from "./lib"; | ||
@@ -3,0 +3,0 @@ const example1 = SphericalUtil.computeHeading( |
@@ -1,31 +0,3 @@ | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { | ||
value: true | ||
}); | ||
Object.defineProperty(exports, "MathUtil", { | ||
enumerable: true, | ||
get: function get() { | ||
return _MathUtil["default"]; | ||
} | ||
}); | ||
Object.defineProperty(exports, "SphericalUtil", { | ||
enumerable: true, | ||
get: function get() { | ||
return _SphericalUtil["default"]; | ||
} | ||
}); | ||
Object.defineProperty(exports, "PolyUtil", { | ||
enumerable: true, | ||
get: function get() { | ||
return _PolyUtil["default"]; | ||
} | ||
}); | ||
var _MathUtil = _interopRequireDefault(require("./MathUtil")); | ||
var _SphericalUtil = _interopRequireDefault(require("./SphericalUtil")); | ||
var _PolyUtil = _interopRequireDefault(require("./PolyUtil")); | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } | ||
export { default as SphericalUtil } from "./SphericalUtil"; | ||
export { default as PolyUtil } from "./PolyUtil"; | ||
export { default as MathUtil } from "./MathUtil"; |
@@ -1,14 +0,1 @@ | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { | ||
value: true | ||
}); | ||
exports["default"] = void 0; | ||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } | ||
function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } | ||
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; } | ||
/* | ||
@@ -29,27 +16,23 @@ * Copyright 2013 Google Inc. | ||
*/ | ||
var log = Math.log, | ||
tan = Math.tan, | ||
atan = Math.atan, | ||
exp = Math.exp, | ||
sin = Math.sin, | ||
asin = Math.asin, | ||
sqrt = Math.sqrt, | ||
cos = Math.cos; | ||
var MathUtil = | ||
/*#__PURE__*/ | ||
function () { | ||
function MathUtil() { | ||
_classCallCheck(this, MathUtil); | ||
} | ||
_createClass(MathUtil, null, [{ | ||
key: "clamp", | ||
var log = Math.log, tan = Math.tan, atan = Math.atan, exp = Math.exp, sin = Math.sin, asin = Math.asin, sqrt = Math.sqrt, cos = Math.cos, PI = Math.PI; | ||
var MathUtil = /** @class */ (function () { | ||
function MathUtil() { | ||
} | ||
Object.defineProperty(MathUtil, "EARTH_RADIUS", { | ||
/** | ||
* The earth's radius, in meters. | ||
* Mean radius as defined by IUGG. | ||
*/ | ||
get: function () { | ||
return 6371009; | ||
}, | ||
enumerable: false, | ||
configurable: true | ||
}); | ||
/** | ||
* Restrict x to the range [low, high]. | ||
*/ | ||
value: function clamp(x, low, high) { | ||
return x < low ? low : x > high ? high : x; | ||
} | ||
MathUtil.clamp = function (x, low, high) { | ||
return x < low ? low : x > high ? high : x; | ||
}; | ||
/** | ||
@@ -61,8 +44,5 @@ * Wraps the given value into the inclusive-exclusive interval between min and max. | ||
*/ | ||
}, { | ||
key: "wrap", | ||
value: function wrap(n, min, max) { | ||
return n >= min && n < max ? n : MathUtil.mod(n - min, max - min) + min; | ||
} | ||
MathUtil.wrap = function (n, min, max) { | ||
return n >= min && n < max ? n : MathUtil.mod(n - min, max - min) + min; | ||
}; | ||
/** | ||
@@ -73,8 +53,5 @@ * Returns the non-negative remainder of x / m. | ||
*/ | ||
}, { | ||
key: "mod", | ||
value: function mod(x, m) { | ||
return (x % m + m) % m; | ||
} | ||
MathUtil.mod = function (x, m) { | ||
return ((x % m) + m) % m; | ||
}; | ||
/** | ||
@@ -84,17 +61,11 @@ * Returns mercator Y corresponding to latitude. | ||
*/ | ||
}, { | ||
key: "mercator", | ||
value: function mercator(lat) { | ||
return log(tan(lat * 0.5 + M_PI / 4)); | ||
} | ||
MathUtil.mercator = function (lat) { | ||
return log(tan(lat * 0.5 + PI / 4)); | ||
}; | ||
/** | ||
* Returns latitude from mercator Y. | ||
*/ | ||
}, { | ||
key: "inverseMercator", | ||
value: function inverseMercator(y) { | ||
return 2 * atan(exp(y)) - M_PI / 2; | ||
} | ||
MathUtil.inverseMercator = function (y) { | ||
return 2 * atan(exp(y)) - PI / 2; | ||
}; | ||
/** | ||
@@ -104,9 +75,6 @@ * Returns haversine(angle-in-radians). | ||
*/ | ||
}, { | ||
key: "hav", | ||
value: function hav(x) { | ||
var sinHalf = sin(x * 0.5); | ||
return sinHalf * sinHalf; | ||
} | ||
MathUtil.hav = function (x) { | ||
var sinHalf = sin(x * 0.5); | ||
return sinHalf * sinHalf; | ||
}; | ||
/** | ||
@@ -117,54 +85,28 @@ * Computes inverse haversine. Has good numerical stability around 0. | ||
*/ | ||
}, { | ||
key: "arcHav", | ||
value: function arcHav(x) { | ||
return 2 * asin(sqrt(x)); | ||
} // Given h==hav(x), returns sin(abs(x)). | ||
}, { | ||
key: "sinFromHav", | ||
value: function sinFromHav(h) { | ||
return 2 * sqrt(h * (1 - h)); | ||
} // Returns hav(asin(x)). | ||
}, { | ||
key: "havFromSin", | ||
value: function havFromSin(x) { | ||
var x2 = x * x; | ||
return x2 / (1 + sqrt(1 - x2)) * 0.5; | ||
} // Returns sin(arcHav(x) + arcHav(y)). | ||
}, { | ||
key: "sinSumFromHav", | ||
value: function sinSumFromHav(x, y) { | ||
var a = sqrt(x * (1 - x)); | ||
var b = sqrt(y * (1 - y)); | ||
return 2 * (a + b - 2 * (a * y + b * x)); | ||
} | ||
MathUtil.arcHav = function (x) { | ||
return 2 * asin(sqrt(x)); | ||
}; | ||
// Given h==hav(x), returns sin(abs(x)). | ||
MathUtil.sinFromHav = function (h) { | ||
return 2 * sqrt(h * (1 - h)); | ||
}; | ||
// Returns hav(asin(x)). | ||
MathUtil.havFromSin = function (x) { | ||
var x2 = x * x; | ||
return (x2 / (1 + sqrt(1 - x2))) * 0.5; | ||
}; | ||
// Returns sin(arcHav(x) + arcHav(y)). | ||
MathUtil.sinSumFromHav = function (x, y) { | ||
var a = sqrt(x * (1 - x)); | ||
var b = sqrt(y * (1 - y)); | ||
return 2 * (a + b - 2 * (a * y + b * x)); | ||
}; | ||
/** | ||
* Returns hav() of distance from (lat1, lng1) to (lat2, lng2) on the unit sphere. | ||
*/ | ||
}, { | ||
key: "havDistance", | ||
value: function havDistance(lat1, lat2, dLng) { | ||
return MathUtil.hav(lat1 - lat2) + MathUtil.hav(dLng) * cos(lat1) * cos(lat2); | ||
} | ||
}, { | ||
key: "EARTH_RADIUS", | ||
/** | ||
* The earth's radius, in meters. | ||
* Mean radius as defined by IUGG. | ||
*/ | ||
get: function get() { | ||
return 6371009; | ||
} | ||
}]); | ||
return MathUtil; | ||
}(); | ||
var _default = MathUtil; | ||
exports["default"] = _default; | ||
MathUtil.havDistance = function (lat1, lat2, dLng) { | ||
return (MathUtil.hav(lat1 - lat2) + MathUtil.hav(dLng) * cos(lat1) * cos(lat2)); | ||
}; | ||
return MathUtil; | ||
}()); | ||
export default MathUtil; |
@@ -1,81 +0,63 @@ | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { | ||
value: true | ||
}); | ||
exports["default"] = void 0; | ||
var _MathUtil = _interopRequireDefault(require("./MathUtil")); | ||
var _SphericalUtil = _interopRequireWildcard(require("./SphericalUtil")); | ||
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {}; if (desc.get || desc.set) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } } newObj["default"] = obj; return newObj; } } | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } | ||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } | ||
function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } | ||
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; } | ||
function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); } | ||
var log = Math.log, | ||
atan = Math.atan, | ||
atan2 = Math.atan2, | ||
cos = Math.cos, | ||
sin = Math.sin, | ||
asin = Math.asin, | ||
sqrt = Math.sqrt, | ||
abs = Math.abs, | ||
round = Math.round; | ||
/* | ||
* Copyright 2013 Google Inc. | ||
* | ||
* https://github.com/googlemaps/android-maps-utils/blob/master/library/src/com/google/maps/android/PolyUtil.java | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
import MathUtil from "./MathUtil"; | ||
import SphericalUtil, { deg2rad } from "./SphericalUtil"; | ||
var max = Math.max, min = Math.min, tan = Math.tan, cos = Math.cos, sin = Math.sin, sqrt = Math.sqrt, round = Math.round; | ||
var DEFAULT_TOLERANCE = 0.1; // meters. | ||
function ord(str) { | ||
return str.charCodeAt(0); | ||
return str.charCodeAt(0); | ||
} | ||
function chr(codePt) { | ||
if (codePt > 0xffff) { | ||
codePt -= 0x10000; | ||
return String.fromCharCode(0xd800 + (codePt >> 10), 0xdc00 + (codePt & 0x3ff)); | ||
} | ||
return String.fromCharCode(codePt); | ||
if (codePt > 0xffff) { | ||
codePt -= 0x10000; | ||
return String.fromCharCode(0xd800 + (codePt >> 10), 0xdc00 + (codePt & 0x3ff)); | ||
} | ||
return String.fromCharCode(codePt); | ||
} | ||
function hexdec(hexString) { | ||
hexString = hexString.charAt(1) != "X" && hexString.charAt(1) != "x" ? hexString = "0X" + hexString : hexString; | ||
hexString = hexString.charAt(2) < 8 ? hexString = hexString - 0x00000000 : hexString = hexString - 0xffffffff - 1; | ||
return parseInt(hexString, 10); | ||
hexString = | ||
hexString.charAt(1) != "X" && hexString.charAt(1) != "x" | ||
? (hexString = "0X" + hexString) | ||
: hexString; | ||
hexString = | ||
hexString.charAt(2) < 8 | ||
? (hexString = hexString - 0x00000000) | ||
: (hexString = hexString - 0xffffffff - 1); | ||
return parseInt(hexString, 10); | ||
} | ||
function isEmpty(value) { | ||
return value === undefined || value === null || _typeof(value) === "object" && Object.keys(value).length === 0 || typeof value === "string" && value.trim().length === 0; | ||
} | ||
function enc(v) { | ||
v = v < 0 ? ~(v << 1) : v << 1; | ||
var result = ""; | ||
while (v >= 0x20) { | ||
result = result + chr(Number((0x20 | v & 0x1f) + 63)); | ||
v >>= 5; | ||
} | ||
result = result + chr(Number(v + 63)); | ||
return result; | ||
v = v < 0 ? ~(v << 1) : v << 1; | ||
var result = ""; | ||
while (v >= 0x20) { | ||
result = result + chr(Number((0x20 | (v & 0x1f)) + 63)); | ||
v >>= 5; | ||
} | ||
result = result + chr(Number(v + 63)); | ||
return result; | ||
} | ||
var PolyUtil = | ||
/*#__PURE__*/ | ||
function () { | ||
function PolyUtil() { | ||
_classCallCheck(this, PolyUtil); | ||
} | ||
_createClass(PolyUtil, null, [{ | ||
key: "tanLatGC", | ||
var PolyUtil = /** @class */ (function () { | ||
function PolyUtil() { | ||
} | ||
Object.defineProperty(PolyUtil, "DEFAULT_TOLERANCE", { | ||
get: function () { | ||
return DEFAULT_TOLERANCE; | ||
}, | ||
enumerable: false, | ||
configurable: true | ||
}); | ||
/** | ||
@@ -85,14 +67,13 @@ * Returns tan(latitude-at-lng3) on the great circle (lat1, lng1) to (lat2, lng2). lng1==0. | ||
*/ | ||
value: function tanLatGC(lat1, lat2, lng2, lng3) { | ||
return (tan(lat1) * sin(lng2 - lng3) + tan(lat2) * sin(lng3)) / sin(lng2); | ||
} | ||
PolyUtil.tanLatGC = function (lat1, lat2, lng2, lng3) { | ||
return (tan(lat1) * sin(lng2 - lng3) + tan(lat2) * sin(lng3)) / sin(lng2); | ||
}; | ||
/** | ||
* Returns mercator(latitude-at-lng3) on the Rhumb line (lat1, lng1) to (lat2, lng2). lng1==0. | ||
*/ | ||
}, { | ||
key: "mercatorLatRhumb", | ||
value: function mercatorLatRhumb(lat1, lat2, lng2, lng3) { | ||
return (_MathUtil["default"].mercator(lat1) * (lng2 - lng3) + _MathUtil["default"].mercator(lat2) * lng3) / lng2; | ||
} | ||
PolyUtil.mercatorLatRhumb = function (lat1, lat2, lng2, lng3) { | ||
return ((MathUtil.mercator(lat1) * (lng2 - lng3) + | ||
MathUtil.mercator(lat2) * lng3) / | ||
lng2); | ||
}; | ||
/** | ||
@@ -103,45 +84,41 @@ * Computes whether the vertical segment (lat3, lng3) to South Pole intersects the segment | ||
*/ | ||
}, { | ||
key: "intersects", | ||
value: function intersects(lat1, lat2, lng2, lat3, lng3, geodesic) { | ||
// Both ends on the same side of lng3. | ||
if (lng3 >= 0 && lng3 >= lng2 || lng3 < 0 && lng3 < lng2) { | ||
return false; | ||
} // Point is South Pole. | ||
if (lat3 <= -Math.PI / 2) { | ||
return false; | ||
} // Any segment end is a pole. | ||
if (lat1 <= -Math.PI / 2 || lat2 <= -Math.PI / 2 || lat1 >= Math.PI / 2 || lat2 >= Math.PI / 2) { | ||
return false; | ||
} | ||
if (lng2 <= -Math.PI) { | ||
return false; | ||
} | ||
var linearLat = (lat1 * (lng2 - lng3) + lat2 * lng3) / lng2; // Northern hemisphere and point under lat-lng line. | ||
if (lat1 >= 0 && lat2 >= 0 && lat3 < linearLat) { | ||
return false; | ||
} // Southern hemisphere and point above lat-lng line. | ||
if (lat1 <= 0 && lat2 <= 0 && lat3 >= linearLat) { | ||
return true; | ||
} // North Pole. | ||
if (lat3 >= -Math.PI / 2) { | ||
return true; | ||
} // Compare lat3 with latitude on the GC/Rhumb segment corresponding to lng3. | ||
// Compare through a strictly-increasing function (tan() or mercator()) as convenient. | ||
return geodesic ? tan(lat3) >= PolyUtil.tanLatGC(lat1, lat2, lng2, lng3) : _MathUtil["default"].mercator(lat3) >= PolyUtil.mercatorLatRhumb(lat1, lat2, lng2, lng3); | ||
} | ||
PolyUtil.intersects = function (lat1, lat2, lng2, lat3, lng3, geodesic) { | ||
// Both ends on the same side of lng3. | ||
if ((lng3 >= 0 && lng3 >= lng2) || (lng3 < 0 && lng3 < lng2)) { | ||
return false; | ||
} | ||
// Point is South Pole. | ||
if (lat3 <= -Math.PI / 2) { | ||
return false; | ||
} | ||
// Any segment end is a pole. | ||
if (lat1 <= -Math.PI / 2 || | ||
lat2 <= -Math.PI / 2 || | ||
lat1 >= Math.PI / 2 || | ||
lat2 >= Math.PI / 2) { | ||
return false; | ||
} | ||
if (lng2 <= -Math.PI) { | ||
return false; | ||
} | ||
var linearLat = (lat1 * (lng2 - lng3) + lat2 * lng3) / lng2; | ||
// Northern hemisphere and point under lat-lng line. | ||
if (lat1 >= 0 && lat2 >= 0 && lat3 < linearLat) { | ||
return false; | ||
} | ||
// Southern hemisphere and point above lat-lng line. | ||
if (lat1 <= 0 && lat2 <= 0 && lat3 >= linearLat) { | ||
return true; | ||
} | ||
// North Pole. | ||
if (lat3 >= -Math.PI / 2) { | ||
return true; | ||
} | ||
// Compare lat3 with latitude on the GC/Rhumb segment corresponding to lng3. | ||
// Compare through a strictly-increasing function (tan() or mercator()) as convenient. | ||
return geodesic | ||
? tan(lat3) >= PolyUtil.tanLatGC(lat1, lat2, lng2, lng3) | ||
: MathUtil.mercator(lat3) >= | ||
PolyUtil.mercatorLatRhumb(lat1, lat2, lng2, lng3); | ||
}; | ||
/** | ||
@@ -155,39 +132,32 @@ * Computes whether the given point lies inside the specified polygon. | ||
*/ | ||
}, { | ||
key: "containsLocation", | ||
value: function containsLocation(point, polygon) { | ||
var geodesic = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false; | ||
var size = polygon.length; | ||
if (size == 0) { | ||
return false; | ||
} | ||
var lat3 = (0, _SphericalUtil.deg2rad)(point["lat"]); | ||
var lng3 = (0, _SphericalUtil.deg2rad)(point["lng"]); | ||
var prev = polygon[size - 1]; | ||
var lat1 = (0, _SphericalUtil.deg2rad)(prev["lat"]); | ||
var lng1 = (0, _SphericalUtil.deg2rad)(prev["lng"]); | ||
var nIntersect = 0; | ||
polygon.forEach(function (val) { | ||
var dLng3 = _MathUtil["default"].wrap(lng3 - lng1, -Math.PI, Math.PI); // Special case: point equal to vertex is inside. | ||
if (lat3 == lat1 && dLng3 == 0) { | ||
return true; | ||
PolyUtil.containsLocation = function (point, polygon, geodesic) { | ||
if (geodesic === void 0) { geodesic = false; } | ||
var size = polygon.length; | ||
if (size == 0) { | ||
return false; | ||
} | ||
var lat2 = (0, _SphericalUtil.deg2rad)(val["lat"]); | ||
var lng2 = (0, _SphericalUtil.deg2rad)(val["lng"]); // Offset longitudes by -lng1. | ||
if (PolyUtil.intersects(lat1, lat2, _MathUtil["default"].wrap(lng2 - lng1, -Math.PI, Math.PI), lat3, dLng3, geodesic)) { | ||
++nIntersect; | ||
} | ||
lat1 = lat2; | ||
lng1 = lng2; | ||
}); | ||
return (nIntersect & 1) != 0; | ||
} | ||
var lat3 = deg2rad(point["lat"]); | ||
var lng3 = deg2rad(point["lng"]); | ||
var prev = polygon[size - 1]; | ||
var lat1 = deg2rad(prev["lat"]); | ||
var lng1 = deg2rad(prev["lng"]); | ||
var nIntersect = 0; | ||
// @ts-ignore | ||
polygon.forEach(function (val) { | ||
var dLng3 = MathUtil.wrap(lng3 - lng1, -Math.PI, Math.PI); | ||
// Special case: point equal to vertex is inside. | ||
if (lat3 == lat1 && dLng3 == 0) { | ||
return true; | ||
} | ||
var lat2 = deg2rad(val["lat"]); | ||
var lng2 = deg2rad(val["lng"]); | ||
// Offset longitudes by -lng1. | ||
if (PolyUtil.intersects(lat1, lat2, MathUtil.wrap(lng2 - lng1, -Math.PI, Math.PI), lat3, dLng3, geodesic)) { | ||
++nIntersect; | ||
} | ||
lat1 = lat2; | ||
lng1 = lng2; | ||
}); | ||
return (nIntersect & 1) != 0; | ||
}; | ||
/** | ||
@@ -199,10 +169,7 @@ * Computes whether the given point lies on or near the edge of a polygon, within a specified | ||
*/ | ||
}, { | ||
key: "isLocationOnEdge", | ||
value: function isLocationOnEdge(point, polygon) { | ||
var tolerance = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : DEFAULT_TOLERANCE; | ||
var geodesic = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : true; | ||
return PolyUtil.isLocationOnEdgeOrPath(point, polygon, true, geodesic, tolerance); | ||
} | ||
PolyUtil.isLocationOnEdge = function (point, polygon, tolerance, geodesic) { | ||
if (tolerance === void 0) { tolerance = DEFAULT_TOLERANCE; } | ||
if (geodesic === void 0) { geodesic = true; } | ||
return PolyUtil.isLocationOnEdgeOrPath(point, polygon, true, geodesic, tolerance); | ||
}; | ||
/** | ||
@@ -214,103 +181,81 @@ * Computes whether the given point lies on or near a polyline, within a specified | ||
*/ | ||
}, { | ||
key: "isLocationOnPath", | ||
value: function isLocationOnPath(point, polyline) { | ||
var tolerance = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : DEFAULT_TOLERANCE; | ||
var geodesic = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : true; | ||
return PolyUtil.isLocationOnEdgeOrPath(point, polyline, false, geodesic, tolerance); | ||
} | ||
}, { | ||
key: "isLocationOnEdgeOrPath", | ||
value: function isLocationOnEdgeOrPath(point, poly, closed, geodesic, toleranceEarth) { | ||
var size = poly.length; | ||
if (size == 0) { | ||
return false; | ||
} | ||
var tolerance = toleranceEarth / _MathUtil["default"].EARTH_RADIUS; | ||
var havTolerance = _MathUtil["default"].hav(tolerance); | ||
var lat3 = (0, _SphericalUtil.deg2rad)(point["lat"]); | ||
var lng3 = (0, _SphericalUtil.deg2rad)(point["lng"]); | ||
var prev = !isEmpty(closed) ? poly[size - 1] : 0; | ||
var lat1 = (0, _SphericalUtil.deg2rad)(prev["lat"]); | ||
var lng1 = (0, _SphericalUtil.deg2rad)(prev["lng"]); | ||
if (geodesic) { | ||
for (var i in poly) { | ||
var val = poly[i]; | ||
var lat2 = (0, _SphericalUtil.deg2rad)(val["lat"]); | ||
var lng2 = (0, _SphericalUtil.deg2rad)(val["lng"]); | ||
if (PolyUtil.isOnSegmentGC(lat1, lng1, lat2, lng2, lat3, lng3, havTolerance)) { | ||
return true; | ||
} | ||
lat1 = lat2; | ||
lng1 = lng2; | ||
PolyUtil.isLocationOnPath = function (point, polyline, tolerance, geodesic) { | ||
if (tolerance === void 0) { tolerance = DEFAULT_TOLERANCE; } | ||
if (geodesic === void 0) { geodesic = true; } | ||
return PolyUtil.isLocationOnEdgeOrPath(point, polyline, false, geodesic, tolerance); | ||
}; | ||
PolyUtil.isLocationOnEdgeOrPath = function (point, poly, closed, geodesic, toleranceEarth) { | ||
var size = poly.length; | ||
if (size == 0) { | ||
return false; | ||
} | ||
} else { | ||
// We project the points to mercator space, where the Rhumb segment is a straight line, | ||
// and compute the geodesic distance between point3 and the closest point on the | ||
// segment. This method is an approximation, because it uses "closest" in mercator | ||
// space which is not "closest" on the sphere -- but the error is small because | ||
// "tolerance" is small. | ||
var minAcceptable = lat3 - tolerance; | ||
var maxAcceptable = lat3 + tolerance; | ||
var y1 = _MathUtil["default"].mercator(lat1); | ||
var y3 = _MathUtil["default"].mercator(lat3); | ||
var xTry = []; | ||
for (var _i in poly) { | ||
var _val = poly[_i]; | ||
var _lat = (0, _SphericalUtil.deg2rad)(_val["lat"]); | ||
var y2 = _MathUtil["default"].mercator(_lat); | ||
var _lng = (0, _SphericalUtil.deg2rad)(_val["lng"]); | ||
if (max(lat1, _lat) >= minAcceptable && min(lat1, _lat) <= maxAcceptable) { | ||
// We offset longitudes by -lng1; the implicit x1 is 0. | ||
var x2 = _MathUtil["default"].wrap(_lng - lng1, -Math.PI, Math.PI); | ||
var x3Base = _MathUtil["default"].wrap(lng3 - lng1, -Math.PI, Math.PI); | ||
xTry[0] = x3Base; // Also explore wrapping of x3Base around the world in both directions. | ||
xTry[1] = x3Base + 2 * Math.PI; | ||
xTry[2] = x3Base - 2 * Math.PI; | ||
for (var _i2 in xTry) { | ||
var x3 = xTry[_i2]; | ||
var dy = y2 - y1; | ||
var len2 = x2 * x2 + dy * dy; | ||
var t = len2 <= 0 ? 0 : _MathUtil["default"].clamp((x3 * x2 + (y3 - y1) * dy) / len2, 0, 1); | ||
var xClosest = t * x2; | ||
var yClosest = y1 + t * dy; | ||
var latClosest = _MathUtil["default"].inverseMercator(yClosest); | ||
var havDist = _MathUtil["default"].havDistance(lat3, latClosest, x3 - xClosest); | ||
if (havDist < havTolerance) { | ||
return true; | ||
} | ||
var tolerance = toleranceEarth / MathUtil.EARTH_RADIUS; | ||
var havTolerance = MathUtil.hav(tolerance); | ||
var lat3 = deg2rad(point["lat"]); | ||
var lng3 = deg2rad(point["lng"]); | ||
var prev = closed ? poly[size - 1] : 0; | ||
// @ts-ignore | ||
var lat1 = deg2rad(prev ? prev['lat'] : 0); | ||
// @ts-ignore | ||
var lng1 = deg2rad(prev ? prev['lng'] : 0); | ||
if (geodesic) { | ||
for (var i in poly) { | ||
var val = poly[i]; | ||
var lat2 = deg2rad(val["lat"]); | ||
var lng2 = deg2rad(val["lng"]); | ||
if (PolyUtil.isOnSegmentGC(lat1, lng1, lat2, lng2, lat3, lng3, havTolerance)) { | ||
return true; | ||
} | ||
lat1 = lat2; | ||
lng1 = lng2; | ||
} | ||
} | ||
lat1 = _lat; | ||
lng1 = _lng; | ||
y1 = y2; | ||
} | ||
} | ||
return false; | ||
} | ||
else { | ||
// We project the points to mercator space, where the Rhumb segment is a straight line, | ||
// and compute the geodesic distance between point3 and the closest point on the | ||
// segment. This method is an approximation, because it uses "closest" in mercator | ||
// space which is not "closest" on the sphere -- but the error is small because | ||
// "tolerance" is small. | ||
var minAcceptable = lat3 - tolerance; | ||
var maxAcceptable = lat3 + tolerance; | ||
var y1 = MathUtil.mercator(lat1); | ||
var y3 = MathUtil.mercator(lat3); | ||
var xTry = []; | ||
for (var i in poly) { | ||
var val = poly[i]; | ||
var lat2 = deg2rad(val["lat"]); | ||
var y2 = MathUtil.mercator(lat2); | ||
var lng2 = deg2rad(val["lng"]); | ||
if (max(lat1, lat2) >= minAcceptable && | ||
min(lat1, lat2) <= maxAcceptable) { | ||
// We offset longitudes by -lng1; the implicit x1 is 0. | ||
var x2 = MathUtil.wrap(lng2 - lng1, -Math.PI, Math.PI); | ||
var x3Base = MathUtil.wrap(lng3 - lng1, -Math.PI, Math.PI); | ||
xTry[0] = x3Base; | ||
// Also explore wrapping of x3Base around the world in both directions. | ||
xTry[1] = x3Base + 2 * Math.PI; | ||
xTry[2] = x3Base - 2 * Math.PI; | ||
for (var i_1 in xTry) { | ||
var x3 = xTry[i_1]; | ||
var dy = y2 - y1; | ||
var len2 = x2 * x2 + dy * dy; | ||
var t = len2 <= 0 | ||
? 0 | ||
: MathUtil.clamp((x3 * x2 + (y3 - y1) * dy) / len2, 0, 1); | ||
var xClosest = t * x2; | ||
var yClosest = y1 + t * dy; | ||
var latClosest = MathUtil.inverseMercator(yClosest); | ||
var havDist = MathUtil.havDistance(lat3, latClosest, x3 - xClosest); | ||
if (havDist < havTolerance) { | ||
return true; | ||
} | ||
} | ||
} | ||
lat1 = lat2; | ||
lng1 = lng2; | ||
y1 = y2; | ||
} | ||
} | ||
return false; | ||
}; | ||
/** | ||
@@ -320,68 +265,47 @@ * Returns sin(initial bearing from (lat1,lng1) to (lat3,lng3) minus initial bearing | ||
*/ | ||
}, { | ||
key: "sinDeltaBearing", | ||
value: function sinDeltaBearing(lat1, lng1, lat2, lng2, lat3, lng3) { | ||
var sinLat1 = sin(lat1); | ||
var cosLat2 = cos(lat2); | ||
var cosLat3 = cos(lat3); | ||
var lat31 = lat3 - lat1; | ||
var lng31 = lng3 - lng1; | ||
var lat21 = lat2 - lat1; | ||
var lng21 = lng2 - lng1; | ||
var a = sin(lng31) * cosLat3; | ||
var c = sin(lng21) * cosLat2; | ||
var b = sin(lat31) + 2 * sinLat1 * cosLat3 * _MathUtil["default"].hav(lng31); | ||
var d = sin(lat21) + 2 * sinLat1 * cosLat2 * _MathUtil["default"].hav(lng21); | ||
var denom = (a * a + b * b) * (c * c + d * d); | ||
return denom <= 0 ? 1 : (a * d - b * c) / sqrt(denom); | ||
} | ||
}, { | ||
key: "isOnSegmentGC", | ||
value: function isOnSegmentGC(lat1, lng1, lat2, lng2, lat3, lng3, havTolerance) { | ||
var havDist13 = _MathUtil["default"].havDistance(lat1, lat3, lng1 - lng3); | ||
if (havDist13 <= havTolerance) { | ||
return true; | ||
} | ||
var havDist23 = _MathUtil["default"].havDistance(lat2, lat3, lng2 - lng3); | ||
if (havDist23 <= havTolerance) { | ||
return true; | ||
} | ||
var sinBearing = PolyUtil.sinDeltaBearing(lat1, lng1, lat2, lng2, lat3, lng3); | ||
var sinDist13 = _MathUtil["default"].sinFromHav(havDist13); | ||
var havCrossTrack = _MathUtil["default"].havFromSin(sinDist13 * sinBearing); | ||
if (havCrossTrack > havTolerance) { | ||
return false; | ||
} | ||
var havDist12 = _MathUtil["default"].havDistance(lat1, lat2, lng1 - lng2); | ||
var term = havDist12 + havCrossTrack * (1 - 2 * havDist12); | ||
if (havDist13 > term || havDist23 > term) { | ||
return false; | ||
} | ||
if (havDist12 < 0.74) { | ||
return true; | ||
} | ||
var cosCrossTrack = 1 - 2 * havCrossTrack; | ||
var havAlongTrack13 = (havDist13 - havCrossTrack) / cosCrossTrack; | ||
var havAlongTrack23 = (havDist23 - havCrossTrack) / cosCrossTrack; | ||
var sinSumAlongTrack = _MathUtil["default"].sinSumFromHav(havAlongTrack13, havAlongTrack23); | ||
return sinSumAlongTrack > 0; // Compare with half-circle == PI using sign of sin(). | ||
} // static isOnSegmentGC(lat1, lng1, lat2, lng2, lat3, lng3, havTolerance) { | ||
PolyUtil.sinDeltaBearing = function (lat1, lng1, lat2, lng2, lat3, lng3) { | ||
var sinLat1 = sin(lat1); | ||
var cosLat2 = cos(lat2); | ||
var cosLat3 = cos(lat3); | ||
var lat31 = lat3 - lat1; | ||
var lng31 = lng3 - lng1; | ||
var lat21 = lat2 - lat1; | ||
var lng21 = lng2 - lng1; | ||
var a = sin(lng31) * cosLat3; | ||
var c = sin(lng21) * cosLat2; | ||
var b = sin(lat31) + 2 * sinLat1 * cosLat3 * MathUtil.hav(lng31); | ||
var d = sin(lat21) + 2 * sinLat1 * cosLat2 * MathUtil.hav(lng21); | ||
var denom = (a * a + b * b) * (c * c + d * d); | ||
return denom <= 0 ? 1 : (a * d - b * c) / sqrt(denom); | ||
}; | ||
PolyUtil.isOnSegmentGC = function (lat1, lng1, lat2, lng2, lat3, lng3, havTolerance) { | ||
var havDist13 = MathUtil.havDistance(lat1, lat3, lng1 - lng3); | ||
if (havDist13 <= havTolerance) { | ||
return true; | ||
} | ||
var havDist23 = MathUtil.havDistance(lat2, lat3, lng2 - lng3); | ||
if (havDist23 <= havTolerance) { | ||
return true; | ||
} | ||
var sinBearing = PolyUtil.sinDeltaBearing(lat1, lng1, lat2, lng2, lat3, lng3); | ||
var sinDist13 = MathUtil.sinFromHav(havDist13); | ||
var havCrossTrack = MathUtil.havFromSin(sinDist13 * sinBearing); | ||
if (havCrossTrack > havTolerance) { | ||
return false; | ||
} | ||
var havDist12 = MathUtil.havDistance(lat1, lat2, lng1 - lng2); | ||
var term = havDist12 + havCrossTrack * (1 - 2 * havDist12); | ||
if (havDist13 > term || havDist23 > term) { | ||
return false; | ||
} | ||
if (havDist12 < 0.74) { | ||
return true; | ||
} | ||
var cosCrossTrack = 1 - 2 * havCrossTrack; | ||
var havAlongTrack13 = (havDist13 - havCrossTrack) / cosCrossTrack; | ||
var havAlongTrack23 = (havDist23 - havCrossTrack) / cosCrossTrack; | ||
var sinSumAlongTrack = MathUtil.sinSumFromHav(havAlongTrack13, havAlongTrack23); | ||
return sinSumAlongTrack > 0; // Compare with half-circle == PI using sign of sin(). | ||
}; | ||
// static isOnSegmentGC(lat1, lng1, lat2, lng2, lat3, lng3, havTolerance) { | ||
// const havDist13 = MathUtil.havDistance(lat1, lat3, lng1 - lng3); | ||
@@ -426,3 +350,2 @@ // if (havDist13 <= havTolerance) { | ||
// } | ||
/** | ||
@@ -436,116 +359,83 @@ * Computes the distance on the sphere between the point p and the line segment start to end. | ||
*/ | ||
}, { | ||
key: "distanceToLine", | ||
value: function distanceToLine(p, start, end) { | ||
if (start == end) { | ||
return _SphericalUtil["default"].computeDistanceBetween(end, p); | ||
} | ||
var s0lat = (0, _SphericalUtil.deg2rad)(p["lat"]); | ||
var s0lng = (0, _SphericalUtil.deg2rad)(p["lng"]); | ||
var s1lat = (0, _SphericalUtil.deg2rad)(start["lat"]); | ||
var s1lng = (0, _SphericalUtil.deg2rad)(start["lng"]); | ||
var s2lat = (0, _SphericalUtil.deg2rad)(end["lat"]); | ||
var s2lng = (0, _SphericalUtil.deg2rad)(end["lng"]); | ||
var s2s1lat = s2lat - s1lat; | ||
var s2s1lng = s2lng - s1lng; | ||
var u = ((s0lat - s1lat) * s2s1lat + (s0lng - s1lng) * s2s1lng) / (s2s1lat * s2s1lat + s2s1lng * s2s1lng); | ||
if (u <= 0) { | ||
return _SphericalUtil["default"].computeDistanceBetween(p, start); | ||
} | ||
if (u >= 1) { | ||
return _SphericalUtil["default"].computeDistanceBetween(p, end); | ||
} | ||
var sa = { | ||
lat: p["lat"] - start["lat"], | ||
lng: p["lng"] - start["lng"] | ||
}; | ||
var sb = { | ||
lat: u * (end["lat"] - start["lat"]), | ||
lng: u * (end["lng"] - start["lng"]) | ||
}; | ||
return _SphericalUtil["default"].computeDistanceBetween(sa, sb); | ||
} | ||
PolyUtil.distanceToLine = function (p, start, end) { | ||
if (start == end) { | ||
return SphericalUtil.computeDistanceBetween(end, p); | ||
} | ||
var s0lat = deg2rad(p["lat"]); | ||
var s0lng = deg2rad(p["lng"]); | ||
var s1lat = deg2rad(start["lat"]); | ||
var s1lng = deg2rad(start["lng"]); | ||
var s2lat = deg2rad(end["lat"]); | ||
var s2lng = deg2rad(end["lng"]); | ||
var s2s1lat = s2lat - s1lat; | ||
var s2s1lng = s2lng - s1lng; | ||
var u = ((s0lat - s1lat) * s2s1lat + (s0lng - s1lng) * s2s1lng) / | ||
(s2s1lat * s2s1lat + s2s1lng * s2s1lng); | ||
if (u <= 0) { | ||
return SphericalUtil.computeDistanceBetween(p, start); | ||
} | ||
if (u >= 1) { | ||
return SphericalUtil.computeDistanceBetween(p, end); | ||
} | ||
var sa = { lat: p["lat"] - start["lat"], lng: p["lng"] - start["lng"] }; | ||
var sb = { | ||
lat: u * (end["lat"] - start["lat"]), | ||
lng: u * (end["lng"] - start["lng"]) | ||
}; | ||
return SphericalUtil.computeDistanceBetween(sa, sb); | ||
}; | ||
/** | ||
* Decodes an encoded path string into a sequence of LatLngs. | ||
*/ | ||
}, { | ||
key: "decode", | ||
value: function decode(encodedPath) { | ||
var len = encodedPath.length - 1; // For speed we preallocate to an upper bound on the final length, then | ||
// truncate the array before returning. | ||
var path = []; | ||
var index = 0; | ||
var lat = 0; | ||
var lng = 0; | ||
while (index < len) { | ||
var result = 1; | ||
var shift = 0; | ||
var b = void 0; | ||
do { | ||
b = ord(encodedPath[index++]) - 63 - 1; | ||
result += b << shift; | ||
shift += 5; | ||
} while (b >= hexdec("0x1f")); | ||
lat += (result & 1) != 0 ? ~(result >> 1) : result >> 1; | ||
result = 1; | ||
shift = 0; | ||
do { | ||
b = ord(encodedPath[index++]) - 63 - 1; | ||
result += b << shift; | ||
shift += 5; | ||
} while (b >= hexdec("0x1f")); | ||
lng += (result & 1) != 0 ? ~(result >> 1) : result >> 1; | ||
path.push({ | ||
lat: lat * 1e-5, | ||
lng: lng * 1e-5 | ||
}); | ||
} | ||
return path; | ||
} | ||
PolyUtil.decode = function (encodedPath) { | ||
var len = encodedPath.length - 1; | ||
// For speed we preallocate to an upper bound on the final length, then | ||
// truncate the array before returning. | ||
var path = []; | ||
var index = 0; | ||
var lat = 0; | ||
var lng = 0; | ||
while (index < len) { | ||
var result = 1; | ||
var shift = 0; | ||
var b = void 0; | ||
do { | ||
b = ord(encodedPath[index++]) - 63 - 1; | ||
result += b << shift; | ||
shift += 5; | ||
} while (b >= hexdec("0x1f")); | ||
lat += (result & 1) != 0 ? ~(result >> 1) : result >> 1; | ||
result = 1; | ||
shift = 0; | ||
do { | ||
b = ord(encodedPath[index++]) - 63 - 1; | ||
result += b << shift; | ||
shift += 5; | ||
} while (b >= hexdec("0x1f")); | ||
lng += (result & 1) != 0 ? ~(result >> 1) : result >> 1; | ||
path.push({ lat: lat * 1e-5, lng: lng * 1e-5 }); | ||
} | ||
return path; | ||
}; | ||
/** | ||
* Encodes a sequence of LatLngs into an encoded path string. | ||
*/ | ||
}, { | ||
key: "encode", | ||
value: function encode(path) { | ||
var lastLat = 0; | ||
var lastLng = 0; | ||
var result = ""; | ||
path.forEach(function (point) { | ||
var lat = round(point["lat"] * 1e5); | ||
var lng = round(point["lng"] * 1e5); | ||
var dLat = lat - lastLat; | ||
var dLng = lng - lastLng; | ||
result = result + enc(dLat); | ||
result = result + enc(dLng); | ||
lastLat = lat; | ||
lastLng = lng; | ||
}); | ||
return result; | ||
} | ||
}, { | ||
key: "DEFAULT_TOLERANCE", | ||
get: function get() { | ||
return DEFAULT_TOLERANCE; | ||
} | ||
}]); | ||
return PolyUtil; | ||
}(); | ||
var _default = PolyUtil; | ||
exports["default"] = _default; | ||
PolyUtil.encode = function (path) { | ||
var lastLat = 0; | ||
var lastLng = 0; | ||
var result = ""; | ||
path.forEach(function (point) { | ||
var lat = round(point["lat"] * 1e5); | ||
var lng = round(point["lng"] * 1e5); | ||
var dLat = lat - lastLat; | ||
var dLng = lng - lastLng; | ||
result = result + enc(dLat); | ||
result = result + enc(dLng); | ||
lastLat = lat; | ||
lastLng = lng; | ||
}); | ||
return result; | ||
}; | ||
return PolyUtil; | ||
}()); | ||
export default PolyUtil; |
@@ -1,47 +0,28 @@ | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { | ||
value: true | ||
}); | ||
exports.deg2rad = deg2rad; | ||
exports.rad2deg = rad2deg; | ||
exports["default"] = void 0; | ||
var _MathUtil = _interopRequireDefault(require("./MathUtil")); | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } | ||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } | ||
function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } | ||
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; } | ||
var log = Math.log, | ||
atan = Math.atan, | ||
atan2 = Math.atan2, | ||
cos = Math.cos, | ||
sin = Math.sin, | ||
asin = Math.asin, | ||
sqrt = Math.sqrt, | ||
abs = Math.abs; | ||
function deg2rad(degrees) { | ||
return degrees * (Math.PI / 180); | ||
/* | ||
* Copyright 2013 Google Inc. | ||
* https://github.com/googlemaps/android-maps-utils/blob/master/library/src/com/google/maps/android/SphericalUtil.java | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
import MathUtil from "./MathUtil"; | ||
var tan = Math.tan, atan2 = Math.atan2, cos = Math.cos, sin = Math.sin, asin = Math.asin, sqrt = Math.sqrt, abs = Math.abs; | ||
export function deg2rad(degrees) { | ||
return degrees * (Math.PI / 180); | ||
} | ||
function rad2deg(radians) { | ||
return radians * (180 / Math.PI); | ||
export function rad2deg(radians) { | ||
return radians * (180 / Math.PI); | ||
} | ||
var SphericalUtil = | ||
/*#__PURE__*/ | ||
function () { | ||
function SphericalUtil() { | ||
_classCallCheck(this, SphericalUtil); | ||
} | ||
_createClass(SphericalUtil, null, [{ | ||
key: "computeHeading", | ||
var SphericalUtil = /** @class */ (function () { | ||
function SphericalUtil() { | ||
} | ||
/** | ||
@@ -52,12 +33,12 @@ * Returns the heading from one LatLng to another LatLng. Headings are | ||
*/ | ||
value: function computeHeading(from, to) { | ||
// http://williams.best.vwh.net/avform.htm#Crs | ||
var fromLat = deg2rad(from["lat"]); | ||
var fromLng = deg2rad(from["lng"]); | ||
var toLat = deg2rad(to["lat"]); | ||
var toLng = deg2rad(to["lng"]); | ||
var dLng = toLng - fromLng; | ||
var heading = atan2(sin(dLng) * cos(toLat), cos(fromLat) * sin(toLat) - sin(fromLat) * cos(toLat) * cos(dLng)); | ||
return _MathUtil["default"].wrap(rad2deg(heading), -180, 180); | ||
} | ||
SphericalUtil.computeHeading = function (from, to) { | ||
// http://williams.best.vwh.net/avform.htm#Crs | ||
var fromLat = deg2rad(from["lat"]); | ||
var fromLng = deg2rad(from["lng"]); | ||
var toLat = deg2rad(to["lat"]); | ||
var toLng = deg2rad(to["lng"]); | ||
var dLng = toLng - fromLng; | ||
var heading = atan2(sin(dLng) * cos(toLat), cos(fromLat) * sin(toLat) - sin(fromLat) * cos(toLat) * cos(dLng)); | ||
return MathUtil.wrap(rad2deg(heading), -180, 180); | ||
}; | ||
/** | ||
@@ -70,22 +51,16 @@ * Returns the LatLng resulting from moving a distance from an origin | ||
*/ | ||
}, { | ||
key: "computeOffset", | ||
value: function computeOffset(from, distance, heading) { | ||
distance /= _MathUtil["default"].EARTH_RADIUS; | ||
heading = deg2rad(heading); // http://williams.best.vwh.net/avform.htm#LL | ||
var fromLat = deg2rad(from["lat"]); | ||
var fromLng = deg2rad(from["lng"]); | ||
var cosDistance = cos(distance); | ||
var sinDistance = sin(distance); | ||
var sinFromLat = sin(fromLat); | ||
var cosFromLat = cos(fromLat); | ||
var sinLat = cosDistance * sinFromLat + sinDistance * cosFromLat * cos(heading); | ||
var dLng = atan2(sinDistance * cosFromLat * sin(heading), cosDistance - sinFromLat * sinLat); | ||
return { | ||
lat: rad2deg(asin(sinLat)), | ||
lng: rad2deg(fromLng + dLng) | ||
}; | ||
} | ||
SphericalUtil.computeOffset = function (from, distance, heading) { | ||
distance /= MathUtil.EARTH_RADIUS; | ||
heading = deg2rad(heading); | ||
// http://williams.best.vwh.net/avform.htm#LL | ||
var fromLat = deg2rad(from["lat"]); | ||
var fromLng = deg2rad(from["lng"]); | ||
var cosDistance = cos(distance); | ||
var sinDistance = sin(distance); | ||
var sinFromLat = sin(fromLat); | ||
var cosFromLat = cos(fromLat); | ||
var sinLat = cosDistance * sinFromLat + sinDistance * cosFromLat * cos(heading); | ||
var dLng = atan2(sinDistance * cosFromLat * sin(heading), cosDistance - sinFromLat * sinLat); | ||
return { lat: rad2deg(asin(sinLat)), lng: rad2deg(fromLng + dLng) }; | ||
}; | ||
/** | ||
@@ -100,46 +75,36 @@ * Returns the location of origin when provided with a LatLng destination, | ||
*/ | ||
}, { | ||
key: "computeOffsetOrigin", | ||
value: function computeOffsetOrigin(to, distance, heading) { | ||
heading = deg2rad(heading); | ||
distance /= _MathUtil["default"].EARTH_RADIUS; // http://lists.maptools.org/pipermail/proj/2008-October/003939.html | ||
var n1 = cos(distance); | ||
var n2 = sin(distance) * cos(heading); | ||
var n3 = sin(distance) * sin(heading); | ||
var n4 = sin(rad2deg(to["lat"])); // There are two solutions for b. b = n2 * n4 +/- sqrt(), one solution results | ||
// in the latitude outside the [-90, 90] range. We first try one solution and | ||
// back off to the other if we are outside that range. | ||
var n12 = n1 * n1; | ||
var discriminant = n2 * n2 * n12 + n12 * n12 - n12 * n4 * n4; | ||
if (discriminant < 0) { | ||
// No real solution which would make sense in LatLng-space. | ||
return null; | ||
} | ||
var b = n2 * n4 + sqrt(discriminant); | ||
b /= n1 * n1 + n2 * n2; | ||
var a = (n4 - n2 * b) / n1; | ||
var fromLatRadians = atan2(a, b); | ||
if (fromLatRadians < -Math.PI / 2 || fromLatRadians > Math.PI / 2) { | ||
b = n2 * n4 - sqrt(discriminant); | ||
SphericalUtil.computeOffsetOrigin = function (to, distance, heading) { | ||
heading = deg2rad(heading); | ||
distance /= MathUtil.EARTH_RADIUS; | ||
// http://lists.maptools.org/pipermail/proj/2008-October/003939.html | ||
var n1 = cos(distance); | ||
var n2 = sin(distance) * cos(heading); | ||
var n3 = sin(distance) * sin(heading); | ||
var n4 = sin(rad2deg(to["lat"])); | ||
// There are two solutions for b. b = n2 * n4 +/- sqrt(), one solution results | ||
// in the latitude outside the [-90, 90] range. We first try one solution and | ||
// back off to the other if we are outside that range. | ||
var n12 = n1 * n1; | ||
var discriminant = n2 * n2 * n12 + n12 * n12 - n12 * n4 * n4; | ||
if (discriminant < 0) { | ||
// No real solution which would make sense in LatLng-space. | ||
return null; | ||
} | ||
var b = n2 * n4 + sqrt(discriminant); | ||
b /= n1 * n1 + n2 * n2; | ||
fromLatRadians = atan2(a, b); | ||
} | ||
if (fromLatRadians < -Math.PI / 2 || fromLatRadians > Math.PI / 2) { | ||
// No solution which would make sense in LatLng-space. | ||
return null; | ||
} | ||
var fromLngRadians = rad2deg(to["lng"]) - atan2(n3, n1 * cos(fromLatRadians) - n2 * sin(fromLatRadians)); | ||
return { | ||
lat: rad2deg(fromLatRadians), | ||
lng: rad2deg(fromLngRadians) | ||
}; | ||
} | ||
var a = (n4 - n2 * b) / n1; | ||
var fromLatRadians = atan2(a, b); | ||
if (fromLatRadians < -Math.PI / 2 || fromLatRadians > Math.PI / 2) { | ||
b = n2 * n4 - sqrt(discriminant); | ||
b /= n1 * n1 + n2 * n2; | ||
fromLatRadians = atan2(a, b); | ||
} | ||
if (fromLatRadians < -Math.PI / 2 || fromLatRadians > Math.PI / 2) { | ||
// No solution which would make sense in LatLng-space. | ||
return null; | ||
} | ||
var fromLngRadians = rad2deg(to["lng"]) - | ||
atan2(n3, n1 * cos(fromLatRadians) - n2 * sin(fromLatRadians)); | ||
return { lat: rad2deg(fromLatRadians), lng: rad2deg(fromLngRadians) }; | ||
}; | ||
/** | ||
@@ -153,44 +118,33 @@ * Returns the LatLng which lies the given fraction of the way between the | ||
*/ | ||
}, { | ||
key: "interpolate", | ||
value: function interpolate(from, to, fraction) { | ||
// http://en.wikipedia.org/wiki/Slerp | ||
var fromLat = deg2rad(from["lat"]); | ||
var fromLng = deg2rad(from["lng"]); | ||
var toLat = deg2rad(to["lat"]); | ||
var toLng = deg2rad(to["lng"]); | ||
var cosFromLat = cos(fromLat); | ||
var cosToLat = cos(toLat); // Computes Spherical interpolation coefficients. | ||
var angle = SphericalUtil.computeAngleBetween(from, to); | ||
var sinAngle = sin(angle); | ||
if (sinAngle < 1e-6) { | ||
return from; | ||
} | ||
var a = sin((1 - fraction) * angle) / sinAngle; | ||
var b = sin(fraction * angle) / sinAngle; // Converts from polar to vector and interpolate. | ||
var x = a * cosFromLat * cos(fromLng) + b * cosToLat * cos(toLng); | ||
var y = a * cosFromLat * sin(fromLng) + b * cosToLat * sin(toLng); | ||
var z = a * sin(fromLat) + b * sin(toLat); // Converts interpolated vector back to polar. | ||
var lat = atan2(z, sqrt(x * x + y * y)); | ||
var lng = atan2(y, x); | ||
return { | ||
lat: rad2deg(lat), | ||
lng: rad2deg(lng) | ||
}; | ||
} | ||
SphericalUtil.interpolate = function (from, to, fraction) { | ||
// http://en.wikipedia.org/wiki/Slerp | ||
var fromLat = deg2rad(from["lat"]); | ||
var fromLng = deg2rad(from["lng"]); | ||
var toLat = deg2rad(to["lat"]); | ||
var toLng = deg2rad(to["lng"]); | ||
var cosFromLat = cos(fromLat); | ||
var cosToLat = cos(toLat); | ||
// Computes Spherical interpolation coefficients. | ||
var angle = SphericalUtil.computeAngleBetween(from, to); | ||
var sinAngle = sin(angle); | ||
if (sinAngle < 1e-6) { | ||
return from; | ||
} | ||
var a = sin((1 - fraction) * angle) / sinAngle; | ||
var b = sin(fraction * angle) / sinAngle; | ||
// Converts from polar to vector and interpolate. | ||
var x = a * cosFromLat * cos(fromLng) + b * cosToLat * cos(toLng); | ||
var y = a * cosFromLat * sin(fromLng) + b * cosToLat * sin(toLng); | ||
var z = a * sin(fromLat) + b * sin(toLat); | ||
// Converts interpolated vector back to polar. | ||
var lat = atan2(z, sqrt(x * x + y * y)); | ||
var lng = atan2(y, x); | ||
return { lat: rad2deg(lat), lng: rad2deg(lng) }; | ||
}; | ||
/** | ||
* Returns distance on the unit sphere; the arguments are in radians. | ||
*/ | ||
}, { | ||
key: "distanceRadians", | ||
value: function distanceRadians(lat1, lng1, lat2, lng2) { | ||
return _MathUtil["default"].arcHav(_MathUtil["default"].havDistance(lat1, lat2, lng1 - lng2)); | ||
} | ||
SphericalUtil.distanceRadians = function (lat1, lng1, lat2, lng2) { | ||
return MathUtil.arcHav(MathUtil.havDistance(lat1, lat2, lng1 - lng2)); | ||
}; | ||
/** | ||
@@ -200,41 +154,31 @@ * Returns the angle between two LatLngs, in radians. This is the same as the distance | ||
*/ | ||
}, { | ||
key: "computeAngleBetween", | ||
value: function computeAngleBetween(from, to) { | ||
return SphericalUtil.distanceRadians(deg2rad(from["lat"]), deg2rad(from["lng"]), deg2rad(to["lat"]), deg2rad(to["lng"])); | ||
} | ||
SphericalUtil.computeAngleBetween = function (from, to) { | ||
return SphericalUtil.distanceRadians(deg2rad(from["lat"]), deg2rad(from["lng"]), deg2rad(to["lat"]), deg2rad(to["lng"])); | ||
}; | ||
/** | ||
* Returns the distance between two LatLngs, in meters. | ||
*/ | ||
}, { | ||
key: "computeDistanceBetween", | ||
value: function computeDistanceBetween(from, to) { | ||
return SphericalUtil.computeAngleBetween(from, to) * _MathUtil["default"].EARTH_RADIUS; | ||
} | ||
SphericalUtil.computeDistanceBetween = function (from, to) { | ||
return SphericalUtil.computeAngleBetween(from, to) * MathUtil.EARTH_RADIUS; | ||
}; | ||
/** | ||
* Returns the length of the given path, in meters, on Earth. | ||
*/ | ||
}, { | ||
key: "computeLength", | ||
value: function computeLength(path) { | ||
if (path.length < 2) { | ||
return 0; | ||
} | ||
var length = 0; | ||
var prev = path[0]; | ||
var prevLat = deg2rad(prev["lat"]); | ||
var prevLng = deg2rad(prev["lng"]); | ||
path.forEach(function (point) { | ||
var lat = deg2rad(point["lat"]); | ||
var lng = deg2rad(point["lng"]); | ||
length += SphericalUtil.distanceRadians(prevLat, prevLng, lat, lng); | ||
prevLat = lat; | ||
prevLng = lng; | ||
}); | ||
return length * _MathUtil["default"].EARTH_RADIUS; | ||
} | ||
SphericalUtil.computeLength = function (path) { | ||
if (path.length < 2) { | ||
return 0; | ||
} | ||
var length = 0; | ||
var prev = path[0]; | ||
var prevLat = deg2rad(prev["lat"]); | ||
var prevLng = deg2rad(prev["lng"]); | ||
path.forEach(function (point) { | ||
var lat = deg2rad(point["lat"]); | ||
var lng = deg2rad(point["lng"]); | ||
length += SphericalUtil.distanceRadians(prevLat, prevLng, lat, lng); | ||
prevLat = lat; | ||
prevLng = lng; | ||
}); | ||
return length * MathUtil.EARTH_RADIUS; | ||
}; | ||
/** | ||
@@ -245,8 +189,5 @@ * Returns the area of a closed path on Earth. | ||
*/ | ||
}, { | ||
key: "computeArea", | ||
value: function computeArea(path) { | ||
return abs(SphericalUtil.computeSignedArea(path)); | ||
} | ||
SphericalUtil.computeArea = function (path) { | ||
return abs(SphericalUtil.computeSignedArea(path)); | ||
}; | ||
/** | ||
@@ -259,8 +200,5 @@ * Returns the signed area of a closed path on Earth. The sign of the area may be used to | ||
*/ | ||
}, { | ||
key: "computeSignedArea", | ||
value: function computeSignedArea(path) { | ||
return SphericalUtil.computeSignedAreaP(path, _MathUtil["default"].EARTH_RADIUS); | ||
} | ||
SphericalUtil.computeSignedArea = function (path) { | ||
return SphericalUtil.computeSignedAreaP(path, MathUtil.EARTH_RADIUS); | ||
}; | ||
/** | ||
@@ -271,27 +209,22 @@ * Returns the signed area of a closed path on a sphere of given radius. | ||
*/ | ||
}, { | ||
key: "computeSignedAreaP", | ||
value: function computeSignedAreaP(path, radius) { | ||
var size = path.length; | ||
if (size < 3) { | ||
return 0; | ||
} | ||
var total = 0; | ||
var prev = path[size - 1]; | ||
var prevTanLat = tan((Math.PI / 2 - deg2rad(prev["lat"])) / 2); | ||
var prevLng = deg2rad(prev["lng"]); // For each edge, accumulate the signed area of the triangle formed by the North Pole | ||
// and that edge ("polar triangle"). | ||
path.forEach(function (point) { | ||
var tanLat = tan((Math.PI / 2 - deg2rad(point["lat"])) / 2); | ||
var lng = deg2rad(point["lng"]); | ||
total += SphericalUtil.polarTriangleArea(tanLat, lng, prevTanLat, prevLng); | ||
prevTanLat = tanLat; | ||
prevLng = lng; | ||
}); | ||
return total * (radius * radius); | ||
} | ||
SphericalUtil.computeSignedAreaP = function (path, radius) { | ||
var size = path.length; | ||
if (size < 3) { | ||
return 0; | ||
} | ||
var total = 0; | ||
var prev = path[size - 1]; | ||
var prevTanLat = tan((Math.PI / 2 - deg2rad(prev["lat"])) / 2); | ||
var prevLng = deg2rad(prev["lng"]); | ||
// For each edge, accumulate the signed area of the triangle formed by the North Pole | ||
// and that edge ("polar triangle"). | ||
path.forEach(function (point) { | ||
var tanLat = tan((Math.PI / 2 - deg2rad(point["lat"])) / 2); | ||
var lng = deg2rad(point["lng"]); | ||
total += SphericalUtil.polarTriangleArea(tanLat, lng, prevTanLat, prevLng); | ||
prevTanLat = tanLat; | ||
prevLng = lng; | ||
}); | ||
return total * (radius * radius); | ||
}; | ||
/** | ||
@@ -304,16 +237,9 @@ * Returns the signed area of a triangle which has North Pole as a vertex. | ||
*/ | ||
}, { | ||
key: "polarTriangleArea", | ||
value: function polarTriangleArea(tan1, lng1, tan2, lng2) { | ||
var deltaLng = lng1 - lng2; | ||
var t = tan1 * tan2; | ||
return 2 * atan2(t * sin(deltaLng), 1 + t * cos(deltaLng)); | ||
} | ||
}]); | ||
return SphericalUtil; | ||
}(); | ||
var _default = SphericalUtil; | ||
exports["default"] = _default; | ||
SphericalUtil.polarTriangleArea = function (tan1, lng1, tan2, lng2) { | ||
var deltaLng = lng1 - lng2; | ||
var t = tan1 * tan2; | ||
return 2 * atan2(t * sin(deltaLng), 1 + t * cos(deltaLng)); | ||
}; | ||
return SphericalUtil; | ||
}()); | ||
export default SphericalUtil; |
{ | ||
"name": "node-geometry-library", | ||
"version": "1.1.1", | ||
"version": "1.2.0", | ||
"description": "Javascript Geometry Library provides utility functions for the computation of geometric data on the surface of the Earth. Code ported from Google Maps Android API.", | ||
"main": "lib/index.js", | ||
"types": "lib/index.d.ts", | ||
"repository": "https://github.com/BunHouth/geometry-library.git", | ||
@@ -13,7 +14,8 @@ "author": "Bunhouth <bunhouth99@gmail.com>", | ||
"@babel/node": "^7.5.5", | ||
"@babel/preset-env": "^7.5.5" | ||
"@babel/preset-env": "^7.5.5", | ||
"typescript": "^3.9.2" | ||
}, | ||
"scripts": { | ||
"test": "echo \"Error: no test specified\" && exit 1", | ||
"build": "babel src -d lib/ src", | ||
"build": "tsc", | ||
"example": "babel-node example.js" | ||
@@ -20,0 +22,0 @@ }, |
@@ -69,3 +69,3 @@ ## Geometry Library Google Maps API V3 | ||
console.log(response) // false | ||
console.log(response) // true | ||
@@ -72,0 +72,0 @@ let response = PolyUtil.containsLocation( |
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
58101
5
1057
1