diff --git a/packages/turf-rhumb-bearing/index.ts b/packages/turf-rhumb-bearing/index.ts index c3d48ccc9..f821a31d1 100644 --- a/packages/turf-rhumb-bearing/index.ts +++ b/packages/turf-rhumb-bearing/index.ts @@ -54,6 +54,10 @@ function rhumbBearing( * var d = p1.rhumbBearingTo(p2); // 116.7 m */ function calculateRhumbBearing(from: number[], to: number[]) { + // Coincident points have no defined bearing (matches Geodesy reference impl) + if (from[0] === to[0] && from[1] === to[1]) { + return NaN; + } // φ => phi // Δλ => deltaLambda // Δψ => deltaPsi diff --git a/packages/turf-rhumb-bearing/test.ts b/packages/turf-rhumb-bearing/test.ts index 377a0c9a4..a9f40767f 100644 --- a/packages/turf-rhumb-bearing/test.ts +++ b/packages/turf-rhumb-bearing/test.ts @@ -46,6 +46,18 @@ test("bearing", (t) => { ); }); + // Coincident points have no defined bearing — must return NaN, not 0 + // Regression test for https://github.com/Turfjs/turf/issues/2478 + const coincident = point([5, 5]); + t.ok( + isNaN(rhumbBearing(coincident, coincident)), + "coincident points return NaN" + ); + t.ok( + isNaN(rhumbBearing(coincident, coincident, { final: true })), + "coincident points return NaN (final bearing)" + ); + t.throws(() => { rhumbBearing(point([12, -54]), "point"); }, "invalid point");