{"version":3,"sources":["/home/runner/work/turf/turf/packages/turf-nearest-point-on-line/dist/cjs/index.cjs","../../index.ts"],"names":[],"mappings":"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","file":"/home/runner/work/turf/turf/packages/turf-nearest-point-on-line/dist/cjs/index.cjs","sourcesContent":[null,"import { Feature, Point, Position, LineString, MultiLineString } from \"geojson\";\nimport { distance } from \"@turf/distance\";\nimport { flattenEach } from \"@turf/meta\";\nimport {\n  point,\n  degreesToRadians,\n  radiansToDegrees,\n  Coord,\n  Units,\n} from \"@turf/helpers\";\nimport { getCoord, getCoords } from \"@turf/invariant\";\n\n/**\n * Returns the nearest point on a line to a given point.\n *\n * If any of the segments in the input line string are antipodal and therefore\n * have an undefined arc, this function will instead return that the point lies\n * on the line.\n *\n * ⚠️ We have begun the process of migrating to different return properties for\n * this function. The new properties we recommend using as of v7.4 are:\n * - lineStringIndex - point was found on the nth LineString of an input MultiLineString. Previously `multiFeatureIndex`\n * - segmentIndex - point was found on the nth segment of the above LineString. Previously `index`\n * - totalDistance - distance from the start of the overall MultiLineString. Previously `location`\n * - lineDistance - distance from the start of the relevant LineString\n * - segmentDistance - distance from the start of the relevant segment\n * - pointDistance - distance between found point is from input reference point. Previously `dist`\n *\n * multiFeatureIndex, index, location, and dist continue to work as previously\n * until at least the next major release.\n *\n * @function\n * @param {Geometry|Feature<LineString|MultiLineString>} lines Lines to snap to\n * @param {Geometry|Feature<Point>|number[]} inputPoint Point to snap from\n * @param {Object} [options={}] Optional parameters\n * @param {Units} [options.units='kilometers'] Supports all valid Turf {@link https://turfjs.org/docs/api/types/Units Units}\n * @returns {Feature<Point>} closest point on the `lines` to the `inputPoint`. The point will have the following properties: `lineStringIndex`: closest point was found on the nth LineString (only relevant if input is MultiLineString), `segmentIndex`: closest point was found on nth line segment of the LineString, `totalDistance`: distance along the line from the absolute start of the MultiLineString, `lineDistance`: distance along the line from the start of the LineString where the closest point was found, `segmentDistance`: distance along the line from the start of the line segment where the closest point was found, `pointDistance`: distance to the input point.\n * @example\n * var line = turf.lineString([\n *     [-77.031669, 38.878605],\n *     [-77.029609, 38.881946],\n *     [-77.020339, 38.884084],\n *     [-77.025661, 38.885821],\n *     [-77.021884, 38.889563],\n *     [-77.019824, 38.892368]\n * ]);\n * var inputPoint = turf.point([-77.037076, 38.884017]);\n *\n * var snapped = turf.nearestPointOnLine(line, inputPoint, {units: 'miles'});\n *\n * //addToMap\n * var addToMap = [line, inputPoint, snapped];\n * snapped.properties['marker-color'] = '#00f';\n */\nfunction nearestPointOnLine<G extends LineString | MultiLineString>(\n  lines: Feature<G> | G,\n  inputPoint: Coord,\n  options: { units?: Units } = {}\n): Feature<\n  Point,\n  {\n    lineStringIndex: number;\n    segmentIndex: number;\n    totalDistance: number;\n    lineDistance: number;\n    segmentDistance: number;\n    pointDistance: number;\n    // deprecated properties START\n    /** @deprecated use `lineStringIndex` instead */\n    multiFeatureIndex: number;\n    /** @deprecated use `segmentIndex` instead */\n    index: number;\n    /** @deprecated use `totalDistance` instead */\n    location: number;\n    /** @deprecated use `pointDistance` instead */\n    dist: number;\n    // deprecated properties END\n    [key: string]: any;\n  }\n> {\n  if (!lines || !inputPoint) {\n    throw new Error(\"lines and inputPoint are required arguments\");\n  }\n\n  const inputPos = getCoord(inputPoint);\n\n  let closestPt = point([Infinity, Infinity], {\n    lineStringIndex: -1,\n    segmentIndex: -1,\n    totalDistance: -1,\n    lineDistance: -1,\n    segmentDistance: -1,\n    pointDistance: Infinity,\n    // deprecated properties START\n    multiFeatureIndex: -1,\n    index: -1,\n    location: -1,\n    dist: Infinity,\n    // deprecated properties END\n  });\n\n  let totalDistance = 0.0;\n  let lineDistance = 0.0;\n  let currentLineStringIndex = -1;\n  flattenEach(\n    lines,\n    function (line: any, _featureIndex: number, lineStringIndex: number) {\n      //reset lineDistance at each changed lineStringIndex\n      if (currentLineStringIndex !== lineStringIndex) {\n        currentLineStringIndex = lineStringIndex;\n        lineDistance = 0.0;\n      }\n\n      const coords: any = getCoords(line);\n\n      for (let i = 0; i < coords.length - 1; i++) {\n        //start - start of current line section\n        const start: Feature<Point, { dist: number }> = point(coords[i]);\n        const startPos = getCoord(start);\n\n        //stop - end of current line section\n        const stop: Feature<Point, { dist: number }> = point(coords[i + 1]);\n        const stopPos = getCoord(stop);\n\n        // segmentLength\n        const segmentLength = distance(start, stop, options);\n        let intersectPos: Position;\n        let wasEnd: boolean;\n\n        // Short circuit if snap point is start or end position of the line\n        // Test the end position first for consistency in case they are\n        // coincident\n        if (stopPos[0] === inputPos[0] && stopPos[1] === inputPos[1]) {\n          [intersectPos, wasEnd] = [stopPos, true];\n        } else if (startPos[0] === inputPos[0] && startPos[1] === inputPos[1]) {\n          [intersectPos, wasEnd] = [startPos, false];\n        } else {\n          // Otherwise, find the nearest point the hard way.\n          [intersectPos, wasEnd] = nearestPointOnSegment(\n            startPos,\n            stopPos,\n            inputPos\n          );\n        }\n\n        const pointDistance = distance(inputPoint, intersectPos, options);\n\n        if (pointDistance < closestPt.properties.pointDistance) {\n          const segmentDistance = distance(start, intersectPos, options);\n          closestPt = point(intersectPos, {\n            lineStringIndex: lineStringIndex,\n            // Legacy behaviour where index progresses to next segment # if we\n            // went with the end point this iteration.\n            segmentIndex: wasEnd ? i + 1 : i,\n            totalDistance: totalDistance + segmentDistance,\n            lineDistance: lineDistance + segmentDistance,\n            segmentDistance: segmentDistance,\n            pointDistance: pointDistance,\n            // deprecated properties START\n            multiFeatureIndex: -1,\n            index: -1,\n            location: -1,\n            dist: Infinity,\n            // deprecated properties END\n          });\n          closestPt.properties = {\n            ...closestPt.properties,\n            multiFeatureIndex: closestPt.properties.lineStringIndex,\n            index: closestPt.properties.segmentIndex,\n            location: closestPt.properties.totalDistance,\n            dist: closestPt.properties.pointDistance,\n            // deprecated properties END\n          };\n        }\n\n        // update totalDistance and lineDistance\n        totalDistance += segmentLength;\n        lineDistance += segmentLength;\n      }\n    }\n  );\n\n  return closestPt;\n}\n\n// A simple Vector3 type for cartesian operations.\ntype Vector = [number, number, number];\n\nfunction dot(v1: Vector, v2: Vector): number {\n  const [v1x, v1y, v1z] = v1;\n  const [v2x, v2y, v2z] = v2;\n  return v1x * v2x + v1y * v2y + v1z * v2z;\n}\n\n// https://en.wikipedia.org/wiki/Cross_product\nfunction cross(v1: Vector, v2: Vector): Vector {\n  const [v1x, v1y, v1z] = v1;\n  const [v2x, v2y, v2z] = v2;\n  return [v1y * v2z - v1z * v2y, v1z * v2x - v1x * v2z, v1x * v2y - v1y * v2x];\n}\n\nfunction magnitude(v: Vector): number {\n  return Math.sqrt(Math.pow(v[0], 2) + Math.pow(v[1], 2) + Math.pow(v[2], 2));\n}\n\nfunction normalize(v: Vector): Vector {\n  const mag = magnitude(v);\n  return [v[0] / mag, v[1] / mag, v[2] / mag];\n}\n\nfunction lngLatToVector(a: Position): Vector {\n  const lat = degreesToRadians(a[1]);\n  const lng = degreesToRadians(a[0]);\n  return [\n    Math.cos(lat) * Math.cos(lng),\n    Math.cos(lat) * Math.sin(lng),\n    Math.sin(lat),\n  ];\n}\n\nfunction vectorToLngLat(v: Vector): Position {\n  const [x, y, z] = v;\n  // Clamp the z-value to ensure that is inside the [-1, 1] domain as required\n  // by asin. Note therefore that this function should only be applied to unit\n  // vectors so z > 1 should not exist\n  const zClamp = Math.min(Math.max(z, -1), 1);\n  const lat = radiansToDegrees(Math.asin(zClamp));\n  const lng = radiansToDegrees(Math.atan2(y, x));\n\n  return [lng, lat];\n}\n\nfunction nearestPointOnSegment(\n  posA: Position, // start point of segment to measure to\n  posB: Position, // end point of segment to measure to\n  posC: Position // point to measure from\n): [Position, boolean] {\n  // Based heavily on this article on finding cross track distance to an arc:\n  // https://gis.stackexchange.com/questions/209540/projecting-cross-track-distance-on-great-circle\n\n  // Convert spherical (lng, lat) to cartesian vector coords (x, y, z)\n  // In the below https://tikz.net/spherical_1/ we convert lng (𝜙) and lat (𝜃)\n  // into vectors with x, y, and z components with a length (r) of 1.\n  const A = lngLatToVector(posA); // the vector from 0,0,0 to posA\n  const B = lngLatToVector(posB); // ... to posB\n  const C = lngLatToVector(posC); // ... to posC\n\n  // The axis (normal vector) of the great circle plane containing the line segment\n  const segmentAxis = cross(A, B);\n\n  // Two degenerate cases exist for the segment axis cross product. The first is\n  // when vectors are aligned (within the bounds of floating point tolerance).\n  // The second is where vectors are antipodal (again within the bounds of\n  // tolerance. Both cases produce a [0, 0, 0] cross product which invalidates\n  // the rest of the algorithm, but each case must be handled separately:\n  // - The aligned case indicates coincidence of A and B. therefore this can be\n  //   an early return assuming the closest point is the end (for consistency).\n  // - The antipodal case is truly degenerate - an infinte number of great\n  //   circles are possible and one will always pass through C. However, given\n  //   that this case is both highly unlikely to occur in practice and that is\n  //   will usually be logically sound to return that the point is on the\n  //   segment, we choose to return the provided point.\n  if (segmentAxis[0] === 0 && segmentAxis[1] === 0 && segmentAxis[2] === 0) {\n    if (dot(A, B) > 0) {\n      return [[...posB], true];\n    } else {\n      return [[...posC], false];\n    }\n  }\n\n  // The axis of the great circle passing through the segment's axis and the\n  // target point\n  const targetAxis = cross(segmentAxis, C);\n\n  // This cross product also has a degenerate case where the segment axis is\n  // coincident with or antipodal to the target point. In this case the point\n  // is equidistant to the entire segment. For consistency, we early return the\n  // endpoint as the matching point.\n  if (targetAxis[0] === 0 && targetAxis[1] === 0 && targetAxis[2] === 0) {\n    return [[...posB], true];\n  }\n\n  // The line of intersection between the two great circle planes\n  const intersectionAxis = cross(targetAxis, segmentAxis);\n\n  // Vectors to the two points these great circles intersect are the normalized\n  // intersection and its antipodes\n  const I1 = normalize(intersectionAxis);\n  const I2: Vector = [-I1[0], -I1[1], -I1[2]];\n\n  // Figure out which is the closest intersection to this segment of the great circle\n  // Note that for points on a unit sphere, the dot product represents the\n  // cosine of the angle between the two vectors which monotonically increases\n  // the closer the two points are together and therefore determines proximity\n  const I = dot(C, I1) > dot(C, I2) ? I1 : I2;\n\n  // I is the closest intersection to the segment, though might not actually be\n  // ON the segment. To test whether the closest intersection lies on the arc or\n  // not, we do a cross product comparison to check rotation around the unit\n  // circle defined by the great circle plane.\n  const segmentAxisNorm = normalize(segmentAxis);\n  const cmpAI = dot(cross(A, I), segmentAxisNorm);\n  const cmpIB = dot(cross(I, B), segmentAxisNorm);\n\n  // When both comparisons are positive, the rotation from A to I to B is in the\n  // same direction, implying that I lies between A and B\n  if (cmpAI >= 0 && cmpIB >= 0) {\n    return [vectorToLngLat(I), false];\n  }\n\n  // Finally process the case where the intersection is not on the segment,\n  // using the dot product with the original point to find the closest endpoint\n  if (dot(A, C) > dot(B, C)) {\n    // Clone position when returning as it is reasonable to not expect structural\n    // sharing on the returned Position in all return cases\n    return [[...posA], false];\n  } else {\n    return [[...posB], true];\n  }\n}\n\nexport { nearestPointOnLine };\nexport default nearestPointOnLine;\n"]}