index.js 3.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. import { getType } from "@turf/invariant";
  2. import { featureEach, geomEach } from "@turf/meta";
  3. import pointToLineDistance from "@turf/point-to-line-distance";
  4. import objectAssign from "object-assign";
  5. /**
  6. * Returns the closest {@link Point|point}, of a {@link FeatureCollection|collection} of points,
  7. * to a {@link LineString|line}. The returned point has a `dist` property indicating its distance to the line.
  8. *
  9. * @name nearestPointToLine
  10. * @param {FeatureCollection|GeometryCollection<Point>} points Point Collection
  11. * @param {Feature|Geometry<LineString>} line Line Feature
  12. * @param {Object} [options] Optional parameters
  13. * @param {string} [options.units='kilometers'] unit of the output distance property
  14. * (eg: degrees, radians, miles, or kilometers)
  15. * @param {Object} [options.properties={}] Translate Properties to Point
  16. * @returns {Feature<Point>} the closest point
  17. * @example
  18. * var pt1 = turf.point([0, 0]);
  19. * var pt2 = turf.point([0.5, 0.5]);
  20. * var points = turf.featureCollection([pt1, pt2]);
  21. * var line = turf.lineString([[1,1], [-1,1]]);
  22. *
  23. * var nearest = turf.nearestPointToLine(points, line);
  24. *
  25. * //addToMap
  26. * var addToMap = [nearest, line];
  27. */
  28. function nearestPointToLine(points, line, options) {
  29. if (options === void 0) { options = {}; }
  30. var units = options.units;
  31. var properties = options.properties || {};
  32. // validation
  33. var pts = normalize(points);
  34. if (!pts.features.length) {
  35. throw new Error("points must contain features");
  36. }
  37. if (!line) {
  38. throw new Error("line is required");
  39. }
  40. if (getType(line) !== "LineString") {
  41. throw new Error("line must be a LineString");
  42. }
  43. var dist = Infinity;
  44. var pt = null;
  45. featureEach(pts, function (point) {
  46. var d = pointToLineDistance(point, line, { units: units });
  47. if (d < dist) {
  48. dist = d;
  49. pt = point;
  50. }
  51. });
  52. /**
  53. * Translate Properties to final Point, priorities:
  54. * 1. options.properties
  55. * 2. inherent Point properties
  56. * 3. dist custom properties created by NearestPointToLine
  57. */
  58. if (pt) {
  59. pt.properties = objectAssign({ dist: dist }, pt.properties, properties);
  60. }
  61. // if (pt) { pt.properties = objectAssign({dist}, pt.properties, properties); }
  62. return pt;
  63. }
  64. /**
  65. * Convert Collection to FeatureCollection
  66. *
  67. * @private
  68. * @param {FeatureCollection|GeometryCollection} points Points
  69. * @returns {FeatureCollection<Point>} points
  70. */
  71. function normalize(points) {
  72. var features = [];
  73. var type = points.geometry ? points.geometry.type : points.type;
  74. switch (type) {
  75. case "GeometryCollection":
  76. geomEach(points, function (geom) {
  77. if (geom.type === "Point") {
  78. features.push({ type: "Feature", properties: {}, geometry: geom });
  79. }
  80. });
  81. return { type: "FeatureCollection", features: features };
  82. case "FeatureCollection":
  83. points.features = points.features.filter(function (feature) {
  84. return feature.geometry.type === "Point";
  85. });
  86. return points;
  87. default:
  88. throw new Error("points must be a Point Collection");
  89. }
  90. }
  91. export default nearestPointToLine;