index.js 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. "use strict";
  2. var __importDefault = (this && this.__importDefault) || function (mod) {
  3. return (mod && mod.__esModule) ? mod : { "default": mod };
  4. };
  5. Object.defineProperty(exports, "__esModule", { value: true });
  6. var bearing_1 = __importDefault(require("@turf/bearing"));
  7. var distance_1 = __importDefault(require("@turf/distance"));
  8. var destination_1 = __importDefault(require("@turf/destination"));
  9. var line_intersect_1 = __importDefault(require("@turf/line-intersect"));
  10. var meta_1 = require("@turf/meta");
  11. var helpers_1 = require("@turf/helpers");
  12. var invariant_1 = require("@turf/invariant");
  13. /**
  14. * Takes a {@link Point} and a {@link LineString} and calculates the closest Point on the (Multi)LineString.
  15. *
  16. * @name nearestPointOnLine
  17. * @param {Geometry|Feature<LineString|MultiLineString>} lines lines to snap to
  18. * @param {Geometry|Feature<Point>|number[]} pt point to snap from
  19. * @param {Object} [options={}] Optional parameters
  20. * @param {string} [options.units='kilometers'] can be degrees, radians, miles, or kilometers
  21. * @returns {Feature<Point>} closest point on the `line` to `point`. The properties object will contain three values: `index`: closest point was found on nth line part, `dist`: distance between pt and the closest point, `location`: distance along the line between start and the closest point.
  22. * @example
  23. * var line = turf.lineString([
  24. * [-77.031669, 38.878605],
  25. * [-77.029609, 38.881946],
  26. * [-77.020339, 38.884084],
  27. * [-77.025661, 38.885821],
  28. * [-77.021884, 38.889563],
  29. * [-77.019824, 38.892368]
  30. * ]);
  31. * var pt = turf.point([-77.037076, 38.884017]);
  32. *
  33. * var snapped = turf.nearestPointOnLine(line, pt, {units: 'miles'});
  34. *
  35. * //addToMap
  36. * var addToMap = [line, pt, snapped];
  37. * snapped.properties['marker-color'] = '#00f';
  38. */
  39. function nearestPointOnLine(lines, pt, options) {
  40. if (options === void 0) { options = {}; }
  41. var closestPt = helpers_1.point([Infinity, Infinity], {
  42. dist: Infinity,
  43. });
  44. var length = 0.0;
  45. meta_1.flattenEach(lines, function (line) {
  46. var coords = invariant_1.getCoords(line);
  47. for (var i = 0; i < coords.length - 1; i++) {
  48. //start
  49. var start = helpers_1.point(coords[i]);
  50. start.properties.dist = distance_1.default(pt, start, options);
  51. //stop
  52. var stop_1 = helpers_1.point(coords[i + 1]);
  53. stop_1.properties.dist = distance_1.default(pt, stop_1, options);
  54. // sectionLength
  55. var sectionLength = distance_1.default(start, stop_1, options);
  56. //perpendicular
  57. var heightDistance = Math.max(start.properties.dist, stop_1.properties.dist);
  58. var direction = bearing_1.default(start, stop_1);
  59. var perpendicularPt1 = destination_1.default(pt, heightDistance, direction + 90, options);
  60. var perpendicularPt2 = destination_1.default(pt, heightDistance, direction - 90, options);
  61. var intersect = line_intersect_1.default(helpers_1.lineString([
  62. perpendicularPt1.geometry.coordinates,
  63. perpendicularPt2.geometry.coordinates,
  64. ]), helpers_1.lineString([start.geometry.coordinates, stop_1.geometry.coordinates]));
  65. var intersectPt = null;
  66. if (intersect.features.length > 0) {
  67. intersectPt = intersect.features[0];
  68. intersectPt.properties.dist = distance_1.default(pt, intersectPt, options);
  69. intersectPt.properties.location =
  70. length + distance_1.default(start, intersectPt, options);
  71. }
  72. if (start.properties.dist < closestPt.properties.dist) {
  73. closestPt = start;
  74. closestPt.properties.index = i;
  75. closestPt.properties.location = length;
  76. }
  77. if (stop_1.properties.dist < closestPt.properties.dist) {
  78. closestPt = stop_1;
  79. closestPt.properties.index = i + 1;
  80. closestPt.properties.location = length + sectionLength;
  81. }
  82. if (intersectPt &&
  83. intersectPt.properties.dist < closestPt.properties.dist) {
  84. closestPt = intersectPt;
  85. closestPt.properties.index = i;
  86. }
  87. // update length
  88. length += sectionLength;
  89. }
  90. });
  91. return closestPt;
  92. }
  93. exports.default = nearestPointOnLine;