index.cjs 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. "use strict";Object.defineProperty(exports, "__esModule", {value: true});var __defProp = Object.defineProperty;
  2. var __defProps = Object.defineProperties;
  3. var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
  4. var __getOwnPropSymbols = Object.getOwnPropertySymbols;
  5. var __hasOwnProp = Object.prototype.hasOwnProperty;
  6. var __propIsEnum = Object.prototype.propertyIsEnumerable;
  7. var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
  8. var __spreadValues = (a, b) => {
  9. for (var prop in b || (b = {}))
  10. if (__hasOwnProp.call(b, prop))
  11. __defNormalProp(a, prop, b[prop]);
  12. if (__getOwnPropSymbols)
  13. for (var prop of __getOwnPropSymbols(b)) {
  14. if (__propIsEnum.call(b, prop))
  15. __defNormalProp(a, prop, b[prop]);
  16. }
  17. return a;
  18. };
  19. var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
  20. // index.ts
  21. var _distance = require('@turf/distance');
  22. var _meta = require('@turf/meta');
  23. var _helpers = require('@turf/helpers');
  24. var _invariant = require('@turf/invariant');
  25. function nearestPointOnLine(lines, pt, options = {}) {
  26. if (!lines || !pt) {
  27. throw new Error("lines and pt are required arguments");
  28. }
  29. const ptPos = _invariant.getCoord.call(void 0, pt);
  30. let closestPt = _helpers.point.call(void 0, [Infinity, Infinity], {
  31. dist: Infinity,
  32. index: -1,
  33. multiFeatureIndex: -1,
  34. location: -1
  35. });
  36. let length = 0;
  37. _meta.flattenEach.call(void 0,
  38. lines,
  39. function(line, _featureIndex, multiFeatureIndex) {
  40. const coords = _invariant.getCoords.call(void 0, line);
  41. for (let i = 0; i < coords.length - 1; i++) {
  42. const start = _helpers.point.call(void 0, coords[i]);
  43. start.properties.dist = _distance.distance.call(void 0, pt, start, options);
  44. const startPos = _invariant.getCoord.call(void 0, start);
  45. const stop = _helpers.point.call(void 0, coords[i + 1]);
  46. stop.properties.dist = _distance.distance.call(void 0, pt, stop, options);
  47. const stopPos = _invariant.getCoord.call(void 0, stop);
  48. const sectionLength = _distance.distance.call(void 0, start, stop, options);
  49. let intersectPos;
  50. let wasEnd;
  51. if (startPos[0] === ptPos[0] && startPos[1] === ptPos[1]) {
  52. [intersectPos, , wasEnd] = [startPos, void 0, false];
  53. } else if (stopPos[0] === ptPos[0] && stopPos[1] === ptPos[1]) {
  54. [intersectPos, , wasEnd] = [stopPos, void 0, true];
  55. } else {
  56. [intersectPos, , wasEnd] = nearestPointOnSegment(
  57. start.geometry.coordinates,
  58. stop.geometry.coordinates,
  59. _invariant.getCoord.call(void 0, pt)
  60. );
  61. }
  62. let intersectPt;
  63. if (intersectPos) {
  64. intersectPt = _helpers.point.call(void 0, intersectPos, {
  65. dist: _distance.distance.call(void 0, pt, intersectPos, options),
  66. multiFeatureIndex,
  67. location: length + _distance.distance.call(void 0, start, intersectPos, options)
  68. });
  69. }
  70. if (intersectPt && intersectPt.properties.dist < closestPt.properties.dist) {
  71. closestPt = __spreadProps(__spreadValues({}, intersectPt), {
  72. properties: __spreadProps(__spreadValues({}, intersectPt.properties), {
  73. // Legacy behaviour where index progresses to next segment # if we
  74. // went with the end point this iteration.
  75. index: wasEnd ? i + 1 : i
  76. })
  77. });
  78. }
  79. length += sectionLength;
  80. }
  81. }
  82. );
  83. return closestPt;
  84. }
  85. function dot(v1, v2) {
  86. const [v1x, v1y, v1z] = v1;
  87. const [v2x, v2y, v2z] = v2;
  88. return v1x * v2x + v1y * v2y + v1z * v2z;
  89. }
  90. function cross(v1, v2) {
  91. const [v1x, v1y, v1z] = v1;
  92. const [v2x, v2y, v2z] = v2;
  93. return [v1y * v2z - v1z * v2y, v1z * v2x - v1x * v2z, v1x * v2y - v1y * v2x];
  94. }
  95. function magnitude(v) {
  96. return Math.sqrt(Math.pow(v[0], 2) + Math.pow(v[1], 2) + Math.pow(v[2], 2));
  97. }
  98. function angle(v1, v2) {
  99. const theta = dot(v1, v2) / (magnitude(v1) * magnitude(v2));
  100. return Math.acos(Math.min(Math.max(theta, -1), 1));
  101. }
  102. function lngLatToVector(a) {
  103. const lat = _helpers.degreesToRadians.call(void 0, a[1]);
  104. const lng = _helpers.degreesToRadians.call(void 0, a[0]);
  105. return [
  106. Math.cos(lat) * Math.cos(lng),
  107. Math.cos(lat) * Math.sin(lng),
  108. Math.sin(lat)
  109. ];
  110. }
  111. function vectorToLngLat(v) {
  112. const [x, y, z] = v;
  113. const lat = _helpers.radiansToDegrees.call(void 0, Math.asin(z));
  114. const lng = _helpers.radiansToDegrees.call(void 0, Math.atan2(y, x));
  115. return [lng, lat];
  116. }
  117. function nearestPointOnSegment(posA, posB, posC) {
  118. const A = lngLatToVector(posA);
  119. const B = lngLatToVector(posB);
  120. const C = lngLatToVector(posC);
  121. const [Cx, Cy, Cz] = C;
  122. const [D, E, F] = cross(A, B);
  123. const a = E * Cz - F * Cy;
  124. const b = F * Cx - D * Cz;
  125. const c = D * Cy - E * Cx;
  126. const f = c * E - b * F;
  127. const g = a * F - c * D;
  128. const h = b * D - a * E;
  129. const t = 1 / Math.sqrt(Math.pow(f, 2) + Math.pow(g, 2) + Math.pow(h, 2));
  130. const I1 = [f * t, g * t, h * t];
  131. const I2 = [-1 * f * t, -1 * g * t, -1 * h * t];
  132. const angleAB = angle(A, B);
  133. const angleAI1 = angle(A, I1);
  134. const angleBI1 = angle(B, I1);
  135. const angleAI2 = angle(A, I2);
  136. const angleBI2 = angle(B, I2);
  137. let I;
  138. if (angleAI1 < angleAI2 && angleAI1 < angleBI2 || angleBI1 < angleAI2 && angleBI1 < angleBI2) {
  139. I = I1;
  140. } else {
  141. I = I2;
  142. }
  143. if (angle(A, I) > angleAB || angle(B, I) > angleAB) {
  144. if (_distance.distance.call(void 0, vectorToLngLat(I), vectorToLngLat(A)) <= _distance.distance.call(void 0, vectorToLngLat(I), vectorToLngLat(B))) {
  145. return [vectorToLngLat(A), true, false];
  146. } else {
  147. return [vectorToLngLat(B), false, true];
  148. }
  149. }
  150. return [vectorToLngLat(I), false, false];
  151. }
  152. var turf_nearest_point_on_line_default = nearestPointOnLine;
  153. exports.default = turf_nearest_point_on_line_default; exports.nearestPointOnLine = nearestPointOnLine;
  154. //# sourceMappingURL=index.cjs.map